From 02567acdc21847bd661e9b8cb090983d9430ec4a Mon Sep 17 00:00:00 2001 From: Adam Coddington Date: Sun, 25 May 2014 12:35:20 -0700 Subject: [PATCH] Minor alterations to @yellowcap's pull request submission: * Using a query parameter argument (rather than the entire query string) to specify the folder into which e-mail messages should be archived. * Duplicating the IMAP tests; this could probably be a bit more simply done, but we'll at least be verifying both archived and non-archived use cases. * Simplifying some aspects of the documentation to include references to this new feature. --- django_mailbox/models.py | 11 +++++-- django_mailbox/tests/test_transports.py | 43 ++++++++++++++++++++++++- docs/topics/mailbox_types.rst | 34 ++++++++++--------- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 761f76b..f4b5dc6 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -18,7 +18,7 @@ from django_mailbox.transports import Pop3Transport, ImapTransport,\ MMDFTransport from django_mailbox.signals import message_received import six -from six.moves.urllib.parse import unquote, urlparse +from six.moves.urllib.parse import parse_qs, unquote, urlparse from .utils import convert_header_to_unicode @@ -115,6 +115,10 @@ class Mailbox(models.Model): def _protocol_info(self): return urlparse(self.uri) + @property + def _query_string(self): + return parse_qs(self._protocol_info.query) + @property def _domain(self): return self._protocol_info.hostname @@ -148,7 +152,10 @@ class Mailbox(models.Model): @property def archive(self): - return self._protocol_info.query + archive_folder = self._query_string.get('archive', None) + if not archive_folder: + return None + return archive_folder[0] def get_connection(self): if not self.uri: diff --git a/django_mailbox/tests/test_transports.py b/django_mailbox/tests/test_transports.py index 132d3f7..7f044d4 100644 --- a/django_mailbox/tests/test_transports.py +++ b/django_mailbox/tests/test_transports.py @@ -6,6 +6,47 @@ from django_mailbox.transports import ImapTransport, Pop3Transport class TestImapTransport(EmailMessageTestCase): + def setUp(self): + self.arbitrary_hostname = 'one.two.three' + self.arbitrary_port = 100 + self.ssl = False + self.transport = ImapTransport( + self.arbitrary_hostname, + self.arbitrary_port, + self.ssl + ) + self.transport.server = None + super(TestImapTransport, self).setUp() + + def test_get_email_message(self): + with mock.patch.object(self.transport, 'server') as server: + server.search.return_value = ( + 'OK', + [ + 'One', # This is totally arbitrary + ] + ) + server.fetch.return_value = ( + 'OK', + [ + [ + '1 (RFC822 {8190}', # Wat? + self._get_email_as_text('generic_message.eml') + ], + ')', + ] + ) + actual_messages = list(self.transport.get_message()) + + self.assertEqual(len(actual_messages), 1) + + actual_message = actual_messages[0] + expected_message = self._get_email_object('generic_message.eml') + + self.assertEqual(expected_message, actual_message) + + +class TestImapArchivedTransport(EmailMessageTestCase): def setUp(self): self.arbitrary_hostname = 'one.two.three' self.arbitrary_port = 100 @@ -18,7 +59,7 @@ class TestImapTransport(EmailMessageTestCase): self.archive ) self.transport.server = None - super(TestImapTransport, self).setUp() + super(TestImapArchivedTransport, self).setUp() def test_get_email_message(self): with mock.patch.object(self.transport, 'server') as server: diff --git a/docs/topics/mailbox_types.rst b/docs/topics/mailbox_types.rst index ee53616..fce8461 100644 --- a/docs/topics/mailbox_types.rst +++ b/docs/topics/mailbox_types.rst @@ -7,25 +7,26 @@ POP3 and IMAP as well as local file-based mailboxes. .. table:: 'Protocol' Options - ============ ============== =============================================================== + ============ ============== ================================================================================================================================================================= Mailbox Type 'Protocol':// Notes - ============ ============== =============================================================== + ============ ============== ================================================================================================================================================================= POP3 ``pop3://`` Can also specify SSL with ``pop3+ssl://`` - IMAP ``imap://`` Can also specify SSL and archive with ``imap+ssl://?myarchive`` + IMAP ``imap://`` Can also specify SSL with ``imap+ssl://``, or specify a folder to save processed messages into by appending ``?archive=my_archive_folder`` to the end of the URI. Maildir ``maildir://`` Mbox ``mbox://`` Babyl ``babyl://`` MH ``mh://`` MMDF ``mmdf://`` Piped Mail *empty* See :ref:`receiving-mail-from-exim4-or-postfix` - ============ ============== =============================================================== + ============ ============== ================================================================================================================================================================= + .. warning:: - This will delete or move any messages it can find in the inbox you specify; + Unless you are using IMAP's 'Archive' feature, + this will delete any messages it can find in the inbox you specify; do not use an e-mail inbox that you would like to share between - applications. For the IMAP protocol you can specify an archive folder where - emails are moved to. + applications. POP3 and IMAP Mailboxes @@ -40,22 +41,25 @@ Basic IMAP Example: ``imap://username:password@server`` Basic POP3 Example: ``pop3://username:password@server`` Most mailboxes these days are SSL-enabled; -if yours is, add ``+ssl`` to your URI. +if yours is, add ``+ssl`` to the protocol section of your URI. Also, if your username or password include any non-ascii characters, they should be URL-encoded (for example, if your username includes an ``@``, it should be changed to ``%40`` in your URI). If you are using an IMAP Mailbox, you can archive all messages before they are deleted from the inbox. To archive emails, add the archive folder -name as a queryparemeter to the uri (for example, if your mailbox has a -folder called myarchive, add ``?myarchive`` to the uri). +name as a query paremeter to the uri. For example, if your mailbox has a +folder named ``myarchivefolder`` that you would like to copy messages to +after processing, add ``?archive=myarchivefolder`` to the end of the URI. -If you have an account named ``youremailaddress@gmail.com`` with a password -of ``1234`` on GMail, which uses a IMAP server of 'imap.gmail.com', requires -SSL and you want to archive all emails, you would enter the following as -your URI:: +For a verbose example, if you have an account named +``youremailaddress@gmail.com`` with a password +of ``1234`` on GMail, which uses a IMAP server of ``imap.gmail.com`` (requiring +SSL) and you would like to archive all processed emails +into a folder named ``Archived``, you +would enter the following as your URI:: - pop3+ssl://youremailaddress%40gmail.com:1234@pop.gmail.com?[GMAIL]/All Mail + pop3+ssl://youremailaddress%40gmail.com:1234@pop.gmail.com?archive=Archived Local File-based Mailboxes