mirror of
https://github.com/python/cpython.git
synced 2025-11-25 12:44:13 +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
|
||||
|
||||
|
||||
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
|
||||
|
||||
.. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue