diff --git a/beetsplug/deezer.py b/beetsplug/deezer.py index 6ea172631..629c87bd4 100644 --- a/beetsplug/deezer.py +++ b/beetsplug/deezer.py @@ -187,16 +187,20 @@ class DeezerPlugin(SearchApiMetadataSourcePlugin[IDResponse]): :param track_data: Deezer Track object dict """ - artist, artist_id = self.get_artist( - track_data.get("contributors", [track_data["artist"]]) - ) + contributors = track_data.get("contributors") + if contributors is None and (artist_data := track_data.get("artist")): + contributors = [artist_data] + if contributors is not None: + artist, artist_id = self.get_artist(contributors) + else: + artist, artist_id = None, None return TrackInfo( title=track_data["title"], track_id=track_data["id"], deezer_track_id=track_data["id"], isrc=track_data.get("isrc"), artist=artist, - artist_id=str(artist_id), + artist_id=str(artist_id) if artist_id is not None else None, length=track_data["duration"], index=track_data.get("track_position"), medium=track_data.get("disk_number"), diff --git a/docs/changelog.rst b/docs/changelog.rst index e75ac5ca0..7a92d72e2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -56,6 +56,11 @@ Bug fixes copyright/rights-statement text verbatim. It's now normalized to a concise label name, stripping copyright markers, years, and corporate, licensing, and territorial boilerplate. Affects both album and track metadata. :bug:`6796` +- :doc:`plugins/deezer`: Track conversion no longer assumes the API sends both + ``contributors`` and ``artist``. The fallback to ``artist`` was evaluated even + when ``contributors`` was present, so a track payload without ``artist`` + raised ``KeyError``. Albums were already guarded; this fixes the remaining + call site. :bug:`4339` .. For plugin developers diff --git a/test/plugins/test_deezer.py b/test/plugins/test_deezer.py index e62514824..fb5cffaa6 100644 --- a/test/plugins/test_deezer.py +++ b/test/plugins/test_deezer.py @@ -39,3 +39,36 @@ class TestSearchQuery: ) assert query == 'album:"Album"' + + +class TestGetTrack: + def track_data(self, **fields): + return { + "id": 1, + "title": "Title", + "duration": 100, + "link": "https://www.deezer.com/track/1", + **fields, + } + + def test_uses_contributors_when_artist_is_missing(self, plugin): + track = plugin._get_track( + self.track_data(contributors=[{"id": 2, "name": "Artist"}]) + ) + + assert track.artist == "Artist" + assert track.artist_id == "2" + + def test_falls_back_to_artist_without_contributors(self, plugin): + track = plugin._get_track( + self.track_data(artist={"id": 2, "name": "Artist"}) + ) + + assert track.artist == "Artist" + assert track.artist_id == "2" + + def test_tolerates_missing_artist_and_contributors(self, plugin): + track = plugin._get_track(self.track_data()) + + assert track.artist is None + assert track.artist_id is None