| 1 | n/a | import os |
|---|
| 2 | n/a | import sys |
|---|
| 3 | n/a | import tempfile |
|---|
| 4 | n/a | import mimetypes |
|---|
| 5 | n/a | import webbrowser |
|---|
| 6 | n/a | |
|---|
| 7 | n/a | # Import the email modules we'll need |
|---|
| 8 | n/a | from email import policy |
|---|
| 9 | n/a | from email.parser import BytesParser |
|---|
| 10 | n/a | |
|---|
| 11 | n/a | # An imaginary module that would make this work and be safe. |
|---|
| 12 | n/a | from imaginary import magic_html_parser |
|---|
| 13 | n/a | |
|---|
| 14 | n/a | # In a real program you'd get the filename from the arguments. |
|---|
| 15 | n/a | with open('outgoing.msg', 'rb') as fp: |
|---|
| 16 | n/a | msg = BytesParser(policy=policy.default).parse(fp) |
|---|
| 17 | n/a | |
|---|
| 18 | n/a | # Now the header items can be accessed as a dictionary, and any non-ASCII will |
|---|
| 19 | n/a | # be converted to unicode: |
|---|
| 20 | n/a | print('To:', msg['to']) |
|---|
| 21 | n/a | print('From:', msg['from']) |
|---|
| 22 | n/a | print('Subject:', msg['subject']) |
|---|
| 23 | n/a | |
|---|
| 24 | n/a | # If we want to print a priview of the message content, we can extract whatever |
|---|
| 25 | n/a | # the least formatted payload is and print the first three lines. Of course, |
|---|
| 26 | n/a | # if the message has no plain text part printing the first three lines of html |
|---|
| 27 | n/a | # is probably useless, but this is just a conceptual example. |
|---|
| 28 | n/a | simplest = msg.get_body(preferencelist=('plain', 'html')) |
|---|
| 29 | n/a | print() |
|---|
| 30 | n/a | print(''.join(simplest.get_content().splitlines(keepends=True)[:3])) |
|---|
| 31 | n/a | |
|---|
| 32 | n/a | ans = input("View full message?") |
|---|
| 33 | n/a | if ans.lower()[0] == 'n': |
|---|
| 34 | n/a | sys.exit() |
|---|
| 35 | n/a | |
|---|
| 36 | n/a | # We can extract the richest alternative in order to display it: |
|---|
| 37 | n/a | richest = msg.get_body() |
|---|
| 38 | n/a | partfiles = {} |
|---|
| 39 | n/a | if richest['content-type'].maintype == 'text': |
|---|
| 40 | n/a | if richest['content-type'].subtype == 'plain': |
|---|
| 41 | n/a | for line in richest.get_content().splitlines(): |
|---|
| 42 | n/a | print(line) |
|---|
| 43 | n/a | sys.exit() |
|---|
| 44 | n/a | elif richest['content-type'].subtype == 'html': |
|---|
| 45 | n/a | body = richest |
|---|
| 46 | n/a | else: |
|---|
| 47 | n/a | print("Don't know how to display {}".format(richest.get_content_type())) |
|---|
| 48 | n/a | sys.exit() |
|---|
| 49 | n/a | elif richest['content-type'].content_type == 'multipart/related': |
|---|
| 50 | n/a | body = richest.get_body(preferencelist=('html')) |
|---|
| 51 | n/a | for part in richest.iter_attachments(): |
|---|
| 52 | n/a | fn = part.get_filename() |
|---|
| 53 | n/a | if fn: |
|---|
| 54 | n/a | extension = os.path.splitext(part.get_filename())[1] |
|---|
| 55 | n/a | else: |
|---|
| 56 | n/a | extension = mimetypes.guess_extension(part.get_content_type()) |
|---|
| 57 | n/a | with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f: |
|---|
| 58 | n/a | f.write(part.get_content()) |
|---|
| 59 | n/a | # again strip the <> to go from email form of cid to html form. |
|---|
| 60 | n/a | partfiles[part['content-id'][1:-1]] = f.name |
|---|
| 61 | n/a | else: |
|---|
| 62 | n/a | print("Don't know how to display {}".format(richest.get_content_type())) |
|---|
| 63 | n/a | sys.exit() |
|---|
| 64 | n/a | with tempfile.NamedTemporaryFile(mode='w', delete=False) as f: |
|---|
| 65 | n/a | # The magic_html_parser has to rewrite the href="cid:...." attributes to |
|---|
| 66 | n/a | # point to the filenames in partfiles. It also has to do a safety-sanitize |
|---|
| 67 | n/a | # of the html. It could be written using html.parser. |
|---|
| 68 | n/a | f.write(magic_html_parser(body.get_content(), partfiles)) |
|---|
| 69 | n/a | webbrowser.open(f.name) |
|---|
| 70 | n/a | os.remove(f.name) |
|---|
| 71 | n/a | for fn in partfiles.values(): |
|---|
| 72 | n/a | os.remove(fn) |
|---|
| 73 | n/a | |
|---|
| 74 | n/a | # Of course, there are lots of email messages that could break this simple |
|---|
| 75 | n/a | # minded program, but it will handle the most common ones. |
|---|