fix(mb): rank release groups by credited artist, not title alone
The worker MB resolver picked release groups on (title_ratio, is_album)
and never scored the artist — even though resolve() knows the followed
artist. For a generic title, same-titled release groups by *different*
artists tie on title, and the is_album tiebreak (added in 06e7f91 for
Off the Wall) then actively preferred a foreign Album over the correct
release. Concretely, following Lake Street Dive's "Fun Machine" EP
resolved to an unrelated band "Bastards of Melody"'s same-titled Album,
which then propagated as the downloaded/imported artist.
Make credited-artist similarity the primary sort key, above title and
above is_album. It's a soft signal, never a hard filter, so credited-
name variations (feat., punctuation) still resolve; is_album now only
breaks ties within the same artist+title, preserving the Off the Wall
fix. Verified live: resolve("Lake Street Dive", "Fun Machine") now
returns the 6-track LSD EP.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,15 +13,39 @@ def _is_album(g: dict) -> bool:
|
||||
return (g.get("primary-type") or "").casefold() == "album"
|
||||
|
||||
|
||||
def _best_release_group(album: str, groups: list) -> dict | None:
|
||||
"""Choose the best release-group match for `album`. Highest title similarity wins;
|
||||
an Album primary-type breaks ties so a famous album (e.g. Michael Jackson's "Off the
|
||||
Wall") isn't resolved to its same-named single, whose short tracklist would then be
|
||||
mapped positionally onto the full album's files. Returns None below the title threshold.
|
||||
Pure — no network I/O."""
|
||||
def _credited_artist(g: dict) -> str:
|
||||
"""Primary credited artist name of a release-group search result, or '' if absent."""
|
||||
credit = g.get("artist-credit")
|
||||
if isinstance(credit, list) and credit and isinstance(credit[0], dict):
|
||||
return (credit[0].get("artist") or {}).get("name", "") or ""
|
||||
return ""
|
||||
|
||||
|
||||
def _best_release_group(artist: str, album: str, groups: list) -> dict | None:
|
||||
"""Choose the best release-group match for `artist`/`album`.
|
||||
|
||||
Ranked, highest first, on `(artist_ratio, title_ratio, is_album)`:
|
||||
* artist match dominates — MusicBrainz relevance ties same-titled release groups by
|
||||
*different* artists (e.g. "Fun Machine" exists as a Lake Street Dive EP and an
|
||||
unrelated band's Album), and the artist we followed is trustworthy, so a credited
|
||||
artist that matches the request outranks everything else;
|
||||
* title similarity is next;
|
||||
* an Album primary-type only breaks ties *within* the same artist+title, so a famous
|
||||
album (Michael Jackson's "Off the Wall") still isn't resolved to its same-named
|
||||
single whose short tracklist would map positionally onto the album's files.
|
||||
Artist is a ranking signal, never a hard filter — a low match sinks a candidate but
|
||||
never drops the release, so credited-name variations (feat., punctuation) still resolve.
|
||||
Returns None below the title threshold. Pure — no network I/O."""
|
||||
if not groups:
|
||||
return None
|
||||
best = max(groups, key=lambda g: (_ratio(album, g.get("title", "")), _is_album(g)))
|
||||
best = max(
|
||||
groups,
|
||||
key=lambda g: (
|
||||
_ratio(artist, _credited_artist(g)),
|
||||
_ratio(album, g.get("title", "")),
|
||||
_is_album(g),
|
||||
),
|
||||
)
|
||||
if _ratio(album, best.get("title", "")) < _MIN_TITLE_RATIO:
|
||||
return None
|
||||
return best
|
||||
@@ -46,7 +70,7 @@ class MusicBrainzResolver:
|
||||
|
||||
res = musicbrainzngs.search_release_groups(query=album, artist=artist, limit=5)
|
||||
groups = res.get("release-group-list", [])
|
||||
rg = _best_release_group(album, groups)
|
||||
rg = _best_release_group(artist, album, groups)
|
||||
if rg is None:
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user