Shorter, cleaner filenames consistent with Jellyfin conventions. Updated all references in source, tests, and documentation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 KiB
3 KiB
Refactoring-Plan: Workflow-Phasen in ripper.py
Stand: 2026-02-19 — Entwurf zur Diskussion
Aktueller Zustand
interactive_rip ist eine ~400-Zeilen-Funktion mit zwei verschränkten Pfaden
(MB-Hit vs. Fallback), die alles in einem monolithischen Block erledigt.
Die apply-Seite ist bereits sauber getrennt (organizer → tagger → playlist).
Vorschlag: 7 logische Phasen
Phase 1: Album-Identifikation (EAN / Barcode)
- EAN-Eingabe per Tastatur oder Foto-Scan
- Vision-LLM: Barcode aus Foto extrahieren
- MusicBrainz-Lookup per EAN → Album-Struktur + MBID
- Ergebnis:
ean,mb_album,mb_mbid(oder alles None)
Phase 2: Cover-Beschaffung
- CAA-Download (front.jpg, back.jpg) per MBID
- Foto-Upload per Scanner-Server (Backcover, ggf. Frontcover)
prepare_cover()für Jellyfin-Format- Ergebnis: Cover-Dateien im album_root
Phase 3: Backcover-Analyse (parallel zu Phase 4)
- Vision-LLM auf Backcover-Foto → vollständige Album-Metadaten
- Läuft als Background-Thread während des Rippens
- Ergebnis:
vision_album: Album | None
Phase 4: Audio-Ripping (pro Disc)
- Disc einlegen → abcde starten (cdparanoia + Encoder)
- CDDB-Lookup als Nebenprodukt von abcde
- CDDB-Bestätigung durch User (Fallback-Pfad)
- Audio-Dateien in album_root/CDn/
- Ergebnis: Audio-Dateien +
cddb_trackspro Disc
Phase 5: Metadaten-Zusammenführung (Priorität: Vision > MB > CDDB)
- Vision-LLM-Ergebnis einsammeln (Timeout 120s)
- Beste Quelle auswählen nach Priorität
- Album-Name, Artist, Year, Genre, Tracklist konsolidieren
- Ergebnis:
final_album: Album
Phase 6: album.json erzeugen + Apply-Hint
final_albumserialisieren → album.json- Kopierbaren
apply-Befehl ausgeben - Hier endet
rip— User prüft/editiert JSON manuell
Phase 7: Apply (bereits separater CLI-Befehl)
- Datei-Mapping erstellen (organizer)
- Umbenennen/Verschieben (sanitize_filename)
- Audio-Tagging (mutagen)
- Cover-Embedding
- M3U-Playlist generieren
Strukturelle Beobachtungen
Was heute vermischt ist
- Phase 1–6 stecken alle in
interactive_rip()mit if/else-Verzweigung für MB-Hit vs. Fallback - Die Disc-Schleife (Phase 4) enthält Logik aus Phase 2 (Cover-Upload während Disc-Insert) und Phase 3 (Vision-Thread starten)
- Phase 5 ist dupliziert: einmal im MB-Pfad (Zeile ~791), einmal im Fallback-Pfad (Zeile ~956)
Was eine Refaktorierung bringen würde
- Die zwei Pfade (MB-Hit / Fallback) konvergieren nach Phase 4 — ab Phase 5 ist die Logik identisch, aber heute kopiert
- Cover-Beschaffung ist über den ganzen Code verstreut (CAA-Download, Scanner-Upload während Disc-Insert, Backcover-Save am Ende)
- Die Vision-LLM-Steuerung (Thread starten, Ergebnis einsammeln) könnte ein eigenes Objekt/Kontext sein
Offene Frage
Soll die Disc-Schleife (Phase 4) eine einheitliche Schnittstelle haben, die beide Pfade bedient? Im MB-Pfad ist die Disc-Anzahl bekannt, im Fallback-Pfad offen (while-Schleife mit "Nächste CD?"). Das ist der größte strukturelle Unterschied.