diff options
Diffstat (limited to 'mail/src')
| -rw-r--r-- | mail/src/leap/mail/adaptors/soledad.py | 24 | ||||
| -rw-r--r-- | mail/src/leap/mail/imap/mailbox.py | 13 | ||||
| -rw-r--r-- | mail/src/leap/mail/imap/server.py | 57 | ||||
| -rw-r--r-- | mail/src/leap/mail/mail.py | 19 | ||||
| -rw-r--r-- | mail/src/leap/mail/mailbox_indexer.py | 2 | 
5 files changed, 100 insertions, 15 deletions
| diff --git a/mail/src/leap/mail/adaptors/soledad.py b/mail/src/leap/mail/adaptors/soledad.py index 542ad94..4dc02a1 100644 --- a/mail/src/leap/mail/adaptors/soledad.py +++ b/mail/src/leap/mail/adaptors/soledad.py @@ -966,6 +966,30 @@ class SoledadMailAdaptor(SoledadIndexMixin):          d.addErrback(self._errback)          return d +    # search api + +    def get_mdoc_id_from_msgid(self, store, mbox_uuid, msgid): +        """ +        Get the UID for a message with the passed msgid (the one in the headers +        msg-id). +        This is used by the MUA to retrieve the recently saved draft. +        """ +        type_ = HeaderDocWrapper.model.type_ +        uuid = mbox_uuid.replace('-', '_') + +        msgid_index = indexes.TYPE_MSGID_IDX + +        def get_mdoc_id(hdoc): +            if not hdoc: +                return None +            hdoc = hdoc[0] +            mdoc_id = hdoc.doc_id.replace("H-", "M-%s-" % uuid) +            return mdoc_id + +        d = store.get_from_index(msgid_index, type_, msgid) +        d.addCallback(get_mdoc_id) +        return d +      # Mailbox handling      def get_or_create_mbox(self, store, name): diff --git a/mail/src/leap/mail/imap/mailbox.py b/mail/src/leap/mail/imap/mailbox.py index c826e86..be7f70c 100644 --- a/mail/src/leap/mail/imap/mailbox.py +++ b/mail/src/leap/mail/imap/mailbox.py @@ -842,18 +842,17 @@ class IMAPMailbox(object):          #   '52D44F11.9060107@dev.bitmask.net']          # TODO hardcoding for now! -- we'll support generic queries later on -        # but doing a quickfix for avoiding duplicat saves in the draft folder. -        # See issue #4209 +        # but doing a quickfix for avoiding duplicate saves in the draft +        # folder.  # See issue #4209          if len(query) > 2:              if query[1] == 'HEADER' and query[2].lower() == "message-id":                  msgid = str(query[3]).strip()                  logger.debug("Searching for %s" % (msgid,)) -                d = self.messages._get_uid_from_msgid(str(msgid)) -                # XXX remove gatherResults -                d1 = defer.gatherResults([d]) -                # we want a list, so return it all the same -                return d1 + +                d = self.collection.get_uid_from_msgid(str(msgid)) +                d.addCallback(lambda result: [result]) +                return d          # nothing implemented for any other query          logger.warning("Cannot process query: %s" % (query,)) diff --git a/mail/src/leap/mail/imap/server.py b/mail/src/leap/mail/imap/server.py index 027fd7a..abe16be 100644 --- a/mail/src/leap/mail/imap/server.py +++ b/mail/src/leap/mail/imap/server.py @@ -199,8 +199,7 @@ class LEAPIMAPServer(imap4.IMAP4Server):          a deferred, the client will only be informed of success (or failure)          when the deferred's callback (or errback) is invoked.          """ -        # TODO return the output of _memstore.is_writing -        # XXX and that should return a deferred! +        # TODO implement a collection of ongoing deferreds?          return None      ############################################################# @@ -499,6 +498,50 @@ class LEAPIMAPServer(imap4.IMAP4Server):      auth_DELETE = (do_DELETE, arg_astring)      select_DELETE = auth_DELETE +    # ----------------------------------------------------------------------- +    # Patched just to allow __cbAppend to receive a deferred from messageCount +    # TODO format and send upstream. +    def do_APPEND(self, tag, mailbox, flags, date, message): +        mailbox = self._parseMbox(mailbox) +        maybeDeferred(self.account.select, mailbox).addCallback( +            self._cbAppendGotMailbox, tag, flags, date, message).addErrback( +            self._ebAppendGotMailbox, tag) + +    def __ebAppend(self, failure, tag): +        self.sendBadResponse(tag, 'APPEND failed: ' + str(failure.value)) + +    def _cbAppendGotMailbox(self, mbox, tag, flags, date, message): +        if not mbox: +            self.sendNegativeResponse(tag, '[TRYCREATE] No such mailbox') +            return + +        d = mbox.addMessage(message, flags, date) +        d.addCallback(self.__cbAppend, tag, mbox) +        d.addErrback(self.__ebAppend, tag) + +    def _ebAppendGotMailbox(self, failure, tag): +        self.sendBadResponse( +            tag, "Server error encountered while opening mailbox.") +        log.err(failure) + +    def __cbAppend(self, result, tag, mbox): + +        # XXX patched --------------------------------- +        def send_response(count): +            self.sendUntaggedResponse('%d EXISTS' % count) +            self.sendPositiveResponse(tag, 'APPEND complete') + +        d = mbox.getMessageCount() +        d.addCallback(send_response) +        return d +        # XXX patched --------------------------------- + +    # ----------------------------------------------------------------------- + +    auth_APPEND = (do_APPEND, arg_astring, imap4.IMAP4Server.opt_plist, +                   imap4.IMAP4Server.opt_datetime, arg_literal) +    select_APPEND = auth_APPEND +      # Need to override the command table after patching      # arg_astring and arg_literal, except on the methods that we are already      # overriding. @@ -511,10 +554,10 @@ class LEAPIMAPServer(imap4.IMAP4Server):      # do_RENAME = imap4.IMAP4Server.do_RENAME      # do_SUBSCRIBE = imap4.IMAP4Server.do_SUBSCRIBE      # do_UNSUBSCRIBE = imap4.IMAP4Server.do_UNSUBSCRIBE +    # do_APPEND = imap4.IMAP4Server.do_APPEND      # -------------------------------------------------      do_LOGIN = imap4.IMAP4Server.do_LOGIN      do_STATUS = imap4.IMAP4Server.do_STATUS -    do_APPEND = imap4.IMAP4Server.do_APPEND      do_COPY = imap4.IMAP4Server.do_COPY      _selectWork = imap4.IMAP4Server._selectWork @@ -539,6 +582,10 @@ class LEAPIMAPServer(imap4.IMAP4Server):      # re-add if we stop overriding DELETE      # auth_DELETE = (do_DELETE, arg_astring)      # select_DELETE = auth_DELETE +    # auth_APPEND = (do_APPEND, arg_astring, opt_plist, opt_datetime, +    #                arg_literal) +    # select_APPEND = auth_APPEND +      # ----------------------------------------------------      auth_RENAME = (do_RENAME, arg_astring, arg_astring) @@ -559,10 +606,6 @@ class LEAPIMAPServer(imap4.IMAP4Server):      auth_STATUS = (do_STATUS, arg_astring, arg_plist)      select_STATUS = auth_STATUS -    auth_APPEND = (do_APPEND, arg_astring, opt_plist, opt_datetime, -                   arg_literal) -    select_APPEND = auth_APPEND -      select_COPY = (do_COPY, arg_seqset, arg_astring)      ############################################################# diff --git a/mail/src/leap/mail/mail.py b/mail/src/leap/mail/mail.py index d986f59..2766524 100644 --- a/mail/src/leap/mail/mail.py +++ b/mail/src/leap/mail/mail.py @@ -460,6 +460,25 @@ class MessageCollection(object):          """          return self.mbox_indexer.all_uid_iter(self.mbox_uuid) +    def get_uid_from_msgid(self, msgid): +        """ +        Return the UID(s) of the matching msg-ids for this mailbox collection. +        """ +        if not self.is_mailbox_collection(): +            raise NotImplementedError() + +        def get_uid(mdoc_id): +            if not mdoc_id: +                return None +            d = self.mbox_indexer.get_uid_from_doc_id( +                self.mbox_uuid, mdoc_id) +            return d + +        d = self.adaptor.get_mdoc_id_from_msgid( +            self.store, self.mbox_uuid, msgid) +        d.addCallback(get_uid) +        return d +      # Manipulate messages      def add_msg(self, raw_msg, flags=tuple(), tags=tuple(), date=""): diff --git a/mail/src/leap/mail/mailbox_indexer.py b/mail/src/leap/mail/mailbox_indexer.py index 4eb0fa8..3bec41e 100644 --- a/mail/src/leap/mail/mailbox_indexer.py +++ b/mail/src/leap/mail/mailbox_indexer.py @@ -120,7 +120,7 @@ class MailboxIndexer(object):          The doc_id must be in the format: -            M+<mailbox>+<content-hash-of-the-message> +            M-<mailbox>-<content-hash-of-the-message>          :param mailbox: the mailbox name          :type mailbox: str | 
