from fastapi import APIRouter, HTTPException, Request from database import ScanHistory, get_session from scheduler import ( get_active_scan_id, is_scan_running, trigger_full_scan, trigger_incremental_scan, ) router = APIRouter(prefix="/api/scan", tags=["scan"]) @router.post("/full") def start_full_scan(request: Request): settings = request.app.state.settings if is_scan_running(): raise HTTPException(status_code=409, detail="A scan is already running") scan_id = trigger_full_scan(settings) if scan_id is None: raise HTTPException(status_code=409, detail="A scan is already running") return {"scan_id": scan_id, "type": "full", "status": "running"} @router.post("/incremental") def start_incremental_scan(request: Request): settings = request.app.state.settings if is_scan_running(): raise HTTPException(status_code=409, detail="A scan is already running") scan_id = trigger_incremental_scan(settings) if scan_id is None: raise HTTPException(status_code=409, detail="A scan is already running") return {"scan_id": scan_id, "type": "incremental", "status": "running"} @router.get("/status/{scan_id}") def get_scan_status(scan_id: int): session = get_session() try: record = session.query(ScanHistory).get(scan_id) if record is None: raise HTTPException(status_code=404, detail="Scan not found") return { "scan_id": record.id, "type": record.scan_type, "status": record.status, "started_at": record.started_at.isoformat() if record.started_at else None, "finished_at": record.finished_at.isoformat() if record.finished_at else None, "files_found": record.files_found, "files_added": record.files_added, "files_removed": record.files_removed, "files_unmatched": record.files_unmatched, "error_message": record.error_message, } finally: session.close() @router.post("/fetch-alt-titles") def fetch_alt_titles_now(): """Trigger a Wikidata alt-title fetch in the background (no file scan).""" def _run(): session = get_session() try: _fetch_alt_titles(session) finally: session.close() threading.Thread(target=_run, daemon=True, name="alt-titles-fetch").start() return {"status": "started"} @router.get("/history") def get_scan_history(): session = get_session() try: records = ( session.query(ScanHistory) .order_by(ScanHistory.started_at.desc()) .limit(20) .all() ) return [ { "scan_id": r.id, "type": r.scan_type, "status": r.status, "started_at": r.started_at.isoformat() if r.started_at else None, "finished_at": r.finished_at.isoformat() if r.finished_at else None, "files_found": r.files_found, "files_added": r.files_added, "files_removed": r.files_removed, "files_unmatched": r.files_unmatched, "error_message": r.error_message, } for r in records ] finally: session.close()