5c7b3feb1f
Share: "Copy Link" button generates a URL with ?s={history_id} that
loads the saved search results without auth. Recipients see the same
movie picks.
Watched: When viewing history results or shared searches, cards for
movies the logged-in user has since watched are dimmed with a green
"Watched" badge. Uses a new POST /api/library/watch-check endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
import asyncio
|
|
|
|
from fastapi import APIRouter, Request
|
|
|
|
from app.database import get_db
|
|
from app.routers.auth import get_current_user
|
|
from app.services.library_sync import sync_movie_metadata, sync_watch_state
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/stats")
|
|
async def library_stats(request: Request):
|
|
await get_current_user(request)
|
|
|
|
db = await get_db()
|
|
try:
|
|
cursor = await db.execute("SELECT COUNT(*) as count FROM movies")
|
|
row = await cursor.fetchone()
|
|
total_movies = row["count"]
|
|
|
|
cursor = await db.execute(
|
|
"SELECT value FROM sync_status WHERE key = 'last_metadata_sync'"
|
|
)
|
|
row = await cursor.fetchone()
|
|
last_sync = row["value"] if row else None
|
|
|
|
return {
|
|
"total_movies": total_movies,
|
|
"last_sync": last_sync,
|
|
}
|
|
finally:
|
|
await db.close()
|
|
|
|
|
|
@router.post("/watch-check")
|
|
async def watch_check(request: Request):
|
|
"""Given a list of jellyfin_ids, return which ones the current user has watched."""
|
|
user = await get_current_user(request)
|
|
body = await request.json()
|
|
ids = body.get("jellyfin_ids", [])
|
|
if not ids:
|
|
return {"watched": []}
|
|
|
|
db = await get_db()
|
|
try:
|
|
placeholders = ",".join("?" for _ in ids)
|
|
cursor = await db.execute(
|
|
f"SELECT jellyfin_id FROM watch_state WHERE user_id = ? AND is_played = 1 AND jellyfin_id IN ({placeholders})",
|
|
[user["id"]] + ids,
|
|
)
|
|
rows = await cursor.fetchall()
|
|
return {"watched": [row["jellyfin_id"] for row in rows]}
|
|
finally:
|
|
await db.close()
|
|
|
|
|
|
@router.post("/sync")
|
|
async def trigger_sync(request: Request):
|
|
await get_current_user(request)
|
|
asyncio.create_task(_do_sync())
|
|
return {"status": "sync started"}
|
|
|
|
|
|
async def _do_sync():
|
|
await sync_movie_metadata()
|
|
await sync_watch_state()
|