Created
March 14, 2012 00:48
-
-
Save reedobrien/2033059 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import smtplib | |
from email.header import Header | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.text import MIMEText | |
from html2text import html2text | |
def get_encoding(unicode_text): | |
""" | |
Guess the charset and return it | |
""" | |
for charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': | |
try: | |
unicode_text.encode(charset) | |
return charset | |
except UnicodeError: | |
pass | |
else: | |
break | |
class Emailer(object): | |
""" | |
:param html: the html for the body of the message with {} string formatting | |
:param text: the text for the body of the message with {} string formatting | |
:param from_addr: the MUA visible from address i.e. the default | |
u"MYORG <[email protected]>" | |
:param listid: the list-id. Default: u'MYORG Notifications <notifications.MYORG.net>' | |
:param recipients: a list of recipients. Default: [] | |
:param sender: the smtp sender for MAIL FROM command Default: | |
u"[email protected]" | |
:param server: the server to connect to for sending mail Default: | |
u'localhost' | |
:param smtplib: the smtplib library to use. Here to pass in a dummy for testing. | |
:param subject: the subject line. Default: u"MYORG Email Update" | |
""" | |
def __init__(self, | |
html, | |
coll, | |
text=None, | |
from_addr=u"MYORG <[email protected]>", | |
listid=u'<notifications.MYORG.net>', | |
recipients=[], | |
sender=u"[email protected]", | |
server=u'abadina.MYORG.org', | |
smtplib=smtplib, | |
subject=u"MYORG Email Update", | |
): | |
self.html = unicode(html) | |
self.text = unicode(text) if text else None | |
self.from_addr = from_addr | |
self.listid = listid | |
self.recipients = recipients | |
self.receivers = [] # like ["[email protected]", ] | |
self.server = smtplib.SMTP(server) | |
self.sender = sender | |
self.subject = subject | |
self.coll = coll | |
def add_recipient(self, userdata): | |
""" | |
:param userdata: a dict structure with the necessary data for | |
the format substitution in the current mailer. It should also | |
have the "_id" and "email". | |
""" | |
self.recipients.append(userdata) | |
def add_bcc(self, bcc_address): | |
""" | |
:param bcc_address: an email address to add to bcc. | |
""" | |
self.receivers.append(bcc_address) | |
def send(self): | |
try: | |
for userdata in self.recipients: | |
html_message = self.html.format(userdata) | |
if self.text is None: | |
text_message = html2text(html_message) | |
else: | |
text_message = self.text.format(userdata) | |
msg_receivers = self.receivers + [userdata['email'], ] | |
print msg_receivers | |
# get engoding since we don't know who has | |
# funny characters | |
body_text_encoding = get_encoding(text_message) | |
body_html_encoding = get_encoding(html_message) | |
# Set up the message instance | |
msg = MIMEMultipart('alternative') | |
## Headers | |
msg['From'] = self.from_addr | |
msg['Subject'] = self.subject | |
# check for international names and encode accordingly | |
todata = u'{0[first_name]} {0[last_name]} <{0[email]}>'.format( | |
userdata).strip() | |
todata_encoding = get_encoding(todata) | |
to = Header(todata.encode(todata_encoding), todata_encoding) | |
msg['To'] = to | |
## Add headers for easy back-reference | |
msg['X-MYORG-Recipient'] = userdata['email'] | |
msg['X-MYORG-User'] = self.sender | |
msg['List-ID'] = self.listid | |
# Record the MIME types of both parts - text/plain and text/html. | |
text_part = MIMEText(text_message.encode(body_text_encoding), 'plain', | |
body_text_encoding) | |
html_part = MIMEText(html_message.encode(body_html_encoding), 'html', | |
body_html_encoding) | |
# Attach parts into message container. | |
# According to RFC 2046, the last part of a multipart message, in this case | |
# the HTML message, is best and preferred. | |
msg.attach(text_part) | |
msg.attach(html_part) | |
# sendmail function takes 3 arguments: sender's address, recipient's address | |
# and message to send - here it is sent as one string. | |
try: | |
self.server.sendmail(self.sender, | |
msg_receivers, | |
msg.as_string()) | |
userdata['sent'] = True | |
userdata['subject'] = self.subject | |
self.coll.save(userdata) | |
except Exception, e: | |
pass # handle exception | |
except Exception, e: | |
print e | |
def quit(self): | |
self.server.quit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment