mirror of
https://github.com/myronblair/kino-app
synced 2026-07-29 14:02:50 -05:00
Add Library Cleanup admin page — missing files, orphaned records, stuck jobs, duplicates
New read-only scan (GET /api/library/cleanup/scan) across movies, episodes, tracks, subtitles, HLS output, transcode queue, and watchlist/progress rows: - Missing files: DB record exists but the file is gone from disk - Orphaned episodes: show_id no longer exists - Orphaned HLS output: transcoded folders left behind by deleted content - Stuck transcode jobs: "running" 2+ hours with no completion (backend-restart artifact) - Duplicate imports: same file imported into the library more than once - Orphaned subtitles / dangling watchlist+progress rows Nothing is deleted until an admin clicks Fix (per-item or Fix All per category) via POST /api/library/cleanup/fix.
This commit is contained in:
@@ -36,6 +36,7 @@ import radarr as radarr_client
|
||||
import sonarr as sonarr_client
|
||||
import services as services_client
|
||||
import library_scan
|
||||
import library_cleanup
|
||||
import musicbrainz as musicbrainz_client
|
||||
import trakt as trakt_client
|
||||
import opensubtitles as opensubs_client
|
||||
@@ -1510,6 +1511,29 @@ async def scan_import(payload: dict, user: dict = Depends(require_admin)):
|
||||
return {"ok": True, "imported": created}
|
||||
|
||||
|
||||
# ============ LIBRARY CLEANUP (admin) ============
|
||||
@api.get("/library/cleanup/scan")
|
||||
async def library_cleanup_scan(user: dict = Depends(require_admin)):
|
||||
return await library_cleanup.scan(db, VIDEOS_DIR, HLS_DIR)
|
||||
|
||||
|
||||
@api.post("/library/cleanup/fix")
|
||||
async def library_cleanup_fix(payload: dict, user: dict = Depends(require_admin)):
|
||||
"""Body: {category: str, items: [<finding dicts as returned by GET /library/cleanup/scan>]}"""
|
||||
category = payload.get("category")
|
||||
items = payload.get("items") or []
|
||||
if not items:
|
||||
raise HTTPException(status_code=400, detail="No items provided")
|
||||
fixed = 0
|
||||
for item in items:
|
||||
try:
|
||||
await library_cleanup.fix_one(db, VIDEOS_DIR, HLS_DIR, category, item)
|
||||
fixed += 1
|
||||
except Exception as e:
|
||||
logger.warning(f"Library cleanup fix failed for {category}/{item.get('id')}: {e}")
|
||||
return {"ok": True, "fixed": fixed}
|
||||
|
||||
|
||||
# ============ MUSIC ============
|
||||
@api.get("/tracks", response_model=List[Track])
|
||||
async def list_tracks(user: dict = Depends(get_current_user)):
|
||||
|
||||
Reference in New Issue
Block a user