banyaro/backend/routes/streak.py

114 lines
4 KiB
Python

"""BAN YARO — Trainings-Streak"""
import datetime
from fastapi import APIRouter, Depends, HTTPException
from database import db
from auth import get_current_user
router = APIRouter()
_today = lambda: datetime.date.today().isoformat()
_yesterday = lambda: (datetime.date.today() - datetime.timedelta(days=1)).isoformat()
# ------------------------------------------------------------------
# GET /streak/leaderboard — Top-10 Streaks (öffentliche Hunde)
# Muss VOR /{dog_id} stehen, sonst greift der int-Parameter zuerst.
# ------------------------------------------------------------------
@router.get("/streak/leaderboard")
async def get_leaderboard(user=Depends(get_current_user)):
with db() as conn:
rows = conn.execute("""
SELECT
u.name AS user_name,
d.name AS dog_name,
d.rasse,
d.foto_url,
ts.current_streak
FROM training_streaks ts
JOIN dogs d ON d.id = ts.dog_id
JOIN users u ON u.id = ts.user_id
WHERE ts.current_streak > 0
AND d.is_public = 1
ORDER BY ts.current_streak DESC
LIMIT 10
""").fetchall()
return [dict(r) for r in rows]
# ------------------------------------------------------------------
# GET /streak/{dog_id} — aktueller Streak eines Hundes
# ------------------------------------------------------------------
@router.get("/streak/{dog_id}")
async def get_streak(dog_id: int, user=Depends(get_current_user)):
uid = user["id"]
with db() as conn:
dog = conn.execute(
"SELECT id FROM dogs WHERE id=? AND user_id=?", (dog_id, uid)
).fetchone()
if not dog:
raise HTTPException(404, "Hund nicht gefunden.")
row = conn.execute(
"SELECT current_streak, longest_streak, last_training_date "
"FROM training_streaks WHERE user_id=? AND dog_id=?",
(uid, dog_id)
).fetchone()
if not row:
return {"current_streak": 0, "longest_streak": 0, "last_training_date": None}
return dict(row)
# ------------------------------------------------------------------
# POST /streak/{dog_id}/ping — Training heute registrieren
# ------------------------------------------------------------------
@router.post("/streak/{dog_id}/ping")
async def ping_streak(dog_id: int, user=Depends(get_current_user)):
uid = user["id"]
today = _today()
yest = _yesterday()
with db() as conn:
dog = conn.execute(
"SELECT id FROM dogs WHERE id=? AND user_id=?", (dog_id, uid)
).fetchone()
if not dog:
raise HTTPException(404, "Hund nicht gefunden.")
row = conn.execute(
"SELECT current_streak, longest_streak, last_training_date "
"FROM training_streaks WHERE user_id=? AND dog_id=?",
(uid, dog_id)
).fetchone()
if row:
cur = row["current_streak"]
longest = row["longest_streak"]
last = row["last_training_date"]
if last == today:
# Bereits heute gepingt — nichts tun
return {"current_streak": cur, "longest_streak": longest, "last_training_date": last}
elif last == yest:
cur += 1
else:
cur = 1
longest = max(longest, cur)
conn.execute(
"UPDATE training_streaks SET current_streak=?, longest_streak=?, last_training_date=? "
"WHERE user_id=? AND dog_id=?",
(cur, longest, today, uid, dog_id)
)
else:
cur = 1
longest = 1
conn.execute(
"INSERT INTO training_streaks (user_id, dog_id, current_streak, longest_streak, last_training_date) "
"VALUES (?,?,?,?,?)",
(uid, dog_id, cur, longest, today)
)
return {"current_streak": cur, "longest_streak": longest, "last_training_date": today}