Path: blob/main/Doc/includes/email-read-alternative.py
12 views
import os1import sys2import tempfile3import mimetypes4import webbrowser56# Import the email modules we'll need7from email import policy8from email.parser import BytesParser91011def magic_html_parser(html_text, partfiles):12"""Return safety-sanitized html linked to partfiles.1314Rewrite the href="cid:...." attributes to point to the filenames in partfiles.15Though not trivial, this should be possible using html.parser.16"""17raise NotImplementedError("Add the magic needed")181920# In a real program you'd get the filename from the arguments.21with open('outgoing.msg', 'rb') as fp:22msg = BytesParser(policy=policy.default).parse(fp)2324# Now the header items can be accessed as a dictionary, and any non-ASCII will25# be converted to unicode:26print('To:', msg['to'])27print('From:', msg['from'])28print('Subject:', msg['subject'])2930# If we want to print a preview of the message content, we can extract whatever31# the least formatted payload is and print the first three lines. Of course,32# if the message has no plain text part printing the first three lines of html33# is probably useless, but this is just a conceptual example.34simplest = msg.get_body(preferencelist=('plain', 'html'))35print()36print(''.join(simplest.get_content().splitlines(keepends=True)[:3]))3738ans = input("View full message?")39if ans.lower()[0] == 'n':40sys.exit()4142# We can extract the richest alternative in order to display it:43richest = msg.get_body()44partfiles = {}45if richest['content-type'].maintype == 'text':46if richest['content-type'].subtype == 'plain':47for line in richest.get_content().splitlines():48print(line)49sys.exit()50elif richest['content-type'].subtype == 'html':51body = richest52else:53print("Don't know how to display {}".format(richest.get_content_type()))54sys.exit()55elif richest['content-type'].content_type == 'multipart/related':56body = richest.get_body(preferencelist=('html'))57for part in richest.iter_attachments():58fn = part.get_filename()59if fn:60extension = os.path.splitext(part.get_filename())[1]61else:62extension = mimetypes.guess_extension(part.get_content_type())63with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f:64f.write(part.get_content())65# again strip the <> to go from email form of cid to html form.66partfiles[part['content-id'][1:-1]] = f.name67else:68print("Don't know how to display {}".format(richest.get_content_type()))69sys.exit()70with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:71f.write(magic_html_parser(body.get_content(), partfiles))72webbrowser.open(f.name)73os.remove(f.name)74for fn in partfiles.values():75os.remove(fn)7677# Of course, there are lots of email messages that could break this simple78# minded program, but it will handle the most common ones.798081