diff --git a/i3pystatus/mail/imap.py b/i3pystatus/mail/imap.py index ebbe8e9..25839ec 100644 --- a/i3pystatus/mail/imap.py +++ b/i3pystatus/mail/imap.py @@ -1,9 +1,62 @@ -import imaplib +try: + from imaplib2 import IMAP4, IMAP4_SSL + use_idle = True +except: + from imaplib import IMAP4, IMAP4_SSL + use_idle = False import socket +from threading import * from i3pystatus.mail import Backend +# This is the threading object that does all the waiting on +# the event +class Idler(object): + def __init__(self, conn, callback, callback_reconnect): + self.thread = Thread(target=self.idle) + self.M = conn + self.callback_reconnect = callback_reconnect + self.event = Event() + self.callback = callback + + def start(self): + self.thread.start() + + def stop(self): + self.event.set() + + def join(self): + self.thread.join() + + def idle(self): + + while True: + if self.event.isSet(): + return + + self.needsync = False + + def callback(args): + if not self.event.isSet(): + self.needsync = True + self.event.set() + + try: + self.M.idle(callback=callback) + self.event.wait() + + if self.needsync: + self.event.clear() + self.callback() + except: + break + + self.M = self.callback_reconnect() + self.stop() + self.start() + + class IMAP(Backend): """ Checks for mail on a IMAP server @@ -23,13 +76,19 @@ class IMAP(Backend): ssl = True mailbox = "INBOX" - imap_class = imaplib.IMAP4 + imap_class = IMAP4 connection = None last = 0 def init(self): if self.ssl: - self.imap_class = imaplib.IMAP4_SSL + self.imap_class = IMAP4_SSL + + self.conn = self.get_connection() + + if use_idle: + idler = Idler(self.conn, self.count_new_mail, self.get_connection) + idler.start() def get_connection(self): if self.connection: @@ -52,6 +111,9 @@ class IMAP(Backend): return self.connection + def count_new_mail(self): + self.last = len(self.conn.search(None, "UnSeen")[1][0].split()) + @property def unread(self): try: @@ -61,7 +123,8 @@ class IMAP(Backend): else: self.last = len(conn.search(None, "UnSeen")[1][0].split()) finally: + if not use_idle: + self.count_new_mail() return self.last - Backend = IMAP