blob: c80305f7e0ebc73d40cb7e5453f787b335de1768 [file] [log] [blame]
Barry Warsaw5b9da892002-10-01 01:05:52 +00001% Copyright (C) 2001,2002 Python Software Foundation
Barry Warsaw5e634632001-09-26 05:23:47 +00002% Author: barry@zope.com (Barry Warsaw)
3
Fred Drakea6a885b2001-09-26 16:52:18 +00004\section{\module{email} ---
Barry Warsaw5e634632001-09-26 05:23:47 +00005 An email and MIME handling package}
6
7\declaremodule{standard}{email}
8\modulesynopsis{Package supporting the parsing, manipulating, and
9 generating email messages, including MIME documents.}
10\moduleauthor{Barry A. Warsaw}{barry@zope.com}
Fred Drake90e68782001-09-27 20:09:39 +000011\sectionauthor{Barry A. Warsaw}{barry@zope.com}
Barry Warsaw5e634632001-09-26 05:23:47 +000012
13\versionadded{2.2}
14
15The \module{email} package is a library for managing email messages,
16including MIME and other \rfc{2822}-based message documents. It
17subsumes most of the functionality in several older standard modules
Barry Warsawc5f8fe32001-09-26 22:21:52 +000018such as \refmodule{rfc822}, \refmodule{mimetools},
19\refmodule{multifile}, and other non-standard packages such as
Barry Warsaw5e17d202001-11-16 22:16:04 +000020\module{mimecntl}. It is specifically \emph{not} designed to do any
21sending of email messages to SMTP (\rfc{2821}) servers; that is the
Barry Warsaw5b9da892002-10-01 01:05:52 +000022function of the \refmodule{smtplib} module. The \module{email}
23package attempts to be as RFC-compliant as possible, supporting in
24addition to \rfc{2822}, such MIME-related RFCs as
25\rfc{2045}-\rfc{2047}, and \rfc{2231}.
Barry Warsaw5e634632001-09-26 05:23:47 +000026
27The primary distinguishing feature of the \module{email} package is
28that it splits the parsing and generating of email messages from the
29internal \emph{object model} representation of email. Applications
30using the \module{email} package deal primarily with objects; you can
31add sub-objects to messages, remove sub-objects from messages,
32completely re-arrange the contents, etc. There is a separate parser
33and a separate generator which handles the transformation from flat
Andrew M. Kuchling43dc1fc2001-11-05 01:55:03 +000034text to the object model, and then back to flat text again. There
Barry Warsaw5e634632001-09-26 05:23:47 +000035are also handy subclasses for some common MIME object types, and a few
36miscellaneous utilities that help with such common tasks as extracting
37and parsing message field values, creating RFC-compliant dates, etc.
38
39The following sections describe the functionality of the
40\module{email} package. The ordering follows a progression that
41should be common in applications: an email message is read as flat
Barry Warsaw5db478f2002-10-01 04:33:16 +000042text from a file or other source, the text is parsed to produce the
43object structure of the email message, this structure is manipulated,
44and finally rendered back into flat text.
Barry Warsaw5e634632001-09-26 05:23:47 +000045
Barry Warsaw5db478f2002-10-01 04:33:16 +000046It is perfectly feasible to create the object structure out of whole
47cloth --- i.e. completely from scratch. From there, a similar
48progression can be taken as above.
Barry Warsaw5e634632001-09-26 05:23:47 +000049
50Also included are detailed specifications of all the classes and
51modules that the \module{email} package provides, the exception
52classes you might encounter while using the \module{email} package,
53some auxiliary utilities, and a few examples. For users of the older
Barry Warsaw5b9da892002-10-01 01:05:52 +000054\module{mimelib} package, or previous versions of the \module{email}
55package, a section on differences and porting is provided.
Barry Warsaw5e634632001-09-26 05:23:47 +000056
Barry Warsaw5e17d202001-11-16 22:16:04 +000057\begin{seealso}
58 \seemodule{smtplib}{SMTP protocol client}
59\end{seealso}
60
Barry Warsaw5e634632001-09-26 05:23:47 +000061\subsection{Representing an email message}
Barry Warsawc5f8fe32001-09-26 22:21:52 +000062\input{emailmessage}
Barry Warsaw5e634632001-09-26 05:23:47 +000063
64\subsection{Parsing email messages}
Barry Warsawc5f8fe32001-09-26 22:21:52 +000065\input{emailparser}
Barry Warsaw5e634632001-09-26 05:23:47 +000066
67\subsection{Generating MIME documents}
Barry Warsawc5f8fe32001-09-26 22:21:52 +000068\input{emailgenerator}
Barry Warsaw5e634632001-09-26 05:23:47 +000069
70\subsection{Creating email and MIME objects from scratch}
Barry Warsaw5b9da892002-10-01 01:05:52 +000071\input{emailmimebase}
Barry Warsaw5e634632001-09-26 05:23:47 +000072
Barry Warsaw5db478f2002-10-01 04:33:16 +000073\subsection{Internationalized headers}
Barry Warsaw5b9da892002-10-01 01:05:52 +000074\input{emailheaders}
Barry Warsaw5e634632001-09-26 05:23:47 +000075
Barry Warsaw5db478f2002-10-01 04:33:16 +000076\subsection{Representing character sets}
77\input{emailcharsets}
78
Barry Warsawc5f8fe32001-09-26 22:21:52 +000079\subsection{Encoders}
80\input{emailencoders}
Barry Warsaw5e634632001-09-26 05:23:47 +000081
Barry Warsawc5f8fe32001-09-26 22:21:52 +000082\subsection{Exception classes}
83\input{emailexc}
Barry Warsaw5e634632001-09-26 05:23:47 +000084
Barry Warsawc5f8fe32001-09-26 22:21:52 +000085\subsection{Miscellaneous utilities}
86\input{emailutil}
Barry Warsaw5e634632001-09-26 05:23:47 +000087
Barry Warsawc5f8fe32001-09-26 22:21:52 +000088\subsection{Iterators}
89\input{emailiter}
Barry Warsaw5e634632001-09-26 05:23:47 +000090
Barry Warsaw5b9da892002-10-01 01:05:52 +000091\subsection{Differences from \module{email} v1 (up to Python 2.2.1)}
92
93Version 1 of the \module{email} package was bundled with Python
94releases up to Python 2.2.1. Version 2 was developed for the Python
952.3 release, and backported to Python 2.2.2. It was also available as
96a separate distutils based package. \module{email} version 2 is
Barry Warsaw5db478f2002-10-01 04:33:16 +000097almost entirely backward compatible with version 1, with the
Barry Warsaw5b9da892002-10-01 01:05:52 +000098following differences:
99
100\begin{itemize}
101\item The \module{email.Header} and \module{email.Charset} modules
102 have been added.
103\item The pickle format for \class{Message} instances has changed.
104 Since this was never (and still isn't) formally defined, this
Barry Warsaw5db478f2002-10-01 04:33:16 +0000105 isn't considered a backward incompatibility. However if your
Barry Warsaw5b9da892002-10-01 01:05:52 +0000106 application pickles and unpickles \class{Message} instances, be
107 aware that in \module{email} version 2, \class{Message}
108 instances now have private variables \var{_charset} and
109 \var{_default_type}.
110\item Several methods in the \class{Message} class have been
Barry Warsaw5db478f2002-10-01 04:33:16 +0000111 deprecated, or their signatures changed. Also, many new methods
Barry Warsaw5b9da892002-10-01 01:05:52 +0000112 have been added. See the documentation for the \class{Message}
Barry Warsaw5db478f2002-10-01 04:33:16 +0000113 class for details. The changes should be completely backward
Barry Warsaw5b9da892002-10-01 01:05:52 +0000114 compatible.
115\item The object structure has changed in the face of
116 \mimetype{message/rfc822} content types. In \module{email}
117 version 1, such a type would be represented by a scalar payload,
118 i.e. the container message's \method{is_multipart()} returned
Barry Warsaw5db478f2002-10-01 04:33:16 +0000119 false, \method{get_payload()} was not a list object, but a single
120 \class{Message} instance.
Barry Warsaw5b9da892002-10-01 01:05:52 +0000121
122 This structure was inconsistent with the rest of the package, so
123 the object representation for \mimetype{message/rfc822} content
Barry Warsaw5db478f2002-10-01 04:33:16 +0000124 types was changed. In \module{email} version 2, the container
Barry Warsaw5b9da892002-10-01 01:05:52 +0000125 \emph{does} return \code{True} from \method{is_multipart()}, and
126 \method{get_payload()} returns a list containing a single
127 \class{Message} item.
128
Barry Warsaw5db478f2002-10-01 04:33:16 +0000129 Note that this is one place that backward compatibility could
Barry Warsaw5b9da892002-10-01 01:05:52 +0000130 not be completely maintained. However, if you're already
131 testing the return type of \method{get_payload()}, you should be
132 fine. You just need to make sure your code doesn't do a
133 \method{set_payload()} with a \class{Message} instance on a
134 container with a content type of \mimetype{message/rfc822}.
135\item The \class{Parser} constructor's \var{strict} argument was
136 added, and its \method{parse()} and \method{parsestr()} methods
137 grew a \var{headersonly} argument. The \var{strict} flag was
138 also added to functions \function{email.message_from_file()}
139 and \function{email.message_from_string()}.
140\item \method{Generator.__call__()} is deprecated; use
141 \method{Generator.flatten()} instead. The \class{Generator}
142 class has also grown the \method{clone()} method.
143\item The \class{DecodedGenerator} class in the
144 \module{email.Generator} module was added.
145\item The intermediate base classes \class{MIMENonMultipart} and
146 \class{MIMEMultipart} have been added, and interposed in the
Barry Warsaw5db478f2002-10-01 04:33:16 +0000147 class hierarchy for most of the other MIME-related derived
Barry Warsaw5b9da892002-10-01 01:05:52 +0000148 classes.
149\item The \var{_encoder} argument to the \class{MIMEText} constructor
150 has been deprecated. Encoding now happens implicitly based
151 on the \var{_charset} argument.
152\item The following functions in the \module{email.Utils} module have
153 been deprecated: \function{dump_address_pairs()},
154 \function{decode()}, and \function{encode()}. The following
155 functions have been added to the module:
156 \function{make_msgid()}, \function{decode_rfc2231()},
157 \function{encode_rfc2231()}, and \function{decode_params()}.
158\item The non-public function \function{email.Iterators._structure()}
159 was added.
160\end{itemize}
161
Barry Warsaw5e634632001-09-26 05:23:47 +0000162\subsection{Differences from \module{mimelib}}
163
164The \module{email} package was originally prototyped as a separate
Barry Warsawc5f8fe32001-09-26 22:21:52 +0000165library called
166\ulink{\module{mimelib}}{http://mimelib.sf.net/}.
167Changes have been made so that
Barry Warsaw5e634632001-09-26 05:23:47 +0000168method names are more consistent, and some methods or modules have
169either been added or removed. The semantics of some of the methods
170have also changed. For the most part, any functionality available in
Fred Drake90e68782001-09-27 20:09:39 +0000171\module{mimelib} is still available in the \refmodule{email} package,
Barry Warsaw5db478f2002-10-01 04:33:16 +0000172albeit often in a different way. Backward compatibility between
173the \module{mimelib} package and the \module{email} package was not a
174priority.
Barry Warsaw5e634632001-09-26 05:23:47 +0000175
176Here is a brief description of the differences between the
Fred Drake90e68782001-09-27 20:09:39 +0000177\module{mimelib} and the \refmodule{email} packages, along with hints on
Barry Warsaw5e634632001-09-26 05:23:47 +0000178how to port your applications.
179
180Of course, the most visible difference between the two packages is
Fred Drake90e68782001-09-27 20:09:39 +0000181that the package name has been changed to \refmodule{email}. In
Barry Warsaw5e634632001-09-26 05:23:47 +0000182addition, the top-level package has the following differences:
183
184\begin{itemize}
185\item \function{messageFromString()} has been renamed to
186 \function{message_from_string()}.
187\item \function{messageFromFile()} has been renamed to
188 \function{message_from_file()}.
189\end{itemize}
190
191The \class{Message} class has the following differences:
192
193\begin{itemize}
194\item The method \method{asString()} was renamed to \method{as_string()}.
195\item The method \method{ismultipart()} was renamed to
196 \method{is_multipart()}.
197\item The \method{get_payload()} method has grown a \var{decode}
198 optional argument.
199\item The method \method{getall()} was renamed to \method{get_all()}.
200\item The method \method{addheader()} was renamed to \method{add_header()}.
201\item The method \method{gettype()} was renamed to \method{get_type()}.
202\item The method\method{getmaintype()} was renamed to
203 \method{get_main_type()}.
204\item The method \method{getsubtype()} was renamed to
205 \method{get_subtype()}.
206\item The method \method{getparams()} was renamed to
207 \method{get_params()}.
208 Also, whereas \method{getparams()} returned a list of strings,
209 \method{get_params()} returns a list of 2-tuples, effectively
Barry Warsawc5f8fe32001-09-26 22:21:52 +0000210 the key/value pairs of the parameters, split on the \character{=}
Barry Warsaw5e634632001-09-26 05:23:47 +0000211 sign.
212\item The method \method{getparam()} was renamed to \method{get_param()}.
213\item The method \method{getcharsets()} was renamed to
214 \method{get_charsets()}.
215\item The method \method{getfilename()} was renamed to
216 \method{get_filename()}.
217\item The method \method{getboundary()} was renamed to
218 \method{get_boundary()}.
219\item The method \method{setboundary()} was renamed to
220 \method{set_boundary()}.
221\item The method \method{getdecodedpayload()} was removed. To get
222 similar functionality, pass the value 1 to the \var{decode} flag
223 of the {get_payload()} method.
224\item The method \method{getpayloadastext()} was removed. Similar
225 functionality
226 is supported by the \class{DecodedGenerator} class in the
227 \refmodule{email.Generator} module.
228\item The method \method{getbodyastext()} was removed. You can get
229 similar functionality by creating an iterator with
230 \function{typed_subpart_iterator()} in the
231 \refmodule{email.Iterators} module.
232\end{itemize}
233
234The \class{Parser} class has no differences in its public interface.
235It does have some additional smarts to recognize
Fred Drakea6a885b2001-09-26 16:52:18 +0000236\mimetype{message/delivery-status} type messages, which it represents as
Barry Warsaw5e634632001-09-26 05:23:47 +0000237a \class{Message} instance containing separate \class{Message}
238subparts for each header block in the delivery status
239notification\footnote{Delivery Status Notifications (DSN) are defined
Fred Drake90e68782001-09-27 20:09:39 +0000240in \rfc{1894}.}.
Barry Warsaw5e634632001-09-26 05:23:47 +0000241
242The \class{Generator} class has no differences in its public
243interface. There is a new class in the \refmodule{email.Generator}
244module though, called \class{DecodedGenerator} which provides most of
245the functionality previously available in the
246\method{Message.getpayloadastext()} method.
247
248The following modules and classes have been changed:
249
250\begin{itemize}
251\item The \class{MIMEBase} class constructor arguments \var{_major}
252 and \var{_minor} have changed to \var{_maintype} and
253 \var{_subtype} respectively.
254\item The \code{Image} class/module has been renamed to
255 \code{MIMEImage}. The \var{_minor} argument has been renamed to
256 \var{_subtype}.
257\item The \code{Text} class/module has been renamed to
258 \code{MIMEText}. The \var{_minor} argument has been renamed to
259 \var{_subtype}.
260\item The \code{MessageRFC822} class/module has been renamed to
261 \code{MIMEMessage}. Note that an earlier version of
262 \module{mimelib} called this class/module \code{RFC822}, but
263 that clashed with the Python standard library module
264 \refmodule{rfc822} on some case-insensitive file systems.
265
266 Also, the \class{MIMEMessage} class now represents any kind of
Fred Drakea6a885b2001-09-26 16:52:18 +0000267 MIME message with main type \mimetype{message}. It takes an
Barry Warsaw5e634632001-09-26 05:23:47 +0000268 optional argument \var{_subtype} which is used to set the MIME
Fred Drakea6a885b2001-09-26 16:52:18 +0000269 subtype. \var{_subtype} defaults to \mimetype{rfc822}.
Barry Warsaw5e634632001-09-26 05:23:47 +0000270\end{itemize}
271
272\module{mimelib} provided some utility functions in its
273\module{address} and \module{date} modules. All of these functions
274have been moved to the \refmodule{email.Utils} module.
275
276The \code{MsgReader} class/module has been removed. Its functionality
277is most closely supported in the \function{body_line_iterator()}
278function in the \refmodule{email.Iterators} module.
279
280\subsection{Examples}
281
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000282Here are a few examples of how to use the \module{email} package to
283read, write, and send simple email messages, as well as more complex
284MIME messages.
285
286First, let's see how to create and send a simple text message:
287
288\begin{verbatim}
289# Import smtplib for the actual sending function
290import smtplib
291
Barry Warsawea66abc2002-10-01 04:48:06 +0000292# Import the email modules we'll need
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000293from email.MIMEText import MIMEText
294
Barry Warsawea66abc2002-10-01 04:48:06 +0000295# Open a plain text file for reading. For this example, assume that
296# the text file contains only ASCII characters.
297fp = open(textfile, 'rb')
298# Create a text/plain message
299msg = MIMEText(fp.read())
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000300fp.close()
301
302# me == the sender's email address
303# you == the recipient's email address
Fred Drake928051f2002-02-15 04:12:59 +0000304msg['Subject'] = 'The contents of %s' % textfile
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000305msg['From'] = me
306msg['To'] = you
307
Barry Warsawea66abc2002-10-01 04:48:06 +0000308# Send the message via our own SMTP server, but don't include the
309# envelope header.
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000310s = smtplib.SMTP()
311s.connect()
Barry Warsawea66abc2002-10-01 04:48:06 +0000312s.sendmail(me, [you], msg.as_string())
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000313s.close()
314\end{verbatim}
315
316Here's an example of how to send a MIME message containing a bunch of
Barry Warsawea66abc2002-10-01 04:48:06 +0000317family pictures that may be residing in a directory:
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000318
319\begin{verbatim}
320# Import smtplib for the actual sending function
321import smtplib
322
323# Here are the email pacakge modules we'll need
324from email.MIMEImage import MIMEImage
Barry Warsawea66abc2002-10-01 04:48:06 +0000325from email.MIMEMultipart import MIMEMultipart
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000326
327COMMASPACE = ', '
328
329# Create the container (outer) email message.
Barry Warsawea66abc2002-10-01 04:48:06 +0000330msg = MIMEMultipart()
331msg['Subject'] = 'Our family reunion'
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000332# me == the sender's email address
333# family = the list of all recipients' email addresses
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000334msg['From'] = me
335msg['To'] = COMMASPACE.join(family)
336msg.preamble = 'Our family reunion'
337# Guarantees the message ends in a newline
338msg.epilogue = ''
339
340# Assume we know that the image files are all in PNG format
341for file in pngfiles:
Barry Warsawea66abc2002-10-01 04:48:06 +0000342 # Open the files in binary mode. Let the MIMEImage class automatically
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000343 # guess the specific image type.
344 fp = open(file, 'rb')
345 img = MIMEImage(fp.read())
346 fp.close()
347 msg.attach(img)
348
349# Send the email via our own SMTP server.
350s = smtplib.SMTP()
351s.connect()
Barry Warsawea66abc2002-10-01 04:48:06 +0000352s.sendmail(me, family, msg.as_string())
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000353s.close()
354\end{verbatim}
355
356Here's an example\footnote{Thanks to Matthew Dixon Cowles for the
357original inspiration and examples.} of how to send the entire contents
358of a directory as an email message:
359
360\begin{verbatim}
361#!/usr/bin/env python
362
363"""Send the contents of a directory as a MIME message.
364
365Usage: dirmail [options] from to [to ...]*
366
367Options:
368 -h / --help
369 Print this message and exit.
370
371 -d directory
372 --directory=directory
373 Mail the contents of the specified directory, otherwise use the
374 current directory. Only the regular files in the directory are sent,
375 and we don't recurse to subdirectories.
376
377`from' is the email address of the sender of the message.
378
379`to' is the email address of the recipient of the message, and multiple
380recipients may be given.
381
382The email is sent by forwarding to your local SMTP server, which then does the
383normal delivery process. Your local machine must be running an SMTP server.
384"""
385
386import sys
387import os
388import getopt
389import smtplib
390# For guessing MIME type based on file name extension
391import mimetypes
392
393from email import Encoders
394from email.Message import Message
395from email.MIMEAudio import MIMEAudio
Barry Warsawea66abc2002-10-01 04:48:06 +0000396from email.MIMEMultipart import MIMEMultipart
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000397from email.MIMEImage import MIMEImage
398from email.MIMEText import MIMEText
399
400COMMASPACE = ', '
401
402
403def usage(code, msg=''):
404 print >> sys.stderr, __doc__
405 if msg:
406 print >> sys.stderr, msg
407 sys.exit(code)
408
409
410def main():
411 try:
412 opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory='])
413 except getopt.error, msg:
414 usage(1, msg)
415
416 dir = os.curdir
417 for opt, arg in opts:
418 if opt in ('-h', '--help'):
419 usage(0)
420 elif opt in ('-d', '--directory'):
421 dir = arg
422
423 if len(args) < 2:
424 usage(1)
425
426 sender = args[0]
427 recips = args[1:]
428
429 # Create the enclosing (outer) message
Barry Warsawea66abc2002-10-01 04:48:06 +0000430 outer = MIMEMultipart()
Fred Drake928051f2002-02-15 04:12:59 +0000431 outer['Subject'] = 'Contents of directory %s' % os.path.abspath(dir)
Raymond Hettingerca0383d2002-06-26 07:51:32 +0000432 outer['To'] = COMMASPACE.join(recips)
433 outer['From'] = sender
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000434 outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
435 # To guarantee the message ends with a newline
436 outer.epilogue = ''
437
438 for filename in os.listdir(dir):
439 path = os.path.join(dir, filename)
440 if not os.path.isfile(path):
441 continue
Barry Warsawea66abc2002-10-01 04:48:06 +0000442 # Guess the content type based on the file's extension. Encoding
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000443 # will be ignored, although we should check for simple things like
Barry Warsawea66abc2002-10-01 04:48:06 +0000444 # gzip'd or compressed files.
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000445 ctype, encoding = mimetypes.guess_type(path)
446 if ctype is None or encoding is not None:
447 # No guess could be made, or the file is encoded (compressed), so
448 # use a generic bag-of-bits type.
449 ctype = 'application/octet-stream'
450 maintype, subtype = ctype.split('/', 1)
451 if maintype == 'text':
452 fp = open(path)
453 # Note: we should handle calculating the charset
454 msg = MIMEText(fp.read(), _subtype=subtype)
455 fp.close()
456 elif maintype == 'image':
457 fp = open(path, 'rb')
458 msg = MIMEImage(fp.read(), _subtype=subtype)
459 fp.close()
460 elif maintype == 'audio':
461 fp = open(path, 'rb')
462 msg = MIMEAudio(fp.read(), _subtype=subtype)
463 fp.close()
464 else:
465 fp = open(path, 'rb')
466 msg = MIMEBase(maintype, subtype)
Barry Warsawea66abc2002-10-01 04:48:06 +0000467 msg.set_payload(fp.read())
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000468 fp.close()
469 # Encode the payload using Base64
470 Encoders.encode_base64(msg)
471 # Set the filename parameter
472 msg.add_header('Content-Disposition', 'attachment', filename=filename)
473 outer.attach(msg)
474
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000475 # Now send the message
476 s = smtplib.SMTP()
477 s.connect()
Barry Warsawea66abc2002-10-01 04:48:06 +0000478 s.sendmail(sender, recips, outer.as_string())
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000479 s.close()
480
481
482if __name__ == '__main__':
483 main()
484\end{verbatim}
485
486And finally, here's an example of how to unpack a MIME message like
487the one above, into a directory of files:
488
489\begin{verbatim}
490#!/usr/bin/env python
491
492"""Unpack a MIME message into a directory of files.
493
494Usage: unpackmail [options] msgfile
495
496Options:
497 -h / --help
498 Print this message and exit.
499
500 -d directory
501 --directory=directory
502 Unpack the MIME message into the named directory, which will be
503 created if it doesn't already exist.
504
505msgfile is the path to the file containing the MIME message.
506"""
507
508import sys
509import os
510import getopt
511import errno
512import mimetypes
513import email
514
515
516def usage(code, msg=''):
517 print >> sys.stderr, __doc__
518 if msg:
519 print >> sys.stderr, msg
520 sys.exit(code)
521
522
523def main():
524 try:
525 opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory='])
526 except getopt.error, msg:
527 usage(1, msg)
528
529 dir = os.curdir
530 for opt, arg in opts:
531 if opt in ('-h', '--help'):
532 usage(0)
533 elif opt in ('-d', '--directory'):
534 dir = arg
535
536 try:
537 msgfile = args[0]
538 except IndexError:
539 usage(1)
540
541 try:
542 os.mkdir(dir)
543 except OSError, e:
544 # Ignore directory exists error
545 if e.errno <> errno.EEXIST: raise
546
547 fp = open(msgfile)
548 msg = email.message_from_file(fp)
549 fp.close()
550
551 counter = 1
552 for part in msg.walk():
553 # multipart/* are just containers
Barry Warsawea66abc2002-10-01 04:48:06 +0000554 if part.get_content_maintype() == 'multipart':
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000555 continue
556 # Applications should really sanitize the given filename so that an
557 # email message can't be used to overwrite important files
558 filename = part.get_filename()
559 if not filename:
560 ext = mimetypes.guess_extension(part.get_type())
561 if not ext:
562 # Use a generic bag-of-bits extension
563 ext = '.bin'
Fred Drake928051f2002-02-15 04:12:59 +0000564 filename = 'part-%03d%s' % (counter, ext)
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000565 counter += 1
566 fp = open(os.path.join(dir, filename), 'wb')
567 fp.write(part.get_payload(decode=1))
568 fp.close()
569
570
571if __name__ == '__main__':
572 main()
573\end{verbatim}