Feature: Filme-Suche, HdM ins Forum + Gewinner-Badge im Profil, SW by-v594
- Filme-Seite: Suchfeld (filtert live nach Titel, Rasse, Genre, Beschreibung)
- Filme-Seite: Tab "Hund des Monats" entfernt
- Forum: kompakte HdM-Kachel über der Suche (Sieger + Stimmen), Klick öffnet Abstimmungs-Modal
- Hundeprofil: goldene Badges für jeden gewonnenen Monat (🏆 Mai 2026 …)
- DB: Tabelle hund_des_monats_wins (dauerhaft, dog_id + monat + stimmen)
- Scheduler: Job am 1. des Monats 00:05 — schreibt Vormonats-Sieger, Push an Besitzer
- Dogs-API: liefert hdm_wins[] pro Hund mit
This commit is contained in:
parent
d00284184b
commit
ea2a83b29e
9 changed files with 348 additions and 7 deletions
|
|
@ -124,6 +124,14 @@ def start():
|
|||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
# 1. des Monats 00:05 — Hund des Monats Sieger festlegen
|
||||
_scheduler.add_job(
|
||||
_job_hdm_winner,
|
||||
CronTrigger(day=1, hour=0, minute=5),
|
||||
id="hdm_winner",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
_scheduler.start()
|
||||
logger.info("Scheduler gestartet — Health-Reminder 08:00, Giftköder-Archiv 03:00, Wetter-Alert 07:30, Meilenstein-Check 00:05, Event-Import So 02:00, Rassen-Seed monatlich 1. des Monats, Status-Report täglich 06:00, Moderation-Overdue 12:00, Quartalsbericht 1. Feb/Mai/Aug/Nov 07:00. OSM-Cache: on-demand (kein Prewarm).")
|
||||
|
||||
|
|
@ -1110,3 +1118,57 @@ def _compute_milestone(today: date, bday: date, dog_name: str):
|
|||
return titel, text
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# JOB: Hund des Monats — Sieger des Vormonats festlegen
|
||||
# ------------------------------------------------------------------
|
||||
async def _job_hdm_winner():
|
||||
"""Läuft am 1. des Monats 00:05 und schreibt den Sieger des Vormonats."""
|
||||
today = datetime.now(tz=_TZ)
|
||||
# Vormonat berechnen
|
||||
first_this = today.replace(day=1)
|
||||
last_month = (first_this - timedelta(days=1)).replace(day=1)
|
||||
monat = last_month.strftime("%Y-%m")
|
||||
|
||||
with db() as conn:
|
||||
# Schon eingetragen?
|
||||
existing = conn.execute(
|
||||
"SELECT id FROM hund_des_monats_wins WHERE monat=?", (monat,)
|
||||
).fetchone()
|
||||
if existing:
|
||||
logger.info(f"HdM-Winner {monat}: bereits eingetragen, übersprungen.")
|
||||
_log_job("hdm_winner", "ok", f"bereits vorhanden für {monat}")
|
||||
return
|
||||
|
||||
winner = conn.execute("""
|
||||
SELECT v.dog_id, d.name, d.user_id, COUNT(v.id) AS stimmen
|
||||
FROM hund_des_monats_votes v
|
||||
JOIN dogs d ON d.id = v.dog_id
|
||||
WHERE v.monat = ?
|
||||
GROUP BY v.dog_id
|
||||
ORDER BY stimmen DESC
|
||||
LIMIT 1
|
||||
""", (monat,)).fetchone()
|
||||
|
||||
if not winner:
|
||||
logger.info(f"HdM-Winner {monat}: keine Stimmen, kein Sieger.")
|
||||
_log_job("hdm_winner", "ok", f"keine Stimmen für {monat}")
|
||||
return
|
||||
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO hund_des_monats_wins (dog_id, monat, stimmen) VALUES (?, ?, ?)",
|
||||
(winner["dog_id"], monat, winner["stimmen"]),
|
||||
)
|
||||
|
||||
month_label = last_month.strftime("%B %Y")
|
||||
send_push_to_user(winner["user_id"], {
|
||||
"type": "hdm_winner",
|
||||
"title": f"🏆 {winner['name']} ist Hund des Monats!",
|
||||
"body": f"{winner['name']} hat den {month_label} gewonnen — herzlichen Glückwunsch!",
|
||||
"data": {"page": "forum"},
|
||||
"tag": f"hdm-{monat}",
|
||||
})
|
||||
|
||||
logger.info(f"HdM-Winner {monat}: Hund {winner['dog_id']} ('{winner['name']}', {winner['stimmen']} Stimmen) eingetragen.")
|
||||
_log_job("hdm_winner", "ok", f"{monat}: {winner['name']} ({winner['stimmen']} Stimmen)")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue