from __future__ import annotations import smtplib from dataclasses import dataclass from email.message import EmailMessage from app.core.config import settings @dataclass class SentEmail: to: str subject: str body: str template: str class MemoryMailer: def __init__(self) -> None: self.sent: list[SentEmail] = [] def send(self, to: str, subject: str, body: str, template: str) -> None: self.sent.append(SentEmail(to=to, subject=subject, body=body, template=template)) def clear(self) -> None: self.sent.clear() def latest_token(self, recipient: str, template: str) -> str | None: for message in reversed(self.sent): if message.to == recipient and message.template == template: for line in message.body.splitlines(): if line.startswith("TOKEN:"): return line.split(":", 1)[1].strip() return None class SmtpMailer: def send(self, to: str, subject: str, body: str, template: str) -> None: _ = template message = EmailMessage() message["From"] = settings.smtp_from message["To"] = to message["Subject"] = subject message.set_content(body) with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=10) as smtp: if settings.smtp_user: smtp.login(settings.smtp_user, settings.smtp_password) smtp.send_message(message) memory_mailer = MemoryMailer() def get_mailer(): if settings.email_delivery_mode == "memory": return memory_mailer return SmtpMailer() def send_template_email(to: str, template: str, subject: str, body: str) -> None: get_mailer().send(to=to, subject=subject, body=body, template=template)