mirror of
https://github.com/python/cpython.git
synced 2025-11-02 11:08:57 +00:00
#20477: add examples of using the new contentmanager API.
This commit is contained in:
parent
aa21297457
commit
02384bfa94
3 changed files with 158 additions and 0 deletions
56
Doc/includes/email-alternative-new-api.py
Normal file
56
Doc/includes/email-alternative-new-api.py
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import smtplib
|
||||||
|
|
||||||
|
from email.message import EmailMessage
|
||||||
|
from email.headerregistry import Address
|
||||||
|
from email.utils import make_msgid
|
||||||
|
|
||||||
|
# Create the base text message.
|
||||||
|
msg = EmailMessage()
|
||||||
|
msg['Subject'] = "Ayons asperges pour le déjeuner"
|
||||||
|
msg['From'] = Address("Pepé Le Pew", "pepe@example.com")
|
||||||
|
msg['To'] = (Address("Penelope Pussycat", "penelope@example.com"),
|
||||||
|
Address("Fabrette Pussycat", "fabrette@example.com"))
|
||||||
|
msg.set_content("""\
|
||||||
|
Salut!
|
||||||
|
|
||||||
|
Cela ressemble à un excellent recipie[1] déjeuner.
|
||||||
|
|
||||||
|
[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718
|
||||||
|
|
||||||
|
--Éric
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Add the html version. This converts the message into a multipart/alternative
|
||||||
|
# container, with the original text message as the first part and the new html
|
||||||
|
# message as the second part.
|
||||||
|
asparagus_cid = make_msgid()
|
||||||
|
msg.add_alternative("""\
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<p>Salut!<\p>
|
||||||
|
<p>Cela ressemble à un excellent
|
||||||
|
<a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718>
|
||||||
|
recipie
|
||||||
|
</a> déjeuner.
|
||||||
|
</p>
|
||||||
|
<img src="cid:{asparagus_cid}" \>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html')
|
||||||
|
# note that we needed to peel the <> off the msgid for use in the html.
|
||||||
|
|
||||||
|
# Now add the related image to the html part.
|
||||||
|
with open("roasted-asparagus.jpg", 'rb') as img:
|
||||||
|
msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg',
|
||||||
|
cid=asparagus_cid)
|
||||||
|
|
||||||
|
# Make a local copy of what we are going to send.
|
||||||
|
with open('outgoing.msg', 'wb') as f:
|
||||||
|
f.write(bytes(msg))
|
||||||
|
|
||||||
|
# Send the message via local SMTP server.
|
||||||
|
with smtplib.SMTP('localhost') as s:
|
||||||
|
s.send_message(msg)
|
||||||
74
Doc/includes/email-read-alternative-new-api.py
Normal file
74
Doc/includes/email-read-alternative-new-api.py
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import mimetypes
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
# Import the email modules we'll need
|
||||||
|
from email import policy
|
||||||
|
from email.parser import BytesParser
|
||||||
|
|
||||||
|
# An imaginary module that would make this work and be safe.
|
||||||
|
from imaginary import magic_html_parser
|
||||||
|
|
||||||
|
# In a real program you'd get the filename from the arguments.
|
||||||
|
msg = BytesParser(policy=policy.default).parse(open('outgoing.msg', 'rb'))
|
||||||
|
|
||||||
|
# Now the header items can be accessed as a dictionary, and any non-ASCII will
|
||||||
|
# be converted to unicode:
|
||||||
|
print('To:', msg['to'])
|
||||||
|
print('From:', msg['from'])
|
||||||
|
print('Subject:', msg['subject'])
|
||||||
|
|
||||||
|
# If we want to print a priview of the message content, we can extract whatever
|
||||||
|
# the least formatted payload is and print the first three lines. Of course,
|
||||||
|
# if the message has no plain text part printing the first three lines of html
|
||||||
|
# is probably useless, but this is just a conceptual example.
|
||||||
|
simplest = msg.get_body(preferencelist=('plain', 'html'))
|
||||||
|
print()
|
||||||
|
print(''.join(simplest.get_content().splitlines(keepends=True)[:3]))
|
||||||
|
|
||||||
|
ans = input("View full message?")
|
||||||
|
if ans.lower()[0] == 'n':
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# We can extract the richest alternative in order to display it:
|
||||||
|
richest = msg.get_body()
|
||||||
|
partfiles = {}
|
||||||
|
if richest['content-type'].maintype == 'text':
|
||||||
|
if richest['content-type'].subtype == 'plain':
|
||||||
|
for line in richest.get_content().splitlines():
|
||||||
|
print(line)
|
||||||
|
sys.exit()
|
||||||
|
elif richest['content-type'].subtype == 'html':
|
||||||
|
body = richest
|
||||||
|
else:
|
||||||
|
print("Don't know how to display {}".format(richest.get_content_type()))
|
||||||
|
sys.exit()
|
||||||
|
elif richest['content-type'].content_type == 'multipart/related':
|
||||||
|
body = richest.get_body(preferencelist=('html'))
|
||||||
|
for part in richest.iter_attachments():
|
||||||
|
fn = part.get_filename()
|
||||||
|
if fn:
|
||||||
|
extension = os.path.splitext(part.get_filename())[1]
|
||||||
|
else:
|
||||||
|
extension = mimetypes.guess_extension(part.get_content_type())
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f:
|
||||||
|
f.write(part.get_content())
|
||||||
|
# again strip the <> to go from email form of cid to html form.
|
||||||
|
partfiles[part['content-id'][1:-1]] = f.name
|
||||||
|
else:
|
||||||
|
print("Don't know how to display {}".format(richest.get_content_type()))
|
||||||
|
sys.exit()
|
||||||
|
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
|
||||||
|
# The magic_html_parser has to rewrite the href="cid:...." attributes to
|
||||||
|
# point to the filenames in partfiles. It also has to do a safety-sanitize
|
||||||
|
# of the html. It could be written using html.parser.
|
||||||
|
f.write(magic_html_parser(body.get_content(), partfiles))
|
||||||
|
webbrowser.open(f.name)
|
||||||
|
os.remove(f.name)
|
||||||
|
for fn in partfiles.values():
|
||||||
|
os.remove(fn)
|
||||||
|
|
||||||
|
# Of course, there are lots of email messages that could break this simple
|
||||||
|
# minded program, but it will handle the most common ones.
|
||||||
|
|
@ -40,6 +40,34 @@ text version: [2]_
|
||||||
.. literalinclude:: ../includes/email-alternative.py
|
.. literalinclude:: ../includes/email-alternative.py
|
||||||
|
|
||||||
|
|
||||||
|
Examples using the Provision API
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Here is a reworking of the last example using the provisional API. To make
|
||||||
|
things a bit more interesting, we include a related image in the html part, and
|
||||||
|
we save a copy of what we are going to send to disk, as well as sending it.
|
||||||
|
|
||||||
|
This example also shows how easy it is to include non-ASCII, and simplifies the
|
||||||
|
sending of the message using the :meth:`.send_message` method of the
|
||||||
|
:mod:`smtplib` module.
|
||||||
|
|
||||||
|
.. literalinclude:: ../includes/email-alternative-new-api.py
|
||||||
|
|
||||||
|
If we were instead sent the message from the last example, here is one
|
||||||
|
way we could process it:
|
||||||
|
|
||||||
|
.. literalinclude:: ../includes/email-read-alternative-new-api.py
|
||||||
|
|
||||||
|
Up to the prompt, the output from the above is::
|
||||||
|
|
||||||
|
To: Penelope Pussycat <"penelope@example.com">, Fabrette Pussycat <"fabrette@example.com">
|
||||||
|
From: Pepé Le Pew <pepe@example.com>
|
||||||
|
Subject: Ayons asperges pour le déjeuner
|
||||||
|
|
||||||
|
Salut!
|
||||||
|
|
||||||
|
Cela ressemble à un excellent recipie[1] déjeuner.
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
.. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples.
|
.. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue