diff --git a/lib/mb_match.py b/lib/mb_match.py index 2be80e4..faa4454 100644 --- a/lib/mb_match.py +++ b/lib/mb_match.py @@ -283,7 +283,11 @@ def _best_release(doc: dict) -> dict: clean = 0 if _is_clean_studio_album(rg) else 1 status_ok = 0 if str(r.get("status", "")).lower() == "official" else 1 date = str(r.get("date", "") or "9999") - return (clean, status_ok, date) + # Official FIRST, then prefer a clean studio album: this still surfaces + # the studio album over an (official) live/comp album for the display + # album/year, but never lets an UNofficial bootleg album outrank an + # official single/EP/comp — which `(clean, status_ok, …)` would. + return (status_ok, clean, date) return sorted(releases, key=sort_key)[0] diff --git a/tests/test_mb_match.py b/tests/test_mb_match.py index 9af0abb..ed793a1 100644 --- a/tests/test_mb_match.py +++ b/tests/test_mb_match.py @@ -202,6 +202,29 @@ def test_parse_recording_doc_normalizes(): assert c["mb_score"] == 98 +def test_best_release_prefers_official_single_over_unofficial_album(): + """An OFFICIAL single/EP must outrank an UNofficial bootleg album for the + canonical album/year: official comes before the studio-album preference, so + a single-only song is never seeded from a bootleg. (`(clean, status_ok, …)` + would wrongly pick the bootleg.)""" + doc = { + "id": "rec-x", "title": "One-Off", "score": 90, + "artist-credit": [ + {"name": "A", "joinphrase": "", + "artist": {"id": "a", "name": "A", "sort-name": "A"}}], + "releases": [ + {"id": "rel-boot", "title": "Boot LP", "status": "Bootleg", + "date": "1990-01-01", "release-group": {"primary-type": "Album"}}, + {"id": "rel-single", "title": "The Single", "status": "Official", + "date": "1988-01-01", "release-group": {"primary-type": "Single"}}, + ], + } + c = m.parse_recording_doc(doc) + assert c["release_id"] == "rel-single" + assert c["album"] == "The Single" + assert c["studio"] is False # a Single isn't a clean studio ALBUM + + def test_parse_recording_doc_joined_artist_credit(): doc = dict(MB_DOC) doc["artist-credit"] = [