diff --git a/linedance-api/app/main.py b/linedance-api/app/main.py index c85f2f19..76677cf1 100644 --- a/linedance-api/app/main.py +++ b/linedance-api/app/main.py @@ -8,7 +8,7 @@ from app.models import ( PlaylistShare, CommunityDance, CommunityDanceAlt, DanceAltRating, SongDance, SongAltDance, ) -from app.routers import auth, projects, songs, alternatives, dances, sync, sharing +from app.routers import auth, projects, songs, alternatives, dances, sync, sharing, live from app.websocket.manager import router as ws_router # Opret tabeller hvis de ikke findes @@ -35,6 +35,7 @@ app.include_router(alternatives.router) app.include_router(dances.router) app.include_router(sync.router) app.include_router(sharing.router) +app.include_router(live.router) @app.on_event("startup") diff --git a/linedance-api/app/routers/live.py b/linedance-api/app/routers/live.py new file mode 100644 index 00000000..bccd6a59 --- /dev/null +++ b/linedance-api/app/routers/live.py @@ -0,0 +1,108 @@ +""" +live.py — Live playliste-status til storskærm/mobil. +Appen pusher status hertil, storskærmen poller hvert 5 sek. +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from pydantic import BaseModel +from typing import Optional +import json +from datetime import datetime, timezone + +from app.core.database import get_db +from app.core.security import get_current_user +from app.models import User, Project + +router = APIRouter(prefix="/live", tags=["live"]) + +# In-memory cache: server_id → {songs, updated_at} +_live_cache: dict = {} + + +class SongStatus(BaseModel): + title: str + artist: str = "" + status: str = "pending" + position: int + dance: str = "" + duration: int = 0 + + +class LiveStatus(BaseModel): + songs: list[SongStatus] + + +# ── Push fra app ────────────────────────────────────────────────────────────── + +@router.post("/{project_id}/status") +def push_status( + project_id: str, + data: LiveStatus, + db: Session = Depends(get_db), + me: User = Depends(get_current_user), +): + """App pusher aktuel playliste-status.""" + p = db.query(Project).filter_by(id=project_id, owner_id=me.id).first() + if not p: + raise HTTPException(404, "Playliste ikke fundet") + + _live_cache[project_id] = { + "name": p.name, + "songs": [s.model_dump() for s in data.songs], + "updated_at": datetime.now(timezone.utc).isoformat(), + } + return {"status": "ok"} + + +# ── Pull til storskærm ──────────────────────────────────────────────────────── + +@router.get("/{project_id}") +def get_live_status(project_id: str, db: Session = Depends(get_db)): + """Storskærm poller dette endpoint — ingen login krævet.""" + # Tjek at playlisten eksisterer og er tilgængelig + p = db.query(Project).filter_by(id=project_id).first() + if not p: + raise HTTPException(404, "Playliste ikke fundet") + + cached = _live_cache.get(project_id) + if cached: + return cached + + # Ingen live data endnu — returner statisk data fra DB + from app.models import ProjectSong, Song + songs = [] + for ps in sorted(p.project_songs, key=lambda x: x.position): + song = db.query(Song).filter_by(id=ps.song_id).first() + if not song: + continue + songs.append({ + "title": song.title, + "artist": song.artist, + "status": ps.status or "pending", + "position": ps.position, + "dance": ps.dance_override or "", + "duration": song.duration_sec or 0, + }) + + return { + "name": p.name, + "songs": songs, + "updated_at": None, + } + + +# ── Liste over aktive live-playlister ───────────────────────────────────────── + +@router.get("/") +def list_live(db: Session = Depends(get_db)): + """Hvilke playlister har aktiv live-data?""" + result = [] + for pid, data in _live_cache.items(): + playing = next((s for s in data["songs"] if s["status"] == "playing"), None) + result.append({ + "id": pid, + "name": data["name"], + "updated_at": data["updated_at"], + "now_playing": playing["title"] if playing else None, + }) + return result diff --git a/linedance-api/web/public/live.html b/linedance-api/web/public/live.html new file mode 100644 index 00000000..dcf52889 --- /dev/null +++ b/linedance-api/web/public/live.html @@ -0,0 +1,403 @@ + + +
+ + +Ingen aktiv playliste fundet. Vælg en nedenfor eller brug URL-parametret ?id=PLAYLIST_ID