summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2015-06-29 11:57:20 -0400
committerKali Kaneko <kali@leap.se>2015-06-29 13:12:47 -0400
commit0dbf2be49db228e43fe4b196199f82ea281886bf (patch)
tree2bc5b874323915bad2669cdd5085954bcbc3e418
parentc0f3a6afa81f93f8d1b078a62e4411b2321ba9f0 (diff)
[bug] allow mailbox to be notified of collection changes
in a previous refactor, we decoupled the incoming mail service from the IMAP layer. However, this left the IMAPMailbox unable to react to changes in the underlying collection when a new message is inserted. in this commit, we add a Listener mechanism to the collection itself, so that IMAPMailbox (and any other object that uses it) can subscribe to changes on the number of messages of the collection. Resolves: #7191 Releases: 0.4.0
-rw-r--r--src/leap/mail/adaptors/soledad.py2
-rw-r--r--src/leap/mail/imap/mailbox.py14
-rw-r--r--src/leap/mail/mail.py16
3 files changed, 28 insertions, 4 deletions
diff --git a/src/leap/mail/adaptors/soledad.py b/src/leap/mail/adaptors/soledad.py
index 4020bd0..2b1d2ff 100644
--- a/src/leap/mail/adaptors/soledad.py
+++ b/src/leap/mail/adaptors/soledad.py
@@ -505,6 +505,8 @@ class MessageWrapper(object):
(key, get_doc_wrapper(doc, ContentDocWrapper))
for (key, doc) in cdocs.items()])
for doc_id, cdoc in zip(self.mdoc.cdocs, self.cdocs.values()):
+ if cdoc.raw == "":
+ log.msg("Empty raw field in cdoc %s" % doc_id)
cdoc.set_future_doc_id(doc_id)
def create(self, store, notify_just_mdoc=False, pending_inserts_dict={}):
diff --git a/src/leap/mail/imap/mailbox.py b/src/leap/mail/imap/mailbox.py
index 139ae66..0de4b40 100644
--- a/src/leap/mail/imap/mailbox.py
+++ b/src/leap/mail/imap/mailbox.py
@@ -91,6 +91,8 @@ class IMAPMailbox(object):
imap4.IMailboxInfo,
imap4.ISearchableMailbox,
# XXX I think we do not need to implement CloseableMailbox, do we?
+ # We could remove ourselves from the collectionListener, although I
+ # think it simply will be garbage collected.
# imap4.ICloseableMailbox
imap4.IMessageCopier)
@@ -116,6 +118,7 @@ class IMAPMailbox(object):
self.rw = rw
self._uidvalidity = None
self.collection = collection
+ self.collection.addListener(self)
@property
def mbox_name(self):
@@ -155,9 +158,10 @@ class IMAPMailbox(object):
if not NOTIFY_NEW:
return
+ listeners = self.listeners
logger.debug('adding mailbox listener: %s. Total: %s' % (
- listener, len(self.listeners)))
- self.listeners.add(listener)
+ listener, len(listeners)))
+ listeners.add(listener)
def removeListener(self, listener):
"""
@@ -371,13 +375,16 @@ class IMAPMailbox(object):
d = self.collection.add_msg(message, flags, date=date,
notify_just_mdoc=notify_just_mdoc)
- d.addCallback(self.notify_new)
d.addErrback(lambda failure: log.err(failure))
return d
def notify_new(self, *args):
"""
Notify of new messages to all the listeners.
+ This will be called indirectly by the underlying collection, that will
+ notify this IMAPMailbox whenever there are changes in the number of
+ messages in the collection, since we have added ourselves to the
+ collection listeners.
:param args: ignored.
"""
@@ -392,6 +399,7 @@ class IMAPMailbox(object):
d = self._get_notify_count()
d.addCallback(cbNotifyNew)
d.addCallback(self.collection.cb_signal_unread_to_ui)
+ d.addErrback(lambda failure: log.err(failure))
def _get_notify_count(self):
"""
diff --git a/src/leap/mail/mail.py b/src/leap/mail/mail.py
index faaabf6..4a73186 100644
--- a/src/leap/mail/mail.py
+++ b/src/leap/mail/mail.py
@@ -378,6 +378,7 @@ class MessageCollection(object):
# of by doc_id. See get_message_by_content_hash
self.mbox_indexer = mbox_indexer
self.mbox_wrapper = mbox_wrapper
+ self._listeners = set([])
def is_mailbox_collection(self):
"""
@@ -639,11 +640,24 @@ class MessageCollection(object):
notify_just_mdoc=notify_just_mdoc,
pending_inserts_dict=self._pending_inserts)
d.addCallback(insert_mdoc_id, wrapper)
- d.addErrback(lambda failure: log.err(failure))
d.addCallback(self.cb_signal_unread_to_ui)
+ d.addCallback(self.notify_new_to_listeners)
+ d.addErrback(lambda failure: log.err(failure))
return d
+ # Listeners
+
+ def addListener(self, listener):
+ self._listeners.add(listener)
+
+ def removeListener(self, listener):
+ self._listeners.remove(listener)
+
+ def notify_new_to_listeners(self, *args):
+ for listener in self._listeners:
+ listener.notify_new()
+
def cb_signal_unread_to_ui(self, result):
"""
Sends an unread event to ui, passing *only* the number of unread