Commander-Befunde (23.07. spaet):
- MANUELLE KORREKTUR (KONZEPT Schritt 5 endlich komplett): Metadaten-Seite
hat jetzt Titelsuche ueber ALLE Quellen (GET /metadata/search) mit
Poster-Kacheln; ein Klick uebernimmt den Treffer (POST /metadata/override)
fuer Karte, Jobs UND merkt ihn sich 30 Tage per Disc-Fingerabdruck —
dieselbe Disc wird beim naechsten Einlegen sofort richtig erkannt
- PC/NAS per Klick: SMB-Freigaben eines Rechners auflisten
(GET /storage-mounts/shares via smbclient) statt //host/share raten
- Berechtigungs-PRUEFUNG beim Einhaengen: Schreibtest, Warnung bei
nur-lesbaren Zielen (API + UI + Log)
- "Standard-Unterordner" verstaendlich gemacht: heisst jetzt "Schnellwahl
beim Rippen" mit Erklaertext; kryptisches Basis-Feld raus
- Preview zeigt Poster; Fingerprint fuer Cache/Override vereinheitlicht
(billiges Label+Groesse statt Mount-Titel)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Jikan (Gratis-Dienst) wirft sporadisch 504 — ein Retry mit 2s Pause;
aktuell ist der Dienst ganz down, die Kette faellt sauber auf OMDb.
Prescan-Cache: 0.6-0.9 verfaellt nach 1 Tag, ab 0.9 nach 7 Tagen —
sonst wuerde ein frueher OMDb-Treffer bessere Quellen fuer immer blocken.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Commander-Befunde (Screenshots 23.07. abends):
- Jikan (MyAnimeList, kostenlos OHNE Key) als Anime-Quelle vor OMDb —
waehlt per Titel-Aehnlichkeit (SequenceMatcher, Schwelle 0.55) statt
blind Treffer 1; damit trifft "Evangelion 2.22" den exakten Film
- Job-Titel: POST /jobs uebernimmt den erkannten Disc-Titel aus dem
DISC_CACHE — Schluss mit "Unbekannt" in der Queue
- Kooperativer Job-Abbruch: POST /jobs/{id}/cancel setzt canceling,
der Worker prueft das Flag bei jedem Fortschritts-Update und killt
den Encoder-Prozess sauber (RipAbbruch); UI-Knopf "Abbrechen" fuer
laufende, Status-Badge "Wird abgebrochen"
- Dark-Mode: Job-Zeilen-Hover war hart hell (hover:bg-slate-50)
- Speicherziele: lokaler Ordner-Browser mit "Ordner anlegen"
(GET /browse + POST /browse/mkdir, nur unter /app/media)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Der Datenmuell-Eintrag ("Episode 110 - ...") war der EINZIGE s=-Treffer
fuer den vollen Titel und brach die Kandidaten-Kette bei 0.8 ab, bevor
"Evangelion" allein probiert wurde. N/A-Werte werden jetzt normalisiert.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Die unscharfe Suche nahm blind Treffer 1 — fuer "Evangelion" war das
"Episode 110 - ..." (ein Review-Podcast ueber den Film, ohne Poster).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- titel_kandidaten strippt hintere Worte iterativ bis auf eins
("Evangelion 2.22" wird auch als "Evangelion" gesucht — OMDb braucht das)
- Nur Treffer ab Confidence 0.6 landen im Redis-Cache: ein gecachtes
"unknown" wurde sonst auch nach Key-Eintrag ewig wieder serviert
(Redis ist persistent; Alt-Eintraege auf der VM geloescht)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Commander-Befunde 23.07. abends:
1. Metadaten "klappen nicht": Wurzel = kryptisches Volume-Label + kein
TMDB-Key. Jetzt: API mountet die Disc read-only (CAP_SYS_ADMIN ist da)
und liest den KLARTEXT-Titel aus BDMV/META/DL/bdmt_*.xml; dazu
progressive Suchdegradation (Titel-Varianten) und OMDb-Unscharf-Suche
(s= + imdbID-Nachladen) — mit dem vorhandenen OMDb-Key gibt es damit
Titel/Jahr/Poster auch ohne TMDB
2. Weisses Fenster beim Pre-Scan: Lucide-Icons sind forwardRef —
Direktaufruf getIcon(...)({size}) crashte die Seite; als JSX gerendert
3. Dashboard sortiert: System-Leiste (Encoder + aktiver Job) oben,
Disc/Geraete -> Stats -> Jobs, Live-Log ans Ende
4. Ziel-Dialog mit ORDNER-BROWSER (GET /browse, nur unter /app/media);
Schnellwahl nutzt die Settings-Unterordner statt Hartkodierung;
Tab "Verzeichnisse" in "Speicherziele" aufgegangen (redundant)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Die Job/Log-Tabellen leben bewusst doppelt in api/ und worker/ —
update_job gab es nur im Worker. Der Import-Smoke-Test prueft Routen,
aber keine Modul-Attribute; Lehre fuer die Etappe "geteiltes Paket".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Pre-Scan verlor den erkannten Typ (BDs hiessen immer "DVD"): scan()
reicht disc_type jetzt in die Zweige durch
- GIFTIG: Cache-Key nur aus Geraetepfad — die naechste Disc im selben
Laufwerk haette die Metadaten der vorherigen geerbt. Key enthaelt jetzt
einen Disc-Fingerabdruck (Label|Groesse)
- Worker-Faehigkeiten: import caps auf Modulebene — im worker_ready-Signal
war /app nicht mehr im sys.path (ModuleNotFoundError im Deploy-Log)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Commander-Befund: Disc wurde erkannt, aber das UI verriet nicht WAS.
- Watcher stoesst beim Einlegen (und beim Start mit bereits eingelegter
Disc) automatisch den Pre-Scan an, Ergebnis landet im DISC_CACHE und
im Log ("Disc erkannt: Titel (Jahr) [typ, Confidence]")
- GET /devices liefert das disc-Feld mit Titel/Jahr/Typ/Confidence/Poster
- UI: prominente Karte "Im Laufwerk erkannt" mit Poster (TMDB relativ
oder OMDb absolut), Beschreibung und Rippen-Start (Ziel-Dialog)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- POST /jobs nimmt target_dir (validiert unter /app/media, .. fliegt raus)
- GET /storage-targets: Verzeichnisse unter /app/media inkl. Mount-Flag
und freiem Platz — NFS/SMB-Shares unter /srv/rippy/media erscheinen
dank rslave-Bind automatisch
- jobs.target_dir (Mini-Migration via ADD COLUMN IF NOT EXISTS)
- Worker: rip_disc(target_dir) mit eigener Validierung; CD/Video/
Transcode-Pfade legen im gewaehlten Ziel ab
- UI: "Rippen starten" oeffnet den Ziel-Dialog (Filme/Serien/Musik oder
eigener Pfad); Modal-Bugfix: customPath wurde still ignoriert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Commander-Entscheid 23.07.: 40-GB-Rohdateien sind kein brauchbares
Endprodukt. Architektur bleibt zweistufig, weil HandBrake AACS nicht
lesen kann: MakeMKV rippt verlustfrei nach /app/temp/raw, HandBrake
macht daraus x265 auf Arbeitsgroesse in /app/media, Roh-Verzeichnis
wird erst NACH komplettem Erfolg geloescht (keepOriginal behaelt es).
- Worker: handbrake-cli im Image, run_handbrake + _komprimiere,
Job-Status "transcoding", Settings aus Postgres (transcodeEnabled/
Preset/keepOriginal), Fortschritt je Datei aggregiert
- makemkvcon: --noscan im Kommando verankert — der Geraete-Scan haengt
(1.18.4) bzw. crasht (1.17.7) im Container, mit --noscan + dev:-Pfad
laeuft es (Befund 23.07., DRV-Zeile beweist Laufwerks-Erkennung)
- UI: Settings-Tab "Verarbeitung" (Toggle/Preset/Original behalten),
Status-Badge "Komprimieren", LiveLog erkennt transcoding als aktiv
- KONZEPT/ROADMAP entsprechend aktualisiert; Tests fuer HandBrake-Cmd
(arbeitet auf DATEI, nie am Geraet) und Progress-Regex
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Praxis-Befund mit echter BD-50: reines UDF, der ISO-PVD-Leser griff nicht.
Jetzt ECMA-167-Weg (AVDP Sektor 256 -> Main VDS -> PVD Tag-ID 1 ->
Volume Identifier als d-string), mit Tests fuer das d-string-Parsing.
ROADMAP Etappe 12 aus der ARM-Vollanalyse: was wir uebernehmen
(Fingerprint-DB, bdmt_eng.xml, Suchdegradation, Manual Mode, Apprise,
Multi-Drive, Backup-Modus) und wo wir ARM schlagen (Serien-Episoden-
Matching, Main-Feature per Laufzeitabgleich).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 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>
Vorher gab es KEINEN Code-Pfad, der je einen Rip ausgelöst hat: kein
POST /jobs, kein udev-Daemon (udev_daemon.py existierte nirgends), GET /jobs
gab hart [] zurück, Postgres lag komplett brach, der SSE-Stream konnte
strukturell nie senden (sse_connections wurde nie befüllt), udevadm lieferte
ohne udevd nichts.
- POST /jobs: legt Job-Zeile an, schickt worker.tasks.rip_disc via Celery
- GET /jobs aus Postgres (running→processing fürs UI)
- Disc-Watcher: 3s-ioctl-Poll statt udev, protokolliert Einwurf/Auswurf
- /devices über /sys (vendor/model) + ioctl-Status — ehrlich statt leer
- /logs + /settings (Settings-Seite sprach vorher gegen 404)
- SSE-Fix, udev aus dem API-Image entfernt, Import-Smoke-Test
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Get devices from /dev/disc/ (udev symlinks)
- Also check direct devices: /dev/sr0, /dev/cdrom, /dev/dvd
- Use udevadm to detect device type (cd/dvd/bluray)
- Extract model and serial for better identification
- docker-compose.yml mit read_only: true, tmpfs, healthchecks
- API- und Worker-Dockerfiles mit minimalem Image
- requirements.txt für Python-Abhängigkeiten