def process_email_ids(self, email_ids): self.set_status(ReaderStatus.READING) self.refresh_source() log.info("Processing messages from IMAP: %d "% (len(email_ids))) for email_id in email_ids: self.import_email(email_id) if self.status != ReaderStatus.READING: break # We imported mails, we need to re-thread self.source.db.flush() # Rethread emails globally (sigh) emails = self.source.db.query(Post).filter_by( discussion_id=self.source.discussion_id ).options(undefer(ImportedPost.imported_blob)).all() AbstractMailbox.thread_mails(emails) self.source.db.commit()
def do_read(self): only_new = not self.reimporting try: self.set_status(ReaderStatus.READING) mailbox = self.mailbox command = "ALL" search_status = None email_ids = None if only_new and self.source.last_imported_email_uid: command = "(UID %s:*)" % self.source.last_imported_email_uid search_status, search_result = mailbox.uid( 'search', None, command) if not is_ok((search_status, )): raise ReaderError(search_result) #log.debug( "UID searched with: "+ command + ", got result "+repr(search_status)+" and found "+repr(search_result)) email_ids = search_result[0].split() #log.debug( email_ids) if (only_new and search_status == 'OK' and email_ids and email_ids[0] == self.source.last_imported_email_uid): # Note: the email_ids[0]==self.source.last_imported_email_uid test is # necessary beacuse according to https://tools.ietf.org/html/rfc3501 # seq-range like "3291:* includes the UID of the last message in # the mailbox, even if that value is less than 3291." # discard the first message, it should be the last imported email. del email_ids[0] else: # Either: # a) we don't import only new messages or # b) the message with self.source.last_imported_email_uid hasn't been found # (may have been deleted) # In this case we request all messages and rely on duplicate # detection command = "ALL" search_status, search_result = mailbox.uid( 'search', None, command) if not is_ok((search_status, )): raise ReaderError(search_result) #log.debug( "UID searched with: "+ command + ", got result "+repr(search_status)+" and found "+repr(search_result)) email_ids = search_result[0].split() if len(email_ids): log.info("Processing messages from IMAP: %d " % (len(email_ids))) for email_id in email_ids: self.import_email(email_id) if self.status != ReaderStatus.READING: break from assembl.models import Post, AbstractMailbox # We imported mails, we need to re-thread self.source.db.flush() # Rethread emails globally (sigh) emails = self.source.db.query(Post).filter_by( discussion_id=self.source.discussion_id).options( undefer(ImportedPost.imported_blob)).all() AbstractMailbox.thread_mails(emails) self.source.db.flush() else: log.debug("No IMAP messages to process") self.successful_read() self.set_status(ReaderStatus.PAUSED) except IMAP4.abort as e: raise IrrecoverableError(e) except IMAP4.error as e: raise ClientError(e)