def deleteEmails( account, listUIDs ) : ''' This function deletes specified emails from a single account. It is meant to be called by a multi-thread execution routine for each account required. account: <DICTIONARY> Contains the settings associated with a particular account. Used to login to said account. listUIDs: <LIST> of <INTEGERS>. Contains the UIDs of the emails that are to be deleted from the specified account. ''' trashFolder = account[ 'trashFolder' ] # Get name of Trash Folder associated with specified account flagDeleteEmails = account[ 'deleteEmails' ] # Get boolean flag which indicates whether emails actually need to be physically deleted, or just copied. from imapServer import imapServer mail = imapServer( account['host'] ) mail.login( account['username'], account['password'] ) mail.select() # Now we have accessed the proper folder: # First we copy the emails to the Trash folder: mail.copy( listUIDs, trashFolder ) # We send the list of UIDs and the name of the trash folder to mail.copy() so that these emails can be copied in to the Trash Folder if flagDeleteEmails : # If the account setting indicates that emails are to be deleted after copying. Set to False for Gmail accounts. mail.delete( listUIDs ) # Provide mail.delete with list of UIDs. The method flags the emails for deletion on the IMAP server. mail.expunge() # This tells the IMAP server to actually delete the emails flagged as such mail.logout() # Logout gracefully from the account
def pollAccount( account ) : """ This function accepts a dictionary associated with a SINGLE account (a particular email address on a particular imap server) and carries out all the actions required to connect with said account (poll it) and get email information AND display it. """ # Note: The way this function is currently constructed it produces no direct ouput to stdout but rather stores it in a buffer class object which it returns. The calling function decides when to display the information. This has been done to facilitate the parallelizing of polling of the accounts. from imapServer import imapServer import re from copy import deepcopy cW = colorWidth # Rename function for easier typing and clarity numUnseen = -1 # Set unequal to zero in case showNums = False mail = imapServer( account['host'], account['useSSL'] ) # We pass in the useSSL flag that we get from config which tells imapServer whether SSL is to be used or not mail.login( account['username'], account['password'] ) mail.examine() out = Output( account ) # Create Output data structure for imminent population if account[ 'showNums' ] : try: (numAll, numUnseen) = mail.numMsgs() except TypeError: # This happens if an error occurred in connecting to the server and so numMsgs() returns a NoneType object out.error = True return out # In this case we return out with the error flag set to True out.numAll = numAll # Store numbers in output object out.numUnseen = numUnseen if not account[ 'showOnlyNums' ] : if account[ 'showUnseen' ] : # show only unseen emails from the folder ids = mail.getUids( "unseen" ) else : ids = mail.getUids( "all" ) out.uids = deepcopy( ids ) # Store the UIDs of the emails retrieived in the general output object if len( ids ) > 0 : # There has to be at least one email to fetch data or otherwise fetchHeaders will throw up an error data = mail.fetchHeaders( ids, ['from', 'subject', 'date'] ) if account[ 'latestEmailFirst' ] : # We define an anonymous function that modifies the order in which we access UIDs based on the configuration. ids.reverse() out.uids.reverse() # We must also flip the order in which the uids are stored so that the lines and uids match if len(ids) > 100 : # Get number of digits of total number of messages. numDigits = len( str( len(ids) ) ) # Used to get number of digits in the number for total number of messages. Crude Hack at best. else : numDigits = 2 out.numDigits = numDigits # Store the number of digits in the object related to the account reFrom = re.compile( '\"?([^<]*?)\"? <.*' ) # We begin by scanning all of the the uids extracted and storing the information in the Output object 'out': for uid in ids : email = Email() # Create a new Email object for insertion in out.emails line = data[ uid ] strFrom = '{:<30.30}'.format( line[ 'from' ] ) m = reFrom.match( strFrom ) if m: strFrom = m.group(1) email.From = emailHeader( strFrom ) # The From and Subject headers can be MIME encoded so we use emailHeader to parse them email.Date = convertDate( line[ 'date' ] ) email.Subject = emailHeader( line[ 'subject' ] ) email.uid = uid # Store the email's uid along with it for later usage out.emails.append( email ) # If we are dealing with all emails we may need additional information stored in 'out' if not account[ 'showUnseen' ] : # this means we are displaying ALL emails, seen and unseen dicFlags = mail.fetchFlags( ids ) reSeen = re.compile( '.*Seen.*' ) for ii in range( len( ids ) ) : m = reSeen.match( dicFlags[ ids[ ii ] ] ) if m : # Flag has a Seen flag. We store that information in 'out' out.emails[ ii ].Seen = True else : out.emails[ ii ].Seen = False else : # We are displaying only unSeen messages for ii in range( len( ids ) ) : out.emails[ ii ].Seen = False # Message is necessarily Unseen mail.logout() return out # Return the Output data structure we have just populated