예제 #1
0
 def get_uids_in_db(self):
     """
     Returns the UIDs of messages in this mailbox & stored in the DB
     """
     uids = set()
     threads = Thread.objects(mailboxes=self.id)
     for t in threads:
         for m in t.messages:
             if self.id in m.mailboxes:
                 uids.add(m.get_uid(self.id))
     return uids
예제 #2
0
    def handle_new_messages(self, messages):
        account_mailboxes = self.imap.directories.values_list("id", flat=True)
        for message in messages:
            if message.message_id is None and message.in_reply_to is None:
                message.assign_new_thread()
                continue

            qs = []
            if message.message_id is not None:
                qs.append({"messages__in_reply_to": message.message_id})
            if message.in_reply_to is not None:
                qs.append({"messages__message_id": message.in_reply_to})
                qs.append({"messages__in_reply_to": message.in_reply_to})

            threads = set()
            for query in qs:
                for t in Thread.objects(mailboxes__in=account_mailboxes).filter(**query):
                    threads.add(t)

            if not threads:
                subject = clean_subject(message.subject)
                if subject != message.subject:
                    # This is a Re: RE or whatever without any In-Reply-To.
                    # Trying to guess which thread it's in.
                    thrds = Thread.objects(mailboxes__in=account_mailboxes)
                    thrds = thrds.filter(messages__subject=subject)
                    for t in thrds.order_by("-date"):
                        threads.add(t)
                        break

            if not threads:
                message.assign_new_thread()
                continue

            current_thread = threads.pop()
            if len(threads) > 0:  # Merge threads
                for thread in threads:
                    current_thread.merge_with(thread, self.id)
            current_thread.add_message(message, self.id)
예제 #3
0
    def update_messages(self, connection=None):
        if connection is None:
            m = self.imap.get_connection()
        else:
            m = connection

        db_uids = self.get_uids_in_db()
        imap_uids = set(self.get_uids(connection=m))

        remove_from_db = list(db_uids - imap_uids)
        remove_from_db = [[self.id, uid] for uid in remove_from_db]
        threads_remove = Thread.objects(mailboxes=self.id, messages__uids__in=remove_from_db)
        for t in threads_remove:
            t.remove_message(self.id, remove_from_db)

        fetch_from_imap = map(str, list(imap_uids - db_uids))

        messages = ()
        if fetch_from_imap:
            print "Updating %s messages" % len(fetch_from_imap)
            while len(fetch_from_imap) > 1000:
                print "%s remaining" % len(fetch_from_imap)
                fetch_this = fetch_from_imap[:1000]
                fetch_from_imap = fetch_from_imap[1000:]
                messages = self.list_messages(force_uids=fetch_this, connection=m)
                self.handle_new_messages(messages)
            messages = self.list_messages(force_uids=fetch_from_imap, connection=m)
            self.handle_new_messages(messages)

        m.select_folder(self.name)
        unseen = m.search(["NOT SEEN"])
        m.close_folder()

        if connection is None:
            m.logout()

        threads = Thread.objects(mailboxes=self.id)
        for t in threads:
            t.ensure_unread(self.id, unseen)
예제 #4
0
 def unread_threads(self):
     if not hasattr(self, "_unread_threads"):
         self._unread_threads = Thread.objects(mailboxes=self.id, messages__read=False).count()
     return self._unread_threads