mirror of
https://github.com/myronblair/kino-app
synced 2026-07-29 14:02:50 -05:00
Add confirm+stop to Library Cleanup scan; branded album art placeholder
- Library Cleanup scan is now a real background job (POST .../start, GET .../status, POST .../stop) instead of one long synchronous request, so a Stop button can actually abandon it instead of just waiting. Frontend confirms before starting (explains it can take a minute+) and polls status while running. - New shared AlbumArt component: shows real art when available, otherwise a branded "Streamhoard" placeholder instead of a bare icon in an empty box. Used in the Music grid, album detail header, and the player bar — swaps to real art automatically once enrichment/a manual edit sets it.
This commit is contained in:
+39
-3
@@ -1537,9 +1537,45 @@ async def scan_import(payload: dict, user: dict = Depends(require_admin)):
|
||||
|
||||
|
||||
# ============ 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)
|
||||
_cleanup_scan_status = {"running": False, "findings": None, "error": "", "scan_id": 0}
|
||||
|
||||
|
||||
async def _run_cleanup_scan(scan_id: int):
|
||||
try:
|
||||
findings = await library_cleanup.scan(db, VIDEOS_DIR, HLS_DIR)
|
||||
if _cleanup_scan_status["scan_id"] == scan_id:
|
||||
_cleanup_scan_status["findings"] = findings
|
||||
except Exception as e:
|
||||
if _cleanup_scan_status["scan_id"] == scan_id:
|
||||
_cleanup_scan_status["error"] = str(e)
|
||||
finally:
|
||||
if _cleanup_scan_status["scan_id"] == scan_id:
|
||||
_cleanup_scan_status["running"] = False
|
||||
|
||||
|
||||
@api.post("/library/cleanup/scan/start")
|
||||
async def library_cleanup_scan_start(user: dict = Depends(require_admin)):
|
||||
if _cleanup_scan_status["running"]:
|
||||
raise HTTPException(status_code=409, detail="Scan already running")
|
||||
_cleanup_scan_status["scan_id"] += 1
|
||||
_cleanup_scan_status.update(running=True, findings=None, error="")
|
||||
asyncio.create_task(_run_cleanup_scan(_cleanup_scan_status["scan_id"]))
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@api.get("/library/cleanup/scan/status")
|
||||
async def library_cleanup_scan_status(user: dict = Depends(require_admin)):
|
||||
return _cleanup_scan_status
|
||||
|
||||
|
||||
@api.post("/library/cleanup/scan/stop")
|
||||
async def library_cleanup_scan_stop(user: dict = Depends(require_admin)):
|
||||
# The already-dispatched file checks finish naturally in the background (there's no clean
|
||||
# way to interrupt a ThreadPoolExecutor mid-flight), but bumping scan_id means whenever they
|
||||
# do finish, _run_cleanup_scan sees a stale id and discards the result instead of surfacing it.
|
||||
_cleanup_scan_status["scan_id"] += 1
|
||||
_cleanup_scan_status["running"] = False
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@api.post("/library/cleanup/fix")
|
||||
|
||||
Reference in New Issue
Block a user