Musiksammlung/docs/refactoring_plan.md
dschlueter 1ca88b0d6d Rename cover files: frontcover.jpg → front.jpg, backcover.jpg → back.jpg
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>
2026-02-20 09:56:12 +01:00

3 KiB
Raw Blame History

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_tracks pro 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_album serialisieren → 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 16 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.