diff options
| -rw-r--r-- | changes/bug_5167_fix-notify-after-copy | 2 | ||||
| -rw-r--r-- | changes/bug_5177_fix_unread_signal_to_ui | 1 | ||||
| -rw-r--r-- | changes/bug_5179_delete_folder | 1 | ||||
| -rw-r--r-- | src/leap/mail/imap/account.py | 9 | ||||
| -rw-r--r-- | src/leap/mail/imap/mailbox.py | 70 | ||||
| -rw-r--r-- | src/leap/mail/imap/memorystore.py | 21 | 
6 files changed, 78 insertions, 26 deletions
| diff --git a/changes/bug_5167_fix-notify-after-copy b/changes/bug_5167_fix-notify-after-copy new file mode 100644 index 0000000..36ecd0b --- /dev/null +++ b/changes/bug_5167_fix-notify-after-copy @@ -0,0 +1,2 @@ +  o Fix bug in which destination folder sometimes was not showing messages after copy/append. +    Closes: #5167 diff --git a/changes/bug_5177_fix_unread_signal_to_ui b/changes/bug_5177_fix_unread_signal_to_ui new file mode 100644 index 0000000..eac79f2 --- /dev/null +++ b/changes/bug_5177_fix_unread_signal_to_ui @@ -0,0 +1 @@ +  o Fix unread notifications to client UI. Only INBOX is notified. Closes: #5177 diff --git a/changes/bug_5179_delete_folder b/changes/bug_5179_delete_folder new file mode 100644 index 0000000..3de52cc --- /dev/null +++ b/changes/bug_5179_delete_folder @@ -0,0 +1 @@ +  o Fix bug in which deleted folder wouldn't show its messages inside. Closes: #5179 diff --git a/src/leap/mail/imap/account.py b/src/leap/mail/imap/account.py index ede63d3..199a2a4 100644 --- a/src/leap/mail/imap/account.py +++ b/src/leap/mail/imap/account.py @@ -329,20 +329,13 @@ class SoledadBackedAccount(WithMsgFields, IndexedDB, MBoxParser):                  raise imap4.MailboxCollision(repr(new))          for (old, new) in inferiors: +            self._memstore.rename_fdocs_mailbox(old, new)              mbox = self._get_mailbox_by_name(old)              mbox.content[self.MBOX_KEY] = new              self._soledad.put_doc(mbox)          self._load_mailboxes() -        # XXX ---- FIXME!!!! ------------------------------------ -        # until here we just renamed the index... -        # We have to rename also the occurrence of this -        # mailbox on ALL the messages that are contained in it!!! -        # ... we maybe could use a reference to the doc_id -        # in each msg, instead of the "mbox" field in msgs -        # ------------------------------------------------------- -      def _inferiorNames(self, name):          """          Return hierarchically inferior mailboxes. diff --git a/src/leap/mail/imap/mailbox.py b/src/leap/mail/imap/mailbox.py index 947cf1b..503e38b 100644 --- a/src/leap/mail/imap/mailbox.py +++ b/src/leap/mail/imap/mailbox.py @@ -337,6 +337,8 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          """          if self._uidvalidity is None:              mbox = self._get_mbox_doc() +            if mbox is None: +                return 0              self._uidvalidity = mbox.content.get(self.CREATED_KEY, 1)          return self._uidvalidity @@ -371,15 +373,7 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          :rtype: int          """          with self.next_uid_lock: -            if self._memstore: -                return self.last_uid + 1 -            else: -                # XXX after lock, it should be safe to -                # return just the increment here, and -                # have a different method that actually increments -                # the counter when really adding. -                self.last_uid += 1 -                return self.last_uid +            return self.last_uid + 1      def getMessageCount(self):          """ @@ -474,7 +468,12 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          d = self._do_add_message(message, flags=flags, date=date)          if PROFILE_CMD:              do_profile_cmd(d, "APPEND") -        # XXX should notify here probably +        # A better place for this would be  the COPY/APPEND dispatcher +        # in server.py, but qtreactor hangs when I do that, so this seems +        # to work fine for now. +        d.addCallback(lambda r: self.reactor.callLater(0, self.notify_new)) +        d.addCallback(self.cb_signal_unread_to_ui) +        d.addErrback(lambda f: log.msg(f.getTraceback()))          return d      def _do_add_message(self, message, flags, date): @@ -485,7 +484,6 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          d = self.messages.add_msg(message, flags=flags, date=date)          return d -    @deferred_to_thread      def notify_new(self, *args):          """          Notify of new messages to all the listeners. @@ -494,13 +492,28 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          """          if not NOTIFY_NEW:              return + +        def cbNotifyNew(result): +            exists, recent = result +            for l in self.listeners: +                l.newMessages(exists, recent) +        d = self._get_notify_count() +        d.addCallback(cbNotifyNew) + +    @deferred_to_thread +    def _get_notify_count(self): +        """ +        Get message count and recent count for this mailbox +        Executed in a separate thread. Called from notify_new. + +        :return: number of messages and number of recent messages. +        :rtype: tuple +        """          exists = self.getMessageCount()          recent = self.getRecentCount()          logger.debug("NOTIFY (%r): there are %s messages, %s recent" % (              self.mbox, exists, recent)) - -        for l in self.listeners: -            l.newMessages(exists, recent) +        return exists, recent      # commands, do not rename methods @@ -595,6 +608,7 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          self.reactor.callInThread(self._do_fetch, messages_asked, uid, d)          if PROFILE_CMD:              do_profile_cmd(d, "FETCH") +        d.addCallback(self.cb_signal_unread_to_ui)          return d      # called in thread @@ -750,14 +764,27 @@ class SoledadMailbox(WithMsgFields, MBoxParser):              for msgid in seq_messg)          return result -    def signal_unread_to_ui(self, *args, **kwargs): +    def cb_signal_unread_to_ui(self, result):          """          Sends unread event to ui. +        Used as a callback in several commands. -        :param args: ignored -        :param kwargs: ignored +        :param result: ignored +        """ +        d = self._get_unseen_deferred() +        d.addCallback(self.__cb_signal_unread_to_ui) +        return result + +    @deferred_to_thread +    def _get_unseen_deferred(self): +        return self.getUnseenCount() + +    def __cb_signal_unread_to_ui(self, unseen): +        """ +        Send the unread signal to UI. +        :param unseen: number of unseen messages. +        :type unseen: int          """ -        unseen = self.getUnseenCount()          leap_events.signal(IMAP_UNREAD_MAIL, str(unseen))      def store(self, messages_asked, flags, mode, uid): @@ -798,6 +825,8 @@ class SoledadMailbox(WithMsgFields, MBoxParser):                                 mode, uid, d)          if PROFILE_CMD:              do_profile_cmd(d, "STORE") +        d.addCallback(self.cb_signal_unread_to_ui) +        d.addErrback(lambda f: log.msg(f.getTraceback()))          return d      def _do_store(self, messages_asked, flags, mode, uid, observer): @@ -880,6 +909,11 @@ class SoledadMailbox(WithMsgFields, MBoxParser):          d = defer.Deferred()          if PROFILE_CMD:              do_profile_cmd(d, "COPY") + +        # A better place for this would be  the COPY/APPEND dispatcher +        # in server.py, but qtreactor hangs when I do that, so this seems +        # to work fine for now. +        d.addCallback(lambda r: self.reactor.callLater(0, self.notify_new))          deferLater(self.reactor, 0, self._do_copy, message, d)          return d diff --git a/src/leap/mail/imap/memorystore.py b/src/leap/mail/imap/memorystore.py index 6206468..d383b79 100644 --- a/src/leap/mail/imap/memorystore.py +++ b/src/leap/mail/imap/memorystore.py @@ -1244,6 +1244,27 @@ class MemoryStore(object):          """          self.permanent_store.set_mbox_closed(mbox, closed) +    # Rename flag-documents + +    def rename_fdocs_mailbox(self, old_mbox, new_mbox): +        """ +        Change the mailbox name for all flag documents in a given mailbox. +        Used from account.rename + +        :param old_mbox: name for the old mbox +        :type old_mbox: str or unicode +        :param new_mbox: name for the new mbox +        :type new_mbox: str or unicode +        """ +        fs = self._fdoc_store +        keys = fs[old_mbox].keys() +        for k in keys: +            fdoc = fs[old_mbox][k] +            fdoc['mbox'] = new_mbox +            fs[new_mbox][k] = fdoc +            fs[old_mbox].pop(k) +            self._dirty.add((new_mbox, k)) +      # Dump-to-disk controls.      @property | 
