Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <link rel="STYLESHEET" href="lib.css" type='text/css' /> | |
5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> | |
6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> | |
7 | <link rel="first" href="lib.html" title='Python Library Reference' /> | |
8 | <link rel='contents' href='contents.html' title="Contents" /> | |
9 | <link rel='index' href='genindex.html' title='Index' /> | |
10 | <link rel='last' href='about.html' title='About this document...' /> | |
11 | <link rel='help' href='about.html' title='About this document...' /> | |
12 | <link rel="prev" href="node596.html" /> | |
13 | <link rel="parent" href="module-email.html" /> | |
14 | <link rel="next" href="module-mailcap.html" /> | |
15 | <meta name='aesop' content='information' /> | |
16 | <title>12.2.13 Examples</title> | |
17 | </head> | |
18 | <body> | |
19 | <DIV CLASS="navigation"> | |
20 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> | |
21 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
22 | <tr> | |
23 | <td class='online-navigation'><a rel="prev" title="12.2.12 Differences from mimelib" | |
24 | href="node596.html"><img src='../icons/previous.png' | |
25 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
26 | <td class='online-navigation'><a rel="parent" title="12.2 email " | |
27 | href="module-email.html"><img src='../icons/up.png' | |
28 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
29 | <td class='online-navigation'><a rel="next" title="12.3 mailcap " | |
30 | href="module-mailcap.html"><img src='../icons/next.png' | |
31 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
32 | <td align="center" width="100%">Python Library Reference</td> | |
33 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
34 | href="contents.html"><img src='../icons/contents.png' | |
35 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
36 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' | |
37 | border='0' height='32' alt='Module Index' width='32' /></a></td> | |
38 | <td class='online-navigation'><a rel="index" title="Index" | |
39 | href="genindex.html"><img src='../icons/index.png' | |
40 | border='0' height='32' alt='Index' width='32' /></A></td> | |
41 | </tr></table> | |
42 | <div class='online-navigation'> | |
43 | <b class="navlabel">Previous:</b> | |
44 | <a class="sectref" rel="prev" href="node596.html">12.2.12 Differences from mimelib</A> | |
45 | <b class="navlabel">Up:</b> | |
46 | <a class="sectref" rel="parent" href="module-email.html">12.2 email </A> | |
47 | <b class="navlabel">Next:</b> | |
48 | <a class="sectref" rel="next" href="module-mailcap.html">12.3 mailcap </A> | |
49 | </div> | |
50 | <hr /></div> | |
51 | </DIV> | |
52 | <!--End of Navigation Panel--> | |
53 | ||
54 | <H2><A NAME="SECTION00142130000000000000000"> | |
55 | 12.2.13 Examples</A> | |
56 | </H2> | |
57 | ||
58 | <P> | |
59 | Here are a few examples of how to use the <tt class="module">email</tt> package to | |
60 | read, write, and send simple email messages, as well as more complex | |
61 | MIME messages. | |
62 | ||
63 | <P> | |
64 | First, let's see how to create and send a simple text message: | |
65 | ||
66 | <P> | |
67 | <div class="verbatim"> | |
68 | <pre># Import smtplib for the actual sending function | |
69 | import smtplib | |
70 | ||
71 | # Import the email modules we'll need | |
72 | from email.MIMEText import MIMEText | |
73 | ||
74 | # Open a plain text file for reading. For this example, assume that | |
75 | # the text file contains only ASCII characters. | |
76 | fp = open(textfile, 'rb') | |
77 | # Create a text/plain message | |
78 | msg = MIMEText(fp.read()) | |
79 | fp.close() | |
80 | ||
81 | # me == the sender's email address | |
82 | # you == the recipient's email address | |
83 | msg['Subject'] = 'The contents of %s' % textfile | |
84 | msg['From'] = me | |
85 | msg['To'] = you | |
86 | ||
87 | # Send the message via our own SMTP server, but don't include the | |
88 | # envelope header. | |
89 | s = smtplib.SMTP() | |
90 | s.connect() | |
91 | s.sendmail(me, [you], msg.as_string()) | |
92 | s.close() | |
93 | </pre> | |
94 | <div class="footer"> | |
95 | <a href="email-simple.txt" type="text/plain">Download as text (original file name: <span class="file">email-simple.py</span>).</a> | |
96 | </div></div> | |
97 | ||
98 | <P> | |
99 | Here's an example of how to send a MIME message containing a bunch of | |
100 | family pictures that may be residing in a directory: | |
101 | ||
102 | <P> | |
103 | <div class="verbatim"> | |
104 | <pre># Import smtplib for the actual sending function | |
105 | import smtplib | |
106 | ||
107 | # Here are the email pacakge modules we'll need | |
108 | from email.MIMEImage import MIMEImage | |
109 | from email.MIMEMultipart import MIMEMultipart | |
110 | ||
111 | COMMASPACE = ', ' | |
112 | ||
113 | # Create the container (outer) email message. | |
114 | msg = MIMEMultipart() | |
115 | msg['Subject'] = 'Our family reunion' | |
116 | # me == the sender's email address | |
117 | # family = the list of all recipients' email addresses | |
118 | msg['From'] = me | |
119 | msg['To'] = COMMASPACE.join(family) | |
120 | msg.preamble = 'Our family reunion' | |
121 | # Guarantees the message ends in a newline | |
122 | msg.epilogue = '' | |
123 | ||
124 | # Assume we know that the image files are all in PNG format | |
125 | for file in pngfiles: | |
126 | # Open the files in binary mode. Let the MIMEImage class automatically | |
127 | # guess the specific image type. | |
128 | fp = open(file, 'rb') | |
129 | img = MIMEImage(fp.read()) | |
130 | fp.close() | |
131 | msg.attach(img) | |
132 | ||
133 | # Send the email via our own SMTP server. | |
134 | s = smtplib.SMTP() | |
135 | s.connect() | |
136 | s.sendmail(me, family, msg.as_string()) | |
137 | s.close() | |
138 | </pre> | |
139 | <div class="footer"> | |
140 | <a href="email-mime.txt" type="text/plain">Download as text (original file name: <span class="file">email-mime.py</span>).</a> | |
141 | </div></div> | |
142 | ||
143 | <P> | |
144 | Here's an example of how to send the entire contents of a directory as | |
145 | an email message: | |
146 | <A NAME="tex2html137" | |
147 | HREF="#foot58630"><SUP>12.5</SUP></A> | |
148 | <P> | |
149 | <div class="verbatim"> | |
150 | <pre>#!/usr/bin/env python | |
151 | ||
152 | """Send the contents of a directory as a MIME message. | |
153 | ||
154 | Usage: dirmail [options] from to [to ...]* | |
155 | ||
156 | Options: | |
157 | -h / --help | |
158 | Print this message and exit. | |
159 | ||
160 | -d directory | |
161 | --directory=directory | |
162 | Mail the contents of the specified directory, otherwise use the | |
163 | current directory. Only the regular files in the directory are sent, | |
164 | and we don't recurse to subdirectories. | |
165 | ||
166 | `from' is the email address of the sender of the message. | |
167 | ||
168 | `to' is the email address of the recipient of the message, and multiple | |
169 | recipients may be given. | |
170 | ||
171 | The email is sent by forwarding to your local SMTP server, which then does the | |
172 | normal delivery process. Your local machine must be running an SMTP server. | |
173 | """ | |
174 | ||
175 | import sys | |
176 | import os | |
177 | import getopt | |
178 | import smtplib | |
179 | # For guessing MIME type based on file name extension | |
180 | import mimetypes | |
181 | ||
182 | from email import Encoders | |
183 | from email.Message import Message | |
184 | from email.MIMEAudio import MIMEAudio | |
185 | from email.MIMEBase import MIMEBase | |
186 | from email.MIMEMultipart import MIMEMultipart | |
187 | from email.MIMEImage import MIMEImage | |
188 | from email.MIMEText import MIMEText | |
189 | ||
190 | COMMASPACE = ', ' | |
191 | ||
192 | def usage(code, msg=''): | |
193 | print >> sys.stderr, __doc__ | |
194 | if msg: | |
195 | print >> sys.stderr, msg | |
196 | sys.exit(code) | |
197 | ||
198 | def main(): | |
199 | try: | |
200 | opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory=']) | |
201 | except getopt.error, msg: | |
202 | usage(1, msg) | |
203 | ||
204 | dir = os.curdir | |
205 | for opt, arg in opts: | |
206 | if opt in ('-h', '--help'): | |
207 | usage(0) | |
208 | elif opt in ('-d', '--directory'): | |
209 | dir = arg | |
210 | ||
211 | if len(args) < 2: | |
212 | usage(1) | |
213 | ||
214 | sender = args[0] | |
215 | recips = args[1:] | |
216 | ||
217 | # Create the enclosing (outer) message | |
218 | outer = MIMEMultipart() | |
219 | outer['Subject'] = 'Contents of directory %s' % os.path.abspath(dir) | |
220 | outer['To'] = COMMASPACE.join(recips) | |
221 | outer['From'] = sender | |
222 | outer.preamble = 'You will not see this in a MIME-aware mail reader.\n' | |
223 | # To guarantee the message ends with a newline | |
224 | outer.epilogue = '' | |
225 | ||
226 | for filename in os.listdir(dir): | |
227 | path = os.path.join(dir, filename) | |
228 | if not os.path.isfile(path): | |
229 | continue | |
230 | # Guess the content type based on the file's extension. Encoding | |
231 | # will be ignored, although we should check for simple things like | |
232 | # gzip'd or compressed files. | |
233 | ctype, encoding = mimetypes.guess_type(path) | |
234 | if ctype is None or encoding is not None: | |
235 | # No guess could be made, or the file is encoded (compressed), so | |
236 | # use a generic bag-of-bits type. | |
237 | ctype = 'application/octet-stream' | |
238 | maintype, subtype = ctype.split('/', 1) | |
239 | if maintype == 'text': | |
240 | fp = open(path) | |
241 | # Note: we should handle calculating the charset | |
242 | msg = MIMEText(fp.read(), _subtype=subtype) | |
243 | fp.close() | |
244 | elif maintype == 'image': | |
245 | fp = open(path, 'rb') | |
246 | msg = MIMEImage(fp.read(), _subtype=subtype) | |
247 | fp.close() | |
248 | elif maintype == 'audio': | |
249 | fp = open(path, 'rb') | |
250 | msg = MIMEAudio(fp.read(), _subtype=subtype) | |
251 | fp.close() | |
252 | else: | |
253 | fp = open(path, 'rb') | |
254 | msg = MIMEBase(maintype, subtype) | |
255 | msg.set_payload(fp.read()) | |
256 | fp.close() | |
257 | # Encode the payload using Base64 | |
258 | Encoders.encode_base64(msg) | |
259 | # Set the filename parameter | |
260 | msg.add_header('Content-Disposition', 'attachment', filename=filename) | |
261 | outer.attach(msg) | |
262 | ||
263 | # Now send the message | |
264 | s = smtplib.SMTP() | |
265 | s.connect() | |
266 | s.sendmail(sender, recips, outer.as_string()) | |
267 | s.close() | |
268 | ||
269 | if __name__ == '__main__': | |
270 | main() | |
271 | </pre> | |
272 | <div class="footer"> | |
273 | <a href="email-dir.txt" type="text/plain">Download as text (original file name: <span class="file">email-dir.py</span>).</a> | |
274 | </div></div> | |
275 | ||
276 | <P> | |
277 | And finally, here's an example of how to unpack a MIME message like | |
278 | the one above, into a directory of files: | |
279 | ||
280 | <P> | |
281 | <div class="verbatim"> | |
282 | <pre>#!/usr/bin/env python | |
283 | ||
284 | """Unpack a MIME message into a directory of files. | |
285 | ||
286 | Usage: unpackmail [options] msgfile | |
287 | ||
288 | Options: | |
289 | -h / --help | |
290 | Print this message and exit. | |
291 | ||
292 | -d directory | |
293 | --directory=directory | |
294 | Unpack the MIME message into the named directory, which will be | |
295 | created if it doesn't already exist. | |
296 | ||
297 | msgfile is the path to the file containing the MIME message. | |
298 | """ | |
299 | ||
300 | import sys | |
301 | import os | |
302 | import getopt | |
303 | import errno | |
304 | import mimetypes | |
305 | import email | |
306 | ||
307 | def usage(code, msg=''): | |
308 | print >> sys.stderr, __doc__ | |
309 | if msg: | |
310 | print >> sys.stderr, msg | |
311 | sys.exit(code) | |
312 | ||
313 | def main(): | |
314 | try: | |
315 | opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory=']) | |
316 | except getopt.error, msg: | |
317 | usage(1, msg) | |
318 | ||
319 | dir = os.curdir | |
320 | for opt, arg in opts: | |
321 | if opt in ('-h', '--help'): | |
322 | usage(0) | |
323 | elif opt in ('-d', '--directory'): | |
324 | dir = arg | |
325 | ||
326 | try: | |
327 | msgfile = args[0] | |
328 | except IndexError: | |
329 | usage(1) | |
330 | ||
331 | try: | |
332 | os.mkdir(dir) | |
333 | except OSError, e: | |
334 | # Ignore directory exists error | |
335 | if e.errno <> errno.EEXIST: raise | |
336 | ||
337 | fp = open(msgfile) | |
338 | msg = email.message_from_file(fp) | |
339 | fp.close() | |
340 | ||
341 | counter = 1 | |
342 | for part in msg.walk(): | |
343 | # multipart/* are just containers | |
344 | if part.get_content_maintype() == 'multipart': | |
345 | continue | |
346 | # Applications should really sanitize the given filename so that an | |
347 | # email message can't be used to overwrite important files | |
348 | filename = part.get_filename() | |
349 | if not filename: | |
350 | ext = mimetypes.guess_extension(part.get_type()) | |
351 | if not ext: | |
352 | # Use a generic bag-of-bits extension | |
353 | ext = '.bin' | |
354 | filename = 'part-%03d%s' % (counter, ext) | |
355 | counter += 1 | |
356 | fp = open(os.path.join(dir, filename), 'wb') | |
357 | fp.write(part.get_payload(decode=1)) | |
358 | fp.close() | |
359 | ||
360 | if __name__ == '__main__': | |
361 | main() | |
362 | </pre> | |
363 | <div class="footer"> | |
364 | <a href="email-unpack.txt" type="text/plain">Download as text (original file name: <span class="file">email-unpack.py</span>).</a> | |
365 | </div></div> | |
366 | <BR><HR><H4>Footnotes</H4> | |
367 | <DL> | |
368 | <DT><A NAME="foot58630">... message:</A><A | |
369 | HREF="node597.html#tex2html137"><SUP>12.5</SUP></A></DT> | |
370 | <DD>Thanks to Matthew Dixon Cowles for the original inspiration | |
371 | and examples. | |
372 | ||
373 | </DD> | |
374 | </DL> | |
375 | <DIV CLASS="navigation"> | |
376 | <div class='online-navigation'> | |
377 | <p></p><hr /> | |
378 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
379 | <tr> | |
380 | <td class='online-navigation'><a rel="prev" title="12.2.12 Differences from mimelib" | |
381 | href="node596.html"><img src='../icons/previous.png' | |
382 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
383 | <td class='online-navigation'><a rel="parent" title="12.2 email " | |
384 | href="module-email.html"><img src='../icons/up.png' | |
385 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
386 | <td class='online-navigation'><a rel="next" title="12.3 mailcap " | |
387 | href="module-mailcap.html"><img src='../icons/next.png' | |
388 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
389 | <td align="center" width="100%">Python Library Reference</td> | |
390 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
391 | href="contents.html"><img src='../icons/contents.png' | |
392 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
393 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' | |
394 | border='0' height='32' alt='Module Index' width='32' /></a></td> | |
395 | <td class='online-navigation'><a rel="index" title="Index" | |
396 | href="genindex.html"><img src='../icons/index.png' | |
397 | border='0' height='32' alt='Index' width='32' /></A></td> | |
398 | </tr></table> | |
399 | <div class='online-navigation'> | |
400 | <b class="navlabel">Previous:</b> | |
401 | <a class="sectref" rel="prev" href="node596.html">12.2.12 Differences from mimelib</A> | |
402 | <b class="navlabel">Up:</b> | |
403 | <a class="sectref" rel="parent" href="module-email.html">12.2 email </A> | |
404 | <b class="navlabel">Next:</b> | |
405 | <a class="sectref" rel="next" href="module-mailcap.html">12.3 mailcap </A> | |
406 | </div> | |
407 | </div> | |
408 | <hr /> | |
409 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> | |
410 | </DIV> | |
411 | <!--End of Navigation Panel--> | |
412 | <ADDRESS> | |
413 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. | |
414 | </ADDRESS> | |
415 | </BODY> | |
416 | </HTML> |