def onMime(self, who, data): ''' Handles incoming MIME messages, such as those sent by NotesBuddy containing embedded image data ''' from email.Parser import Parser from StringIO import StringIO print '<mime>%s' % who[0] msg = Parser().parsestr(data) html = StringIO() # combined text segments images = {} # map of Content-ID:binary image for part in msg.walk(): mt = part.get_content_maintype() if mt == 'text': html.write(part.get_payload(decode=True)) elif mt == 'image': cid = part.get('Content-ID') images[cid] = part.get_payload(decode=True) print ' <text/html>:', html.getvalue() html.close() print ' <images>:', [k[1:-1] for k in images.keys()]
f = open("tmp.mime", 'w') except Exception, e: print >> sys.stderr, e else: f.write(data) f.close() # second, parse and display msg = Parser().parsestr(data) html = StringIO() # combined text segments images = {} # map of Content-ID:binary image for part in msg.walk(): mt = part.get_content_maintype() if mt == 'text': html.write(part.get_payload(decode=True)) elif mt == 'image': cid = part.get('Content-ID') images[cid] = part.get_payload(decode=True) print ' <text/html>:', html.getvalue() html.close() print ' <images>:', [k[1:-1] for k in images.keys()] def onSubject(self, who, subj): print '<subject>%s: "%s"' % (who[0], subj)
def fetch(folder, username, password, server='imap.gmail.com', archive=True, archive_folder=None, accept_only=None): """ Connects over IMAP to a mailbox and extracts attachments from all emails folder The IMAP folder name to parse for emails server The IMAP server URL username The username to connect to IMAP with password The username to connect to IMAP with archive Optionally move completed emails to a different folder (default: True) archive_folder: The folder to move completed mails to (default: folder + "_archive") accept_only (list): One or more file type suffixes to extract from emails, from this list: csv excel zip gz (Default: any from that list) """ mime_types = [] if accept_only is None: accept_only = ('csv', 'excel', 'zip', 'gz') if 'csv' in accept_only: mime_types.extend(['text/csv', 'application/csv']) if 'zip' in accept_only: mime_types.extend([ 'application/zip', 'multipart/x-zip', 'application/x-zip-compressed', 'application/octet-stream', ]) if 'gz' in accept_only: mime_types.extend(['application/x-gzip', 'multipart/x-gzip']) if 'excel' in accept_only: mime_types.extend([ 'vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', 'application/octet-stream', ]) # default the IMAP archive folder for completed emails if archive and archive_folder is None: archive_folder = "{0}_archive".format(folder) try: # login to IMAP M = imaplib.IMAP4_SSL(server) M.login(username, password) except socket.gaierror: raise Exception("Bad credentials for IMAP server {0}".format(server)) files = [] to_archive = [] try: # look at all mail in this IMAP folder result, data = M.select(folder) result, data = M.search(None, "ALL") id_list = data[0].split() for id in id_list: result, data = M.fetch(id, "(RFC822)") content = data[0][1] if sys.version < '3': msg = Parser().parsestr(content) else: msg = Parser().parsestr(content.decode('utf-8')) # only look at if has attachment. if msg.is_multipart(): for part in msg.walk(): if part.get_content_type() in mime_types: # download attachment into temp file tmpfile = tempfile.mkstemp(part.get_filename()) tmp_fhandle, tmp_fname = tmpfile if sys.version < '3': with os.fdopen(tmp_fhandle, "w") as f: f.write(part.get_payload(decode=True)) else: with os.fdopen(tmp_fhandle, "wb") as f: f.write(part.get_payload(decode=True)) # decompress zip/gz into contained files if _is_compressed(tmp_fname): files.extend(_extract_csvs_from_zip(tmp_fname)) else: files.append(tmp_fname) # mark this email for archival if archive is True: to_archive.append(str(id)) # move mails from mailbox to archive_mbox if len(to_archive) > 0: message_set = ",".join(to_archive) M.copy(message_set, archive_folder) M.store(message_set, "+FLAGS", r"(\Deleted)") M.expunge() finally: # close the mailbox and disconnect the IMAP connection M.close() M.logout() return files