From ff57477e5ef84f85985f0531d6d745aa45529145 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 21 Jan 2015 00:50:27 -0400 Subject: imap: implement setting of message flags --- src/leap/mail/imap/mailbox.py | 51 +++++++++++++++++++++++------------------- src/leap/mail/imap/messages.py | 23 ------------------- src/leap/mail/imap/server.py | 6 ----- src/leap/mail/mail.py | 38 +++++++++---------------------- 4 files changed, 39 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/leap/mail/imap/mailbox.py b/src/leap/mail/imap/mailbox.py index a000133..58fc514 100644 --- a/src/leap/mail/imap/mailbox.py +++ b/src/leap/mail/imap/mailbox.py @@ -231,7 +231,7 @@ class IMAPMailbox(object): """ return self.collection.get_mbox_attr("created") - def getUID(self, message): + def getUID(self, message_number): """ Return the UID of a message in the mailbox @@ -239,15 +239,15 @@ class IMAPMailbox(object): but in the future will be useful to get absolute UIDs from message sequence numbers. - :param message: the message uid + :param message: the message sequence number. :type message: int :rtype: int + :return: the UID of the message. """ - # TODO --- return the uid if it has it!!! - d = self.collection.get_msg_by_uid(message) - d.addCallback(lambda m: m.getUID()) - return d + # TODO support relative sequences. The (imap) message should + # receive a sequence number attribute: a deferred is not expected + return message_number def getUIDNext(self): """ @@ -451,15 +451,6 @@ class IMAPMailbox(object): def _close_cb(self, result): self.closed = True - # TODO server already calls expunge for closing - #def close(self): - #""" - #Expunge and mark as closed - #""" - #d = self.expunge() - #d.addCallback(self._close_cb) - #return d - def expunge(self): """ Remove all messages flagged \\Deleted @@ -641,9 +632,6 @@ class IMAPMailbox(object): return map(str, self.flags) def pack_flags(result): - #if result is None: - #print "No result" - #return _uid, _flags = result return _uid, flagsPart(_uid, _flags) @@ -790,14 +778,31 @@ class IMAPMailbox(object): :type observer: deferred """ # XXX implement also sequence (uid = 0) - # XXX we should prevent client from setting Recent flag? + # TODO we should prevent client from setting Recent flag leap_assert(not isinstance(flags, basestring), "flags cannot be a string") flags = tuple(flags) - messages_asked = self._bound_seq(messages_asked) - seq_messg = self._filter_msg_seq(messages_asked) - self.collection.set_flags( - self.mbox_name, seq_messg, flags, mode, observer) + + def set_flags_for_seq(sequence): + + def return_result_dict(list_of_flags): + result = dict(zip(list(sequence), list_of_flags)) + observer.callback(result) + return result + + d_all_set = [] + for msgid in sequence: + d = self.collection.get_message_by_uid(msgid) + d.addCallback(lambda msg: self.collection.update_flags( + msg, flags, mode)) + d_all_set.append(d) + got_flags_setted = defer.gatherResults(d_all_set) + got_flags_setted.addCallback(return_result_dict) + return got_flags_setted + + d_seq = self._get_sequence_of_messages(messages_asked) + d_seq.addCallback(set_flags_for_seq) + return d_seq # ISearchableMailbox diff --git a/src/leap/mail/imap/messages.py b/src/leap/mail/imap/messages.py index d4b5d1f..df50323 100644 --- a/src/leap/mail/imap/messages.py +++ b/src/leap/mail/imap/messages.py @@ -73,29 +73,6 @@ class IMAPMessage(object): """ return self.message.get_flags() - # setFlags not in the interface spec but we use it with store command. - - # XXX if we can move it to a collection method, we don't need to pass - # collection to the IMAPMessage - - # lookup method? IMAPMailbox? - - #def setFlags(self, flags, mode): - #""" - #Sets the flags for this message -# - #:param flags: the flags to update in the message. - #:type flags: tuple of str - #:param mode: the mode for setting. 1 is append, -1 is remove, 0 set. - #:type mode: int - #""" - #leap_assert(isinstance(flags, tuple), "flags need to be a tuple") - # XXX - # return new flags - # map to str - #self.message.set_flags(flags, mode) - #self.collection.update_flags(self.message, flags, mode) - def getInternalDate(self): """ Retrieve the date internally associated with this message diff --git a/src/leap/mail/imap/server.py b/src/leap/mail/imap/server.py index 38a3fd4..f294f42 100644 --- a/src/leap/mail/imap/server.py +++ b/src/leap/mail/imap/server.py @@ -112,7 +112,6 @@ class LEAPIMAPServer(imap4.IMAP4Server): ebFetch = self._IMAP4Server__ebFetch if len(query) == 1 and str(query[0]) == "flags": - print ">>>>>>>>> fetching flags" self._oldTimeout = self.setTimeout(None) # no need to call iter, we get a generator maybeDeferred( @@ -122,7 +121,6 @@ class LEAPIMAPServer(imap4.IMAP4Server): ).addErrback(ebFetch, tag) elif len(query) == 1 and str(query[0]) == "rfc822.header": - print ">>>>>>>> fetching headers" self._oldTimeout = self.setTimeout(None) # no need to call iter, we get a generator maybeDeferred( @@ -131,7 +129,6 @@ class LEAPIMAPServer(imap4.IMAP4Server): cbFetch, tag, query, uid ).addErrback(ebFetch, tag) else: - print ">>>>>>> Fetching other" self._oldTimeout = self.setTimeout(None) # no need to call iter, we get a generator maybeDeferred( @@ -370,7 +367,6 @@ class LEAPIMAPServer(imap4.IMAP4Server): # TODO subscribe method had also to be changed to accomodate deferred def do_SUBSCRIBE(self, tag, name): - print "DOING SUBSCRIBE" name = self._parseMbox(name) def _subscribeCb(_): @@ -433,8 +429,6 @@ class LEAPIMAPServer(imap4.IMAP4Server): def _renameEb(failure): m = failure.value - print "SERVER rename failure!" - print m if failure.check(TypeError): self.sendBadResponse(tag, 'Invalid command syntax') elif failure.check(imap4.MailboxException): diff --git a/src/leap/mail/mail.py b/src/leap/mail/mail.py index 976df5a..9b7a562 100644 --- a/src/leap/mail/mail.py +++ b/src/leap/mail/mail.py @@ -272,8 +272,7 @@ class MessageCollection(object): store = None messageklass = Message - def __init__(self, adaptor, store, mbox_indexer=None, mbox_wrapper=None, - count=None): + def __init__(self, adaptor, store, mbox_indexer=None, mbox_wrapper=None): """ Constructor for a MessageCollection. """ @@ -288,15 +287,6 @@ class MessageCollection(object): # TODO --- review this count shit. I think it's better to patch server # to accept deferreds. - # TODO need to initialize count here because imap server does not - # expect a defered for the count. caller should return the deferred for - # prime_count (ie, initialize) when returning the collection - # TODO should increment and decrement when adding/deleting. - # TODO recent count should also be static. - - if not count: - count = 0 - self._count = count def is_mailbox_collection(self): """ @@ -386,18 +376,6 @@ class MessageCollection(object): d.addCallback(wrap_in_tuple) return d - # TODO ------------------------------ FIXME FIXME FIXME implement this! - def set_flags(self, *args, **kw): - pass - - # 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. @@ -479,6 +457,7 @@ class MessageCollection(object): Copy the message to another collection. (it only makes sense for mailbox collections) """ + # TODO currently broken ------------------FIXME- if not self.is_mailbox_collection(): raise NotImplementedError() @@ -555,19 +534,21 @@ class MessageCollection(object): final = new return final - def udpate_flags(self, msg, flags, mode): + def update_flags(self, msg, flags, mode): """ Update flags for a given message. """ wrapper = msg.get_wrapper() current = wrapper.fdoc.flags - newflags = self._update_flags_or_tags(current, flags, mode) + newflags = map(str, self._update_flags_or_tags(current, flags, mode)) wrapper.fdoc.flags = newflags wrapper.fdoc.seen = MessageFlags.SEEN_FLAG in newflags wrapper.fdoc.deleted = MessageFlags.DELETED_FLAG in newflags - return self.adaptor.update_msg(self.store, msg) + d = self.adaptor.update_msg(self.store, msg) + d.addCallback(lambda _: newflags) + return d def update_tags(self, msg, tags, mode): """ @@ -576,8 +557,11 @@ class MessageCollection(object): wrapper = msg.get_wrapper() current = wrapper.fdoc.tags newtags = self._update_flags_or_tags(current, tags, mode) + wrapper.fdoc.tags = newtags - return self.adaptor.update_msg(self.store, msg) + d = self.adaptor.update_msg(self.store, msg) + d.addCallback(newtags) + return d class Account(object): -- cgit v1.2.3