def copy_mime_root(msg, strip_content=True): """Make a copy of the non_payload root mime part of msg and change content type to multipart/alternativ. By default drop old Content- headers. """ msg_new = MIMEMultipart() # drop default keys for k in msg_new.keys(): del msg_new[k] # make copy of old header for k, v in msg.items(): if strip_content and k.startswith('Content-'): continue msg_new[k] = v if msg.get_unixfrom(): msg_new.set_unixfrom(msg.get_unixfrom()) if msg.preamble: msg_new.preamble = msg.preamble else: msg_new.preamble = "This is a multi-part message in MIME format...\n" if msg.epilogue: msg_new.epilogue = msg.epilogue # set msg_new type msg_new.set_type('multipart/alternative') return msg_new
def _mail_recipient(recipient_name, recipient_email, sender_name, sender_url, subject, body, body_html=None, headers=None): if not headers: headers = {} mail_from = config.get('smtp.mail_from') reply_to = config.get('smtp.reply_to') if body_html: # multipart msg = MIMEMultipart('alternative') part1 = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') part2 = MIMEText(body_html.encode('utf-8'), 'html', 'utf-8') msg.attach(part1) msg.attach(part2) else: # just plain text msg = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') for k, v in headers.items(): if k in msg.keys(): msg.replace_header(k, v) else: msg.add_header(k, v) subject = Header(subject.encode('utf-8'), 'utf-8') msg['Subject'] = subject msg['From'] = _("%s <%s>") % (sender_name, mail_from) recipient = u"%s <%s>" % (recipient_name, recipient_email) msg['To'] = Header(recipient, 'utf-8') msg['Date'] = utils.formatdate(time()) msg['X-Mailer'] = "CKAN %s" % ckan.__version__ if reply_to and reply_to != '': msg['Reply-to'] = reply_to _mail_payload(msg, mail_from, recipient_email)
def from_notebook_node(self, nb, resources=None, **kw): output, resources = super(MailExporter, self).from_notebook_node(nb, resources=resources, **kw) msg = MIMEMultipart('mixed') meta = nb['metadata'].get('nb2mail') if meta: for header in set(meta.keys()) & {'To', 'From', 'Subject'}: 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" maintype, subtype = ctype.split("/", 1) mode = 'r' + ('b' if maintype != "text" else '') constructors = { "text": MIMEText, "image": MIMEImage, "audio": MIMEAudio } 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) attachment.add_header("Content-Disposition", "attachment", filename=fileToSend) msg.attach(attachment) if not 'Subject' in msg.keys(): msg['Subject'] = resources['metadata']['name'] msg.attach(MIMEText(output, 'html')) if 'attach_data' in resources['metadata']: for id, img in resources['metadata']['attach_data'].items(): img = MIMEImage(img) img.add_header('Content-ID', '<%s>' % id) msg.attach(img) output = msg.as_string() return output, resources
def _mail_recipient(recipient_name, recipient_email, sender_name, sender_url, subject, body, body_html=None, headers=None): if not headers: headers = {} mail_from = config.get('smtp.mail_from') reply_to = config.get('smtp.reply_to') if body_html: # multipart msg = MIMEMultipart('alternative') part1 = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') part2 = MIMEText(body_html.encode('utf-8'), 'html', 'utf-8') msg.attach(part1) msg.attach(part2) else: # just plain text msg = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') for k, v in headers.items(): if k in msg.keys(): msg.replace_header(k, v) else: msg.add_header(k, v) subject = Header(subject.encode('utf-8'), 'utf-8') msg['Subject'] = subject msg['From'] = _("%s <%s>") % (sender_name, mail_from) msg['To'] = u"%s <%s>" % (recipient_name, recipient_email) msg['Date'] = utils.formatdate(time()) msg['X-Mailer'] = "CKAN %s" % ckan.__version__ if reply_to and reply_to != '': msg['Reply-to'] = reply_to # Send the email using Python's smtplib. if 'smtp.test_server' in config: # If 'smtp.test_server' is configured we assume we're running tests, # and don't use the smtp.server, starttls, user, password etc. options. smtp_server = config['smtp.test_server'] smtp_starttls = False smtp_user = None smtp_password = None else: smtp_server = config.get('smtp.server', 'localhost') smtp_starttls = ckan.common.asbool( config.get('smtp.starttls')) smtp_user = config.get('smtp.user') smtp_password = config.get('smtp.password') try: smtp_connection = smtplib.SMTP(smtp_server) except (socket.error, smtplib.SMTPConnectError) as e: log.exception(e) raise MailerException('SMTP server could not be connected to: "%s" %s' % (smtp_server, e)) try: # Identify ourselves and prompt the server for supported features. smtp_connection.ehlo() # If 'smtp.starttls' is on in CKAN config, try to put the SMTP # connection into TLS mode. if smtp_starttls: if smtp_connection.has_extn('STARTTLS'): smtp_connection.starttls() # Re-identify ourselves over TLS connection. smtp_connection.ehlo() else: raise MailerException("SMTP server does not support STARTTLS") # If 'smtp.user' is in CKAN config, try to login to SMTP server. if smtp_user: assert smtp_password, ("If smtp.user is configured then " "smtp.password must be configured as well.") smtp_connection.login(smtp_user, smtp_password) smtp_connection.sendmail(mail_from, [recipient_email], msg.as_string()) log.info("Sent email to {0}".format(recipient_email)) except smtplib.SMTPException as e: msg = '%r' % e log.exception(msg) raise MailerException(msg) finally: smtp_connection.quit()