diff --git a/imbox/imbox.py b/imbox/imbox.py index f8dfc14..89fa616 100644 --- a/imbox/imbox.py +++ b/imbox/imbox.py @@ -1,15 +1,19 @@ +import imaplib + from imbox.imap import ImapTransport from imbox.messages import Messages import logging -from imbox.vendors import GmailMessages, hostname_vendorname_dict +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, vendor=None): @@ -21,10 +25,20 @@ class Imbox: 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 ""))) - self.vendor = vendor or hostname_vendorname_dict.get(self.hostname) def __enter__(self): return self @@ -62,19 +76,19 @@ 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)) - messages_class = Messages - - if self.vendor == 'gmail': - messages_class = GmailMessages - return messages_class(connection=self.connection, parser_policy=self.parser_policy, **kwargs) 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 index f983626..da8a6b9 100644 --- a/imbox/vendors/__init__.py +++ b/imbox/vendors/__init__.py @@ -1,7 +1,10 @@ from imbox.vendors.gmail import GmailMessages +vendors = [GmailMessages] -hostname_vendorname_dict = {GmailMessages.hostname: GmailMessages.name} +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__ = ['GmailMessages', - 'hostname_vendorname_dict'] \ No newline at end of file + 'hostname_vendorname_dict', + 'name_authentication_string_dict'] \ No newline at end of file diff --git a/imbox/vendors/gmail.py b/imbox/vendors/gmail.py index a9dfa4b..97c97d9 100644 --- a/imbox/vendors/gmail.py +++ b/imbox/vendors/gmail.py @@ -2,5 +2,28 @@ 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)