def __buildemail(self): i = 0 soup = BeautifulSoup(self.mail_template.text, "html.parser") imgs = [] for img in soup.findAll("img"): if not img.has_attr( "src") or not img["src"][:5].lower() == "data:": continue tmp = img["src"].split(',') if len(tmp) > 1: base64 = tmp[1] mime = tmp[0].split(';')[0].split(':')[1] mimeimg = MIMEImage(b64decode(base64)) mimeimg.set_type(mime) mimeimg.add_header('Content-ID', '<img%s>' % i) imgs.append(mimeimg) img["src"] = "cid:img%s" % i if "style" in img: styles = img["style"].split(";") height = 0 width = 0 for style in styles: if "height" in style: tmp = style.split(":")[1].replace("px", "") height = str(int(tmp) * 75 / 100) if "width" in style: tmp = style.split(":")[1].replace("px", "") width = str(int(tmp) * 75 / 100) if height != 0: img["height"] = height if width != 0: img["width"] = width i += 1 if self.enable_mail_tracker: if not soup.findAll("img", attrs={"src": "FIXMEMAILTRACKER"}): img = soup.new_tag("img", src="FIXMEMAILTRACKER") soup.body.append(img) return {"text": str(soup), "imgs": imgs}
def html_email(from_='', to=[], cc=None, bcc=None, subject='', text_body='', html_body='', files=None, images=[], smtp_server='', smtp_port=25, smtp_username='', smtp_password=''): """ Generate a HTML email and send it to various recipients via an authenticated SMTP server. +-------------------------------------------------------+ | multipart/mixed | | | | +-------------------------------------------------+ | | | multipart/related | | | | | | | | +-------------------------------------------+ | | | | | multipart/alternative | | | | | | | | | | | | +-------------------------------------+ | | | | | | | text can contain [cid:logo.png] | | | | | | | +-------------------------------------+ | | | | | | | | | | | | +-------------------------------------+ | | | | | | | html can contain src="cid:logo.png" | | | | | | | +-------------------------------------+ | | | | | | | | | | | +-------------------------------------------+ | | | | | | | | +-------------------------------------------+ | | | | | image logo.png "inline" attachement | | | | | +-------------------------------------------+ | | | | | | | +-------------------------------------------------+ | | | | +-------------------------------------------------+ | | | pdf ("download" attachment, not inline) | | | +-------------------------------------------------+ | | | +-------------------------------------------------------+ see: https://www.anomaly.net.au/blog/constructing-multipart-mime-messages-for-sending-emails-in-python/ """ message = MIMEMultipart('mixed') del message['sender'] del message['errors-to'] message['To'] = COMMASPACE.join(to) if cc: message['Cc'] = COMMASPACE.join(cc) message['From'] = from_ message['Subject'] = subject message['Date'] = formatdate(localtime=True) message['Message-ID'] = make_msgid() message.epilogue = '' body = MIMEMultipart('alternative') text_part = MIMEText(text_body, 'plain') # text_part.set_type('text/plain') # text_part.set_charset('iso-8859-1') # text_part.replace_header('Content-Transfer-Encoding', 'quoted-printable') body.attach(text_part) html_part = MIMEText(html_body, 'html') body.attach(html_part) related = MIMEMultipart('related') related.attach(body) for count, image in enumerate(images, 1): if isinstance(image, basestring): with open(image, 'rb') as image_file: image_data = image_file.read() image_part = MIMEImage(image_data) image_filename = os.path.basename(image) elif isinstance(image, (tuple)): image_part = MIMEImage(image[1]) image_filename = image[0] mime_type = mimetypes.guess_type(image_filename)[0] if mime_type: image_part.set_type(mime_type) image_part.add_header('Content-Location', image_filename) image_part.add_header('Content-Disposition', 'inline', filename=image_filename) image_part.add_header('Content-ID', '<image{}>'.format(count)) related.attach(image_part) message.attach(related) if files: for attachment in files: part = MIMEBase( 'application', 'octet-stream') # 'octet-stream' filtered by MS Exchange. with open(attachment, 'rb') as attachment_file: attachment_data = attachment_file.read() mime_type = mimetypes.guess_type(attachment)[0] if mime_type: part.set_type(mime_type) part.set_payload(attachment_data) encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attachment)) message.attach(part) smtp = smtplib.SMTP(smtp_server, smtp_port) smtp.ehlo() smtp.starttls() if smtp_username: smtp.login(smtp_username, smtp_password) if cc: to += cc if bcc: to += bcc smtp.sendmail(from_, to, message.as_string()) smtp.quit()