Files
TK-Wiki-Newsletter/app/services/smtp_sender.py
smueller e5e4d812c7 Update configuration and enhance newsletter generation features
- Change WIKI_API_URL in .env.example and config to point to the new API endpoint.
- Set COOKIE_SECURE to false for local development in .env.example and config.
- Improve the newsletter generation logic to handle new and edited articles separately.
- Add display options for showing date, user, and category in the newsletter output.
- Enhance error handling for Wiki API requests and update templates for better user feedback.
- Update CSS for new UI elements and improve overall layout in dashboard and login pages.
2026-07-03 12:47:35 +02:00

93 lines
3.4 KiB
Python

import smtplib
from datetime import datetime
from email.mime.multipart import MIMEMultipart
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 = MIMEMultipart("alternative")
msg.attach(MIMEText(text_content, "plain", "utf-8"))
msg.attach(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()