diff --git a/docs/conf.py b/docs/conf.py index 5e81c13..e477125 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,6 +54,14 @@ MOCK_MODULES = [ "khal", "khal.cli", "khal.settings", + "requests.auth", + "requests.sessions", + "requests.packages", + "requests.packages.urllib3", + "requests.packages.urllib3.response", + "lxml.etree", + "requests.adapters", + "exchangelib" ] for mod_name in MOCK_MODULES: diff --git a/i3pystatus/mail/ews.py b/i3pystatus/mail/ews.py new file mode 100644 index 0000000..1390b5e --- /dev/null +++ b/i3pystatus/mail/ews.py @@ -0,0 +1,71 @@ +import exchangelib +import contextlib +import time + +from i3pystatus.mail import Backend + + +class ExchangeMailAccount(Backend): + """ + Checks for mail on an Exchange account. + + Requires the python exchangelib library - https://github.com/ecederstrand/exchangelib. + """ + + settings = ( + ("host", 'The url to connect to. If unset, autodiscover is tried with the email address domain. If set, autodiscover is disabled.'), + "username", "password", "email_address", + ('keyring_backend', 'alternative keyring backend for retrieving credentials'), + ) + required = ("username", "password", "email_address") + keyring_backend = None + + host = None + + account = None + last = 0 + + @contextlib.contextmanager + def ensure_connection(self): + try: + if not self.account: + credentials = exchangelib.ServiceAccount( + username=self.username, + password=self.password) + if self.host: + config = exchangelib.Configuration( + server=self.host, + credentials=credentials) + self.account = exchangelib.Account( + primary_smtp_address=self.email_address, + config=config, + autodiscover=False, + access_type=exchangelib.DELEGATE) + else: + self.account = exchangelib.Account( + primary_smtp_address=self.email_address, + credentials=credentials, + autodiscover=True, + access_type=exchangelib.DELEGATE) + yield + except Exception as e: + # NOTE(sileht): retry just once if the connection have been + # broken to ensure this is not a sporadic connection lost. + # Like wifi reconnect, sleep wake up + # Wait a bit when disconnection occurs to not hog the cpu + self.logger.warn(e) + time.sleep(1) + self.connection = None + + def count_new_mail(self): + self.account.inbox.refresh() + self.last = self.account.inbox.unread_count + + @property + def unread(self): + with self.ensure_connection(): + self.count_new_mail() + return self.last + + +Backend = ExchangeMailAccount