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