""" Simple module to ease the task of sending out a simple email message with MIME attachments from Python. The code is based on ideas from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52243 and http://sourceforge.net/snippet/detail.php?type=snippet&id=100444 Prabhu Ramachandran """ import sys, os, time import smtplib, MimeWriter, base64, StringIO, mimetypes class MailMsgError(Exception): pass class MailMsg: """Simple class that makes it easy to send a multipart email message with text and base 64 encoded attachments. """ def __init__(self, from_=None, subject='No Subject'): """ The constructor. Arguments: from_ -- The From header. Defaults to None. subject -- The subject header of the email. Defaults to 'No Subject' """ self.finished = 0 self.msg = StringIO.StringIO() self.writer = MimeWriter.MimeWriter(self.msg) if from_: self.writer.addheader('From', from_) t_str = time.strftime ("%a %b %e %H:%M:%S %Z %Y", time.localtime()) self.writer.addheader('Date', t_str) self.writer.addheader('Subject', subject) self.writer.addheader('MIME-Version', '1.0') body = self.writer.startmultipartbody('mixed') body.write("This is a multi-part message in MIME format.\n") def addText(self, txt): """When passed an argument containing the text adds a text/plain body to the message containing the text. Arguments: txt -- text to be sent. """ part = self.writer.nextpart() body = part.startbody('text/plain') body.write(txt + '\n') def addHtml(self, html_txt): """When passed an argument containing the text adds a text/html body to the message containing the text. Arguments: html_txt -- HTML text to be attached. """ part = self.writer.nextpart() part.addheader("Content-Transfer-Encoding","8bit") body = part.startbody("text/html", [("charset","iso-8859-1")]) body.write(html_txt + "\n") def addAttachment(self, file_name): """ Encodes file pointed to by the passed file name using base64 encoding and attaches a mime body with the contents of the file. Arguments: file_name -- Name of file to be attached. """ if not os.path.isfile(file_name): msg = "Specified file %s does not exist!"%file_name raise MailMsgError, msg type = mimetypes.guess_type(file_name) if type[0] is None: msg = "Sorry unable to determine mime type of file: "\ "%s"%file_name raise MailMsgError, msg part = self.writer.nextpart() part.addheader('Content-Transfer-Encoding', 'base64') hdr = "%s; name=%s"%(type[0], os.path.basename(file_name)) body = part.startbody(hdr) base64.encode(open(file_name, 'rb'), body) def finish(self): """Finish the email. This function must be called before you can send the message out.""" self.writer.lastpart() self.finished = 1 def mail(self, from_addr, to_addrs, host='localhost', port=0, mail_options=[], rcpt_options=[]): """This command sends the message out using SMTP. The arguments are: - from_addr : The address sending this mail. - to_addrs : A list of addresses to send this mail to. A bare string will be treated as a list with 1 address. - host : The SMTP host to connect to - defaults to localhost. - port : The port where the mailer is listening - defaults to 0 (which should work). - mail_options : List of ESMTP options (such as 8bitmime) for the mail command. - rcpt_options : List of ESMTP options (such as DSN commands) for all the rcpt commands. """ if not self.finished: self.finish() smtp = smtplib.SMTP(host, port) smtp.sendmail(from_addr, to_addrs, self.msg.getvalue(), mail_options, rcpt_options) smtp.quit()