Skip to content

Commit 4e865a6

Browse files
authored
Discogs featured artist fix (#6040)
Fixes #6038 - Appends featured artists in the extraartists field to the artist tag, similar to the MusicBrainz plugin. Works well with ftintitle for consistency as well. ## To Do May need adjustment for common artist delimiters used - but appears to match the MusicBrainz standard at the moment.
2 parents bc9d34e + 85201a4 commit 4e865a6

File tree

3 files changed

+71
-9
lines changed

3 files changed

+71
-9
lines changed

beetsplug/discogs.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ def get_album_info(self, result):
339339
# convenient `.tracklist` property, which will strip out useful artist
340340
# information and leave us with skeleton `Artist` objects that will
341341
# each make an API call just to get the same data back.
342-
tracks = self.get_tracks(result.data["tracklist"])
342+
tracks = self.get_tracks(result.data["tracklist"], artist, artist_id)
343343

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

449-
def get_tracks(self, tracklist):
445+
def get_tracks(self, tracklist, album_artist, album_artist_id):
450446
"""Returns a list of TrackInfo objects for a discogs tracklist."""
451447
try:
452448
clean_tracklist = self.coalesce_tracks(tracklist)
@@ -471,7 +467,9 @@ def get_tracks(self, tracklist):
471467
# divisions.
472468
divisions += next_divisions
473469
del next_divisions[:]
474-
track_info = self.get_track_info(track, index, divisions)
470+
track_info = self.get_track_info(
471+
track, index, divisions, album_artist, album_artist_id
472+
)
475473
track_info.track_alt = track["position"]
476474
tracks.append(track_info)
477475
else:
@@ -638,7 +636,9 @@ def strip_disambiguation(self, text: str) -> str:
638636
return text
639637
return DISAMBIGUATION_RE.sub("", text)
640638

641-
def get_track_info(self, track, index, divisions):
639+
def get_track_info(
640+
self, track, index, divisions, album_artist, album_artist_id
641+
):
642642
"""Returns a TrackInfo object for a discogs track."""
643643
title = track["title"]
644644
if self.config["index_tracks"]:
@@ -650,8 +650,21 @@ def get_track_info(self, track, index, divisions):
650650
artist, artist_id = self.get_artist(
651651
track.get("artists", []), join_key="join"
652652
)
653-
artist = self.strip_disambiguation(artist)
653+
# If no artist and artist is returned, set to match album artist
654+
if not artist:
655+
artist = album_artist
656+
artist_id = album_artist_id
654657
length = self.get_track_length(track["duration"])
658+
# Add featured artists
659+
extraartists = track.get("extraartists", [])
660+
featured = [
661+
artist["name"]
662+
for artist in extraartists
663+
if "Featuring" in artist["role"]
664+
]
665+
if featured:
666+
artist = f"{artist} feat. {', '.join(featured)}"
667+
artist = self.strip_disambiguation(artist)
655668
return TrackInfo(
656669
title=title,
657670
track_id=track_id,

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ New features:
1515
converted files.
1616
- :doc:`plugins/discogs`: New config option `strip_disambiguation` to toggle
1717
stripping discogs numeric disambiguation on artist and label fields.
18+
- :doc:`plugins/discogs` Added support for featured artists.
1819

1920
Bug fixes:
2021

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

test/plugins/test_discogs.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,52 @@ def test_strip_disambiguation_false(self):
450450
assert d.artist == "ARTIST NAME (2) & OTHER ARTIST (5)"
451451
assert d.tracks[0].artist == "TEST ARTIST (5)"
452452
assert d.label == "LABEL NAME (5)"
453+
config["discogs"]["strip_disambiguation"] = True
454+
455+
456+
@pytest.mark.parametrize(
457+
"track, expected_artist",
458+
[
459+
(
460+
{
461+
"type_": "track",
462+
"title": "track",
463+
"position": "1",
464+
"duration": "5:00",
465+
"artists": [
466+
{"name": "NEW ARTIST", "tracks": "", "id": 11146},
467+
{"name": "VOCALIST", "tracks": "", "id": 344, "join": "&"},
468+
],
469+
"extraartists": [
470+
{
471+
"name": "SOLOIST",
472+
"role": "Featuring",
473+
},
474+
{
475+
"name": "PERFORMER (1)",
476+
"role": "Other Role, Featuring",
477+
},
478+
{
479+
"name": "RANDOM",
480+
"role": "Written-By",
481+
},
482+
{
483+
"name": "MUSICIAN",
484+
"role": "Featuring [Uncredited]",
485+
},
486+
],
487+
},
488+
"NEW ARTIST, VOCALIST feat. SOLOIST, PERFORMER, MUSICIAN",
489+
),
490+
],
491+
)
492+
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
493+
def test_parse_featured_artists(track, expected_artist):
494+
"""Tests the plugins ability to parse a featured artist.
495+
Initial check with one featured artist, two featured artists,
496+
and three. Ignores artists that are not listed as featured."""
497+
t = DiscogsPlugin().get_track_info(track, 1, 1, "ARTIST", 2)
498+
assert t.artist == expected_artist
453499

454500

455501
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)