diff options
-rw-r--r-- | mail/changes/bug_5167_fix-notify-after-copy | 2 | ||||
-rw-r--r-- | mail/changes/bug_5177_fix_unread_signal_to_ui | 1 | ||||
-rw-r--r-- | mail/changes/bug_5179_delete_folder | 1 | ||||
-rw-r--r-- | mail/src/leap/mail/imap/account.py | 9 | ||||
-rw-r--r-- | mail/src/leap/mail/imap/mailbox.py | 70 | ||||
-rw-r--r-- | mail/src/leap/mail/imap/memorystore.py | 21 |
6 files changed, 78 insertions, 26 deletions
diff --git a/mail/changes/bug_5167_fix-notify-after-copy b/mail/changes/bug_5167_fix-notify-after-copy new file mode 100644 index 00000000..36ecd0b7 --- /dev/null +++ b/mail/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/mail/changes/bug_5177_fix_unread_signal_to_ui b/mail/changes/bug_5177_fix_unread_signal_to_ui new file mode 100644 index 00000000..eac79f24 --- /dev/null +++ b/mail/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/mail/changes/bug_5179_delete_folder b/mail/changes/bug_5179_delete_folder new file mode 100644 index 00000000..3de52ccc --- /dev/null +++ b/mail/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/mail/src/leap/mail/imap/account.py b/mail/src/leap/mail/imap/account.py index ede63d38..199a2a46 100644 --- a/mail/src/leap/mail/imap/account.py +++ b/mail/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/mail/src/leap/mail/imap/mailbox.py b/mail/src/leap/mail/imap/mailbox.py index 947cf1bc..503e38bd 100644 --- a/mail/src/leap/mail/imap/mailbox.py +++ b/mail/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/mail/src/leap/mail/imap/memorystore.py b/mail/src/leap/mail/imap/memorystore.py index 6206468d..d383b79c 100644 --- a/mail/src/leap/mail/imap/memorystore.py +++ b/mail/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 |