Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 02384bf

Browse files
committed
#20477: add examples of using the new contentmanager API.
1 parent aa21297 commit 02384bf

3 files changed

Lines changed: 158 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
3+
import smtplib
4+
5+
from email.message import EmailMessage
6+
from email.headerregistry import Address
7+
from email.utils import make_msgid
8+
9+
# Create the base text message.
10+
msg = EmailMessage()
11+
msg['Subject'] = "Ayons asperges pour le déjeuner"
12+
msg['From'] = Address("Pepé Le Pew", "[email protected]")
13+
msg['To'] = (Address("Penelope Pussycat", "[email protected]"),
14+
Address("Fabrette Pussycat", "[email protected]"))
15+
msg.set_content("""\
16+
Salut!
17+
18+
Cela ressemble à un excellent recipie[1] déjeuner.
19+
20+
[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718
21+
22+
--Éric
23+
""")
24+
25+
# Add the html version. This converts the message into a multipart/alternative
26+
# container, with the original text message as the first part and the new html
27+
# message as the second part.
28+
asparagus_cid = make_msgid()
29+
msg.add_alternative("""\
30+
<html>
31+
<head></head>
32+
<body>
33+
<p>Salut!<\p>
34+
<p>Cela ressemble à un excellent
35+
<a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718>
36+
recipie
37+
</a> déjeuner.
38+
</p>
39+
<img src="cid:{asparagus_cid}" \>
40+
</body>
41+
</html>
42+
""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html')
43+
# note that we needed to peel the <> off the msgid for use in the html.
44+
45+
# Now add the related image to the html part.
46+
with open("roasted-asparagus.jpg", 'rb') as img:
47+
msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg',
48+
cid=asparagus_cid)
49+
50+
# Make a local copy of what we are going to send.
51+
with open('outgoing.msg', 'wb') as f:
52+
f.write(bytes(msg))
53+
54+
# Send the message via local SMTP server.
55+
with smtplib.SMTP('localhost') as s:
56+
s.send_message(msg)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import os
2+
import sys
3+
import tempfile
4+
import mimetypes
5+
import webbrowser
6+
7+
# Import the email modules we'll need
8+
from email import policy
9+
from email.parser import BytesParser
10+
11+
# An imaginary module that would make this work and be safe.
12+
from imaginary import magic_html_parser
13+
14+
# In a real program you'd get the filename from the arguments.
15+
msg = BytesParser(policy=policy.default).parse(open('outgoing.msg', 'rb'))
16+
17+
# Now the header items can be accessed as a dictionary, and any non-ASCII will
18+
# be converted to unicode:
19+
print('To:', msg['to'])
20+
print('From:', msg['from'])
21+
print('Subject:', msg['subject'])
22+
23+
# If we want to print a priview of the message content, we can extract whatever
24+
# the least formatted payload is and print the first three lines. Of course,
25+
# if the message has no plain text part printing the first three lines of html
26+
# is probably useless, but this is just a conceptual example.
27+
simplest = msg.get_body(preferencelist=('plain', 'html'))
28+
print()
29+
print(''.join(simplest.get_content().splitlines(keepends=True)[:3]))
30+
31+
ans = input("View full message?")
32+
if ans.lower()[0] == 'n':
33+
sys.exit()
34+
35+
# We can extract the richest alternative in order to display it:
36+
richest = msg.get_body()
37+
partfiles = {}
38+
if richest['content-type'].maintype == 'text':
39+
if richest['content-type'].subtype == 'plain':
40+
for line in richest.get_content().splitlines():
41+
print(line)
42+
sys.exit()
43+
elif richest['content-type'].subtype == 'html':
44+
body = richest
45+
else:
46+
print("Don't know how to display {}".format(richest.get_content_type()))
47+
sys.exit()
48+
elif richest['content-type'].content_type == 'multipart/related':
49+
body = richest.get_body(preferencelist=('html'))
50+
for part in richest.iter_attachments():
51+
fn = part.get_filename()
52+
if fn:
53+
extension = os.path.splitext(part.get_filename())[1]
54+
else:
55+
extension = mimetypes.guess_extension(part.get_content_type())
56+
with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f:
57+
f.write(part.get_content())
58+
# again strip the <> to go from email form of cid to html form.
59+
partfiles[part['content-id'][1:-1]] = f.name
60+
else:
61+
print("Don't know how to display {}".format(richest.get_content_type()))
62+
sys.exit()
63+
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
64+
# The magic_html_parser has to rewrite the href="cid:...." attributes to
65+
# point to the filenames in partfiles. It also has to do a safety-sanitize
66+
# of the html. It could be written using html.parser.
67+
f.write(magic_html_parser(body.get_content(), partfiles))
68+
webbrowser.open(f.name)
69+
os.remove(f.name)
70+
for fn in partfiles.values():
71+
os.remove(fn)
72+
73+
# Of course, there are lots of email messages that could break this simple
74+
# minded program, but it will handle the most common ones.

Doc/library/email-examples.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,34 @@ text version: [2]_
4040
.. literalinclude:: ../includes/email-alternative.py
4141

4242

43+
Examples using the Provision API
44+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45+
Here is a reworking of the last example using the provisional API. To make
46+
things a bit more interesting, we include a related image in the html part, and
47+
we save a copy of what we are going to send to disk, as well as sending it.
48+
49+
This example also shows how easy it is to include non-ASCII, and simplifies the
50+
sending of the message using the :meth:`.send_message` method of the
51+
:mod:`smtplib` module.
52+
53+
.. literalinclude:: ../includes/email-alternative-new-api.py
54+
55+
If we were instead sent the message from the last example, here is one
56+
way we could process it:
57+
58+
.. literalinclude:: ../includes/email-read-alternative-new-api.py
59+
60+
Up to the prompt, the output from the above is::
61+
62+
To: Penelope Pussycat <"[email protected]">, Fabrette Pussycat <"[email protected]">
63+
From: Pepé Le Pew <[email protected]>
64+
Subject: Ayons asperges pour le déjeuner
65+
66+
Salut!
67+
68+
Cela ressemble à un excellent recipie[1] déjeuner.
69+
70+
4371
.. rubric:: Footnotes
4472

4573
.. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples.

0 commit comments

Comments
 (0)