Fixes for global search (#1554)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 11 Aug 2024 17:04:49 +0000 (19:04 +0200)
committerGitHub <noreply@github.com>
Sun, 11 Aug 2024 17:04:49 +0000 (19:04 +0200)
Prefer library items in global search

music_assistant/client/music.py
music_assistant/server/controllers/media/base.py
music_assistant/server/controllers/music.py

index 9cdadb3a21425bafb39cf51d498a0615e911009e..5a57d247ab0aae3825785d16c06cd45743ee70de 100644 (file)
@@ -416,6 +416,7 @@ class Music:
         search_query: str,
         media_types: list[MediaType] = MediaType.ALL,
         limit: int = 50,
+        library_only: bool = False,
     ) -> SearchResults:
         """Perform global search for media items on all providers.
 
@@ -429,6 +430,7 @@ class Music:
                 search_query=search_query,
                 media_types=media_types,
                 limit=limit,
+                library_only=library_only,
             ),
         )
 
index 9e3444ea185a59b2e5abe8ac8b0034338dc1f050..4f077975a43439c70c0f5c3bf88d776f5ee3bdf9 100644 (file)
@@ -274,7 +274,7 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         # create safe search string
         search_query = search_query.replace("/", " ").replace("'", "")
         if provider_instance_id_or_domain == "library":
-            return [item async for item in await self.iter_library_items(search=search_query)]
+            return await self.library_items(search=search_query, limit=limit)
         prov = self.mass.get_provider(provider_instance_id_or_domain)
         if prov is None:
             return []
index 0dc7864cf6b64343feb4cf0479ae21e4c489b24d..4db16ee7eb1c5fa5aa0b04ddb80dd841df0a4657 100644 (file)
@@ -177,6 +177,7 @@ class MusicController(CoreController):
         search_query: str,
         media_types: list[MediaType] = MediaType.ALL,
         limit: int = 25,
+        library_only: bool = False,
     ) -> SearchResults:
         """Perform global search for media items on all providers.
 
@@ -219,8 +220,10 @@ class MusicController(CoreController):
                     else:
                         return SearchResults()
 
-        # include results from all (unique) music providers
+        # include results from library +  all (unique) music providers
+        search_providers = [] if library_only else self.get_unique_providers()
         results_per_provider: list[SearchResults] = await asyncio.gather(
+            self.search_library(search_query, media_types, limit=limit),
             *[
                 self.search_provider(
                     search_query,
@@ -228,8 +231,8 @@ class MusicController(CoreController):
                     media_types,
                     limit=limit,
                 )
-                for provider_instance in self.get_unique_providers()
-            ]
+                for provider_instance in search_providers
+            ],
         )
         # return result from all providers while keeping index
         # so the result is sorted as each provider delivered
@@ -278,7 +281,6 @@ class MusicController(CoreController):
         :param search_query: Search query
         :param provider_instance_id_or_domain: instance_id or domain of the provider
                                                to perform the search on.
-        :param provider_instance: instance id of the provider to perform the search on.
         :param media_types: A list of media_types to include.
         :param limit: number of items to return in the search (per type).
         """
@@ -311,6 +313,35 @@ class MusicController(CoreController):
             )
         return result
 
+    async def search_library(
+        self,
+        search_query: str,
+        media_types: list[MediaType],
+        limit: int = 10,
+    ) -> SearchResults:
+        """Perform search on the library.
+
+        :param search_query: Search query
+        :param media_types: A list of media_types to include.
+        :param limit: number of items to return in the search (per type).
+        """
+        result = SearchResults()
+        for media_type in media_types:
+            ctrl = self.get_controller(media_type)
+            search_results = await ctrl.search(search_query, "library", limit=limit)
+            if search_results:
+                if media_type == MediaType.ARTIST:
+                    result.artists = search_results
+                elif media_type == MediaType.ALBUM:
+                    result.albums = search_results
+                elif media_type == MediaType.TRACK:
+                    result.tracks = search_results
+                elif media_type == MediaType.PLAYLIST:
+                    result.playlists = search_results
+                elif media_type == MediaType.RADIO:
+                    result.radio = search_results
+        return result
+
     @api_command("music/browse")
     async def browse(self, path: str | None = None) -> list[MediaItemType]:
         """Browse Music providers."""