示例#1
0
 async def search_artist_by_album(self, artistname, albumname=None, album_upc=None):
     """Retrieve musicbrainz artist id by providing the artist name and albumname or upc."""
     for searchartist in [
         re.sub(LUCENE_SPECIAL, r"\\\1", artistname),
         get_compare_string(artistname),
     ]:
         if album_upc:
             endpoint = "release"
             params = {"query": "barcode:%s" % album_upc}
         else:
             searchalbum = re.sub(LUCENE_SPECIAL, r"\\\1", albumname)
             endpoint = "release"
             params = {
                 "query": 'artist:"%s" AND release:"%s"'
                 % (searchartist, searchalbum)
             }
         result = await self.get_data(endpoint, params)
         if result and "releases" in result:
             for strictness in [True, False]:
                 for item in result["releases"]:
                     if album_upc or compare_strings(
                         item["title"], albumname, strictness
                     ):
                         for artist in item["artist-credit"]:
                             if compare_strings(
                                 artist["artist"]["name"], artistname, strictness
                             ):
                                 return artist["artist"]["id"]
                             for alias in artist.get("aliases", []):
                                 if compare_strings(
                                     alias["name"], artistname, strictness
                                 ):
                                     return artist["id"]
     return ""
示例#2
0
 async def search_artist_by_track(self, artistname, trackname=None, track_isrc=None):
     """Retrieve artist id by providing the artist name and trackname or track isrc."""
     endpoint = "recording"
     searchartist = re.sub(LUCENE_SPECIAL, r"\\\1", artistname)
     # searchartist = searchartist.replace('/','').replace('\\','').replace('-', '')
     if track_isrc:
         endpoint = "isrc/%s" % track_isrc
         params = {"inc": "artist-credits"}
     else:
         searchtrack = re.sub(LUCENE_SPECIAL, r"\\\1", trackname)
         endpoint = "recording"
         params = {"query": '"%s" AND artist:"%s"' % (searchtrack, searchartist)}
     result = await self.get_data(endpoint, params)
     if result and "recordings" in result:
         for strictness in [True, False]:
             for item in result["recordings"]:
                 if track_isrc or compare_strings(
                     item["title"], trackname, strictness
                 ):
                     for artist in item["artist-credit"]:
                         if compare_strings(
                             artist["artist"]["name"], artistname, strictness
                         ):
                             return artist["artist"]["id"]
                         for alias in artist.get("aliases", []):
                             if compare_strings(
                                 alias["name"], artistname, strictness
                             ):
                                 return artist["id"]
     return ""
示例#3
0
 async def _match_prov_artist(self, db_artist: Artist,
                              provider: MusicProvider):
     """Try to find matching artists on given provider for the provided (database) artist."""
     LOGGER.debug("Trying to match artist %s on provider %s",
                  db_artist.name, provider.name)
     # try to get a match with some reference tracks of this artist
     for ref_track in await self.get_artist_toptracks(
             db_artist.item_id, db_artist.provider):
         # make sure we have a full track
         if isinstance(ref_track.album, ItemMapping):
             ref_track = await self.get_track(ref_track.item_id,
                                              ref_track.provider)
         searchstr = "%s %s" % (db_artist.name, ref_track.name)
         search_results = await self.search_provider(searchstr,
                                                     provider.id,
                                                     [MediaType.Track],
                                                     limit=25)
         for search_result_item in search_results.tracks:
             if compare_track(search_result_item, ref_track):
                 # get matching artist from track
                 for search_item_artist in search_result_item.artists:
                     if compare_strings(db_artist.name,
                                        search_item_artist.name):
                         # 100% album match
                         # get full artist details so we have all metadata
                         prov_artist = await self._get_provider_artist(
                             search_item_artist.item_id,
                             search_item_artist.provider)
                         await self.mass.database.update_artist(
                             db_artist.item_id, prov_artist)
                         return True
     # try to get a match with some reference albums of this artist
     artist_albums = await self.get_artist_albums(db_artist.item_id,
                                                  db_artist.provider)
     for ref_album in artist_albums:
         if ref_album.album_type == AlbumType.Compilation:
             continue
         searchstr = "%s %s" % (db_artist.name, ref_album.name)
         search_result = await self.search_provider(searchstr,
                                                    provider.id,
                                                    [MediaType.Album],
                                                    limit=25)
         for search_result_item in search_result.albums:
             # artist must match 100%
             if not compare_strings(db_artist.name,
                                    search_result_item.artist.name):
                 continue
             if compare_album(search_result_item, ref_album):
                 # 100% album match
                 # get full artist details so we have all metadata
                 prov_artist = await self._get_provider_artist(
                     search_result_item.artist.item_id,
                     search_result_item.artist.provider,
                 )
                 await self.mass.database.update_artist(
                     db_artist.item_id, prov_artist)
                 return True
     return False
示例#4
0
 def new_cast_status(self, cast_status) -> None:
     """Handle updates of the cast status."""
     self.cast_status = cast_status
     self._is_speaker_group = (
         self._cast_info.is_audio_group and self._chromecast.mz_controller
         and self._chromecast.mz_controller.members and compare_strings(
             self._chromecast.mz_controller.members[0], self.player_id))
     self.update_state()
示例#5
0
    async def match_track(self, db_track: Track):
        """
        Try to find matching track on all providers for the provided (database) track_id.

        This is used to link objects of different providers/qualities together.
        """
        assert (db_track.provider == "database"
                ), "Matching only supported for database items!"
        if isinstance(db_track.album, ItemMapping):
            # matching only works if we have a full track object
            db_track = await self.mass.database.get_track(db_track.item_id)
        for provider in self.mass.get_providers(ProviderType.MUSIC_PROVIDER):
            if MediaType.Track not in provider.supported_mediatypes:
                continue
            LOGGER.debug("Trying to match track %s on provider %s",
                         db_track.name, provider.name)
            match_found = False
            for db_track_artist in db_track.artists:
                if match_found:
                    break
                searchstr = "%s %s" % (db_track_artist.name, db_track.name)
                if db_track.version:
                    searchstr += " " + db_track.version
                search_result = await self.search_provider(searchstr,
                                                           provider.id,
                                                           [MediaType.Track],
                                                           limit=25)
                for search_result_item in search_result.tracks:
                    if not search_result_item.available:
                        continue
                    if compare_track(search_result_item, db_track):
                        # 100% match, we can simply update the db with additional provider ids
                        match_found = True
                        await self.mass.database.update_track(
                            db_track.item_id, search_result_item)
                        # while we're here, also match the artist
                        if db_track_artist.provider == "database":
                            for artist in search_result_item.artists:
                                if not compare_strings(db_track_artist.name,
                                                       artist.name):
                                    continue
                                prov_artist = await self._get_provider_artist(
                                    artist.item_id, artist.provider)
                                await self.mass.database.update_artist(
                                    db_track_artist.item_id, prov_artist)

            if not match_found:
                LOGGER.debug(
                    "Could not find match for Track %s on provider %s",
                    db_track.name,
                    provider.name,
                )
示例#6
0
 async def get_album_versions(self, item_id: str,
                              provider_id: str) -> Set[Album]:
     """Return all versions of an album we can find on all providers."""
     album = await self.get_album(item_id, provider_id)
     provider_ids = {
         item.id
         for item in self.mass.get_providers(ProviderType.MUSIC_PROVIDER)
     }
     search_query = f"{album.artist.name} {album.name}"
     return {
         prov_item
         for prov_items in await asyncio.gather(*[
             self.search_provider(search_query, prov_id, [MediaType.Album],
                                  25) for prov_id in provider_ids
         ]) for prov_item in prov_items.albums
         if compare_strings(prov_item.artist.name, album.artist.name)
     }