Fix race condition causing a (potential) endless loop (#1361)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Fri, 14 Jun 2024 11:57:37 +0000 (13:57 +0200)
committerGitHub <noreply@github.com>
Fri, 14 Jun 2024 11:57:37 +0000 (13:57 +0200)
music_assistant/server/controllers/media/albums.py
music_assistant/server/controllers/media/artists.py

index 21e6d4559b2bc2b0e9b85b5b3c0e58da2cec4243..22d337ed82628bf37f47d193943bd8c4146f3e97 100644 (file)
@@ -151,19 +151,20 @@ class AlbumsController(MediaControllerBase[Album]):
         in_library_only: bool = False,
     ) -> UniqueList[AlbumTrack]:
         """Return album tracks for the given provider album id."""
-        full_album = await self.get(item_id, provider_instance_id_or_domain)
-        db_items = (
-            await self.get_library_album_tracks(full_album.item_id)
-            if full_album.provider == "library"
-            else []
+        # always check if we have a library item for this album
+        library_album = await self.get_library_item_by_prov_id(
+            item_id, provider_instance_id_or_domain
         )
-        # return all (unique) items from all providers
+        if not library_album:
+            return await self._get_provider_album_tracks(item_id, provider_instance_id_or_domain)
+        db_items = await self.get_library_album_tracks(library_album.item_id)
         result: UniqueList[AlbumTrack] = UniqueList(db_items)
-        if full_album.provider == "library" and in_library_only:
+        if in_library_only:
             # return in-library items only
             return sorted(db_items, key=lambda x: (x.disc_number, x.track_number))
+        # return all (unique) items from all providers
         unique_ids: set[str] = {f"{x.disc_number or 1}.{x.track_number}" for x in db_items}
-        for provider_mapping in full_album.provider_mappings:
+        for provider_mapping in library_album.provider_mappings:
             provider_tracks = await self._get_provider_album_tracks(
                 provider_mapping.item_id, provider_mapping.provider_instance
             )
@@ -172,7 +173,7 @@ class AlbumsController(MediaControllerBase[Album]):
                 if unique_id in unique_ids:
                     continue
                 unique_ids.add(unique_id)
-                result.append(AlbumTrack.from_track(provider_track, full_album))
+                result.append(AlbumTrack.from_track(provider_track, library_album))
         # NOTE: we need to return the results sorted on disc/track here
         # to ensure the correct order at playback
         return sorted(result, key=lambda x: (x.disc_number, x.track_number))
@@ -183,7 +184,7 @@ class AlbumsController(MediaControllerBase[Album]):
         provider_instance_id_or_domain: str,
     ) -> UniqueList[Album]:
         """Return all versions of an album we can find on all providers."""
-        album = await self.get(item_id, provider_instance_id_or_domain, add_to_library=False)
+        album = await self.get_provider_item(item_id, provider_instance_id_or_domain)
         search_query = f"{album.artists[0].name} - {album.name}" if album.artists else album.name
         result: UniqueList[Album] = UniqueList()
         for provider_id in self.mass.music.get_unique_providers():
index 1168712430d3db9acdb8be175a91a4eade675c9f..e6c1dec80d13f45b3b1622d5ddc09197603ac8ef 100644 (file)
@@ -105,19 +105,20 @@ class ArtistsController(MediaControllerBase[Artist]):
         in_library_only: bool = False,
     ) -> UniqueList[Track]:
         """Return all/top tracks for an artist."""
-        full_artist = await self.get(item_id, provider_instance_id_or_domain)
-        db_items = (
-            await self.get_library_artist_tracks(full_artist.item_id)
-            if full_artist.provider == "library"
-            else []
+        # always check if we have a library item for this artist
+        library_artist = await self.get_library_item_by_prov_id(
+            item_id, provider_instance_id_or_domain
         )
+        if not library_artist:
+            return await self.get_provider_artist_toptracks(item_id, provider_instance_id_or_domain)
+        db_items = await self.get_library_artist_tracks(library_artist.item_id)
         result: UniqueList[Track] = UniqueList(db_items)
-        if full_artist.provider == "library" and in_library_only:
+        if in_library_only:
             # return in-library items only
             return result
         # return all (unique) items from all providers
         unique_ids: set[str] = set()
-        for provider_mapping in full_artist.provider_mappings:
+        for provider_mapping in library_artist.provider_mappings:
             provider_tracks = await self.get_provider_artist_toptracks(
                 provider_mapping.item_id, provider_mapping.provider_instance
             )
@@ -142,19 +143,20 @@ class ArtistsController(MediaControllerBase[Artist]):
         in_library_only: bool = False,
     ) -> UniqueList[Album]:
         """Return (all/most popular) albums for an artist."""
-        full_artist = await self.get(item_id, provider_instance_id_or_domain)
-        db_items = (
-            await self.get_library_artist_albums(full_artist.item_id)
-            if full_artist.provider == "library"
-            else []
+        # always check if we have a library item for this artist
+        library_artist = await self.get_library_item_by_prov_id(
+            item_id, provider_instance_id_or_domain
         )
+        if not library_artist:
+            return await self.get_provider_artist_albums(item_id, provider_instance_id_or_domain)
+        db_items = await self.get_library_artist_albums(library_artist.item_id)
         result: UniqueList[Album] = UniqueList(db_items)
-        if full_artist.provider == "library" and in_library_only:
+        if in_library_only:
             # return in-library items only
             return result
         # return all (unique) items from all providers
         unique_ids: set[str] = set()
-        for provider_mapping in full_artist.provider_mappings:
+        for provider_mapping in library_artist.provider_mappings:
             provider_albums = await self.get_provider_artist_albums(
                 provider_mapping.item_id, provider_mapping.provider_instance
             )