Feature: Tagesmail — Action Items + neue Nutzer heute
This commit is contained in:
parent
d04110c2ae
commit
df8c4cc279
1 changed files with 67 additions and 4 deletions
|
|
@ -650,6 +650,34 @@ async def _job_ki_health_report():
|
|||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def _action_items_html(metrics: dict) -> str:
|
||||
items = [
|
||||
("jobs_pending", "Bewerbungen offen"),
|
||||
("breeder_pending", "Züchter-Anträge"),
|
||||
("reports_open", "Forum-Meldungen"),
|
||||
("fotos_pending", "Foto-Einreichungen"),
|
||||
("poi_edits_pending", "POI-Korrekturen"),
|
||||
]
|
||||
open_items = [(label, metrics.get(key, 0)) for key, label in items if metrics.get(key, 0) > 0]
|
||||
|
||||
if not open_items:
|
||||
body = '<span style="color:#16a34a;font-weight:700">✅ Alles erledigt — nichts offen</span>'
|
||||
else:
|
||||
pills = "".join(
|
||||
f'<span style="display:inline-block;background:#fff3e0;color:#c45000;border:1px solid #e8a857;'
|
||||
f'border-radius:999px;padding:3px 12px;font-size:12px;font-weight:700;margin:2px 4px 2px 0">'
|
||||
f'{label} <strong style="background:#c45000;color:#fff;border-radius:999px;'
|
||||
f'padding:0 7px;margin-left:4px">{count}</strong></span>'
|
||||
for label, count in open_items
|
||||
)
|
||||
body = f'<div style="font-size:13px;font-weight:600;color:#c45000;margin-bottom:8px">⚠️ {len(open_items)} Punkt{"e" if len(open_items)!=1 else ""} brauchen deine Aufmerksamkeit</div>{pills}'
|
||||
|
||||
link = '<div style="margin-top:10px"><a href="https://banyaro.app/app/admin" style="font-size:12px;color:#C4843A">→ Admin-Panel öffnen</a></div>'
|
||||
return f'<div style="padding:20px 28px;border-bottom:2px solid #e8a857;background:#fffbf5">' \
|
||||
f'<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:#C4843A;margin-bottom:10px">Heute zu erledigen</div>' \
|
||||
f'{body}{link}</div>'
|
||||
|
||||
|
||||
# JOB: Status-Report per Mail (täglich 06:00 Uhr)
|
||||
# ------------------------------------------------------------------
|
||||
async def _job_status_report():
|
||||
|
|
@ -677,6 +705,7 @@ async def _job_status_report():
|
|||
|
||||
# Community
|
||||
metrics["users"] = conn.execute("SELECT COUNT(*) FROM users").fetchone()[0]
|
||||
metrics["users_today"] = conn.execute("SELECT COUNT(*) FROM users WHERE DATE(created_at)=DATE('now')").fetchone()[0]
|
||||
metrics["dogs"] = conn.execute("SELECT COUNT(*) FROM dogs").fetchone()[0]
|
||||
metrics["diary_entries"] = conn.execute("SELECT COUNT(*) FROM diary").fetchone()[0]
|
||||
metrics["poison_active"] = conn.execute("SELECT COUNT(*) FROM poison WHERE geloest=0").fetchone()[0]
|
||||
|
|
@ -685,6 +714,28 @@ async def _job_status_report():
|
|||
except Exception:
|
||||
metrics["lost_active"] = 0
|
||||
|
||||
# Action Items
|
||||
try:
|
||||
metrics["jobs_pending"] = conn.execute("SELECT COUNT(*) FROM job_applications WHERE status IN ('pending','reviewing')").fetchone()[0]
|
||||
except Exception:
|
||||
metrics["jobs_pending"] = 0
|
||||
try:
|
||||
metrics["breeder_pending"] = conn.execute("SELECT COUNT(*) FROM users WHERE breeder_status='pending'").fetchone()[0]
|
||||
except Exception:
|
||||
metrics["breeder_pending"] = 0
|
||||
try:
|
||||
metrics["reports_open"] = conn.execute("SELECT COUNT(*) FROM forum_reports WHERE resolved=0").fetchone()[0]
|
||||
except Exception:
|
||||
metrics["reports_open"] = 0
|
||||
try:
|
||||
metrics["fotos_pending"] = conn.execute("SELECT COUNT(*) FROM wiki_foto_submissions WHERE status='pending'").fetchone()[0]
|
||||
except Exception:
|
||||
metrics["fotos_pending"] = 0
|
||||
try:
|
||||
metrics["poi_edits_pending"] = conn.execute("SELECT COUNT(*) FROM osm_poi_edits WHERE status='pending'").fetchone()[0]
|
||||
except Exception:
|
||||
metrics["poi_edits_pending"] = 0
|
||||
|
||||
# Wiki-Interesse
|
||||
try:
|
||||
metrics["interesse_hat"] = conn.execute("SELECT COUNT(*) FROM wiki_breed_interest WHERE typ='hat'").fetchone()[0]
|
||||
|
|
@ -736,6 +787,9 @@ async def _job_status_report():
|
|||
<div style="opacity:.88;font-size:13px">{now_str} Uhr</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Items -->
|
||||
{_action_items_html(metrics)}
|
||||
|
||||
<!-- Scheduler-Status -->
|
||||
<div style="padding:20px 28px;border-bottom:1px solid #f0e8dc">
|
||||
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:#C4843A;margin-bottom:10px">Scheduler-Jobs</div>
|
||||
|
|
@ -749,14 +803,14 @@ async def _job_status_report():
|
|||
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:#C4843A;margin-bottom:10px">Community</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px">
|
||||
{"".join(f'<div style="background:#fdf6ef;border-radius:8px;padding:10px 14px"><div style="font-size:20px;font-weight:800;color:#C4843A">{v}</div><div style="font-size:11px;color:#888">{k}</div></div>' for k,v in [
|
||||
("Nutzer",metrics["users"]),
|
||||
("Nutzer gesamt",metrics["users"]),
|
||||
("Neue Nutzer heute",metrics["users_today"]),
|
||||
("Hunde",metrics["dogs"]),
|
||||
("Tagebuch-Einträge",metrics["diary_entries"]),
|
||||
("Aktive Giftköder",metrics["poison_active"]),
|
||||
("Vermisste Hunde",metrics["lost_active"]),
|
||||
("'So einen hab ich'",metrics["interesse_hat"]),
|
||||
("'Interessiert mich'",metrics["interesse_will"]),
|
||||
("Züchter (pending)",metrics["zuchter_pending"]),
|
||||
])}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -770,19 +824,28 @@ async def _job_status_report():
|
|||
</body>
|
||||
</html>"""
|
||||
|
||||
action_open = [l for k,l in [
|
||||
("jobs_pending","Bewerbungen"),("breeder_pending","Züchter-Anträge"),
|
||||
("reports_open","Meldungen"),("fotos_pending","Fotos"),("poi_edits_pending","POI-Korrekturen"),
|
||||
] if metrics.get(k,0) > 0]
|
||||
plain = f"""Ban Yaro Status-Report — {now_str}
|
||||
|
||||
=== HEUTE ZU ERLEDIGEN ===
|
||||
{"✅ Alles erledigt" if not action_open else "⚠️ " + ", ".join(f"{l} ({metrics[k]})" for k,l in [
|
||||
("jobs_pending","Bewerbungen"),("breeder_pending","Züchter-Anträge"),
|
||||
("reports_open","Meldungen"),("fotos_pending","Fotos"),("poi_edits_pending","POI-Korrekturen"),
|
||||
] if metrics.get(k,0) > 0)}
|
||||
|
||||
=== Scheduler-Jobs ===
|
||||
{job_rows_txt}
|
||||
=== Community ===
|
||||
Nutzer: {metrics['users']}
|
||||
Nutzer gesamt: {metrics['users']} (+{metrics['users_today']} heute)
|
||||
Hunde: {metrics['dogs']}
|
||||
Tagebuch-Einträge: {metrics['diary_entries']}
|
||||
Aktive Giftköder: {metrics['poison_active']}
|
||||
Vermisste Hunde: {metrics['lost_active']}
|
||||
'So einen hab ich': {metrics['interesse_hat']}
|
||||
'Interessiert mich': {metrics['interesse_will']}
|
||||
Züchter (pending): {metrics['zuchter_pending']}
|
||||
"""
|
||||
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue