48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
|
|
"""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")
|
||
|
|
],
|
||
|
|
}
|