diff --git a/CHANGELOG.md b/CHANGELOG.md index 351756c..d43522a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), [Also based on](https://github.com/conventional-changelog/standard-version/blob/master/CHANGELOG.md) so decending. +## [0.1.2] - 2021-02-07 +### Added +- adds unique constrain to the message id and a bit of a change on how to create a message +- adds formatting updates and testing updates + ## [0.1.1] - 2021-02-03 ### Added - adds modified documenation diff --git a/django_mailbox/migrations/0009_auto_20210207_0221.py b/django_mailbox/migrations/0009_auto_20210207_0221.py new file mode 100644 index 0000000..88f958a --- /dev/null +++ b/django_mailbox/migrations/0009_auto_20210207_0221.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.6 on 2021-02-07 02:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("django_mailbox", "0008_auto_20190219_1553"), + ] + + operations = [ + migrations.AlterField( + model_name="message", + name="message_id", + field=models.CharField( + blank=None, + max_length=255, + null=None, + unique=True, + verbose_name="Message ID", + ), + ), + ] diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 486bf22..d6166fd 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -352,7 +352,10 @@ class Mailbox(models.Model): return new def _process_message(self, message): - msg = Message() + try: + msg = Message(message_id=message["message-id"][0:255].strip()) + except Exception: + msg = Message() msg._email_object = message settings = utils.get_settings() @@ -369,8 +372,13 @@ class Mailbox(models.Model): msg.to_header = utils.convert_header_to_unicode(message["to"]) elif "Delivered-To" in message: msg.to_header = utils.convert_header_to_unicode(message["Delivered-To"]) - msg.save() - message = self._get_dehydrated_message(message, msg) + try: + msg.save() + message = self._get_dehydrated_message(message, msg) + except django.db.utils.IntegrityError: + logger.warning("Already loaded") + return None + try: body = message.as_string() except KeyError as exc: @@ -467,7 +475,9 @@ class Message(models.Model): subject = models.CharField(_("Subject"), max_length=255) - message_id = models.CharField(_("Message ID"), max_length=255) + message_id = models.CharField( + _("Message ID"), max_length=255, blank=None, null=None, unique=True + ) in_reply_to = models.ForeignKey( "django_mailbox.Message", diff --git a/django_mailbox/signals.py b/django_mailbox/signals.py index 9de31ae..9af4af7 100644 --- a/django_mailbox/signals.py +++ b/django_mailbox/signals.py @@ -1,3 +1,3 @@ from django.dispatch.dispatcher import Signal -message_received = Signal(providing_args=["message"]) +message_received = Signal() diff --git a/django_mailbox/tests/test_process_email.py b/django_mailbox/tests/test_process_email.py index 2403a2d..c0d4c68 100644 --- a/django_mailbox/tests/test_process_email.py +++ b/django_mailbox/tests/test_process_email.py @@ -10,7 +10,7 @@ from django_mailbox.models import Mailbox, Message from django_mailbox.utils import convert_header_to_unicode from django_mailbox import utils from django_mailbox.tests.base import EmailMessageTestCase -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.core.mail import EmailMessage __all__ = ["TestProcessEmail"] @@ -347,11 +347,11 @@ class TestProcessEmail(EmailMessageTestCase): email_object = self._get_email_object( "message_with_long_content.eml", ) - size = len(force_text(email_object.as_string())) + size = len(force_str(email_object.as_string())) msg = self.mailbox.process_incoming_message(email_object) - self.assertEqual(size, len(force_text(msg.get_email_object().as_string()))) + self.assertEqual(size, len(force_str(msg.get_email_object().as_string()))) def test_message_saved(self): message = self._get_email_object("generic_message.eml") @@ -365,7 +365,7 @@ class TestProcessEmail(EmailMessageTestCase): msg = self.mailbox.process_incoming_message(message) - self.assertNotEquals(msg.eml, None) + self.assertNotEqual(msg.eml, None) self.assertTrue(msg.eml.name.endswith(".eml")) @@ -384,7 +384,7 @@ class TestProcessEmail(EmailMessageTestCase): msg = self.mailbox.process_incoming_message(message) - self.assertEquals(msg.eml, None) + self.assertEqual(msg.eml, None) def test_message_compressed(self): message = self._get_email_object("generic_message.eml") diff --git a/django_mailbox/transports/imap.py b/django_mailbox/transports/imap.py index e3de110..8808c67 100644 --- a/django_mailbox/transports/imap.py +++ b/django_mailbox/transports/imap.py @@ -1,7 +1,5 @@ import imaplib import logging -from os.path import exists -import json from django.conf import settings from .base import EmailTransport, MessageParseError @@ -36,9 +34,6 @@ class ImapTransport(EmailTransport): self.delete_message_from_server = getattr( settings, "DJANGO_MAILBOX_DELETE_MESSAGE_FROM_SERVER", True ) - self.delete_message_store = getattr( - settings, "DJANGO_MAILBOX_DELETE_MESSAGE_ID_STORE", "/tmp/store.json" - ) self.hostname = hostname self.port = port self.archive = archive @@ -111,28 +106,7 @@ class ImapTransport(EmailTransport): # If the archive folder does not exist, create it self.server.create(self.archive) - # PoC of alternative method of storing email - if not self.delete_message_from_server: - j = {"uids": []} - if exists("store.json"): - with open("store.json", "r") as f: - j = json.load(f) - else: - with open("store.json", "w") as f: - json.dump(j, f) - # PoC of alternative method of storing email - for uid in message_ids: - # PoC of alternative method of storing email - if not self.delete_message_from_server: - if uid in j["uids"]: - continue - else: - j["uids"].append(uid) - with open("store.json", "w") as f: - json.dump(j, f) - # PoC of alternative method of storing email - try: typ, msg_contents = self.server.uid("fetch", uid, "(RFC822)") if not msg_contents: diff --git a/readme.rst b/readme.rst index 8966d95..a787ce4 100644 --- a/readme.rst +++ b/readme.rst @@ -14,7 +14,8 @@ These ingested messages will be stored in the database in Django models and you or -- if you're in a hurry -- by using a signal receiver. -### Usage +Usage +----- 1. poetry add django-mailbox @@ -36,3 +37,9 @@ or -- if you're in a hurry -- by using a signal receiver. `Github `_. - Test status available on `Travis-CI `_. + +Development +----------- + +export DJANGO_SETTINGS_MODULE=websrv.settings +