Credit: Matthew Dixon Cowles
If you often deal with composing or parsing mail messages, or
mail-like messages such as Usenet news posts, the new
email
module gives you sparkling new
opportunities:
#!/usr/bin/env python import base64, quopri import mimetypes, email.Generator, email.Message import cStringIO, os # sample addresses toAddr="example@example.com" fromAddr="example@example.com" outputFile="dirContentsMail" def main( ): mainMsg = email.Message.Message( ) mainMsg["To"] = toAddr mainMsg["From"] = fromAddr mainMsg["Subject"] = "Directory contents" mainMsg["Mime-version"] = "1.0" mainMsg["Content-type"] = "Multipart/mixed" mainMsg.preamble = "Mime message\n" mainMsg.epilogue = "" # to ensure that message ends with newline # Get names of plain files (not subdirectories or special files) fileNames = [f for f in os.listdir(os.curdir) if os.path.isfile(f)] for fileName in fileNames: contentType,ignored = mimetypes.guess_type(fileName) if contentType==None: # If no guess, use generic opaque type contentType = "application/octet-stream" contentsEncoded = cStringIO.StringIO( ) f = open(fileName, "rb") mainType = contentType[:contentType.find("/")] if mainType=="text": cte = "quoted-printable" quopri.encode(f, contentsEncoded, 1) # 1 to encode tabs else: cte = "base64" base64.encode(f, contentsEncoded) f.close( ) subMsg = email.Message.Message( ) subMsg.add_header("Content-type", contentType, name=fileName) subMsg.add_header("Content-transfer-encoding", cte) subMsg.add_payload(contentsEncoded.getvalue( )) contentsEncoded.close( ) mainMsg.add_payload(subMsg) f = open(outputFile,"wb") g = email.Generator.Generator(f) g(mainMsg) f.close( ) return None if _ _name_ _=="_ _main_ _": main( )
The email
module, new in Python 2.2, makes
manipulating MIME messages easier than it used to be (with the
standard Python library modules already present in Python 2.1 and
earlier). This is not a trivial point, so this
recipe’s example may be useful. See the standard
Library Reference for detailed documentation
about the email
module.
MIME (Multipurpose Internet Mail Extensions) is the Internet standard for sending files and non-ASCII data by email. The standard is specified in RFCs 2045-2049. There are a few points that are especially worth keeping in mind:
The original specification for the format of an email (RFC 822) didn’t allow for non-ASCII characters and had no provision for attaching or enclosing a file along with a text message. Therefore, not surprisingly, MIME messages are very common these days.
Messages that follow the MIME standard are backward-compatible with ordinary RFC 822 (now RFC 2822) messages. A mail reader that doesn’t understand the MIME specification will probably not be able to display a MIME message in a way that’s useful to the user, but the message will be legal and therefore shouldn’t cause unexpected behavior.
An RFC 2822 message consists of a set of headers, a blank line, and a body. MIME handles attachments and other multipart documents by specifying a format for the message’s body. In multipart MIME messages, the body is divided into submessages, each of which has a set of headers, a blank line, and a body. Generally, each submessage is referred to a MIME part, and parts may nest recursively.
MIME parts (whether in a multipart message or not) that contain characters outside of the strict US-ASCII range are encoded as either base-64 or quoted-printable data, so that the resulting mail message contains only ordinary ASCII characters. Data can be encoded with either method, but generally, only data that has few non-ASCII characters (basically text, possibly with a few extra characters outside of the ASCII range, such as national characters in Latin-1 and similar codes) is worth encoding as quoted-printable, because even without decoding it may be readable. If the data is essentially binary, with all bytes being equally likely, base-64 encoding is more compact.
Not surprisingly, given all that, manipulating MIME messages is often
considered to be a nuisance. Before Python 2.2, the standard
library’s modules for dealing with MIME messages
were quite useful but rather miscellaneous. In particular, putting
MIME messages together and taking them apart required two distinct
approaches. The email
module, new in Python 2.2,
unifies and simplifies these two related jobs.
Recipe 10.12 shows how the
email
module can be used to unpack a MIME message;
documentation for the standard library modules
email
, smtplib
,
mimetypes
, base64
,
quopri
, and cStringIO
in the
Library Reference. attachments.
Get Python Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.