summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/bitmask/cli/mail.py29
-rw-r--r--src/leap/bitmask/core/dispatcher.py5
-rw-r--r--src/leap/bitmask/core/mail_services.py74
-rw-r--r--src/leap/bitmask/mail/incoming/service.py7
-rw-r--r--ui/app/lib/bitmask.js9
5 files changed, 116 insertions, 8 deletions
diff --git a/src/leap/bitmask/cli/mail.py b/src/leap/bitmask/cli/mail.py
index 46251313..73e21965 100644
--- a/src/leap/bitmask/cli/mail.py
+++ b/src/leap/bitmask/cli/mail.py
@@ -17,6 +17,11 @@
"""
Bitmask Command Line interface: mail
"""
+import argparse
+import sys
+
+from colorama import Fore
+
from leap.bitmask.cli import command
@@ -35,4 +40,26 @@ SUBCOMMANDS:
'''.format(name=command.appname)
- commands = ['enable', 'disable', 'status', 'get_token']
+ commands = ['enable', 'disable', 'get_token']
+
+ def status(self, raw_args):
+ parser = argparse.ArgumentParser(
+ description='Bitmask email status',
+ prog='%s %s %s' % tuple(sys.argv[:3]))
+ parser.add_argument('uid', nargs='?', default=None,
+ help='uid to check the status of')
+ subargs = parser.parse_args(raw_args)
+
+ self.data.append('status')
+ if subargs.uid:
+ self.data.append(subargs.uid)
+ return self._send(self._print_status)
+
+ def _print_status(self, status, depth=0):
+ spaces = depth * " "
+ for k, v in status.items():
+ if type(v) == dict:
+ print(spaces + k + ":")
+ self._print_status(v, depth + 1)
+ else:
+ print(spaces + k + ": " + Fore.GREEN + str(v) + Fore.RESET)
diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py
index f96bd457..7c1cdbd4 100644
--- a/src/leap/bitmask/core/dispatcher.py
+++ b/src/leap/bitmask/core/dispatcher.py
@@ -229,7 +229,10 @@ class MailCmd(SubCommand):
@register_method('dict')
def do_STATUS(self, mail, *parts, **kw):
- d = mail.do_status()
+ userid = None
+ if len(parts) > 2:
+ userid = parts[2]
+ d = mail.do_status(userid)
return d
@register_method('dict')
diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py
index bc85889d..2842b5d8 100644
--- a/src/leap/bitmask/core/mail_services.py
+++ b/src/leap/bitmask/core/mail_services.py
@@ -449,6 +449,7 @@ class StandardMailService(service.MultiService, HookableService):
self._sendmail_opts = {}
self._service_tokens = {}
self._active_user = None
+ self._status = {}
super(StandardMailService, self).__init__()
self.initializeChildrenServices()
@@ -560,9 +561,41 @@ class StandardMailService(service.MultiService, HookableService):
# commands
- def do_status(self):
- status = 'running' if self.running else 'disabled'
- return {'mail': status}
+ @defer.inlineCallbacks
+ def do_status(self, userid=None):
+ smtp = self.getServiceNamed('smtp')
+ imap = self.getServiceNamed('imap')
+ childrenStatus = {
+ 'smtp': smtp.status(),
+ 'imap': imap.status()
+ }
+ if userid is not None:
+ incoming = self.getServiceNamed('incoming_mail')
+ childrenStatus['incoming'] = yield incoming.status(userid)
+
+ def key(service):
+ status = childrenStatus[service]
+ level = {
+ "on": 0,
+ "starting": 1,
+ "off": 10,
+ "stopping": 11,
+ "failure": 100
+ }
+ return level.get(status["status"], -1)
+
+ service = max(childrenStatus, key=key)
+
+ status = childrenStatus[service]["status"]
+ error = childrenStatus[service]["error"]
+
+ res = {}
+ for s in childrenStatus.values():
+ res.update(s)
+ res['status'] = status
+ res['error'] = error
+ res['childrenStatus'] = childrenStatus
+ defer.returnValue(res)
def get_token(self):
active_user = self._active_user
@@ -624,6 +657,12 @@ class IMAPService(service.Service):
self._factory.doStop()
super(IMAPService, self).stopService()
+ def status(self):
+ return {
+ 'status': 'on' if self.running else 'off',
+ 'error': None
+ }
+
class SMTPService(service.Service):
@@ -660,6 +699,12 @@ class SMTPService(service.Service):
self._factory.doStop()
super(SMTPService, self).stopService()
+ def status(self):
+ return {
+ 'status': 'on' if self.running else 'off',
+ 'error': None
+ }
+
class IncomingMailService(service.MultiService):
"""
@@ -671,6 +716,7 @@ class IncomingMailService(service.MultiService):
def __init__(self, mail_service):
super(IncomingMailService, self).__init__()
self._mail = mail_service
+ self._status = {}
def startService(self):
logger.info('starting incoming mail service')
@@ -682,6 +728,7 @@ class IncomingMailService(service.MultiService):
# Individual accounts
def startInstance(self, userid):
+ self._status[userid] = {"status": "starting", "error": None}
soledad = self._mail.get_soledad_session(userid)
keymanager = self._mail.get_keymanager_session(userid)
@@ -689,6 +736,16 @@ class IncomingMailService(service.MultiService):
self._start_incoming_mail_instance(
keymanager, soledad, userid)
+ @defer.inlineCallbacks
+ def status(self, userid):
+ if userid not in self._status:
+ defer.returnValue({'status': 'off', 'error': None, 'unread': None})
+
+ status = self._status[userid]
+ incoming = self.getServiceNamed(userid)
+ status['unread'] = yield incoming.unread()
+ defer.returnValue(status)
+
def _start_incoming_mail_instance(self, keymanager, soledad,
userid, start_sync=True):
@@ -701,13 +758,22 @@ class IncomingMailService(service.MultiService):
incoming_mail.setName(userid)
self.addService(incoming_mail)
+ def setStatusOn(res):
+ self._status[userid]["status"] = "on"
+ return res
+
acc = Account(soledad, userid)
d = acc.callWhenReady(
lambda _: acc.get_collection_by_mailbox(INBOX_NAME))
d.addCallback(setUpIncomingMail)
- d.addErrback(lambda r: logger.error(str(r)))
+ d.addCallback(setStatusOn)
+ d.addErrback(self._errback, userid)
return d
+ def _errback(self, failure, userid):
+ self._status[userid] = {"status": "failure", "error": str(failure)}
+ logger.error(str(failure))
+
# --------------------------------------------------------------------
#
# config utilities. should be moved to bonafide
diff --git a/src/leap/bitmask/mail/incoming/service.py b/src/leap/bitmask/mail/incoming/service.py
index 4807c8f7..ac7a5d18 100644
--- a/src/leap/bitmask/mail/incoming/service.py
+++ b/src/leap/bitmask/mail/incoming/service.py
@@ -205,6 +205,13 @@ class IncomingMail(Service):
self._loop = None
Service.stopService(self)
+ def unread(self):
+ """
+ :returns: a deferred that will be fired with the number of unread
+ messages
+ """
+ return self._inbox_collection.count_unseen()
+
#
# Private methods.
#
diff --git a/ui/app/lib/bitmask.js b/ui/app/lib/bitmask.js
index a6cf8e56..21dbb652 100644
--- a/ui/app/lib/bitmask.js
+++ b/ui/app/lib/bitmask.js
@@ -223,10 +223,15 @@ var bitmask = function(){
/**
* Check the status of the email service
*
+ * @param {string} uid The uid to get status about
+ *
* @return {Promise<string>} User readable status
*/
- status: function() {
- return call(['mail', 'status']);
+ status: function(uid) {
+ if (typeof uid !== 'string') {
+ uid = null
+ }
+ return call(['mail', 'status', uid]);
},
/**