Feature: 3 Community-Features — Foto-Challenge, Stamm-Gassis, Rassen-Chip (SW by-v700)
- Foto-Challenge der Woche: DB-Tabellen, routes/challenges.py (current/submit/vote/winners), Scheduler-Job jeden Montag 08:00, walks.js Challenge-Tab mit Banner, Galerie, Voting-Herz - Gassi-Zeiten-Pool: DB-Tabelle gassi_zeiten, routes/gassi_zeiten.py (CRUD + Umkreis), walks.js Stamm-Gassis-Tab mit Karten, Wochentag-Selector, Mitmachen→Chat - Rassen-Treffen-Chip: GET /api/friends/same-breed, dog-profile.js zeigt Chip wenn andere User gleiche Rasse haben, Klick → Forum mit Rassen-Suche vorausgefüllt
This commit is contained in:
parent
d6206d378e
commit
aa4849d947
10 changed files with 1322 additions and 22 deletions
|
|
@ -156,6 +156,14 @@ def start():
|
|||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
# Jeden Montag 08:00 Uhr — Neue Foto-Challenge anlegen
|
||||
_scheduler.add_job(
|
||||
_job_new_foto_challenge,
|
||||
CronTrigger(day_of_week='mon', hour=8, minute=0),
|
||||
id="new_foto_challenge",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
# Täglich 07:00 Uhr — Goldene Gassi-Stunde
|
||||
_scheduler.add_job(
|
||||
_job_golden_gassi_hour,
|
||||
|
|
@ -181,7 +189,7 @@ def start():
|
|||
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, Streak-Reminder 19:00, Rückruf-Check 08:00, Goldene-Gassi-Stunde 07:00, Jahrestags-Erinnerungen 09:00, Monatlicher-Rückblick 1. des Monats 10:00. OSM-Cache: on-demand (kein Prewarm).")
|
||||
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, Streak-Reminder 19:00, Rückruf-Check 08:00, Goldene-Gassi-Stunde 07:00, Jahrestags-Erinnerungen 09:00, Monatlicher-Rückblick 1. des Monats 10:00, Foto-Challenge Mo 08:00. OSM-Cache: on-demand (kein Prewarm).")
|
||||
|
||||
|
||||
def stop():
|
||||
|
|
@ -1544,6 +1552,46 @@ async def _job_monthly_recap():
|
|||
_log_job("monthly_recap", "ok", f"{sent_total} Push für {month_label}")
|
||||
|
||||
|
||||
async def _job_new_foto_challenge():
|
||||
"""Jeden Montag 08:00 — neue Foto-Challenge für die aktuelle Woche anlegen."""
|
||||
from datetime import date, timedelta
|
||||
from routes.challenges import _CHALLENGE_THEMEN, _current_week_monday, _current_week_sunday
|
||||
|
||||
monday = _current_week_monday()
|
||||
sunday = _current_week_sunday()
|
||||
|
||||
week_num = date.today().isocalendar()[1]
|
||||
thema = _CHALLENGE_THEMEN[week_num % len(_CHALLENGE_THEMEN)]
|
||||
|
||||
with db() as conn:
|
||||
existing = conn.execute(
|
||||
"SELECT id FROM foto_challenge WHERE start_date = ?", (monday,)
|
||||
).fetchone()
|
||||
if existing:
|
||||
logger.info(f"Foto-Challenge: Woche {monday} bereits vorhanden (id={existing['id']}).")
|
||||
_log_job("new_foto_challenge", "ok", f"Bereits vorhanden für {monday}")
|
||||
return
|
||||
|
||||
cur = conn.execute(
|
||||
"INSERT INTO foto_challenge (thema, beschreibung, start_date, end_date, created_by) "
|
||||
"VALUES (?, ?, ?, ?, NULL)",
|
||||
(thema, f"Diese Woche: {thema}", monday, sunday)
|
||||
)
|
||||
challenge_id = cur.lastrowid
|
||||
|
||||
# Push an alle User
|
||||
send_push_to_all({
|
||||
"type": "foto_challenge",
|
||||
"title": "📸 Neue Foto-Challenge!",
|
||||
"body": f"Diese Woche: {thema} — mach mit!",
|
||||
"data": {"page": "walks", "tab": "challenge"},
|
||||
"tag": f"challenge-{monday}",
|
||||
})
|
||||
|
||||
logger.info(f"Foto-Challenge angelegt: '{thema}' für {monday}–{sunday} (id={challenge_id}).")
|
||||
_log_job("new_foto_challenge", "ok", f"'{thema}' für {monday}")
|
||||
|
||||
|
||||
async def _fetch_hourly_weather(lat: float, lon: float) -> list[dict]:
|
||||
"""Holt stündliche Wetterdaten für heute von Open-Meteo."""
|
||||
import httpx
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue