Playliste - online
This commit is contained in:
@@ -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")
|
||||
|
||||
108
linedance-api/app/routers/live.py
Normal file
108
linedance-api/app/routers/live.py
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user