Metadaten-Fallback OMDb + Pre-Scan repariert + Eject-Endpoint

- clients/omdb.py: OMDb als zweite Quelle (Fallback-Kette: TMDB exakt ->
  OMDb -> bester TMDB-Vorschlag mit niedriger Confidence -> unknown)
- Pre-Scan-Reparatur: Titel kam nie an — makemkvcon existiert nur im
  Worker, isosize war nirgends installiert (fiel still auf "DVD" zurueck).
  Jetzt: ISO-9660-Volume-Label direkt vom Medium + Label-Normalisierung
  (PULP_FICTION -> Pulp Fiction), Disc-Typ ueber zentrale detection.py
- POST /devices/{name}/eject (CDROMEJECT-ioctl) mit Job-Schutz (409 wenn
  auf dem Laufwerk gerade gerippt wird)
- OMDB_API_KEY in compose/.env.example; .env.example komplett ehrlich
  dokumentiert (JWT-Pflicht, MakeMKV-Beta-Key-Rhythmus)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-23 15:30:09 +02:00
parent 96c6e1fe42
commit 5528e0f652
9 changed files with 270 additions and 43 deletions
+18
View File
@@ -209,6 +209,24 @@ async def create_job(request: JobCreateRequest):
return {"id": job_id, "status": "pending", "device": device_path}
@app.post("/devices/{name}/eject")
async def eject_device(name: str):
"""Wirft die Disc aus. Verweigert, wenn auf dem Gerät gerade ein Job läuft."""
device_path = f"/dev/{name}"
if device_path not in device_discovery.list_optical_devices():
raise HTTPException(status_code=404, detail=f"Laufwerk {device_path} nicht gefunden")
if await asyncio.to_thread(db.has_active_job, device_path):
raise HTTPException(
status_code=409, detail="Auf diesem Laufwerk läuft gerade ein Job"
)
try:
await asyncio.to_thread(device_discovery.eject, device_path)
except OSError as e:
raise HTTPException(status_code=500, detail=f"Auswurf fehlgeschlagen: {e}")
await asyncio.to_thread(db.add_log, "info", "api", f"Disc ausgeworfen: {device_path}")
return {"status": "ejected", "device": device_path}
@app.get("/logs")
async def get_logs(limit: int = 200):
"""Echte Ereignisse aus der Datenbank (Watcher, API, Worker)."""