122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
"""
|
|
alt_dance_ratings.py — Community alternativ-dans ratings endpoint.
|
|
"""
|
|
import uuid as _uuid
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from pydantic import BaseModel
|
|
from app.core.database import get_db
|
|
from app.core.security import get_current_user
|
|
from app.models import User, Song, Dance, CommunityDanceAlt, DanceAltRating
|
|
|
|
router = APIRouter(prefix="/alt-ratings", tags=["alt-ratings"])
|
|
|
|
|
|
class SubmitAltRequest(BaseModel):
|
|
song_id: str # server song UUID
|
|
dance_name: str
|
|
rating: int # 1-5
|
|
|
|
|
|
@router.post("/submit")
|
|
def submit_alt_rating(
|
|
req: SubmitAltRequest,
|
|
db: Session = Depends(get_db),
|
|
me: User = Depends(get_current_user),
|
|
):
|
|
"""Indsend eller opdater rating for en alternativ-dans på en sang."""
|
|
if not 1 <= req.rating <= 5:
|
|
raise HTTPException(400, "Rating skal være 1-5")
|
|
|
|
song = db.query(Song).filter_by(id=req.song_id).first()
|
|
if not song:
|
|
raise HTTPException(404, "Sang ikke fundet")
|
|
|
|
dance = db.query(Dance).filter(
|
|
Dance.name.ilike(req.dance_name)
|
|
).first()
|
|
if not dance:
|
|
raise HTTPException(404, "Dans ikke fundet")
|
|
|
|
# Find eller opret community alt-dans
|
|
alt = db.query(CommunityDanceAlt).filter_by(
|
|
song_mbid=song.mbid or None,
|
|
song_title=song.title,
|
|
song_artist=song.artist,
|
|
alt_dance_id=dance.id,
|
|
).first()
|
|
|
|
if not alt:
|
|
alt = CommunityDanceAlt(
|
|
id=str(_uuid.uuid4()),
|
|
song_mbid=song.mbid or None,
|
|
song_title=song.title,
|
|
song_artist=song.artist,
|
|
alt_dance_id=dance.id,
|
|
submitted_by=me.id,
|
|
avg_rating=float(req.rating),
|
|
rating_count=1,
|
|
)
|
|
db.add(alt)
|
|
db.flush()
|
|
|
|
# Opdater eller indsæt brugerens rating
|
|
existing_rating = db.query(DanceAltRating).filter_by(
|
|
alternative_id=alt.id,
|
|
user_id=me.id,
|
|
).first()
|
|
|
|
if existing_rating:
|
|
old_score = existing_rating.score
|
|
existing_rating.score = req.rating
|
|
# Opdater gennemsnit
|
|
total = alt.avg_rating * alt.rating_count - old_score + req.rating
|
|
alt.avg_rating = total / alt.rating_count
|
|
else:
|
|
db.add(DanceAltRating(
|
|
id=str(_uuid.uuid4()),
|
|
alternative_id=alt.id,
|
|
user_id=me.id,
|
|
score=req.rating,
|
|
))
|
|
# Opdater gennemsnit
|
|
total = alt.avg_rating * alt.rating_count + req.rating
|
|
alt.rating_count += 1
|
|
alt.avg_rating = total / alt.rating_count
|
|
|
|
db.commit()
|
|
return {"status": "ok", "avg_rating": alt.avg_rating, "rating_count": alt.rating_count}
|
|
|
|
|
|
@router.get("/for-song/{song_id}")
|
|
def get_alt_ratings_for_song(
|
|
song_id: str,
|
|
db: Session = Depends(get_db),
|
|
me: User = Depends(get_current_user),
|
|
):
|
|
"""Hent community alternativ-danse med ratings for en sang."""
|
|
song = db.query(Song).filter_by(id=song_id).first()
|
|
if not song:
|
|
raise HTTPException(404, "Sang ikke fundet")
|
|
|
|
alts = db.query(CommunityDanceAlt).filter(
|
|
(CommunityDanceAlt.song_mbid == song.mbid) if song.mbid else
|
|
((CommunityDanceAlt.song_title == song.title) &
|
|
(CommunityDanceAlt.song_artist == song.artist))
|
|
).all()
|
|
|
|
result = []
|
|
for alt in alts:
|
|
my_rating = db.query(DanceAltRating).filter_by(
|
|
alternative_id=alt.id,
|
|
user_id=me.id,
|
|
).first()
|
|
result.append({
|
|
"dance_name": alt.alt_dance.name,
|
|
"avg_rating": round(alt.avg_rating, 1),
|
|
"rating_count": alt.rating_count,
|
|
"my_rating": my_rating.score if my_rating else None,
|
|
})
|
|
|
|
return result
|