birthday testmail when most contacts

This commit is contained in:
2026-08-07 21:37:50 +02:00
parent 5e1a2b0b92
commit 047766df86
3 changed files with 35 additions and 7 deletions
+16 -4
View File
@@ -10,7 +10,7 @@ Benutzernamen im Remote-User-Header mitschickt."""
import json import json
import logging import logging
import secrets import secrets
from datetime import date, datetime from datetime import datetime
from urllib.parse import quote_plus from urllib.parse import quote_plus
from fastapi import Depends, FastAPI, Query, Request from fastapi import Depends, FastAPI, Query, Request
@@ -424,7 +424,6 @@ def admin_test_send(
if not is_admin: if not is_admin:
return RedirectResponse(url="/", status_code=303) return RedirectResponse(url="/", status_code=303)
target = date(2026, 8, 6)
try: try:
Config.validate_mailer() Config.validate_mailer()
except RuntimeError as exc: except RuntimeError as exc:
@@ -453,9 +452,22 @@ def admin_test_send(
status_code=400, status_code=400,
) )
sent_count = 0
errors = []
with db.get_connection() as conn: with db.get_connection() as conn:
target = db.get_most_common_birthday(conn)
if target is None:
return templates.TemplateResponse(
"admin.html",
{
"request": request,
"current_user": current_user,
"show_all": request.session.get("show_all", False),
"error": "Keine Kontakte mit Geburtstag in der Datenbank",
},
status_code=400,
)
sent_count = 0
errors = []
for account in mail_accounts: for account in mail_accounts:
birthdays = fetch_todays_birthdays_for_account(conn, account.name, target) birthdays = fetch_todays_birthdays_for_account(conn, account.name, target)
if not birthdays: if not birthdays:
+2 -2
View File
@@ -227,10 +227,10 @@
<div class="card"> <div class="card">
<div class="card-title">E-Mail-Test</div> <div class="card-title">E-Mail-Test</div>
<form method="post" action="/admin/test-send"> <form method="post" action="/admin/test-send">
<button type="submit" class="btn">Test-Geburtstagsmail senden (06.08.)</button> <button type="submit" class="btn">Test-Geburtstagsmail senden</button>
</form> </form>
<div class="test-info"> <div class="test-info">
Sendet eine Test-Geburtstagsmail an die im Account hinterlegte Adresse (birthday_mail_to) mit allen Kontakten, die am 6. August Geburtstag haben. Das Layout entspricht der täglichen Geburtstagsmail. Sendet eine Test-Geburtstagsmail an die im Account hinterlegte Adresse (birthday_mail_to) mit allen Kontakten, die am beliebtesten Geburtstag haben. Das Layout entspricht der täglichen Geburtstagsmail.
</div> </div>
</div> </div>
</div> </div>
+17 -1
View File
@@ -5,7 +5,7 @@ import logging
import os import os
import uuid import uuid
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime, timezone from datetime import date, datetime, timezone
import pymysql import pymysql
from pymysql.cursors import DictCursor from pymysql.cursors import DictCursor
@@ -231,6 +231,22 @@ def search_contacts_without_social(conn, account: str | None) -> list[dict]:
return cur.fetchall() return cur.fetchall()
def get_most_common_birthday(conn) -> date | None:
with conn.cursor() as cur:
cur.execute(
"""SELECT MONTH(birthday) AS m, DAY(birthday) AS d, COUNT(*) AS cnt
FROM contacts
WHERE birthday IS NOT NULL
GROUP BY m, d
ORDER BY cnt DESC
LIMIT 1"""
)
row = cur.fetchone()
if not row:
return None
return date(datetime.now().year, row["m"], row["d"])
def get_upcoming_birthdays(conn, account: str | None, days: int = 7) -> list[dict]: def get_upcoming_birthdays(conn, account: str | None, days: int = 7) -> list[dict]:
where_clause, params = _account_filter_clause(account) where_clause, params = _account_filter_clause(account)
today = datetime.now(Config.TIMEZONE).date() today = datetime.now(Config.TIMEZONE).date()