From 2490293dcf299fff7a3b72c6d5bf1d4b28507c6c Mon Sep 17 00:00:00 2001 From: dschlueter Date: Thu, 19 Feb 2026 14:31:09 +0100 Subject: [PATCH] Fix MB-hit path: poll scanner for backcover photo at disc insert prompt If Cover Art Archive has no backcover, the scanner server (already running since EAN prompt) is now also monitored at each disc insert prompt via _input_or_scan. On photo upload, Vision-LLM starts in the background and the photo is saved as backcover.jpg after ripping. Phone photo takes priority over any CAA cover. Co-Authored-By: Claude Sonnet 4.6 --- src/musiksammlung/ripper.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/musiksammlung/ripper.py b/src/musiksammlung/ripper.py index 729b817..286cbe9 100644 --- a/src/musiksammlung/ripper.py +++ b/src/musiksammlung/ripper.py @@ -695,8 +695,9 @@ def interactive_rip(config: RipperConfig) -> None: if mb_mbid: download_caa_covers(mb_mbid, album_root) - # Vision-LLM im Hintergrund starten, falls Back-Cover vorhanden + # Vision-LLM im Hintergrund starten, falls CAA-Backcover vorhanden vision_queue = None + uploaded_photo: Path | None = None backcover = album_root / "backcover.jpg" if backcover.exists(): print( @@ -706,15 +707,31 @@ def interactive_rip(config: RipperConfig) -> None: vision_queue = _start_vision_thread( backcover, config.vision_model, config.vision_url ) + else: + print( + " Kein Backcover in Cover Art Archive." + f" Optional: Backcover hochladen — {scanner_url}", + flush=True, + ) for disc in mb_album.discs: disc_num = disc.disc_number disc_dir = album_root / f"CD{disc_num}" - input( + _, disc_photo = _input_or_scan( f"\n CD {disc_num}/{total_discs} einlegen und Enter drücken " - f"({len(disc.tracks)} Tracks) ..." + f"({len(disc.tracks)} Tracks) ...", + scanner, ) + if disc_photo and vision_queue is None: + uploaded_photo = disc_photo + print( + " Backcover-Foto empfangen → Vision-LLM-Analyse gestartet...", + flush=True, + ) + vision_queue = _start_vision_thread( + disc_photo, config.vision_model, config.vision_url + ) print(f" Ripping to: {disc_dir}") print(" " + "-" * 50) @@ -766,6 +783,12 @@ def interactive_rip(config: RipperConfig) -> None: flush=True, ) + # Hochgeladenes Backcover speichern (Handy-Foto hat Vorrang vor CAA) + if uploaded_photo and uploaded_photo.exists(): + dest = album_root / "backcover.jpg" + prepare_cover(uploaded_photo, dest) + print(f" backcover.jpg gespeichert: {dest}", flush=True) + json_path = album_root / "album.json" json_path.write_text( final_album.model_dump_json(indent=2), encoding="utf-8"