New features:
- EAN/Barcode can now be entered by typing or by photographing the CD sleeve;
Vision-LLM (extract_barcode_from_image) reads the barcode from the photo
- Scanner server (port 8765) starts at the beginning of every album loop,
serving both EAN barcode scanning and back cover upload via QR code
- Vision-LLM analyses back cover in background thread while ripping;
priority: Vision-LLM > MusicBrainz > CDDB
- _find_abcde_mbid reads MBID from abcde temp dirs for CAA cover download
even when the CD barcode is not linked in MusicBrainz
- Concrete copy-paste apply commands shown after each album in 'Next steps'
- _sanitize_name: whitelist approach (removes brackets and punctuation)
- qrcode added as dependency for terminal QR code display
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MusicBrainz always returns HTTP 200; an empty result set is definitive.
Retrying would never yield a different outcome.
- lookup_by_barcode(): retries parameter removed, random import removed
- Removed 3 retry-related tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Up to 3 retries with 2–6 s random wait between attempts, as MusicBrainz
occasionally returns no results on the first try. retries parameter is
configurable (default: 3).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New module musicbrainz.py: lookup_by_barcode() via EAN-13/UPC-12,
two-step API (barcode search → release detail with recordings),
respects 1 req/s rate limit with User-Agent header
- cli.py: scan command gets --barcode option as highest-priority mode
(no images needed); _scan_to_album() dispatches to MusicBrainz first
- ripper.py: interactive_rip() prompts for optional EAN after album name;
MusicBrainz data (incl. year) takes priority over CDDB for album.json;
album_root.mkdir() added so JSON can be written even when MB changes dir
- tests: test_musicbrainz.py (16 tests), test_ripper.py +6 barcode tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>