diff --git a/imbox/__init__.py b/imbox/__init__.py index 5e02e04..232f7a2 100644 --- a/imbox/__init__.py +++ b/imbox/__init__.py @@ -6,3 +6,4 @@ __version__ = '.'.join([str(x) for x in __version_info__]) __all__ = ['Imbox'] + diff --git a/imbox/imbox.py b/imbox/imbox.py index e06d467..89fa616 100644 --- a/imbox/imbox.py +++ b/imbox/imbox.py @@ -1,23 +1,42 @@ +import imaplib + from imbox.imap import ImapTransport from imbox.messages import Messages import logging +from imbox.vendors import GmailMessages, hostname_vendorname_dict, name_authentication_string_dict + logger = logging.getLogger(__name__) class Imbox: + authentication_error_message = None + def __init__(self, hostname, username=None, password=None, ssl=True, - port=None, ssl_context=None, policy=None, starttls=False): + port=None, ssl_context=None, policy=None, starttls=False, + vendor=None): self.server = ImapTransport(hostname, ssl=ssl, port=port, ssl_context=ssl_context, starttls=starttls) + self.hostname = hostname self.username = username self.password = password self.parser_policy = policy - self.connection = self.server.connect(username, password) + self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) + + if self.vendor is not None: + self.authentication_error_message = name_authentication_string_dict.get(self.vendor) + + try: + self.connection = self.server.connect(username, password) + except imaplib.IMAP4.error as e: + if self.authentication_error_message is None: + raise + raise imaplib.IMAP4.error(self.authentication_error_message + '\n' + str(e)) + logger.info("Connected to IMAP Server with user {username} on {hostname}{ssl}".format( hostname=hostname, username=username, ssl=(" over SSL" if ssl or starttls else ""))) @@ -57,16 +76,22 @@ class Imbox: def messages(self, **kwargs): folder = kwargs.get('folder', False) + messages_class = Messages + + if self.vendor == 'gmail': + messages_class = GmailMessages + if folder: - self.connection.select(folder) + self.connection.select(messages_class.folder_lookup.get((folder.lower())) or folder) msg = " from folder '{}'".format(folder) else: msg = " from inbox" logger.info("Fetch list of messages{}".format(msg)) - return Messages(connection=self.connection, - parser_policy=self.parser_policy, - **kwargs) + + return messages_class(connection=self.connection, + parser_policy=self.parser_policy, + **kwargs) def folders(self): - return self.connection.list() \ No newline at end of file + return self.connection.list() diff --git a/imbox/messages.py b/imbox/messages.py index 3d44f42..baefae7 100644 --- a/imbox/messages.py +++ b/imbox/messages.py @@ -8,6 +8,8 @@ logger = logging.getLogger(__name__) class Messages: + folder_lookup = {} + def __init__(self, connection, parser_policy, diff --git a/imbox/vendors/__init__.py b/imbox/vendors/__init__.py new file mode 100644 index 0000000..ed26aef --- /dev/null +++ b/imbox/vendors/__init__.py @@ -0,0 +1,11 @@ +from imbox.vendors.gmail import GmailMessages + +vendors = [GmailMessages] + +hostname_vendorname_dict = {vendor.hostname: vendor.name for vendor in vendors} +name_authentication_string_dict = {vendor.name: vendor.authentication_error_message for vendor in vendors} + +__all__ = [v.__name__ for v in vendors] + +__all__ += ['hostname_vendorname_dict', + 'name_authentication_string_dict'] diff --git a/imbox/vendors/gmail.py b/imbox/vendors/gmail.py new file mode 100644 index 0000000..97c97d9 --- /dev/null +++ b/imbox/vendors/gmail.py @@ -0,0 +1,29 @@ +from imbox.messages import Messages + + +class GmailMessages(Messages): + authentication_error_message = ('If you\'re not using an app-specific password, grab one here: ' + 'https://myaccount.google.com/apppasswords') + hostname = 'imap.gmail.com' + name = 'gmail' + folder_lookup = { + + 'all_mail': '"[Gmail]/All Mail"', + 'all': '"[Gmail]/All Mail"', + 'all mail': '"[Gmail]/All Mail"', + 'sent': '"[Gmail]/Sent Mail"', + 'sent mail': '"[Gmail]/Sent Mail"', + 'sent_mail': '"[Gmail]/Sent Mail"', + 'drafts': '"[Gmail]/Drafts"', + 'important': '"[Gmail]/Important"', + 'spam': '"[Gmail]/Spam"', + 'starred': '"[Gmail]/Starred"', + 'trash': '"[Gmail]/Trash"', + + } + + def __init__(self, + connection, + parser_policy, + **kwargs): + super().__init__(connection, parser_policy, **kwargs)