if maintype ='multipart'multipart/*container continue elif fulltype ='message/rfc ' eskip message/rfc continue skip all message/tooelsefilenamecontype self partname(partixyield (filenamecontypepartdef partname(selfpartix)""extract filename and content type from message partfilenametries content-dispositionthen content-type name paramor generates one based on mimetype guess""filename part get_filename(filename in msg hdrscontype part get_content_type(lowercase maintype/subtype if not filenamefilename part get_param('name'try content-type name if not filenameif contype ='text/plain'hardcode plain text ext ext txtelse guesses kshelseext mimetypes guess_extension(contypeif not extext binuse generic default filename 'part-% % (ixextreturn (filenamecontypedef saveparts(selfsavedirmessage)""store all parts of message as files in local directoryreturns [('maintype/subtype''filename')list for use by callersbut does not open any parts or attachments hereget_payload decodes base quoted-printableuuencoded datamail parser may give us none payload for oddball types we probably should skip overconvert to str here to be safe""if not os path exists(savedir)os mkdir(savedirpartfiles [for (filenamecontypepartin self walknamedparts(message)fullname os path join(savedirfilenamefileobj open(fullname'wb'use binary mode content part get_payload(decode= decode base ,qp,uu if not isinstance(contentbytes) eneed bytes for rb content '(no content)decode= returns bytesfileobj write(contentbut some payloads none fileobj close( enot str(contentpartfiles append((contypefullname)for caller to open return partfiles def saveonepart(selfsavedirpartnamemessage)""dittobut find and save just one part by name "" client-side scripting