Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions maildump/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import asyncore
import gevent
from gevent.pywsgi import WSGIServer
from logbook import Logger

from maildump.db import connect, create_tables, disconnect
from maildump.smtp import SMTPServer, smtp_handler
from maildump.smtp import start_smtp_server, smtp_handler
from maildump.web import app

log = Logger(__name__)
stopper = None
smtp_controller = None


def start(http_host, http_port, smtp_host, smtp_port, db_path=None):
global stopper
global stopper, smtp_controller
# Webserver
log.notice(f'Starting web server on http://{http_host}:{http_port}')
http_server = WSGIServer((http_host, http_port), app)
stopper = http_server.close
# SMTP server
log.notice(f'Starting smtp server on {smtp_host}:{smtp_port}')
SMTPServer((smtp_host, smtp_port), smtp_handler)
gevent.spawn(asyncore.loop)
smtp_controller = start_smtp_server(smtp_host, smtp_port, smtp_handler)
# Database
connect(db_path)
create_tables()
Expand Down
28 changes: 21 additions & 7 deletions maildump/smtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,32 @@
from logbook import Logger

from maildump.db import add_message
from maildump.vendor import smtpd
from aiosmtpd.controller import Controller

log = Logger(__name__)


class SMTPServer(smtpd.SMTPServer):
def __init__(self, listener, handler):
super().__init__(listener, None)
self._handler = handler

def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
return self._handler(sender=mailfrom, recipients=rcpttos, body=data)
# aiosmtpd handler class
class SMTPHandler:
def __init__(self, handler_func):
self._handler = handler_func

async def handle_DATA(self, server, session, envelope):
# envelope.content is bytes
result = self._handler(
sender=envelope.mail_from,
recipients=envelope.rcpt_tos,
body=envelope.content
)
return '250 Message accepted for delivery'


def start_smtp_server(host, port, handler_func):
handler = SMTPHandler(handler_func)
controller = Controller(handler, hostname=host, port=port)
controller.start()
return controller


def smtp_handler(sender, recipients, body):
Expand Down
Loading