""##############################################################################parsing and attachment extractanalysesave (see __init__ for docstest##############################################################################""import osmimetypessys import email parser import email header import email utils from email message import message from mailtool import mailtool mimemap type to name parse text to message object eheaders decode/encode eaddr header parse/decode message may be traversed epackage-relative class mailparser(mailtool)""methods for parsing message textattachments subtle thingmessage object payloads are either simple string for non-multipart messagesor list of message objects if multipart (possibly nested)we don' need to distinguish between the two cases herebecause the message walk generator always returns self firstand so works fine on non-multipart messages too ( single object is walked)for simple messagesthe message body is always considered here to be the sole part of the mailfor multipart messagesthe parts list includes the main message textas well as all attachmentsthis allows simple messages not of type text to be handled like attachments in ui ( savedopened)message payload may also be none for some oddball part types notein py text part payloads are returned as bytes for decode= and might be str otherwisein mailtoolstext is stored as bytes for file savesbut main-text bytes payloads are decoded to unicode str per mail header info or platform default+guessclients may need to convert other payloadspymailgui uses headers to decode parts saved to binary files supports fetched message header auto-decoding per its own contentboth for general headers such as subjectas well as for names in address header such as from and toclient must request this after parsebefore displayparser doesn' decode""def walknamedparts(selfmessage)""generator to avoid repeating part naming logicskips multipart headersmakes part filenamesmessage is already parsed email message message objectdoesn' skip oddball typespayload may be nonemust handle in part savessome others may warrant skips too""for (ixpartin enumerate(message walk())walk includes message fulltype part get_content_type(ix includes parts skipped the mailtools utility package