diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index ea0ab951a..0f04b49c3 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -302,23 +302,76 @@ class LastGenrePlugin(plugins.BeetsPlugin): def fetch_album_genre(self, obj): """Return raw album genres from Last.fm for this Item or Album.""" - return self._last_lookup( + genre = self._last_lookup( "album", LASTFM.get_album, obj.albumartist, obj.album ) + if genre: + return genre + + # If no genres found for the joint 'albumartist', try the individual + # album artists if available in 'albumartists'. + if obj.albumartists and len(obj.albumartists) > 1: + for albumartist in obj.albumartists: + genre = self._last_lookup( + "album", LASTFM.get_album, albumartist, obj.album + ) + + if genre: + return genre + + return genre def fetch_album_artist_genre(self, obj): """Return raw album artist genres from Last.fm for this Item or Album.""" - return self._last_lookup("artist", LASTFM.get_artist, obj.albumartist) + genres = self._last_lookup("artist", LASTFM.get_artist, obj.albumartist) + if genres: + return genres - def fetch_artist_genre(self, item): + # If not genres found for the joint 'albumartist', try the individual + # album artists if available in 'albumartists'. + if obj.ablumartists and len(obj.albumartists) > 1: + for albumartist in obj.albumartists: + genre = self._last_lookup( + "artist", LASTFM.get_artist, albumartist + ) + + if genre: + return genre + return genres + + def fetch_artist_genre(self, obj): """Returns raw track artist genres from Last.fm for this Item.""" - return self._last_lookup("artist", LASTFM.get_artist, item.artist) + genres = self._last_lookup("artist", LASTFM.get_artist, obj.artist) + if genres: + return genres + + # If not genres found for the joint 'artist', try the individual + # album artists if available in 'artists'. + if obj.artists and len(obj.artists) > 1: + for artist in obj.artists: + genre = self._last_lookup("artist", LASTFM.get_artist, artist) + if genre: + return genre + return genres def fetch_track_genre(self, obj): """Returns raw track genres from Last.fm for this Item.""" - return self._last_lookup( + genres = self._last_lookup( "track", LASTFM.get_track, obj.artist, obj.title ) + if genres: + return genres + + # If not genres found for the joint 'artist', try the individual + # album artists if available in 'artists'. + if obj.artists and len(obj.artists) > 1: + for artist in obj.artists: + genre = self._last_lookup( + "track", LASTFM.get_track, artist, obj.title + ) + if genre: + return genre + return genres # Main processing: _get_genre() and helpers. diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index b3c653682..ee5069e38 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -302,6 +302,21 @@ class SpotifyPlugin( self._log.error("Request failed. Error: {}", e) raise APIError("Request failed.") + def _multi_artist_credit( + self, artists: list[dict[str | int, str]] + ) -> tuple[list[str], list[str]]: + """Given a list representing an ``artist``, accumulate data into a pair + of lists: the first being the artist names, and the second being the + artist IDs. + """ + artist_names = [] + artist_ids = [] + for artist in artists: + name, id = self.get_artist([artist]) + artist_names.append(name) + artist_ids.append(id) + return artist_names, artist_ids + def album_for_id(self, album_id: str) -> AlbumInfo | None: """Fetch an album by its Spotify ID or URL and return an AlbumInfo object or None if the album is not found. @@ -321,7 +336,8 @@ class SpotifyPlugin( if album_data["name"] == "": self._log.debug("Album removed from Spotify: {}", album_id) return None - artist, artist_id = self.get_artist(album_data["artists"]) + artists_names, artists_ids = self._multi_artist_credit(album_data["artists"]) + artist = ", ".join(artists_names) date_parts = [ int(part) for part in album_data["release_date"].split("-") @@ -364,8 +380,10 @@ class SpotifyPlugin( album_id=spotify_id, spotify_album_id=spotify_id, artist=artist, - artist_id=artist_id, - spotify_artist_id=artist_id, + artist_id=artists_ids[0], + spotify_artist_id=artists_ids[0], + artists=artists_names, + artists_ids=artists_ids, tracks=tracks, albumtype=album_data["album_type"], va=len(album_data["artists"]) == 1 @@ -388,7 +406,8 @@ class SpotifyPlugin( :returns: TrackInfo object for track """ - artist, artist_id = self.get_artist(track_data["artists"]) + artists_names, artists_ids = self._multi_artist_credit(track_data["artists"]) + artist = ", ".join(artists_names) # Get album information for spotify tracks try: @@ -401,8 +420,10 @@ class SpotifyPlugin( spotify_track_id=track_data["id"], artist=artist, album=album, - artist_id=artist_id, - spotify_artist_id=artist_id, + artist_id=artists_ids[0], + spotify_artist_id=artists_ids[0], + artists=artists_names, + artists_ids=artists_ids, length=track_data["duration_ms"] / 1000, index=track_data["track_number"], medium=track_data["disc_number"],