Handles big libraries (your ~8500 movies) like music does instead of rendering
everything at once.
- DB: sort_title populated article-aware on upsert ('The Matrix' files under M);
query_library(kind, search, letter, sort, status, page, limit) does all
filtering/sorting/paging in SQL and returns music's pagination shape
{page,total_pages,total_count,has_prev,has_next} + badge fields (resolution,
owned/episode counts).
- GET /api/video/library now takes those params (per kind) instead of dumping
everything.
- Library page: 75/page with ← Previous / Page X of Y / Next → (music's exact
controls/classes), Sort (Title/Year/Recently Added) + Owned/Wanted filter,
server-side search + A–Z. Cards gain a resolution chip (4K/1080p/…) and the
owned/wanted meta. Still not clickable.
124 tests green.
32 lines
1.1 KiB
Python
32 lines
1.1 KiB
Python
"""Video library listing endpoint.
|
|
|
|
GET /api/video/library -> {"movies": [...], "shows": [...]}
|
|
Reads what the last scan mirrored from the media server into video.db.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from flask import jsonify, request
|
|
|
|
from utils.logging_config import get_logger
|
|
|
|
logger = get_logger("video_api.library")
|
|
|
|
|
|
def register_routes(bp):
|
|
@bp.route("/library", methods=["GET"])
|
|
def video_library():
|
|
from . import get_video_db
|
|
try:
|
|
return jsonify(get_video_db().query_library(
|
|
request.args.get("kind", "movies"),
|
|
search=request.args.get("search") or None,
|
|
letter=request.args.get("letter") or None,
|
|
sort=request.args.get("sort", "title"),
|
|
status=request.args.get("status", "all"),
|
|
page=request.args.get("page", 1),
|
|
limit=request.args.get("limit", 75),
|
|
))
|
|
except Exception:
|
|
logger.exception("Failed to query video library")
|
|
return jsonify({"error": "Failed to load video library"}), 500
|