Skip to content

Commit

Permalink
Merge pull request #9 from wil/8-configurable-headers
Browse files Browse the repository at this point in the history
Make headers configurable in mail exporter
  • Loading branch information
nfultz authored Apr 8, 2019
2 parents 9b8bfb0 + 9a85bc4 commit 43b5a79
Showing 1 changed file with 47 additions and 31 deletions.
78 changes: 47 additions & 31 deletions nb2mail/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import smtplib
import sys

from traitlets import default, Unicode, Int
from traitlets import default, Unicode, Int, Dict
from traitlets.config import Config

from nbconvert.exporters.html import HTMLExporter
Expand Down Expand Up @@ -45,6 +45,14 @@ class MailExporter(HTMLExporter):
"""
Exports to a mail document (.mail)
"""

headers = Dict(help="Mail Headers", traits={
'from': Unicode(help="From header"),
'to': Unicode(help="Comma-separated To header"),
'cc': Unicode(help="Comma-separated Cc header"),
'subject': Unicode(help="Subject header")
}).tag(config=True)

def __init__(self, config=None, **kw):
"""
Public constructor
Expand Down Expand Up @@ -85,41 +93,45 @@ def from_notebook_node(self, nb, resources=None, **kw):

output, resources = super(MailExporter, self).from_notebook_node(nb, resources=resources, **kw)


msg = MIMEMultipart('mixed')

# Set headers from configuration values (if non-blank)
for header, val in self.headers.items():
msg[header] = val

meta = nb['metadata'].get('nb2mail')
if meta :
for header in set(meta.keys()) & {'To', 'From', 'Subject'}:
msg[header] = meta[header]
# Overrides from nb meta
meta = nb['metadata'].get('nb2mail', {})
for header in set(meta.keys()) & {'From', 'To', 'Cc', 'Subject'}:
del msg[header] # ensure that we are not adding duplicate header
msg[header] = meta[header]

# Email attachements
files = meta.get('attachments')
for fileToSend in files or []:
ctype, encoding = mimetypes.guess_type(fileToSend)
if ctype is None or encoding is not None:
ctype = "application/octet-stream"
# Use notebook name if there's no subject
if not 'Subject' in msg.keys():
msg['Subject'] = resources['metadata']['name']

maintype, subtype = ctype.split("/", 1)
mode = 'r' + ('b' if maintype != "text" else '')
# Email attachements
files = meta.get('attachments')
for fileToSend in files or []:
ctype, encoding = mimetypes.guess_type(fileToSend)
if ctype is None or encoding is not None:
ctype = "application/octet-stream"

constructors = {"text": MIMEText, "image": MIMEImage, "audio": MIMEAudio}
maintype, subtype = ctype.split("/", 1)
mode = 'r' + ('b' if maintype != "text" else '')

with open(fileToSend, mode) as fp:
if maintype in constructors:
# Note: we should handle calculating the charset for text
attachment = constructors[maintype](fp.read(), _subtype=subtype)
else:
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
encoders.encode_base64(attachment)
constructors = {"text": MIMEText, "image": MIMEImage, "audio": MIMEAudio}

attachment.add_header("Content-Disposition", "attachment", filename=fileToSend)
msg.attach(attachment)
with open(fileToSend, mode) as fp:
if maintype in constructors:
# Note: we should handle calculating the charset for text
attachment = constructors[maintype](fp.read(), _subtype=subtype)
else:
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
encoders.encode_base64(attachment)

if not 'Subject' in msg.keys():
msg['Subject'] = resources['metadata']['name']
attachment.add_header("Content-Disposition", "attachment", filename=fileToSend)
msg.attach(attachment)

msg.attach(MIMEText(output, 'html'))

Expand Down Expand Up @@ -152,11 +164,15 @@ def postprocess(self, input):

with open(input) as f:
email = Parser().parse(f)
# Set recipients from notebook metadata

if not self.recipient:
# Set recipients from .mail file
# Multiple recipients can be comma seperated
self.recipient = email.get('To', self.recipient)
f.seek(0)
self.recipient = ','.join(filter(None, [email.get('To'), email.get('Cc')]))
else:
# Set To header from config
email['To'] = self.recipient

smtpserver.sendmail(self.smtp_user, self.recipient.split(','), f.read())
smtpserver.sendmail(self.smtp_user, self.recipient.split(','), email.as_string())

smtpserver.close()

0 comments on commit 43b5a79

Please sign in to comment.