Fetch pop3 email using Python
Fetchs POP3 mail using poplib and email module:
The Code
# -*- coding: utf-8 -*- import poplib import email import email.Parser import email.header import os import sys import base64 from optparse import OptionParser __version__ = u'0.0.1' __author__ = u'MeaCulpa ' __all__ = [u'fetchmail'] class email_attachment: def __init__(self, messagenum, attachmentnum, filename, contents): ''' arguments: messagenum - message number of this message in the Inbox attachmentnum - attachment number for this attachment filename - filename for this attachment contents - attachment contents ''' self.messagenum=messagenum self.attachmentnum=attachmentnum self.filename=filename self.contents=contents return def save(self, savepath, savefilename=None): ''' Method to save the contents of an attachment to a file arguments: savepath - path where file is to be saved safefilename - optional name (if None will use filename of attachment ''' savefilename=savefilename or self.filename f=open(os.path.join(savepath, savefilename),"wb") f.write(self.contents) f.close() return class email_msg: def __init__(self, messagenum, contents): self.messagenum=messagenum self.contents=contents self.attachments_index=0 # Index of attachments for next method self.ATTACHMENTS=[] # List of attachment objects self.msglines='\n'.join(contents[1]) # # See if I can parse the message lines with email.Parser # self.msg=email.Parser.Parser().parsestr(self.msglines) if self.msg.is_multipart(): attachmentnum=0 for part in self.msg.walk(): # multipart/* are just containers mptype=part.get_content_maintype() filename = part.get_filename() if mptype == "multipart": continue if filename: # Attached object with filename attachmentnum+=1 self.ATTACHMENTS.append(email_attachment(messagenum, attachmentnum, filename, part.get_payload(decode=1))) print "Attachment filename=%s" % filename else: # Must be body portion of multipart self.body=base64.b64decode(part.get_payload()) else: # Not multipart, only body portion exists self.body=base64.b64decode(self.msg.get_payload()) return def get(self, key): try: return self.msg.get(key) except: emsg="email_msg-Unable to get email key=%s information" % key print emsg sys.exit(emsg) def has_attachments(self): return (len(self.ATTACHMENTS) > 0) def __iter__(self): return self def next(self): # # Try to get the next attachment # try: ATTACHMENT=self.ATTACHMENTS[self.attachments_index] except: self.attachments_index=0 raise StopIteration # # Increment the index pointer for the next call # self.attachments_index+=1 return ATTACHMENT class pop3_inbox: def __init__(self, server, userid, password): self._trace=0 if self._trace: print "pop3_inbox.__init__-Entering" self.result=0 # Result of server communication self.MESSAGES=[] # List for storing message objects self.messages_index=0 # Index of message for next method # # See if I can connect using information provided # try: if self._trace: print "pop3_inbox.__init__-Calling poplib.POP3(server)" self.connection=poplib.POP3(server) if self._trace: print "pop3_inbox.__init__-Calling connection.user(userid)" self.connection.user(userid) if self._trace: print "pop3_inbox.__init__-Calling connection.pass_(password)" self.connection.pass_(password) except: if self._trace: print "pop3_inbox.__init__-Login failure, closing connection" self.result=1 self.connection.quit() # # Get count of messages and size of mailbox # if self._trace: print "pop3_inbox.__init__-Calling connection.stat()" self.msgcount, self.size=self.connection.stat() # # Loop over all the messages processing each one in turn # for msgnum in range(1, self.msgcount+1): self.MESSAGES.append(email_msg(msgnum, self.connection.retr(msgnum))) if self._trace: print "pop3_inbox.__init__-Leaving" return def close(self): self.connection.quit() return def remove(self, msgnumorlist): if isinstance(msgnumorlist, int): self.connection.dele(msgnumorlist) elif isinstance(msgnumorlist, (list, tuple)): map(self.connection.dele, msgnumorlist) else: emsg="pop3_inbox.remove-msgnumorlist must be type int, list, or tuple, not %s" % type(msgnumorlist) print emsg sys.exit(emsg) return def __iter__(self): return self def next(self): # # Try to get the next attachment # try: MESSAGE=self.MESSAGES[self.messages_index] except: self.messages_index=0 raise StopIteration # # Increment the index pointer for the next call # self.messages_index+=1 return MESSAGE if __name__=="__main__": # parse commandline options optparse = OptionParser(version=__version__) optparse.add_option('-s', '--server', dest = 'server', default = '', help = 'smtp server') optparse.add_option('-u', '--userid', dest = 'userid', default = '', help = 'smtp userid') optparse.add_option('-p', '--password', dest = 'password', default = '', help = 'smtp password') opts, args = optparse.parse_args() if args: optparse.error(u'invalid arguments') sys.exit() #if in-sufficient option print help if len(sys.argv) < 3: optparse.print_help() sys.exit() inbox=pop3_inbox(opts.server, opts.userid, opts.password) if inbox.result: emsg="Failure connecting to pop3_inbox" print emsg sys.exit(emsg) print "Message count=%i, Inbox size=%i" % (inbox.msgcount, inbox.size) counter=0 for m in inbox: counter+=1 print "Subject: %s" % email.header.decode_header(m.get('subject'))[0][0] print "-------------Message (%i) body lines---------------" % counter print m.body print "-------------End message (%i) body lines-----------" % counter if m.has_attachments(): acounter=0 for a in m: acounter+=1 print "-------------Message (%i) attachments-------------" % counter print "%i: %s" % (acounter, a.filename) print "-------------End message (%i) attachments---------" % counter a.save(os.path.join(os.getcwd(), u'tmp')) else: print "-------------Message has no attachments----------" inbox.close()

Discussion