1# vim:fileencoding=utf-8:noet 2from __future__ import (unicode_literals, division, absolute_import, print_function) 3 4import re 5 6from imaplib import IMAP4_SSL_PORT, IMAP4_SSL, IMAP4 7from collections import namedtuple 8 9from powerline.lib.threaded import KwThreadedSegment 10from powerline.segments import with_docstring 11 12 13_IMAPKey = namedtuple('Key', 'username password server port folder use_ssl') 14 15 16class EmailIMAPSegment(KwThreadedSegment): 17 interval = 60 18 19 @staticmethod 20 def key(username, password, server='imap.gmail.com', port=IMAP4_SSL_PORT, folder='INBOX', use_ssl=None, **kwargs): 21 if use_ssl is None: 22 use_ssl = (port == IMAP4_SSL_PORT) 23 return _IMAPKey(username, password, server, port, folder, use_ssl) 24 25 def compute_state(self, key): 26 if not key.username or not key.password: 27 self.warn('Username and password are not configured') 28 return None 29 if key.use_ssl: 30 mail = IMAP4_SSL(key.server, key.port) 31 else: 32 mail = IMAP4(key.server, key.port) 33 mail.login(key.username, key.password) 34 rc, message = mail.status(key.folder, '(UNSEEN)') 35 unread_str = message[0].decode('utf-8') 36 unread_count = int(re.search('UNSEEN (\d+)', unread_str).group(1)) 37 return unread_count 38 39 @staticmethod 40 def render_one(unread_count, max_msgs=None, **kwargs): 41 if not unread_count: 42 return None 43 elif type(unread_count) != int or not max_msgs: 44 return [{ 45 'contents': str(unread_count), 46 'highlight_groups': ['email_alert'], 47 }] 48 else: 49 return [{ 50 'contents': str(unread_count), 51 'highlight_groups': ['email_alert_gradient', 'email_alert'], 52 'gradient_level': min(unread_count * 100.0 / max_msgs, 100), 53 }] 54 55 56email_imap_alert = with_docstring(EmailIMAPSegment(), 57('''Return unread e-mail count for IMAP servers. 58 59:param str username: 60 login username 61:param str password: 62 login password 63:param str server: 64 e-mail server 65:param int port: 66 e-mail server port 67:param str folder: 68 folder to check for e-mails 69:param int max_msgs: 70 Maximum number of messages. If there are more messages then max_msgs then it 71 will use gradient level equal to 100, otherwise gradient level is equal to 72 ``100 * msgs_num / max_msgs``. If not present gradient is not computed. 73:param bool use_ssl: 74 If ``True`` then use SSL connection. If ``False`` then do not use it. 75 Default is ``True`` if port is equal to {ssl_port} and ``False`` otherwise. 76 77Highlight groups used: ``email_alert_gradient`` (gradient), ``email_alert``. 78''').format(ssl_port=IMAP4_SSL_PORT)) 79