summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorR David Murray <rdmurray@bitdance.com>2014-02-07 15:55:17 (GMT)
committerR David Murray <rdmurray@bitdance.com>2014-02-07 15:55:17 (GMT)
commit02384bfa9481d7e6276dfa6cf2fcfb0f59012be2 (patch)
tree9e173714bcbd00f2e47d25be5103df8de74a7356
parentaa21297457ef0e5647602e19a89c4b797183c16e (diff)
downloadcpython-02384bfa9481d7e6276dfa6cf2fcfb0f59012be2.zip
cpython-02384bfa9481d7e6276dfa6cf2fcfb0f59012be2.tar.gz
cpython-02384bfa9481d7e6276dfa6cf2fcfb0f59012be2.tar.bz2
#20477: add examples of using the new contentmanager API.
-rw-r--r--Doc/includes/email-alternative-new-api.py56
-rw-r--r--Doc/includes/email-read-alternative-new-api.py74
-rw-r--r--Doc/library/email-examples.rst28
3 files changed, 158 insertions, 0 deletions
diff --git a/Doc/includes/email-alternative-new-api.py b/Doc/includes/email-alternative-new-api.py
new file mode 100644
index 0000000..eeabf34
--- /dev/null
+++ b/Doc/includes/email-alternative-new-api.py
@@ -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)
diff --git a/Doc/includes/email-read-alternative-new-api.py b/Doc/includes/email-read-alternative-new-api.py
new file mode 100644
index 0000000..8ab4e9f
--- /dev/null
+++ b/Doc/includes/email-read-alternative-new-api.py
@@ -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.
diff --git a/Doc/library/email-examples.rst b/Doc/library/email-examples.rst
index 32cecf3..294e131 100644
--- a/Doc/library/email-examples.rst
+++ b/Doc/library/email-examples.rst
@@ -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.