diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 0f0ac9d..bfdda0a 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -17,6 +17,7 @@ import mimetypes import os.path import sys import uuid +from datetime import timedelta from tempfile import NamedTemporaryFile import django @@ -35,6 +36,8 @@ from django_mailbox.transports import Pop3Transport, ImapTransport, \ logger = logging.getLogger(__name__) +INITIAL_IMPORT_LOOKBACK_DAYS = 365 + class MailboxQuerySet(models.QuerySet): def get_new_mail(self): @@ -420,7 +423,12 @@ class Mailbox(models.Model): connection = self.get_connection() if not connection: return - for message in connection.get_message(condition): + + since = self.last_polling + if since is None: + since = now() - timedelta(days=INITIAL_IMPORT_LOOKBACK_DAYS) + + for message in connection.get_message_ro(since=since): msg = self.process_incoming_message(message) if not msg is None: yield msg diff --git a/django_mailbox/transports/generic.py b/django_mailbox/transports/generic.py index 5832fda..a43918a 100644 --- a/django_mailbox/transports/generic.py +++ b/django_mailbox/transports/generic.py @@ -24,3 +24,6 @@ class GenericFileMailbox(EmailTransport): yield message repository.flush() repository.unlock() + + def get_message_ro(self, since=None): + raise NotImplementedError("GenericFileMailbox.get_message_ro not implemented!") diff --git a/django_mailbox/transports/imap.py b/django_mailbox/transports/imap.py index 2599ada..fc6951b 100644 --- a/django_mailbox/transports/imap.py +++ b/django_mailbox/transports/imap.py @@ -99,19 +99,47 @@ class ImapTransport(EmailTransport): if not message_ids: return - # Limit the uids to the small ones if we care about that - if self.max_message_size: - message_ids = self._get_small_message_ids(message_ids) - if self.archive: typ, folders = self.server.list(pattern=self.archive) if folders[0] is None: # If the archive folder does not exist, create it self.server.create(self.archive) + for message in self._iter_messages(message_ids): + yield message + + self.server.expunge() + return + + def get_message_ro(self, since): + """Read-only version of `get_message`. Uses a timestamp to fetch only messages + originating later than `since` parameter. + """ + + date_format = "%d-%b-%Y" + typ, [raw_msg_ids] = self.server.search(None, '(since "%s")' % (since.strftime(date_format))) + + message_ids = raw_msg_ids.decode().split() + + if not message_ids: + return + + for message in self._iter_messages(message_ids, archive=False, delete=False): + yield message + + self.server.expunge() + return + + + def _iter_messages(self, message_ids, condition=None, archive=True, delete=True): + + # Limit the uids to the small ones if we care about that + if self.max_message_size: + message_ids = self._get_small_message_ids(message_ids) + for uid in message_ids: try: - typ, msg_contents = self.server.uid('fetch', uid, '(RFC822)') + typ, msg_contents = self.server.fetch(uid, '(RFC822)') if not msg_contents: continue try: @@ -129,9 +157,8 @@ class ImapTransport(EmailTransport): except MessageParseError: continue - if self.archive: + if archive and self.archive: self.server.uid('copy', uid, self.archive) - self.server.uid('store', uid, "+FLAGS", "(\\Deleted)") - self.server.expunge() - return + if delete: + self.server.uid('store', uid, "+FLAGS", "(\\Deleted)") \ No newline at end of file diff --git a/django_mailbox/transports/pop3.py b/django_mailbox/transports/pop3.py index 6dbe995..526538e 100644 --- a/django_mailbox/transports/pop3.py +++ b/django_mailbox/transports/pop3.py @@ -42,3 +42,6 @@ class Pop3Transport(EmailTransport): self.server.dele(i + 1) self.server.quit() return + + def get_message_ro(self, since=None): + raise NotImplementedError("Pop3Transport.get_message_ro not implemented!") \ No newline at end of file