1
0
Fork 0

Support for Django 5.0 and python 3.12 + Fix CI (#277)

* Upgrade to last Django & Python supported versions

* flake8 fixes

* Add CI

* Add final version of Django 5.0
This commit is contained in:
Pascal F 2023-12-10 04:01:53 +01:00 committed by GitHub
parent 462fdd3e49
commit 7fde5f7165
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 119 additions and 89 deletions

View file

@ -5,3 +5,5 @@ from django.utils.translation import gettext_lazy as _
class MailBoxConfig(AppConfig):
name = 'django_mailbox'
verbose_name = _("Mail Box")
default_auto_field = "django.db.models.AutoField"

View file

@ -15,7 +15,6 @@ import email
import logging
import mimetypes
import os.path
import sys
import uuid
from tempfile import NamedTemporaryFile
@ -42,7 +41,7 @@ class MailboxQuerySet(models.QuerySet):
for mailbox in self.all():
logger.debug('Receiving mail for %s' % mailbox)
count += sum(1 for i in mailbox.get_new_mail())
logger.debug('Received %d %s.', count, 'mails' if count != 1 else 'mail')
logger.debug('Received %d %s.', count, 'mail(s)')
class MailboxManager(models.Manager):
@ -123,6 +122,13 @@ class Mailbox(models.Model):
objects = MailboxManager()
active_mailboxes = ActiveMailboxManager()
class Meta:
verbose_name = _('Mailbox')
verbose_name_plural = _('Mailboxes')
def __str__(self):
return self.name
@property
def _protocol_info(self):
return urlparse(self.uri)
@ -448,13 +454,12 @@ class Mailbox(models.Model):
def get_new_mail(self, condition=None):
"""Connect to this transport and fetch new messages."""
new_mail = []
connection = self.get_connection()
if not connection:
return
for message in connection.get_message(condition):
msg = self.process_incoming_message(message)
if not msg is None:
if msg is not None:
yield msg
self.last_polling = now()
if django.VERSION >= (1, 5): # Django 1.5 introduces update_fields
@ -483,14 +488,6 @@ class Mailbox(models.Model):
)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Mailbox')
verbose_name_plural = _('Mailboxes')
class IncomingMessageManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(
@ -757,7 +754,7 @@ class Message(models.Model):
"""Returns an `email.message.EmailMessage` instance representing the
contents of this message and all attachments.
See [email.message.EmailMessage]_ for more information as to what methods
See [email.message.EmailMessage]_ for more information like what methods
and properties are available on `email.message.EmailMessage` instances.
.. note::

View file

@ -1,3 +1,3 @@
from django.dispatch.dispatcher import Signal
message_received = Signal(providing_args=['message'])
message_received = Signal() # providing_args=['message']

View file

@ -1,6 +1,5 @@
import gzip
import os.path
import sys
import copy
from unittest import mock
@ -9,7 +8,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']
@ -367,12 +366,12 @@ 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())))
len(force_str(msg.get_email_object().as_string())))
def test_message_saved(self):
message = self._get_email_object('generic_message.eml')
@ -386,7 +385,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'))
@ -408,7 +407,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')

View file

@ -1,34 +1,25 @@
from distutils.version import LooseVersion
from unittest import mock
from django.core.management import call_command, CommandError
from django.test import TestCase
import django
class CommandsTestCase(TestCase):
def test_processincomingmessage_no_args(self):
"""Check that processincomingmessage works with no args"""
mailbox_name = None
# Mock handle so that the test doesn't hang waiting for input. Note that we are only testing
# the argument parsing here -- functionality should be tested elsewhere
with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle:
# Don't care about the return value
handle.return_value = None
call_command('processincomingmessage')
args, kwargs = handle.call_args
# Make sure that we called with the right arguments
try:
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
except KeyError:
# Handle Django 1.7
# It uses optparse instead of argparse, so instead of being
# set to None, mailbox_name is simply left out altogether
# Thus we expect an empty tuple here
self.assertEqual(args, tuple())
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
def test_processincomingmessage_with_arg(self):
"""Check that processincomingmessage works with mailbox_name given"""
@ -37,29 +28,14 @@ class CommandsTestCase(TestCase):
with mock.patch('django_mailbox.management.commands.processincomingmessage.Command.handle') as handle:
handle.return_value = None
call_command('processincomingmessage', mailbox_name)
args, kwargs = handle.call_args
try:
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
except (AssertionError, KeyError):
# Handle Django 1.7
# It uses optparse instead of argparse, so instead of being
# in kwargs, mailbox_name is in args
self.assertEqual(args[0], mailbox_name)
self.assertEqual(kwargs['mailbox_name'], mailbox_name)
def test_processincomingmessage_too_many_args(self):
"""Check that processincomingmessage raises an error if too many args"""
# Only perform this test for Django versions greater than 1.7.*. This
# is because, with optparse, too many arguments doesn't result in an
# error, which means this test is worthless anyway
# For the "compatibility" versions, unexpected arguments aren't handled
# very well, and result in a TypeError
if (LooseVersion(django.get_version()) >= LooseVersion('1.8') and
LooseVersion(django.get_version()) < LooseVersion('1.10')):
with self.assertRaises(TypeError):
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
# In 1.10 and later a proper CommandError should be raised
elif LooseVersion(django.get_version()) >= LooseVersion('1.10'):
with self.assertRaises(CommandError):
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')
with self.assertRaises(CommandError):
call_command('processincomingmessage', 'foo_mailbox', 'invalid_arg')

View file

@ -8,7 +8,7 @@ from django_mailbox.transports import ImapTransport, Pop3Transport
FAKE_UID_SEARCH_ANSWER = (
'OK',
[
b'18 19 20 21 22 23 24 25 26 27 28 29 ' +
b'18 19 20 21 22 23 24 25 26 27 28 29 ' +
b'30 31 32 33 34 35 36 37 38 39 40 41 42 43 44'
]
)

View file

@ -9,4 +9,3 @@ class EmailTransport:
message = email.message_from_bytes(contents)
return message

View file

@ -1,4 +1,4 @@
import sys
from .base import EmailTransport

View file

@ -63,4 +63,3 @@ class Office365Transport(EmailTransport):
o365message.delete()
return