summaryrefslogtreecommitdiff
path: root/src/leap/mail/mail.py
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2015-01-07 12:12:24 -0400
committerKali Kaneko <kali@leap.se>2015-02-11 14:05:43 -0400
commit9c40103a3c3dcdb3e4c4edae9f466f1701e022fc (patch)
treeca7c482e10a8084609816ee4f2c21534cf6da97a /src/leap/mail/mail.py
parentf7030295a936cc5da33f50411b5ff60ae0eec7cc (diff)
Complete IMAP implementation, update tests
Diffstat (limited to 'src/leap/mail/mail.py')
-rw-r--r--src/leap/mail/mail.py114
1 files changed, 93 insertions, 21 deletions
diff --git a/src/leap/mail/mail.py b/src/leap/mail/mail.py
index b2caa33..8137f97 100644
--- a/src/leap/mail/mail.py
+++ b/src/leap/mail/mail.py
@@ -172,7 +172,7 @@ class Message(object):
:return: An RFC822-formatted date string.
:rtype: str
"""
- return self._wrapper.fdoc.date
+ return self._wrapper.hdoc.date
# imap.IMessageParts
@@ -271,9 +271,10 @@ class MessageCollection(object):
store = None
messageklass = Message
- def __init__(self, adaptor, store, mbox_indexer=None, mbox_wrapper=None):
+ def __init__(self, adaptor, store, mbox_indexer=None, mbox_wrapper=None,
+ count=None):
"""
- Constructore for a MessageCollection.
+ Constructor for a MessageCollection.
"""
self.adaptor = adaptor
self.store = store
@@ -317,7 +318,7 @@ class MessageCollection(object):
wrapper = getattr(self, "mbox_wrapper", None)
if not wrapper:
return None
- return wrapper.mbox_uuid
+ return wrapper.uuid
def get_mbox_attr(self, attr):
return getattr(self.mbox_wrapper, attr)
@@ -364,10 +365,18 @@ class MessageCollection(object):
self.messageklass, self.store,
doc_id, uid=uid, get_cdocs=get_cdocs)
- d = self.mbox_indexer.get_doc_id_from_uid(self.mbox_name, uid)
+ d = self.mbox_indexer.get_doc_id_from_uid(self.mbox_uuid, uid)
d.addCallback(get_msg_from_mdoc_id)
return d
+ # TODO deprecate ??? ---
+ def _prime_count(self):
+ def update_count(count):
+ self._count = count
+ d = self.mbox_indexer.count(self.mbox_name)
+ d.addCallback(update_count)
+ return d
+
def count(self):
"""
Count the messages in this collection.
@@ -376,7 +385,17 @@ class MessageCollection(object):
"""
if not self.is_mailbox_collection():
raise NotImplementedError()
- return self.mbox_indexer.count(self.mbox_name)
+
+ d = self.mbox_indexer.count(self.mbox_uuid)
+ return d
+
+ def count_recent(self):
+ # FIXME HACK
+ return 0
+
+ def count_unseen(self):
+ # FIXME hack
+ return 0
def get_uid_next(self):
"""
@@ -385,7 +404,13 @@ class MessageCollection(object):
:return: a Deferred that will fire with the integer for the next uid.
:rtype: Deferred
"""
- return self.mbox_indexer.get_next_uid(self.mbox_name)
+ return self.mbox_indexer.get_next_uid(self.mbox_uuid)
+
+ def all_uid_iter(self):
+ """
+ Iterator through all the uids for this collection.
+ """
+ return self.mbox_indexer.all_uid_iter(self.mbox_uuid)
# Manipulate messages
@@ -397,6 +422,7 @@ class MessageCollection(object):
flags = tuple()
if not tags:
tags = tuple()
+
leap_assert_type(flags, tuple)
leap_assert_type(date, str)
@@ -408,10 +434,10 @@ class MessageCollection(object):
else:
mbox_id = self.mbox_uuid
+ wrapper.set_mbox_uuid(mbox_id)
wrapper.set_flags(flags)
wrapper.set_tags(tags)
wrapper.set_date(date)
- wrapper.set_mbox_uuid(mbox_id)
def insert_mdoc_id(_, wrapper):
doc_id = wrapper.mdoc.doc_id
@@ -420,6 +446,8 @@ class MessageCollection(object):
d = wrapper.create(self.store)
d.addCallback(insert_mdoc_id, wrapper)
+ d.addErrback(lambda f: f.printTraceback())
+
return d
def copy_msg(self, msg, newmailbox):
@@ -453,8 +481,47 @@ class MessageCollection(object):
d.addCallback(delete_mdoc_id, wrapper)
return d
+ def delete_all_flagged(self):
+ """
+ Delete all messages flagged as \\Deleted.
+ Used from IMAPMailbox.expunge()
+ """
+ def get_uid_list(hashes):
+ d = []
+ for h in hashes:
+ d.append(self.mbox_indexer.get_uid_from_doc_id(
+ self.mbox_uuid, h))
+ return defer.gatherResults(d), hashes
+
+ def delete_uid_entries((uids, hashes)):
+ d = []
+ for h in hashes:
+ d.append(self.mbox_indexer.delete_doc_by_hash(
+ self.mbox_uuid, h))
+ return defer.gatherResults(d).addCallback(
+ lambda _: uids)
+
+ mdocs_deleted = self.adaptor.del_all_flagged_messages(
+ self.store, self.mbox_uuid)
+ mdocs_deleted.addCallback(get_uid_list)
+ mdocs_deleted.addCallback(delete_uid_entries)
+ return mdocs_deleted
+
# TODO should add a delete-by-uid to collection?
+ def delete_all_docs(self):
+ def del_all_uid(uid_list):
+ deferreds = []
+ for uid in uid_list:
+ d = self.get_message_by_uid(uid)
+ d.addCallback(lambda msg: msg.delete())
+ deferreds.append(d)
+ return defer.gatherResults(deferreds)
+
+ d = self.all_uid_iter()
+ d.addCallback(del_all_uid)
+ return d
+
def _update_flags_or_tags(self, old, new, mode):
if mode == Flagsmode.APPEND:
final = list((set(tuple(old) + new)))
@@ -509,45 +576,49 @@ class Account(object):
adaptor_class = SoledadMailAdaptor
store = None
- def __init__(self, store):
+ def __init__(self, store, ready_cb=None):
self.store = store
self.adaptor = self.adaptor_class()
self.mbox_indexer = MailboxIndexer(self.store)
+ self.deferred_initialization = defer.Deferred()
self._initialized = False
- self._deferred_initialization = defer.Deferred()
+ self._ready_cb = ready_cb
- self._initialize_storage()
+ self._init_d = self._initialize_storage()
def _initialize_storage(self):
def add_mailbox_if_none(mboxes):
if not mboxes:
- self.add_mailbox(INBOX_NAME)
+ return self.add_mailbox(INBOX_NAME)
def finish_initialization(result):
self._initialized = True
- self._deferred_initialization.callback(None)
+ self.deferred_initialization.callback(None)
+ if self._ready_cb is not None:
+ self._ready_cb()
d = self.adaptor.initialize_store(self.store)
d.addCallback(lambda _: self.list_all_mailbox_names())
d.addCallback(add_mailbox_if_none)
d.addCallback(finish_initialization)
+ return d
def callWhenReady(self, cb, *args, **kw):
- # use adaptor.store_ready instead?
if self._initialized:
cb(self, *args, **kw)
return defer.succeed(None)
else:
- self._deferred_initialization.addCallback(cb, *args, **kw)
- return self._deferred_initialization
+ self.deferred_initialization.addCallback(cb, *args, **kw)
+ return self.deferred_initialization
#
# Public API Starts
#
def list_all_mailbox_names(self):
+
def filter_names(mboxes):
return [m.mbox for m in mboxes]
@@ -563,8 +634,11 @@ class Account(object):
def create_uuid(wrapper):
if not wrapper.uuid:
- wrapper.uuid = uuid.uuid4()
- return wrapper.update(self.store)
+ wrapper.uuid = str(uuid.uuid4())
+ d = wrapper.update(self.store)
+ d.addCallback(lambda _: wrapper)
+ return d
+ return wrapper
def create_uid_table_cb(wrapper):
d = self.mbox_indexer.create_table(wrapper.uuid)
@@ -599,7 +673,7 @@ class Account(object):
def _rename_mbox(wrapper):
wrapper.mbox = newname
- return wrapper.update(self.store)
+ return wrapper, wrapper.update(self.store)
d = self.adaptor.get_or_create_mbox(self.store, oldname)
d.addCallback(_rename_mbox)
@@ -616,8 +690,6 @@ class Account(object):
return MessageCollection(
self.adaptor, self.store, self.mbox_indexer, mbox_wrapper)
- mboxwrapper_klass = self.adaptor.mboxwrapper_klass
- #d = mboxwrapper_klass.get_or_create(name)
d = self.adaptor.get_or_create_mbox(self.store, name)
d.addCallback(get_collection_for_mailbox)
return d