blob: cbbcf879efebdc9769664a4c73f5c6055a60812d [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
292# Here are the email pacakge modules we'll need
293from email import Encoders
294from email.MIMEText import MIMEText
295
296# Open a plain text file for reading
297fp = open(textfile)
298# Create a text/plain message, using Quoted-Printable encoding for non-ASCII
299# characters.
300msg = MIMEText(fp.read(), _encoder=Encoders.encode_quopri)
301fp.close()
302
303# me == the sender's email address
304# you == the recipient's email address
Fred Drake928051f2002-02-15 04:12:59 +0000305msg['Subject'] = 'The contents of %s' % textfile
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000306msg['From'] = me
307msg['To'] = you
308
309# Send the message via our own SMTP server. Use msg.as_string() with
310# unixfrom=0 so as not to confuse SMTP.
311s = smtplib.SMTP()
312s.connect()
313s.sendmail(me, [you], msg.as_string(0))
314s.close()
315\end{verbatim}
316
317Here's an example of how to send a MIME message containing a bunch of
318family pictures:
319
320\begin{verbatim}
321# Import smtplib for the actual sending function
322import smtplib
323
324# Here are the email pacakge modules we'll need
325from email.MIMEImage import MIMEImage
326from email.MIMEBase import MIMEBase
327
328COMMASPACE = ', '
329
330# Create the container (outer) email message.
331# me == the sender's email address
332# family = the list of all recipients' email addresses
333msg = MIMEBase('multipart', 'mixed')
334msg['Subject'] = 'Our family reunion'
335msg['From'] = me
336msg['To'] = COMMASPACE.join(family)
337msg.preamble = 'Our family reunion'
338# Guarantees the message ends in a newline
339msg.epilogue = ''
340
341# Assume we know that the image files are all in PNG format
342for file in pngfiles:
343 # Open the files in binary mode. Let the MIMEIMage class automatically
344 # guess the specific image type.
345 fp = open(file, 'rb')
346 img = MIMEImage(fp.read())
347 fp.close()
348 msg.attach(img)
349
350# Send the email via our own SMTP server.
351s = smtplib.SMTP()
352s.connect()
353s.sendmail(me, family, msg.as_string(unixfrom=0))
354s.close()
355\end{verbatim}
356
357Here's an example\footnote{Thanks to Matthew Dixon Cowles for the
358original inspiration and examples.} of how to send the entire contents
359of a directory as an email message:
360
361\begin{verbatim}
362#!/usr/bin/env python
363
364"""Send the contents of a directory as a MIME message.
365
366Usage: dirmail [options] from to [to ...]*
367
368Options:
369 -h / --help
370 Print this message and exit.
371
372 -d directory
373 --directory=directory
374 Mail the contents of the specified directory, otherwise use the
375 current directory. Only the regular files in the directory are sent,
376 and we don't recurse to subdirectories.
377
378`from' is the email address of the sender of the message.
379
380`to' is the email address of the recipient of the message, and multiple
381recipients may be given.
382
383The email is sent by forwarding to your local SMTP server, which then does the
384normal delivery process. Your local machine must be running an SMTP server.
385"""
386
387import sys
388import os
389import getopt
390import smtplib
391# For guessing MIME type based on file name extension
392import mimetypes
393
394from email import Encoders
395from email.Message import Message
396from email.MIMEAudio import MIMEAudio
397from email.MIMEBase import MIMEBase
398from email.MIMEImage import MIMEImage
399from email.MIMEText import MIMEText
400
401COMMASPACE = ', '
402
403
404def usage(code, msg=''):
405 print >> sys.stderr, __doc__
406 if msg:
407 print >> sys.stderr, msg
408 sys.exit(code)
409
410
411def main():
412 try:
413 opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory='])
414 except getopt.error, msg:
415 usage(1, msg)
416
417 dir = os.curdir
418 for opt, arg in opts:
419 if opt in ('-h', '--help'):
420 usage(0)
421 elif opt in ('-d', '--directory'):
422 dir = arg
423
424 if len(args) < 2:
425 usage(1)
426
427 sender = args[0]
428 recips = args[1:]
429
430 # Create the enclosing (outer) message
431 outer = MIMEBase('multipart', 'mixed')
Fred Drake928051f2002-02-15 04:12:59 +0000432 outer['Subject'] = 'Contents of directory %s' % os.path.abspath(dir)
Raymond Hettingerca0383d2002-06-26 07:51:32 +0000433 outer['To'] = COMMASPACE.join(recips)
434 outer['From'] = sender
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000435 outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
436 # To guarantee the message ends with a newline
437 outer.epilogue = ''
438
439 for filename in os.listdir(dir):
440 path = os.path.join(dir, filename)
441 if not os.path.isfile(path):
442 continue
443 # Guess the Content-Type: based on the file's extension. Encoding
444 # will be ignored, although we should check for simple things like
445 # gzip'd or compressed files
446 ctype, encoding = mimetypes.guess_type(path)
447 if ctype is None or encoding is not None:
448 # No guess could be made, or the file is encoded (compressed), so
449 # use a generic bag-of-bits type.
450 ctype = 'application/octet-stream'
451 maintype, subtype = ctype.split('/', 1)
452 if maintype == 'text':
453 fp = open(path)
454 # Note: we should handle calculating the charset
455 msg = MIMEText(fp.read(), _subtype=subtype)
456 fp.close()
457 elif maintype == 'image':
458 fp = open(path, 'rb')
459 msg = MIMEImage(fp.read(), _subtype=subtype)
460 fp.close()
461 elif maintype == 'audio':
462 fp = open(path, 'rb')
463 msg = MIMEAudio(fp.read(), _subtype=subtype)
464 fp.close()
465 else:
466 fp = open(path, 'rb')
467 msg = MIMEBase(maintype, subtype)
468 msg.add_payload(fp.read())
469 fp.close()
470 # Encode the payload using Base64
471 Encoders.encode_base64(msg)
472 # Set the filename parameter
473 msg.add_header('Content-Disposition', 'attachment', filename=filename)
474 outer.attach(msg)
475
476 fp = open('/tmp/debug.pck', 'w')
477 import cPickle
478 cPickle.dump(outer, fp)
479 fp.close()
480 # Now send the message
481 s = smtplib.SMTP()
482 s.connect()
483 s.sendmail(sender, recips, outer.as_string(0))
484 s.close()
485
486
487if __name__ == '__main__':
488 main()
489\end{verbatim}
490
491And finally, here's an example of how to unpack a MIME message like
492the one above, into a directory of files:
493
494\begin{verbatim}
495#!/usr/bin/env python
496
497"""Unpack a MIME message into a directory of files.
498
499Usage: unpackmail [options] msgfile
500
501Options:
502 -h / --help
503 Print this message and exit.
504
505 -d directory
506 --directory=directory
507 Unpack the MIME message into the named directory, which will be
508 created if it doesn't already exist.
509
510msgfile is the path to the file containing the MIME message.
511"""
512
513import sys
514import os
515import getopt
516import errno
517import mimetypes
518import email
519
520
521def usage(code, msg=''):
522 print >> sys.stderr, __doc__
523 if msg:
524 print >> sys.stderr, msg
525 sys.exit(code)
526
527
528def main():
529 try:
530 opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory='])
531 except getopt.error, msg:
532 usage(1, msg)
533
534 dir = os.curdir
535 for opt, arg in opts:
536 if opt in ('-h', '--help'):
537 usage(0)
538 elif opt in ('-d', '--directory'):
539 dir = arg
540
541 try:
542 msgfile = args[0]
543 except IndexError:
544 usage(1)
545
546 try:
547 os.mkdir(dir)
548 except OSError, e:
549 # Ignore directory exists error
550 if e.errno <> errno.EEXIST: raise
551
552 fp = open(msgfile)
553 msg = email.message_from_file(fp)
554 fp.close()
555
556 counter = 1
557 for part in msg.walk():
558 # multipart/* are just containers
559 if part.get_main_type() == 'multipart':
560 continue
561 # Applications should really sanitize the given filename so that an
562 # email message can't be used to overwrite important files
563 filename = part.get_filename()
564 if not filename:
565 ext = mimetypes.guess_extension(part.get_type())
566 if not ext:
567 # Use a generic bag-of-bits extension
568 ext = '.bin'
Fred Drake928051f2002-02-15 04:12:59 +0000569 filename = 'part-%03d%s' % (counter, ext)
Barry Warsaw2bb077f2001-11-05 17:50:53 +0000570 counter += 1
571 fp = open(os.path.join(dir, filename), 'wb')
572 fp.write(part.get_payload(decode=1))
573 fp.close()
574
575
576if __name__ == '__main__':
577 main()
578\end{verbatim}