diff options
| author | Kali Kaneko <kali@leap.se> | 2013-08-16 18:35:21 +0200 | 
|---|---|---|
| committer | Kali Kaneko <kali@leap.se> | 2013-08-16 19:01:32 +0200 | 
| commit | a0d0b28ae044cb0c7b71a2fe7402b697c0dcfe62 (patch) | |
| tree | 884bcae20983c78725ecc8c99033342ee243dc0e /mail/src/leap | |
| parent | 7cf45f776fcf1d4d401a2fa55d034d2ddffd3591 (diff) | |
add imap events
Diffstat (limited to 'mail/src/leap')
| -rw-r--r-- | mail/src/leap/mail/imap/fetch.py | 60 | ||||
| -rw-r--r-- | mail/src/leap/mail/imap/service/imap.py | 34 | 
2 files changed, 75 insertions, 19 deletions
| diff --git a/mail/src/leap/mail/imap/fetch.py b/mail/src/leap/mail/imap/fetch.py index 9b76592..267af38 100644 --- a/mail/src/leap/mail/imap/fetch.py +++ b/mail/src/leap/mail/imap/fetch.py @@ -1,15 +1,43 @@ +# -*- coding: utf-8 -*- +# fetch.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. +""" +Incoming mail fetcher. +"""  import logging  import json  import ssl +import time  from twisted.python import log  from twisted.internet import defer  from twisted.internet.task import LoopingCall  from twisted.internet.threads import deferToThread +from leap.common import events as leap_events  from leap.common.check import leap_assert, leap_assert_type  from leap.soledad import Soledad +from leap.common.events.events_pb2 import IMAP_FETCHED_INCOMING +from leap.common.events.events_pb2 import IMAP_MSG_PROCESSING +from leap.common.events.events_pb2 import IMAP_MSG_DECRYPTED +from leap.common.events.events_pb2 import IMAP_MSG_SAVED_LOCALLY +from leap.common.events.events_pb2 import IMAP_MSG_DELETED_INCOMING + +  logger = logging.getLogger(__name__) @@ -100,8 +128,12 @@ class LeapIncomingMail(object):          try:              self._soledad.sync() +            fetched_ts = time.mktime(time.gmtime())              doclist = self._soledad.get_from_index("just-mail", "*") -            log.msg("there are %s mails" % (len(doclist),)) +            num_mails = len(doclist) +            log.msg("there are %s mails" % (num_mails,)) +            leap_events.signal( +                IMAP_FETCHED_INCOMING, str(num_mails), str(fetched_ts))              return doclist          except ssl.SSLError as exc:              logger.warning('SSL Error while syncing soledad: %r' % (exc,)) @@ -117,8 +149,12 @@ class LeapIncomingMail(object):          if not doclist:              logger.debug("no docs found")              return -        for doc in doclist: -            logger.debug("processing doc: %s" % doc) +        num_mails = len(doclist) +        for index, doc in enumerate(doclist): +            logger.debug("processing doc %d of %d: %s" % ( +                index, num_mails, doc)) +            leap_events.signal( +                IMAP_MSG_PROCESSING, str(index), str(num_mails))              keys = doc.content.keys()              if self.ENC_SCHEME_KEY in keys and self.ENC_JSON_KEY in keys: @@ -133,11 +169,17 @@ class LeapIncomingMail(object):      def _decrypt_msg(self, doc, encdata):          log.msg('decrypting msg')          key = self._pkey -        decrdata = (self._keymanager.decrypt( -            encdata, key, -            # XXX get from public method instead -            passphrase=self._soledad._passphrase)) - +        try: +            decrdata = (self._keymanager.decrypt( +                encdata, key, +                # XXX get from public method instead +                passphrase=self._soledad._passphrase)) +            ok = True +        except Exception as exc: +            logger.warning("Error while decrypting msg: %r" % (exc,)) +            decrdata = "" +            ok = False +        leap_events.signal(IMAP_MSG_DECRYPTED, ok)          # XXX TODO: defer this properly          return self._process_decrypted(doc, decrdata) @@ -183,8 +225,10 @@ class LeapIncomingMail(object):                  rawmsg = rawmsg.replace(pgp_message, decrdata)              # add to inbox and delete from soledad              self._inbox.addMessage(rawmsg, (self.RECENT_FLAG,)) +            leap_events.signal(IMAP_MSG_SAVED_LOCALLY)              doc_id = doc.doc_id              self._soledad.delete_doc(doc)              log.msg("deleted doc %s from incoming" % doc_id) +            leap_events.signal(IMAP_MSG_DELETED_INCOMING)          except Exception as e:              logger.error("Problem processing incoming mail: %r" % (e,)) diff --git a/mail/src/leap/mail/imap/service/imap.py b/mail/src/leap/mail/imap/service/imap.py index 1a8c15c..380324c 100644 --- a/mail/src/leap/mail/imap/service/imap.py +++ b/mail/src/leap/mail/imap/service/imap.py @@ -27,6 +27,7 @@ from twisted.internet.protocol import ServerFactory  from twisted.mail import imap4  from twisted.python import log +from leap.common import events as leap_events  from leap.common.check import leap_assert, leap_assert_type  from leap.keymanager import KeyManager  from leap.mail.imap.server import SoledadBackedAccount @@ -42,6 +43,10 @@ INCOMING_CHECK_PERIOD = 5  # The period between succesive checks of the incoming mail  # queue (in seconds) +from leap.common.events.events_pb2 import IMAP_SERVICE_STARTED +from leap.common.events.events_pb2 import IMAP_SERVICE_FAILED_TO_START +from leap.common.events.events_pb2 import IMAP_CLIENT_LOGIN +  class LeapIMAPServer(imap4.IMAP4Server):      """ @@ -84,6 +89,7 @@ class LeapIMAPServer(imap4.IMAP4Server):      def authenticateLogin(self, username, password):          # all is allowed so far. use realm instead +        leap_events.signal(IMAP_CLIENT_LOGIN, True)          return imap4.IAccount, self.theAccount, lambda: None @@ -150,15 +156,21 @@ def run_service(*args, **kwargs):      factory = LeapIMAPFactory(uuid, soledad)      from twisted.internet import reactor -    reactor.listenTCP(port, factory) - -    fetcher = LeapIncomingMail( -        keymanager, -        soledad, -        factory.theAccount, -        check_period) - -    fetcher.start_loop() -    logger.debug("IMAP4 Server is RUNNING in port  %s" % (port,)) -    return fetcher +    try: +        reactor.listenTCP(port, factory) +        fetcher = LeapIncomingMail( +            keymanager, +            soledad, +            factory.theAccount, +            check_period) +    except Exception as exc: +        # XXX cannot listen? +        logger.error("Error launching IMAP service: %r" % (exc,)) +        leap_events.signal(IMAP_SERVICE_FAILED_TO_START, str(port)) +        return +    else: +        fetcher.start_loop() +        logger.debug("IMAP4 Server is RUNNING in port  %s" % (port,)) +        leap_events.signal(IMAP_SERVICE_STARTED, str(port)) +        return fetcher | 
