Recipe 13.6. Bundling Files in a MIME MessageCredit: Matthew Dixon Cowles, Hans Fangohr, John Pywtorak ProblemYou want to create a multipart MIME (Multipurpose Internet Mail Extensions) message that includes all files in the current directory. SolutionIf you often deal with composing or parsing mail messages, or mail-like messages such as Usenet news posts, the Python Standard Library email package gives you very powerful tools to work with. Here is a module that uses email to solve the task posed in the "Problem": #!/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 is 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 also 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.set_payload(contentsEncoded.getvalue( )) contentsEncoded.close( ) mainMsg.attach(subMsg) f = open(outputFile, "wb") g = email.Generator.Generator(f) g.flatten(mainMsg) f.close( ) return None if _ _name_ _=="_ _main_ _": main( ) DiscussionThe email package makes manipulating MIME messages a snap. The Python Standard Library also offers other older modules that can serve many of the same purposes, but I suggest you look into email as an alternative to all such other modules. email requires some study because it is a very functionally rich package, but it will amply repay the time you spend studying it. MIME is the Internet standard for sending files and non-ASCII data by email. The standard is specified in RFCs 2045-2049. A few points are especially worth keeping in mind:
Not surprisingly, given all of these issues, manipulating MIME messages is often considered to be a nuisance. In the old times, back 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 package, which was added in Python 2.2, unified and simplified these two related jobs. See AlsoRecipe 13.7 shows how the email package can be used to unpack a MIME message; documentation for the standard library modules email, mimetypes, base64, quopri, and cStringIO in the Library Reference and Python in a Nutshell. |