"""BAN YARO — Hunde-Wiki Routes""" from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from database import db from auth import get_current_user router = APIRouter() # ------------------------------------------------------------------ # Schemas # ------------------------------------------------------------------ class BerichtCreate(BaseModel): rasse: str titel: str text: str # ------------------------------------------------------------------ # Hilfsfunktion Quiz-Scoring # ------------------------------------------------------------------ def _quiz_score(rasse: dict, params: dict) -> int: score = 0 if params.get("groesse") and rasse["groesse"] == params["groesse"]: score += 2 # Aktivität: exakt = 2, eine Stufe daneben = 1 aktiv_map = {"niedrig": 0, "mittel": 1, "hoch": 2, "sehr_hoch": 3} if params.get("aktivitaet"): a_user = aktiv_map.get(params["aktivitaet"], -1) a_rasse = aktiv_map.get(rasse["aktivitaet"], -1) diff = abs(a_user - a_rasse) if diff == 0: score += 2 elif diff == 1: score += 1 # Erfahrung: anfaenger bekommt Bonus für einfache Rassen erf_map = {"anfaenger": 0, "fortgeschritten": 1, "experte": 2} if params.get("erfahrung"): e_user = erf_map.get(params["erfahrung"], -1) e_rasse = erf_map.get(rasse["erfahrung"], -1) if e_user >= e_rasse: score += 2 elif e_user == e_rasse - 1: score += 1 # Kinder if params.get("kinder") in ("true", "True", "1"): if rasse["kinder_geeignet"]: score += 1 # Wohnung if params.get("wohnung") in ("true", "True", "1"): if rasse["wohnung_geeignet"]: score += 2 elif params.get("wohnung") in ("false", "False", "0"): if not rasse["wohnung_geeignet"]: score += 1 return score # ------------------------------------------------------------------ # GET /api/wiki/stats — Seed-Status # ------------------------------------------------------------------ @router.get("/stats") async def get_stats(): with db() as conn: row = conn.execute("SELECT COUNT(*) as total FROM wiki_rassen").fetchone() total = row["total"] if row else 0 return {"total_breeds": total, "seeded": total > 0} # ------------------------------------------------------------------ # GET /api/wiki/rassen — alle Rassen (Übersicht, paginiert) # ------------------------------------------------------------------ @router.get("/rassen") async def get_rassen( search: str = Query(""), gruppe: str = Query(""), limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0), ): conditions = [] args = [] if search: conditions.append("(LOWER(name) LIKE ? OR LOWER(gruppe) LIKE ? OR LOWER(temperament) LIKE ?)") like = f"%{search.lower()}%" args += [like, like, like] if gruppe: conditions.append("gruppe = ?") args.append(gruppe) where = ("WHERE " + " AND ".join(conditions)) if conditions else "" args_paged = args + [limit, offset] with db() as conn: rows = conn.execute(f""" SELECT id, name, gruppe, groesse, aktivitaet, erfahrung, foto_url, slug, kinder_geeignet, wohnung_geeignet FROM wiki_rassen {where} ORDER BY name ASC LIMIT ? OFFSET ? """, args_paged).fetchall() count_row = conn.execute(f""" SELECT COUNT(*) as total FROM wiki_rassen {where} """, args).fetchone() # Alle Gruppen für Filter-Dropdown gruppen_rows = conn.execute( "SELECT DISTINCT gruppe FROM wiki_rassen WHERE gruppe IS NOT NULL ORDER BY gruppe" ).fetchall() return { "breeds": [dict(r) for r in rows], "total": count_row["total"] if count_row else 0, "gruppen": [r["gruppe"] for r in gruppen_rows], } # ------------------------------------------------------------------ # GET /api/wiki/rassen/{slug} — Rasse-Detail + Community-Berichte # ------------------------------------------------------------------ @router.get("/rassen/{rasse_slug}") async def get_rasse(rasse_slug: str): with db() as conn: rasse = conn.execute( "SELECT * FROM wiki_rassen WHERE slug = ?", (rasse_slug,) ).fetchone() if not rasse: raise HTTPException(404, "Rasse nicht gefunden.") rows = conn.execute( """SELECT wb.id, wb.titel, wb.text, wb.created_at, u.name as autor FROM wiki_berichte wb JOIN users u ON u.id = wb.user_id WHERE wb.rasse = ? ORDER BY wb.created_at DESC LIMIT 50""", (rasse_slug,), ).fetchall() result = dict(rasse) result["berichte"] = [dict(r) for r in rows] return result # ------------------------------------------------------------------ # POST /api/wiki/berichte — Community-Bericht hinzufügen # ------------------------------------------------------------------ @router.post("/berichte") async def create_bericht(data: BerichtCreate, user=Depends(get_current_user)): # Prüfen ob die Rasse in der DB existiert with db() as conn: rasse_row = conn.execute( "SELECT slug FROM wiki_rassen WHERE slug = ?", (data.rasse,) ).fetchone() if not rasse_row: raise HTTPException(400, "Ungültige Rasse.") if not data.titel.strip(): raise HTTPException(400, "Titel darf nicht leer sein.") if not data.text.strip(): raise HTTPException(400, "Text darf nicht leer sein.") with db() as conn: cur = conn.execute( """INSERT INTO wiki_berichte (user_id, rasse, titel, text) VALUES (?, ?, ?, ?)""", (user["id"], data.rasse, data.titel.strip(), data.text.strip()), ) row = conn.execute( "SELECT wb.id, wb.titel, wb.text, wb.created_at, u.name as autor " "FROM wiki_berichte wb JOIN users u ON u.id = wb.user_id " "WHERE wb.id = ?", (cur.lastrowid,), ).fetchone() return dict(row) # ------------------------------------------------------------------ # DELETE /api/wiki/berichte/{id} — Bericht löschen (nur eigene) # ------------------------------------------------------------------ @router.delete("/berichte/{bericht_id}") async def delete_bericht(bericht_id: int, user=Depends(get_current_user)): with db() as conn: row = conn.execute( "SELECT id, user_id FROM wiki_berichte WHERE id = ?", (bericht_id,), ).fetchone() if not row: raise HTTPException(404, "Bericht nicht gefunden.") if row["user_id"] != user["id"]: raise HTTPException(403, "Nicht erlaubt.") conn.execute("DELETE FROM wiki_berichte WHERE id = ?", (bericht_id,)) return {"ok": True} # ------------------------------------------------------------------ # GET /api/wiki/quiz/result — Quiz-Ergebnis berechnen # ------------------------------------------------------------------ @router.get("/quiz/result") async def quiz_result( groesse: str = Query(""), aktivitaet: str = Query(""), erfahrung: str = Query(""), kinder: str = Query(""), wohnung: str = Query(""), ): params = { "groesse": groesse, "aktivitaet": aktivitaet, "erfahrung": erfahrung, "kinder": kinder, "wohnung": wohnung, } with db() as conn: rows = conn.execute( """SELECT id, name, gruppe, groesse, aktivitaet, erfahrung, foto_url, slug, kinder_geeignet, wohnung_geeignet, temperament, bred_for FROM wiki_rassen ORDER BY name ASC""" ).fetchall() rassen = [dict(r) for r in rows] if not rassen: return {"results": []} scored = sorted( rassen, key=lambda r: _quiz_score(r, params), reverse=True, ) top3 = [ { "slug": r["slug"], "name": r["name"], "gruppe": r["gruppe"], "groesse": r["groesse"], "aktivitaet": r["aktivitaet"], "erfahrung": r["erfahrung"], "foto_url": r["foto_url"], "kinder_geeignet": r["kinder_geeignet"], "wohnung_geeignet":r["wohnung_geeignet"], "temperament": r["temperament"], "score": _quiz_score(r, params), } for r in scored[:3] ] return {"results": top3}