use less api calls for match logic
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 11 Aug 2024 22:43:35 +0000 (00:43 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 11 Aug 2024 22:43:35 +0000 (00:43 +0200)
music_assistant/server/controllers/media/albums.py
music_assistant/server/controllers/media/artists.py
music_assistant/server/controllers/media/base.py
music_assistant/server/controllers/media/tracks.py

index e5b45ba906c9e97d544c064c0fa31eb3df15db2a..57c226f2acfacea1aff4c28f62b617419d53bfb1 100644 (file)
@@ -395,31 +395,25 @@ class AlbumsController(MediaControllerBase[Album]):
                 "Trying to match album %s on provider %s", db_album.name, provider.name
             )
             match_found = False
-            for search_str in (
-                db_album.name,
-                f"{artist_name} - {db_album.name}",
-                f"{artist_name} {db_album.name}",
-            ):
-                if match_found:
-                    break
-                search_result = await self.search(search_str, provider.instance_id)
-                for search_result_item in search_result:
-                    if not search_result_item.available:
-                        continue
-                    if not compare_media_item(db_album, search_result_item):
-                        continue
-                    # we must fetch the full album version, search results can be simplified objects
-                    prov_album = await self.get_provider_item(
-                        search_result_item.item_id,
-                        search_result_item.provider,
-                        fallback=search_result_item,
-                    )
-                    if compare_album(db_album, prov_album):
-                        # 100% match, we update the db with the additional provider mapping(s)
-                        match_found = True
-                        for provider_mapping in search_result_item.provider_mappings:
-                            await self.add_provider_mapping(db_album.item_id, provider_mapping)
-                            db_album.provider_mappings.add(provider_mapping)
+            search_str = f"{artist_name} - {db_album.name}"
+            search_result = await self.search(search_str, provider.instance_id)
+            for search_result_item in search_result:
+                if not search_result_item.available:
+                    continue
+                if not compare_media_item(db_album, search_result_item):
+                    continue
+                # we must fetch the full album version, search results can be simplified objects
+                prov_album = await self.get_provider_item(
+                    search_result_item.item_id,
+                    search_result_item.provider,
+                    fallback=search_result_item,
+                )
+                if compare_album(db_album, prov_album):
+                    # 100% match, we update the db with the additional provider mapping(s)
+                    match_found = True
+                    for provider_mapping in search_result_item.provider_mappings:
+                        await self.add_provider_mapping(db_album.item_id, provider_mapping)
+                        db_album.provider_mappings.add(provider_mapping)
             return match_found
 
         # try to find match on all providers
index 52750a242929d8b1ad6140df50d0a7eb299b3225..bd38eed5c39e64ad7b9a53f95b91ffe9e3c90b12 100644 (file)
@@ -460,33 +460,27 @@ class ArtistsController(MediaControllerBase[Artist]):
                         provider_mapping.item_id, provider_mapping.provider_instance
                     )
         for ref_track in ref_tracks:
-            for search_str in (
-                f"{db_artist.name} - {ref_track.name}",
-                f"{db_artist.name} {ref_track.name}",
-                ref_track.name,
-            ):
-                search_results = await self.mass.music.tracks.search(search_str, provider.domain)
-                for search_result_item in search_results:
-                    if not compare_strings(search_result_item.name, ref_track.name, strict=True):
+            search_str = f"{db_artist.name} - {ref_track.name}"
+            search_results = await self.mass.music.tracks.search(search_str, provider.domain)
+            for search_result_item in search_results:
+                if not compare_strings(search_result_item.name, ref_track.name, strict=True):
+                    continue
+                # get matching artist from track
+                for search_item_artist in search_result_item.artists:
+                    if not compare_strings(search_item_artist.name, db_artist.name, strict=True):
                         continue
-                    # get matching artist from track
-                    for search_item_artist in search_result_item.artists:
-                        if not compare_strings(
-                            search_item_artist.name, db_artist.name, strict=True
-                        ):
-                            continue
-                        # 100% track match
-                        # get full artist details so we have all metadata
-                        prov_artist = await self.get_provider_item(
-                            search_item_artist.item_id,
-                            search_item_artist.provider,
-                            fallback=search_result_item,
-                        )
-                        # 100% match, we update the db with the additional provider mapping(s)
-                        for provider_mapping in prov_artist.provider_mappings:
-                            await self.add_provider_mapping(db_artist.item_id, provider_mapping)
-                            db_artist.provider_mappings.add(provider_mapping)
-                        return True
+                    # 100% track match
+                    # get full artist details so we have all metadata
+                    prov_artist = await self.get_provider_item(
+                        search_item_artist.item_id,
+                        search_item_artist.provider,
+                        fallback=search_result_item,
+                    )
+                    # 100% match, we update the db with the additional provider mapping(s)
+                    for provider_mapping in prov_artist.provider_mappings:
+                        await self.add_provider_mapping(db_artist.item_id, provider_mapping)
+                        db_artist.provider_mappings.add(provider_mapping)
+                    return True
         # try to get a match with some reference albums of this artist
         ref_albums = await self.mass.music.artists.albums(db_artist.item_id, db_artist.provider)
         if len(ref_albums) < 10:
@@ -501,29 +495,25 @@ class ArtistsController(MediaControllerBase[Artist]):
                 continue
             if not ref_album.artists:
                 continue
-            for search_str in (
-                ref_album.name,
-                f"{db_artist.name} - {ref_album.name}",
-                f"{db_artist.name} {ref_album.name}",
-            ):
-                search_result = await self.mass.music.albums.search(search_str, provider.domain)
-                for search_result_item in search_result:
-                    if not search_result_item.artists:
-                        continue
-                    if not compare_strings(search_result_item.name, ref_album.name):
-                        continue
-                    # artist must match 100%
-                    if not compare_artist(db_artist, search_result_item.artists[0]):
-                        continue
-                    # 100% match
-                    # get full artist details so we have all metadata
-                    prov_artist = await self.get_provider_item(
-                        search_result_item.artists[0].item_id,
-                        search_result_item.artists[0].provider,
-                        fallback=search_result_item,
-                    )
-                    await self._update_library_item(db_artist.item_id, prov_artist)
-                    return True
+            search_str = f"{db_artist.name} - {ref_album.name}"
+            search_result = await self.mass.music.albums.search(search_str, provider.domain)
+            for search_result_item in search_result:
+                if not search_result_item.artists:
+                    continue
+                if not compare_strings(search_result_item.name, ref_album.name):
+                    continue
+                # artist must match 100%
+                if not compare_artist(db_artist, search_result_item.artists[0]):
+                    continue
+                # 100% match
+                # get full artist details so we have all metadata
+                prov_artist = await self.get_provider_item(
+                    search_result_item.artists[0].item_id,
+                    search_result_item.artists[0].provider,
+                    fallback=search_result_item,
+                )
+                await self._update_library_item(db_artist.item_id, prov_artist)
+                return True
         return False
 
     def _artist_from_item_mapping(self, item: ItemMapping) -> Artist:
index 4f077975a43439c70c0f5c3bf88d776f5ee3bdf9..1dca9f02e1748ae1879179cd2b57cb7c3662300e 100644 (file)
@@ -286,7 +286,7 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
 
         # prefer cache items (if any)
         cache_key = f"{prov.lookup_key}.search.{self.media_type.value}.{search_query}.{limit}"
-        cache_key = cache_key.lower().replace("", "")
+        cache_key = cache_key.lower().replace(" ", "").strip()
         if (cache := await self.mass.cache.get(cache_key)) is not None:
             return [media_from_dict(x) for x in cache]
         # no items in cache - get listing from provider
index f9f724ac6927228664a1975dba45d0a2c95597e2..31a9e3d0530579bd8b8807dde235e01b1b0fa739 100644 (file)
@@ -282,28 +282,22 @@ class TracksController(MediaControllerBase[Track]):
         for artist in ref_track.artists:
             if matches:
                 break
-            for search_str in (
-                ref_track.name,
-                f"{artist.name} - {ref_track.name}",
-                f"{artist.name} {ref_track.name}",
-            ):
-                if matches:
-                    break
-                search_result = await self.search(search_str, provider.domain)
-                for search_result_item in search_result:
-                    if not search_result_item.available:
-                        continue
-                    # do a basic compare first
-                    if not compare_media_item(ref_track, search_result_item, strict=False):
-                        continue
-                    # we must fetch the full version, search results can be simplified objects
-                    prov_track = await self.get_provider_item(
-                        search_result_item.item_id,
-                        search_result_item.provider,
-                        fallback=search_result_item,
-                    )
-                    if compare_track(ref_track, prov_track, strict=strict, track_albums=ref_albums):
-                        matches.update(search_result_item.provider_mappings)
+            search_str = f"{artist.name} - {ref_track.name}"
+            search_result = await self.search(search_str, provider.domain)
+            for search_result_item in search_result:
+                if not search_result_item.available:
+                    continue
+                # do a basic compare first
+                if not compare_media_item(ref_track, search_result_item, strict=False):
+                    continue
+                # we must fetch the full version, search results can be simplified objects
+                prov_track = await self.get_provider_item(
+                    search_result_item.item_id,
+                    search_result_item.provider,
+                    fallback=search_result_item,
+                )
+                if compare_track(ref_track, prov_track, strict=strict, track_albums=ref_albums):
+                    matches.update(search_result_item.provider_mappings)
 
         if not matches:
             self.logger.debug(