Fix librray queries should only get items with actual in_library mappings attached
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 16 Dec 2025 23:29:00 +0000 (00:29 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 16 Dec 2025 23:29:00 +0000 (00:29 +0100)
music_assistant/controllers/media/albums.py
music_assistant/controllers/media/artists.py
music_assistant/controllers/media/audiobooks.py
music_assistant/controllers/media/base.py
music_assistant/controllers/media/podcasts.py
music_assistant/controllers/media/tracks.py

index a7a4f785f0e58e63d7e2c300971fbe9b6b87efb7..718fbd48b50ea4bd102504bb96e62f12462d5e3b 100644 (file)
@@ -170,6 +170,7 @@ class AlbumsController(MediaControllerBase[Album]):
             extra_query_parts=extra_query_parts,
             extra_query_params=extra_query_params,
             extra_join_parts=extra_join_parts,
+            in_library_only=True,
         )
 
         # Calculate how many more items we need to reach the original limit
index d9acdd9ee80798030c6650b81443624e10b5efab..e1d0d21652513a0a5cf850a9033d720aa3ad7ccb 100644 (file)
@@ -103,6 +103,7 @@ class ArtistsController(MediaControllerBase[Artist]):
             provider_filter=self._ensure_provider_filter(provider),
             extra_query_parts=extra_query_parts,
             extra_query_params=extra_query_params,
+            in_library_only=True,
         )
 
     async def tracks(
index 54d37657dab05b2c874e4266e947ae10c34cc184..b21df2552067f812f1bc5bf9382782009de47ac4 100644 (file)
@@ -92,6 +92,7 @@ class AudiobooksController(MediaControllerBase[Audiobook]):
             provider_filter=self._ensure_provider_filter(provider),
             extra_query_parts=extra_query_parts,
             extra_query_params=extra_query_params,
+            in_library_only=True,
         )
         if search and len(result) < 25 and not offset:
             # append author items to result
@@ -107,6 +108,7 @@ class AudiobooksController(MediaControllerBase[Audiobook]):
                 provider_filter=self._ensure_provider_filter(provider),
                 extra_query_parts=extra_query_parts,
                 extra_query_params=extra_query_params,
+                in_library_only=True,
             )
         return result
 
index 517f75ddbf979cdb6b9892ed33d0be9fc7bc58a2..cd17cd070a9536db8d2a83cf4ed2e875159716a0 100644 (file)
@@ -257,6 +257,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
             provider_filter=self._ensure_provider_filter(provider),
             extra_query_parts=[extra_query] if extra_query else None,
             extra_query_params=extra_query_params,
+            in_library_only=True,
         )
 
     async def iter_library_items(
@@ -762,6 +763,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
         extra_query_parts: list[str] | None = None,
         extra_query_params: dict[str, Any] | None = None,
         extra_join_parts: list[str] | None = None,
+        in_library_only: bool = False,
     ) -> list[ItemCls]:
         """Fetch MediaItem records from database by building the query."""
         query_params = extra_query_params or {}
@@ -777,6 +779,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
                 favorite=favorite,
                 search=search,
                 provider_filter=provider_filter,
+                in_library_only=in_library_only,
                 limit=limit,
             )
         else:
@@ -788,6 +791,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
                 favorite=favorite,
                 search=search,
                 provider_filter=provider_filter,
+                in_library_only=in_library_only,
             )
         # build and execute final query
         sql_query = self._build_final_query(query_parts, join_parts, order_by)
@@ -822,6 +826,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
         favorite: bool | None,
         search: str | None,
         provider_filter: list[str] | None,
+        in_library_only: bool,
         limit: int,
     ) -> None:
         """Build a fast random subquery with all filters applied."""
@@ -836,6 +841,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
             favorite=favorite,
             search=search,
             provider_filter=provider_filter,
+            in_library_only=in_library_only,
         )
 
         # Build the subquery
@@ -864,6 +870,7 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
         favorite: bool | None,
         search: str | None,
         provider_filter: list[str] | None,
+        in_library_only: bool,
     ) -> None:
         """Apply search, favorite, and provider filters."""
         # handle search
@@ -881,9 +888,15 @@ class MediaControllerBase[ItemCls: "MediaItemType"](metaclass=ABCMeta):
             join_parts.append(
                 f"JOIN provider_mappings ON provider_mappings.item_id = {self.db_table}.item_id "
                 f"AND provider_mappings.media_type = '{self.media_type.value}' "
-                "AND provider_mappings.in_library = 1 "
+                f"AND provider_mappings.in_library = {in_library_only} "
                 f"AND ({' OR '.join(provider_conditions)})"
             )
+        elif in_library_only:
+            join_parts.append(
+                f"JOIN provider_mappings ON provider_mappings.item_id = {self.db_table}.item_id "
+                f"AND provider_mappings.media_type = '{self.media_type.value}' "
+                f"AND provider_mappings.in_library = {in_library_only} "
+            )
 
     @final
     def _build_final_query(
index 7530b95894176e92a4ec12f0bfd94154a52804b7..6fa8122c1079a02c0db411e034a64e95a468d82f 100644 (file)
@@ -75,6 +75,7 @@ class PodcastsController(MediaControllerBase[Podcast]):
             provider_filter=self._ensure_provider_filter(provider),
             extra_query_parts=extra_query_parts,
             extra_query_params=extra_query_params,
+            in_library_only=True,
         )
         if search and len(result) < 25 and not offset:
             # append publisher items to result
@@ -90,6 +91,7 @@ class PodcastsController(MediaControllerBase[Podcast]):
                 provider_filter=self._ensure_provider_filter(provider),
                 extra_query_parts=extra_query_parts,
                 extra_query_params=extra_query_params,
+                in_library_only=True,
             )
         return result
 
index 7a9e555f5eed01924d7a0764641ae084b7bd989f..4e8daf50e3cbccab4c8e2d5b86d455e3ef325294 100644 (file)
@@ -207,6 +207,7 @@ class TracksController(MediaControllerBase[Track]):
             extra_query_parts=extra_query_parts,
             extra_query_params=extra_query_params,
             extra_join_parts=extra_join_parts,
+            in_library_only=True,
         )
         if search and len(result) < 25 and not offset:
             # append artist items to result
@@ -227,6 +228,7 @@ class TracksController(MediaControllerBase[Track]):
                 extra_query_parts=extra_query_parts,
                 extra_query_params=extra_query_params,
                 extra_join_parts=extra_join_parts,
+                in_library_only=True,
             ):
                 # prevent duplicates (when artist is also in the title)
                 if _track.uri not in existing_uris: