"""Plex integration API. Read endpoints (browse/search/stream/image/state) are available to ANY authenticated user — the whole point of the module is to be an access layer to the Plex library WITHOUT requiring a plex.tv account, and playback is a local file (no quota/credit cost), so demo + pure-Siftlode users are allowed. Admin endpoints configure + test the connection and trigger a sync. P0 ships only the admin connectivity endpoints; browse/search/player land in P1/P2. """ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.db import get_db from app.models import User from app.plex.client import PlexClient, PlexError, PlexNotConfigured from app.routes.admin import admin_user router = APIRouter(prefix="/api/plex", tags=["plex"]) @router.post("/test") def test_connection(_: User = Depends(admin_user), db: Session = Depends(get_db)) -> dict: """Admin: verify the configured Plex server URL + token, returning the server name and the available library sections (movie/show) for the config library-picker.""" try: with PlexClient(db) as plex: info = plex.server_info() sections = plex.sections() except PlexNotConfigured as e: raise HTTPException(status_code=400, detail=str(e)) except PlexError as e: raise HTTPException(status_code=422, detail=f"Plex connection failed: {e}") return { "ok": True, "server_name": info.get("friendlyName") or info.get("title1") or "Plex", "version": info.get("version"), "sections": [ { "key": str(s.get("key")), "title": s.get("title"), "type": s.get("type"), "count": s.get("count"), } for s in sections if s.get("type") in ("movie", "show") ], }