aports/community/py3-django-extensions/1841_update-mail-debug-command-to-use-aiosmtpd.patch

94 lines
3.5 KiB
Diff

From 37d56c4a4704c823ac6a4ef7c3de4c0232ceee64 Mon Sep 17 00:00:00 2001
From: Wes Lord <weslord@gmail.com>
Date: Tue, 17 Oct 2023 21:06:57 -0700
Subject: [PATCH] Update mail_debug command to use aiosmtpd
smtpd deprecated by Python 3.6, removed in Python 3.12
---
.../management/commands/mail_debug.py | 22 ++++++++++---------
requirements-dev.txt | 1 +
tests/management/commands/test_mail_debug.py | 4 ++--
3 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/django_extensions/management/commands/mail_debug.py b/django_extensions/management/commands/mail_debug.py
index 7a8424dc4..c76007612 100644
--- a/django_extensions/management/commands/mail_debug.py
+++ b/django_extensions/management/commands/mail_debug.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-import asyncore
+import asyncio
import sys
+from aiosmtpd.controller import Controller
from logging import getLogger
-from smtpd import SMTPServer
from typing import List
from django.core.management.base import BaseCommand, CommandError
@@ -12,14 +12,12 @@
logger = getLogger(__name__)
-class ExtensionDebuggingServer(SMTPServer):
- """Duplication of smtpd.DebuggingServer, but using logging instead of print."""
-
- # Do something with the gathered message
- def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
+class CustomHandler:
+ async def handle_DATA(self, server, session, envelope):
"""Output will be sent to the module logger at INFO level."""
+ peer = session.peer
inheaders = 1
- lines = data.split('\n')
+ lines = envelope.content.decode('utf8', errors='replace').splitlines()
logger.info('---------- MESSAGE FOLLOWS ----------')
for line in lines:
# headers first
@@ -28,6 +26,7 @@ def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
inheaders = 0
logger.info(line)
logger.info('------------ END MESSAGE ------------')
+ return '250 OK'
class Command(BaseCommand):
@@ -78,8 +77,11 @@ def handle(self, addrport='', *args, **options):
def inner_run():
quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'
print("Now accepting mail at %s:%s -- use %s to quit" % (addr, port, quit_command))
- ExtensionDebuggingServer((addr, port), None, decode_data=True)
- asyncore.loop()
+ handler = CustomHandler()
+ controller = Controller(handler, hostname=addr, port=port)
+ controller.start()
+ loop = asyncio.get_event_loop()
+ loop.run_forever()
try:
inner_run()
diff --git a/requirements-dev.txt b/requirements-dev.txt
index cc9112252..08578babd 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -8,6 +8,7 @@ factory-boy
requests
pygments
vobject
+aiosmtpd
types-pyOpenSSL
types-PyYAML
diff --git a/tests/management/commands/test_mail_debug.py b/tests/management/commands/test_mail_debug.py
index c75dbede1..f723f52c5 100644
--- a/tests/management/commands/test_mail_debug.py
+++ b/tests/management/commands/test_mail_debug.py
@@ -4,6 +4,6 @@
def test_initialize_mail_server():
- with mock.patch('django_extensions.management.commands.mail_debug.asyncore.loop') as loop:
+ with mock.patch('django_extensions.management.commands.mail_debug.asyncio') as asyncio:
call_command('mail_debug', '2525')
- assert loop.called, 'asyncore.loop was not called'
+ assert asyncio.get_event_loop.called, 'asyncio.get_event_loop was not called'