Fix crash on vinyl track positions like 'A1', 'B2' from MusicBrainz

MusicBrainz returns vinyl track numbers as 'A1', 'B3' etc. instead of
plain integers. int('A1') raised ValueError crashing the entire album.

metadata_resolver.py: parse vinyl positions with regex before int():
- 'A1' → track 1, disc 1 (side A)
- 'B3' → track 3, disc 1 (side B)
- 'C1' → track 1, disc 2 (side C)
- Non-vinyl: extract first digit group via re.search

hint_extractor.py: guard int(tl_track) in tracklist matching with
try/except + re.search so any non-numeric track position is skipped
gracefully instead of crashing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-04-29 09:12:31 +02:00
commit cd6c0ae185
2 changed files with 18 additions and 3 deletions

View file

@ -578,8 +578,12 @@ def extract_hints(scan: AlbumScan, use_ocr: bool = True) -> AlbumHints:
assumed_disc = disc_num if disc_num else 1 assumed_disc = disc_num if disc_num else 1
for tl_entry in parsed_tracklist: for tl_entry in parsed_tracklist:
tl_track = tl_entry.get("track") tl_track = tl_entry.get("track")
try:
tl_disc = int(tl_entry.get("disc", "1")) tl_disc = int(tl_entry.get("disc", "1"))
if (tl_track and int(tl_track) == track_num tl_track_int = int(re.search(r"\d+", str(tl_track)).group()) if tl_track else None
except (ValueError, AttributeError):
continue
if (tl_track_int is not None and tl_track_int == track_num
and tl_disc == assumed_disc): and tl_disc == assumed_disc):
matched_tl = tl_entry matched_tl = tl_entry
break break

View file

@ -549,9 +549,20 @@ def resolve(
for medium in full_release.get("medium-list", []): for medium in full_release.get("medium-list", []):
disc_num = medium.get("position", 1) disc_num = medium.get("position", 1)
for track in medium.get("track-list", []): for track in medium.get("track-list", []):
raw_num = str(track.get("number", "0") or "0").strip()
# Vinyl: "A1"→track 1 disc 1, "B3"→track 3 disc 1, "C1"→disc 2, "D1"→disc 2
vinyl_match = re.match(r"^([A-Za-z])(\d+)$", raw_num)
if vinyl_match:
side_letter = vinyl_match.group(1).upper()
track_number = int(vinyl_match.group(2))
# A,B → disc 1; C,D → disc 2; E,F → disc 3 …
disc_num = (ord(side_letter) - ord("A")) // 2 + 1
else:
num_match = re.search(r"\d+", raw_num)
track_number = int(num_match.group()) if num_match else 0
mb_tracks.append({ mb_tracks.append({
"disc": disc_num, "disc": disc_num,
"number": int(track.get("number", 0) or 0), "number": track_number,
"title": track.get("recording", {}).get("title", ""), "title": track.get("recording", {}).get("title", ""),
"artist": track.get("artist-credit-phrase", ""), "artist": track.get("artist-credit-phrase", ""),
"mbid": track.get("recording", {}).get("id"), "mbid": track.get("recording", {}).get("id"),