109 lines
3.6 KiB
Python
109 lines
3.6 KiB
Python
"""
|
|
dances.py — Endpoints til dans-navne, niveauer og community alternativer.
|
|
"""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy import func
|
|
from pydantic import BaseModel
|
|
from app.core.database import get_db
|
|
from app.core.security import get_current_user
|
|
from app.models import User
|
|
|
|
router = APIRouter(prefix="/dances", tags=["dances"])
|
|
|
|
|
|
# ── Schemas ───────────────────────────────────────────────────────────────────
|
|
|
|
class DanceLevelOut(BaseModel):
|
|
id: int
|
|
sort_order: int
|
|
name: str
|
|
description: str
|
|
model_config = {"from_attributes": True}
|
|
|
|
class DanceNameOut(BaseModel):
|
|
name: str
|
|
use_count: int
|
|
|
|
class DanceNameSubmit(BaseModel):
|
|
name: str
|
|
|
|
class CommunityDanceOut(BaseModel):
|
|
id: str
|
|
song_mbid: str | None
|
|
dance_name: str
|
|
level_id: int | None
|
|
level_name: str | None
|
|
submitted_by: str
|
|
use_count: int
|
|
|
|
class CommunityAltOut(BaseModel):
|
|
id: str
|
|
song_mbid: str | None
|
|
dance_name: str
|
|
alt_dance_name: str
|
|
level_id: int | None
|
|
level_name: str | None
|
|
note: str
|
|
bayesian_score: float
|
|
rating_count: int
|
|
my_rating: int | None
|
|
|
|
|
|
# ── Dans-niveauer ─────────────────────────────────────────────────────────────
|
|
|
|
@router.get("/levels", response_model=list[DanceLevelOut])
|
|
def get_levels(db: Session = Depends(get_db)):
|
|
"""Hent alle dans-niveauer — bruges til synkronisering i appen."""
|
|
from sqlalchemy import text
|
|
rows = db.execute(text(
|
|
"SELECT id, sort_order, name, description FROM dance_levels ORDER BY sort_order"
|
|
)).fetchall()
|
|
return [{"id": r[0], "sort_order": r[1], "name": r[2], "description": r[3]} for r in rows]
|
|
|
|
|
|
# ── Dans-navne ────────────────────────────────────────────────────────────────
|
|
|
|
@router.get("/names", response_model=list[DanceNameOut])
|
|
def get_dance_names(prefix: str = "", limit: int = 50, db: Session = Depends(get_db)):
|
|
"""Hent kendte dans-navne — bruges til autoudfyld og synkronisering."""
|
|
from sqlalchemy import text
|
|
pattern = f"{prefix}%"
|
|
rows = db.execute(text(
|
|
"SELECT name, use_count FROM dance_names "
|
|
"WHERE name LIKE :pattern "
|
|
"ORDER BY use_count DESC, name "
|
|
"LIMIT :limit"
|
|
), {"pattern": pattern, "limit": limit}).fetchall()
|
|
return [{"name": r[0], "use_count": r[1]} for r in rows]
|
|
|
|
|
|
@router.post("/names", status_code=201)
|
|
def submit_dance_name(
|
|
data: DanceNameSubmit,
|
|
db: Session = Depends(get_db),
|
|
me: User = Depends(get_current_user),
|
|
):
|
|
"""Indsend et dans-navn — opretter eller tæller op."""
|
|
from sqlalchemy import text
|
|
name = data.name.strip()
|
|
if not name:
|
|
raise HTTPException(400, "Navn må ikke være tomt")
|
|
existing = db.execute(
|
|
text("SELECT id FROM dance_names WHERE name = :name COLLATE NOCASE"),
|
|
{"name": name}
|
|
).fetchone()
|
|
if existing:
|
|
db.execute(
|
|
text("UPDATE dance_names SET use_count = use_count + 1 WHERE id = :id"),
|
|
{"id": existing[0]}
|
|
)
|
|
else:
|
|
db.execute(
|
|
text("INSERT INTO dance_names (name, use_count) VALUES (:name, 1)"),
|
|
{"name": name}
|
|
)
|
|
db.commit()
|
|
return {"detail": "ok"}
|