109 lines
3.5 KiB
Python
109 lines
3.5 KiB
Python
"""
|
|
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
|