From 1a84ef38a4ff9244c4a33052777750653cca4208 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Mon, 12 Aug 2024 00:43:35 +0200 Subject: [PATCH] use less api calls for match logic --- .../server/controllers/media/albums.py | 44 ++++------ .../server/controllers/media/artists.py | 88 ++++++++----------- .../server/controllers/media/base.py | 2 +- .../server/controllers/media/tracks.py | 38 ++++---- 4 files changed, 75 insertions(+), 97 deletions(-) diff --git a/music_assistant/server/controllers/media/albums.py b/music_assistant/server/controllers/media/albums.py index e5b45ba9..57c226f2 100644 --- a/music_assistant/server/controllers/media/albums.py +++ b/music_assistant/server/controllers/media/albums.py @@ -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 diff --git a/music_assistant/server/controllers/media/artists.py b/music_assistant/server/controllers/media/artists.py index 52750a24..bd38eed5 100644 --- a/music_assistant/server/controllers/media/artists.py +++ b/music_assistant/server/controllers/media/artists.py @@ -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: diff --git a/music_assistant/server/controllers/media/base.py b/music_assistant/server/controllers/media/base.py index 4f077975..1dca9f02 100644 --- a/music_assistant/server/controllers/media/base.py +++ b/music_assistant/server/controllers/media/base.py @@ -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 diff --git a/music_assistant/server/controllers/media/tracks.py b/music_assistant/server/controllers/media/tracks.py index f9f724ac..31a9e3d0 100644 --- a/music_assistant/server/controllers/media/tracks.py +++ b/music_assistant/server/controllers/media/tracks.py @@ -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( -- 2.34.1