summaryrefslogtreecommitdiff
path: root/src/leap/mail/imap/fetch.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/mail/imap/fetch.py')
-rw-r--r--src/leap/mail/imap/fetch.py86
1 files changed, 66 insertions, 20 deletions
diff --git a/src/leap/mail/imap/fetch.py b/src/leap/mail/imap/fetch.py
index 60ae387..df5d046 100644
--- a/src/leap/mail/imap/fetch.py
+++ b/src/leap/mail/imap/fetch.py
@@ -1,17 +1,31 @@
+import logging
import json
from twisted.python import log
+from twisted.internet import defer
+from twisted.internet.threads import deferToThread
from leap.common.check import leap_assert, leap_assert_type
from leap.soledad import Soledad
from leap.common.keymanager import openpgp
+logger = logging.getLogger(__name__)
+
class LeapIncomingMail(object):
"""
Fetches mail from the incoming queue.
"""
+
+ ENC_SCHEME_KEY = "_enc_scheme"
+ ENC_JSON_KEY = "_enc_json"
+
+ RECENT_FLAG = "\\Recent"
+
+ INCOMING_KEY = "incoming"
+ CONTENT_KEY = "content"
+
def __init__(self, keymanager, soledad, imap_account):
"""
@@ -33,57 +47,89 @@ class LeapIncomingMail(object):
self._keymanager = keymanager
self._soledad = soledad
self.imapAccount = imap_account
+ self._inbox = self.imapAccount.getMailbox('inbox')
self._pkey = self._keymanager.get_all_keys_in_local_db(
private=True).pop()
def fetch(self):
"""
- Get new mail by syncing database, store it in the INBOX for the
- user account, and remove from the incoming db.
+ Fetch incoming mail, to be called periodically.
+
+ Calls a deferred that will execute the fetch callback
+ in a separate thread
"""
+ logger.debug('fetching mail...')
+ d = deferToThread(self._sync_soledad)
+ d.addCallbacks(self._process_doclist, self._sync_soledad_err)
+ return d
+
+ def _sync_soledad(self):
+ log.msg('syncing soledad...')
+ logger.debug('in soledad sync')
+ #import ipdb; ipdb.set_trace()
+
self._soledad.sync()
gen, doclist = self._soledad.get_all_docs()
- #log.msg("there are %s docs" % (len(doclist),))
+ #logger.debug("there are %s docs" % (len(doclist),))
+ log.msg("there are %s docs" % (len(doclist),))
+ return doclist
- if doclist:
- inbox = self.imapAccount.getMailbox('inbox')
+ def _sync_soledad_err(self, f):
+ log.err("error syncing soledad: %s" % (f.value,))
+ return f
- key = self._pkey
+ def _process_doclist(self, doclist):
+ log.msg('processing doclist')
for doc in doclist:
keys = doc.content.keys()
- if '_enc_scheme' in keys and '_enc_json' in keys:
+ if self.ENC_SCHEME_KEY in keys and self.ENC_JSON_KEY in keys:
# XXX should check for _enc_scheme == "pubkey" || "none"
# that is what incoming mail uses.
+ encdata = doc.content[self.ENC_JSON_KEY]
+ d = defer.Deferred(self._decrypt_msg, doc, encdata)
+ d.addCallback(self._process_decrypted)
- encdata = doc.content['_enc_json']
- decrdata = openpgp.decrypt_asym(
- encdata, key,
- # XXX get from public method instead
- passphrase=self._soledad._passphrase)
- if decrdata:
- self.process_decrypted(doc, decrdata, inbox)
- # XXX launch sync callback / defer
+ def _decrypt_msg(self, doc, encdata):
+ log.msg('decrypting msg')
+ key = self._pkey
+ decrdata = (openpgp.decrypt_asym(
+ encdata, key,
+ # XXX get from public method instead
+ passphrase=self._soledad._passphrase))
+ return doc, decrdata
- def process_decrypted(self, doc, data, inbox):
+ def _process_decrypted(self, doc, data):
"""
- Process a successfully decrypted message
+ Process a successfully decrypted message.
+
+ :param doc: a LeapDocument instance containing the incoming message
+ :type doc: LeapDocument
+
+ :param data: the json-encoded, decrypted content of the incoming
+ message
+ :type data: str
+
+ :param inbox: a open SoledadMailbox instance where this message is
+ to be saved
+ :type inbox: SoledadMailbox
"""
log.msg("processing incoming message!")
msg = json.loads(data)
if not isinstance(msg, dict):
return False
- if not msg.get('incoming', False):
+ if not msg.get(self.INCOMING_KEY, False):
return False
# ok, this is an incoming message
- rawmsg = msg.get('content', None)
+ rawmsg = msg.get(self.CONTENT_KEY, None)
if not rawmsg:
return False
+ logger.debug('got incoming message: %s' % (rawmsg,))
#log.msg("we got raw message")
# add to inbox and delete from soledad
- inbox.addMessage(rawmsg, ("\\Recent",))
+ self.inbox.addMessage(rawmsg, (self.RECENT_FLAG,))
doc_id = doc.doc_id
self._soledad.delete_doc(doc)
log.msg("deleted doc %s from incoming" % doc_id)