90 lines
3.2 KiB
Python
90 lines
3.2 KiB
Python
import smtplib
|
|
from datetime import datetime
|
|
from email.mime.text import MIMEText
|
|
from typing import Sequence
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.system import SendLog
|
|
from app.services.config_store import get_config
|
|
|
|
|
|
def get_smtp_settings(db: Session) -> dict[str, str]:
|
|
return {
|
|
"enabled": get_config(db, "smtp.enabled", "false"),
|
|
"host": get_config(db, "smtp.host", ""),
|
|
"port": get_config(db, "smtp.port", "587"),
|
|
"username": get_config(db, "smtp.username", ""),
|
|
"password": get_config(db, "smtp.password", ""),
|
|
"from_email": get_config(db, "smtp.from_email", ""),
|
|
"use_tls": get_config(db, "smtp.use_tls", "true"),
|
|
"recipients": get_config(db, "smtp.recipients", ""),
|
|
"schedule_time": get_config(db, "smtp.schedule_time", "08:00"),
|
|
"last_scheduled_date": get_config(db, "smtp.last_scheduled_date", ""),
|
|
}
|
|
|
|
|
|
def send_newsletter(
|
|
db: Session,
|
|
subject: str,
|
|
html_content: str,
|
|
text_content: str,
|
|
recipients: Sequence[str],
|
|
scheduled: bool = False,
|
|
) -> None:
|
|
settings = get_smtp_settings(db)
|
|
if settings["enabled"].lower() != "true":
|
|
_log(db, subject, recipients, "skipped", "SMTP ist deaktiviert.", scheduled)
|
|
return
|
|
if not settings["host"] or not settings["from_email"] or not recipients:
|
|
_log(db, subject, recipients, "failed", "SMTP unvollständig konfiguriert.", scheduled)
|
|
return
|
|
|
|
msg = MIMEText(html_content, "html", "utf-8")
|
|
msg["Subject"] = subject
|
|
msg["From"] = settings["from_email"]
|
|
msg["To"] = ", ".join(recipients)
|
|
|
|
try:
|
|
port = int(settings["port"])
|
|
with smtplib.SMTP(settings["host"], port, timeout=20) as server:
|
|
if settings["use_tls"].lower() == "true":
|
|
server.starttls()
|
|
if settings["username"]:
|
|
server.login(settings["username"], settings["password"])
|
|
server.sendmail(settings["from_email"], list(recipients), msg.as_string())
|
|
_log(db, subject, recipients, "sent", "Versand erfolgreich.", scheduled)
|
|
except Exception as exc:
|
|
_log(db, subject, recipients, "failed", f"Versandfehler: {exc}", scheduled)
|
|
|
|
|
|
def run_scheduled_send_if_due(db: Session, subject: str, html_content: str, text_content: str) -> None:
|
|
settings = get_smtp_settings(db)
|
|
if settings["enabled"].lower() != "true":
|
|
return
|
|
now = datetime.now()
|
|
schedule_time = settings["schedule_time"] or "08:00"
|
|
if now.strftime("%H:%M") < schedule_time:
|
|
return
|
|
today = now.strftime("%Y-%m-%d")
|
|
if settings["last_scheduled_date"] == today:
|
|
return
|
|
recipients = [r.strip() for r in settings["recipients"].split(",") if r.strip()]
|
|
send_newsletter(db, subject, html_content, text_content, recipients, scheduled=True)
|
|
from app.services.config_store import set_config
|
|
|
|
set_config(db, "smtp.last_scheduled_date", today)
|
|
|
|
|
|
def _log(db: Session, subject: str, recipients: Sequence[str], status: str, detail: str, scheduled: bool) -> None:
|
|
db.add(
|
|
SendLog(
|
|
subject=subject,
|
|
recipients=", ".join(recipients) if recipients else "-",
|
|
status=status,
|
|
detail=detail,
|
|
scheduled=scheduled,
|
|
)
|
|
)
|
|
db.commit()
|