mail test method

This commit is contained in:
2026-08-07 12:39:21 +02:00
parent e3ca295ebd
commit 8eaac47ef6
3 changed files with 123 additions and 5 deletions
+54
View File
@@ -23,6 +23,7 @@ import db
from api.auth import get_current_user, resolve_account_for_user
from api.schemas import ContactListResponse, ContactOut, SyncRunOut
from config import Config
from mailer import build_message, fetch_birthdays_for_date, send_message
logging.basicConfig(level=Config.LOG_LEVEL, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger("api")
@@ -283,6 +284,59 @@ def admin_toggle(
return RedirectResponse(url="/admin", status_code=303)
@app.post("/admin/test-send")
def admin_test_send(
request: Request,
current_user: str = Depends(get_current_user),
):
_, is_admin, _ = _resolve_effective_account(request, current_user)
if not is_admin:
return RedirectResponse(url="/", status_code=303)
target = date(2026, 8, 6)
try:
Config.validate_mailer()
except RuntimeError as exc:
return templates.TemplateResponse(
"admin.html",
{
"request": request,
"current_user": current_user,
"show_all": request.session.get("show_all", False),
"error": str(exc),
},
status_code=400,
)
with db.get_connection() as conn:
birthdays = fetch_birthdays_for_date(conn, target)
msg = build_message(birthdays, target_date=target)
try:
send_message(msg)
except Exception as exc:
return templates.TemplateResponse(
"admin.html",
{
"request": request,
"current_user": current_user,
"show_all": request.session.get("show_all", False),
"error": f"Versand fehlgeschlagen: {exc}",
},
status_code=500,
)
return templates.TemplateResponse(
"admin.html",
{
"request": request,
"current_user": current_user,
"show_all": request.session.get("show_all", False),
"success": f"Test-Mail für {target.strftime('%d.%m.%Y')} gesendet ({len(birthdays)} Kontakte).",
},
)
@app.get("/search/special", response_class=HTMLResponse)
def web_search_special(
request: Request,
+61
View File
@@ -143,6 +143,50 @@
background: #f8f9fa;
color: #666;
}
.btn {
display: inline-block;
padding: 0.75rem 1.5rem;
background: #0066cc;
color: #fff;
border: none;
border-radius: 6px;
font-size: 0.875rem;
cursor: pointer;
text-decoration: none;
}
.btn:hover {
background: #0055aa;
}
.btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.flash {
margin-top: 1rem;
padding: 0.75rem;
border-radius: 6px;
font-size: 0.875rem;
}
.flash-success {
background: #d4edda;
color: #155724;
}
.flash-error {
background: #f8d7da;
color: #721c24;
}
.test-info {
font-size: 0.8125rem;
color: #888;
margin-top: 0.75rem;
}
</style>
</head>
<body>
@@ -172,6 +216,23 @@
{% endif %}
</div>
</div>
{% if success %}
<div class="flash flash-success">{{ success }}</div>
{% endif %}
{% if error %}
<div class="flash flash-error">{{ error }}</div>
{% endif %}
<div class="card">
<div class="card-title">E-Mail-Test</div>
<form method="post" action="/admin/test-send">
<button type="submit" class="btn">Test-Geburtstagsmail senden (06.08.)</button>
</form>
<div class="test-info">
Sendet eine Test-Geburtstagsmail an die konfigurierte Adresse (MAIL_TO) mit allen Kontakten, die am 6. August Geburtstag haben. Das Layout entspricht der täglichen Geburtstagsmail.
</div>
</div>
</div>
</body>
</html>
+8 -5
View File
@@ -18,8 +18,7 @@ logging.basicConfig(level=Config.LOG_LEVEL, format="%(asctime)s [%(levelname)s]
logger = logging.getLogger("mailer")
def fetch_todays_birthdays(conn) -> list[dict]:
today = date.today()
def fetch_birthdays_for_date(conn, target_date: date) -> list[dict]:
with conn.cursor() as cur:
cur.execute(
"""SELECT id, account, full_name, birthday, organization, photo_url
@@ -28,11 +27,15 @@ def fetch_todays_birthdays(conn) -> list[dict]:
AND MONTH(birthday) = %s
AND DAY(birthday) = %s
ORDER BY full_name""",
(today.month, today.day),
(target_date.month, target_date.day),
)
return cur.fetchall()
def fetch_todays_birthdays(conn) -> list[dict]:
return fetch_birthdays_for_date(conn, date.today())
def already_sent_today(conn) -> bool:
today = date.today()
with conn.cursor() as cur:
@@ -50,8 +53,8 @@ def log_sent(conn, count: int):
conn.commit()
def build_message(birthdays: list[dict]) -> EmailMessage:
today = date.today()
def build_message(birthdays: list[dict], target_date: date | None = None) -> EmailMessage:
today = target_date or date.today()
msg = EmailMessage()
msg["From"] = Config.MAIL_FROM
msg["To"] = Config.MAIL_TO