diff options
author | Tomás Touceda <chiiph@leap.se> | 2013-05-29 10:25:32 -0300 |
---|---|---|
committer | Tomás Touceda <chiiph@leap.se> | 2013-05-29 10:25:32 -0300 |
commit | 9a5a325831230687a7da4ad5300c99f03aebba72 (patch) | |
tree | 6569fff23c2c553b55f624e9db1744b6cf943330 /src/leap/mail/imap/fetch.py | |
parent | e5fa0790f5231c333aba4bc5f6766556e062aa6c (diff) | |
parent | efed933415a2f6dead78dd6deca0f2383c889f3f (diff) |
Merge remote-tracking branch 'kali/bug/imap-service-use-defer-to-thread' into develop
Diffstat (limited to 'src/leap/mail/imap/fetch.py')
-rw-r--r-- | src/leap/mail/imap/fetch.py | 86 |
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) |