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()
Beispiel #2
0
    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)