Skip to content
Merged
31 changes: 22 additions & 9 deletions beetsplug/discogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def get_album_info(self, result):
# convenient `.tracklist` property, which will strip out useful artist
# information and leave us with skeleton `Artist` objects that will
# each make an API call just to get the same data back.
tracks = self.get_tracks(result.data["tracklist"])
tracks = self.get_tracks(result.data["tracklist"], artist, artist_id)

# Extract information for the optional AlbumInfo fields, if possible.
va = result.data["artists"][0].get("name", "").lower() == "various"
Expand Down Expand Up @@ -386,10 +386,6 @@ def get_album_info(self, result):
for track in tracks:
track.media = media
track.medium_total = mediums.count(track.medium)
if not track.artist: # get_track_info often fails to find artist
track.artist = artist
if not track.artist_id:
track.artist_id = artist_id
# Discogs does not have track IDs. Invent our own IDs as proposed
# in #2336.
track.track_id = f"{album_id}-{track.track_alt}"
Expand Down Expand Up @@ -446,7 +442,7 @@ def format(self, classification):
else:
return None

def get_tracks(self, tracklist):
def get_tracks(self, tracklist, album_artist, album_artist_id):
"""Returns a list of TrackInfo objects for a discogs tracklist."""
try:
clean_tracklist = self.coalesce_tracks(tracklist)
Expand All @@ -471,7 +467,9 @@ def get_tracks(self, tracklist):
# divisions.
divisions += next_divisions
del next_divisions[:]
track_info = self.get_track_info(track, index, divisions)
track_info = self.get_track_info(
track, index, divisions, album_artist, album_artist_id
)
track_info.track_alt = track["position"]
tracks.append(track_info)
else:
Expand Down Expand Up @@ -638,7 +636,9 @@ def strip_disambiguation(self, text: str) -> str:
return text
return DISAMBIGUATION_RE.sub("", text)

def get_track_info(self, track, index, divisions):
def get_track_info(
self, track, index, divisions, album_artist, album_artist_id
):
"""Returns a TrackInfo object for a discogs track."""
title = track["title"]
if self.config["index_tracks"]:
Expand All @@ -650,8 +650,21 @@ def get_track_info(self, track, index, divisions):
artist, artist_id = self.get_artist(
track.get("artists", []), join_key="join"
)
artist = self.strip_disambiguation(artist)
# If no artist and artist is returned, set to match album artist
if not artist:
artist = album_artist
artist_id = album_artist_id
length = self.get_track_length(track["duration"])
# Add featured artists
extraartists = track.get("extraartists", [])
featured = [
artist["name"]
for artist in extraartists
if "Featuring" in artist["role"]
]
if featured:
artist = f"{artist} feat. {', '.join(featured)}"
artist = self.strip_disambiguation(artist)
return TrackInfo(
title=title,
track_id=track_id,
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ New features:
converted files.
- :doc:`plugins/discogs`: New config option `strip_disambiguation` to toggle
stripping discogs numeric disambiguation on artist and label fields.
- :doc:`plugins/discogs` Added support for featured artists.

Bug fixes:

Expand All @@ -27,6 +28,8 @@ Bug fixes:
matching. :bug:`5189`
- :doc:`plugins/discogs` Fixed inconsistency in stripping disambiguation from
artists but not labels. :bug:`5366`
- :doc:`plugins/discogs` Fixed issue with ignoring featured artists in the
extraartists field.
- :doc:`plugins/spotify` Fixed an issue where candidate lookup would not find
matches due to query escaping (single vs double quotes).

Expand Down
46 changes: 46 additions & 0 deletions test/plugins/test_discogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,52 @@ def test_strip_disambiguation_false(self):
assert d.artist == "ARTIST NAME (2) & OTHER ARTIST (5)"
assert d.tracks[0].artist == "TEST ARTIST (5)"
assert d.label == "LABEL NAME (5)"
config["discogs"]["strip_disambiguation"] = True


@pytest.mark.parametrize(
"track, expected_artist",
[
(
{
"type_": "track",
"title": "track",
"position": "1",
"duration": "5:00",
"artists": [
{"name": "NEW ARTIST", "tracks": "", "id": 11146},
{"name": "VOCALIST", "tracks": "", "id": 344, "join": "&"},
],
"extraartists": [
{
"name": "SOLOIST",
"role": "Featuring",
},
{
"name": "PERFORMER (1)",
"role": "Other Role, Featuring",
},
{
"name": "RANDOM",
"role": "Written-By",
},
{
"name": "MUSICIAN",
"role": "Featuring [Uncredited]",
},
],
},
"NEW ARTIST, VOCALIST feat. SOLOIST, PERFORMER, MUSICIAN",
),
],
)
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
def test_parse_featured_artists(track, expected_artist):
"""Tests the plugins ability to parse a featured artist.
Initial check with one featured artist, two featured artists,
and three. Ignores artists that are not listed as featured."""
t = DiscogsPlugin().get_track_info(track, 1, 1, "ARTIST", 2)
assert t.artist == expected_artist


@pytest.mark.parametrize(
Expand Down
Loading