diff --git a/music_assistant/common/models/media_items.py b/music_assistant/common/models/media_items.py index ed0ecc0a3..8cdd22bdc 100755 --- a/music_assistant/common/models/media_items.py +++ b/music_assistant/common/models/media_items.py @@ -20,7 +20,7 @@ MetadataTypes = int | bool | str | list[str] -@dataclass +@dataclass(kw_only=True) class AudioFormat(DataClassDictMixin): """Model for AudioFormat details.""" @@ -54,7 +54,7 @@ def pcm_sample_size(self) -> int: return int(self.sample_rate * (self.bit_depth / 8) * self.channels) -@dataclass(frozen=True) +@dataclass(frozen=True, kw_only=True) class ProviderMapping(DataClassDictMixin): """Model for a MediaItem's provider mapping details.""" @@ -89,7 +89,7 @@ def __eq__(self, other: ProviderMapping) -> bool: return self.provider_instance == other.provider_instance and self.item_id == other.item_id -@dataclass(frozen=True) +@dataclass(frozen=True, kw_only=True) class MediaItemLink(DataClassDictMixin): """Model for a link.""" @@ -105,7 +105,7 @@ def __eq__(self, other: MediaItemLink) -> bool: return self.url == other.url -@dataclass(frozen=True) +@dataclass(frozen=True, kw_only=True) class MediaItemImage(DataClassDictMixin): """Model for a image.""" @@ -124,7 +124,7 @@ def __eq__(self, other: MediaItemImage) -> bool: return self.__hash__() == other.__hash__() -@dataclass(frozen=True) +@dataclass(frozen=True, kw_only=True) class MediaItemChapter(DataClassDictMixin): """Model for a chapter.""" @@ -142,7 +142,7 @@ def __eq__(self, other: MediaItemChapter) -> bool: return self.chapter_id == other.chapter_id -@dataclass +@dataclass(kw_only=True) class MediaItemMetadata(DataClassDictMixin): """Model for a MediaItem's metadata.""" @@ -247,7 +247,7 @@ def __eq__(self, other: ItemMapping) -> bool: return self.uri == other.uri -@dataclass +@dataclass(kw_only=True) class ItemMapping(DataClassDictMixin): """Representation of a minimized item object.""" @@ -395,7 +395,7 @@ def __post_init__(self): MediaItemType = Artist | Album | Track | Radio | Playlist | BrowseFolder -@dataclass +@dataclass(kw_only=True) class PagedItems(DataClassDictMixin): """Model for a paged listing.""" @@ -417,7 +417,7 @@ def parse(cls, raw: dict[str, Any], item_type: type) -> PagedItems: ) -@dataclass +@dataclass(kw_only=True) class SearchResults(DataClassDictMixin): """Model for results from a search query.""" @@ -443,7 +443,7 @@ def media_from_dict(media_item: dict) -> MediaItemType: return MediaItem.from_dict(media_item) -@dataclass +@dataclass(kw_only=True) class StreamDetails(DataClassDictMixin): """Model for streamdetails.""" diff --git a/music_assistant/server/controllers/media/base.py b/music_assistant/server/controllers/media/base.py index 6156bcf04..d9ba03a34 100644 --- a/music_assistant/server/controllers/media/base.py +++ b/music_assistant/server/controllers/media/base.py @@ -122,7 +122,7 @@ async def library_items( total = offset + count else: total = await self.mass.music.database.get_count_from_query(sql_query, params) - return PagedItems(items, count, limit, offset, total) + return PagedItems(items=items, count=count, limit=limit, offset=offset, total=total) async def iter_library_items( self, diff --git a/music_assistant/server/controllers/metadata.py b/music_assistant/server/controllers/metadata.py index a72088039..d6b8c0524 100755 --- a/music_assistant/server/controllers/metadata.py +++ b/music_assistant/server/controllers/metadata.py @@ -213,7 +213,9 @@ async def get_playlist_metadata(self, playlist: Playlist) -> None: img_data = await create_collage(self.mass, list(images)) async with aiofiles.open(img_path, "wb") as _file: await _file.write(img_data) - playlist.metadata.images = [MediaItemImage(ImageType.THUMB, img_path, "file")] + playlist.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=img_path, provider="file") + ] except Exception as err: LOGGER.debug("Error while creating playlist image", exc_info=err) # set timestamp, used to determine when this function was last called diff --git a/music_assistant/server/models/music_provider.py b/music_assistant/server/models/music_provider.py index d256b6595..b68a8a9c5 100644 --- a/music_assistant/server/models/music_provider.py +++ b/music_assistant/server/models/music_provider.py @@ -427,7 +427,9 @@ async def sync_library(self, media_types: tuple[MediaType, ...]) -> None: ) cur_db_ids.add(library_item.item_id) except MusicAssistantError as err: - self.logger.warning("Skipping sync of item %s: %s", prov_item.uri, str(err)) + self.logger.warning( + "Skipping sync of item %s - error details: %s", prov_item.uri, str(err) + ) # process deletions (= no longer in library) cache_key = f"library_items.{media_type}.{self.instance_id}" diff --git a/music_assistant/server/providers/deezer/__init__.py b/music_assistant/server/providers/deezer/__init__.py index 091ac8661..b48aa88ba 100644 --- a/music_assistant/server/providers/deezer/__init__.py +++ b/music_assistant/server/providers/deezer/__init__.py @@ -546,17 +546,17 @@ def parse_track( duration=track.duration, artists=[ ItemMapping( - MediaType.ARTIST, - str(track.artist.id), - self.instance_id, - track.artist.name, + media_type=MediaType.ARTIST, + item_id=str(track.artist.id), + provider=self.domain, + name=track.artist.name, ) ], album=ItemMapping( - MediaType.ALBUM, - str(track.album.id), - self.instance_id, - track.album.title, + media_type=MediaType.ALBUM, + item_id=str(track.album.id), + provider=self.domain, + name=track.album.title, ), provider_mappings={ ProviderMapping( diff --git a/music_assistant/server/providers/fanarttv/__init__.py b/music_assistant/server/providers/fanarttv/__init__.py index f3b00077d..5c04e8278 100644 --- a/music_assistant/server/providers/fanarttv/__init__.py +++ b/music_assistant/server/providers/fanarttv/__init__.py @@ -91,7 +91,7 @@ async def get_artist_metadata(self, artist: Artist) -> MediaItemMetadata | None: if not items: continue for item in items: - metadata.images.append(MediaItemImage(img_type, item["url"])) + metadata.images.append(MediaItemImage(type=img_type, path=item["url"])) return metadata return None @@ -110,7 +110,7 @@ async def get_album_metadata(self, album: Album) -> MediaItemMetadata | None: if not items: continue for item in items: - metadata.images.append(MediaItemImage(img_type, item["url"])) + metadata.images.append(MediaItemImage(type=img_type, path=item["url"])) return metadata return None diff --git a/music_assistant/server/providers/filesystem_local/base.py b/music_assistant/server/providers/filesystem_local/base.py index 3d2041242..b7865c840 100644 --- a/music_assistant/server/providers/filesystem_local/base.py +++ b/music_assistant/server/providers/filesystem_local/base.py @@ -746,7 +746,7 @@ async def _parse_track( # much space and bandwidth. Instead we set the filename as value so the image can # be retrieved later in realtime. track.metadata.images = [ - MediaItemImage(ImageType.THUMB, file_item.path, self.instance_id) + MediaItemImage(type=ImageType.THUMB, url=file_item.path, provider=self.instance_id) ] if track.album and not track.album.metadata.images: @@ -819,7 +819,12 @@ async def _parse_artist( provider=self.instance_id, name=name, provider_mappings={ - ProviderMapping(artist_path, self.instance_id, self.instance_id, url=artist_path) + ProviderMapping( + item_id=artist_path, + provider_domain=self.domain, + provider_instance=self.instance_id, + url=artist_path, + ) }, mbid=VARIOUS_ARTISTS_ID_MBID if compare_strings(name, VARIOUS_ARTISTS_NAME) else None, ) @@ -876,7 +881,11 @@ async def _parse_album( artists=artists, provider_mappings={ ProviderMapping( - album_path, self.instance_id, self.instance_id, url=album_path, barcode=barcode + item_id=album_path, + provider_domain=self.instance_id, + provider_instance=self.instance_id, + url=album_path, + barcode=barcode, ) }, ) @@ -933,12 +942,18 @@ async def _get_local_images(self, folder: str) -> list[MediaItemImage]: if item.ext != ext: continue try: - images.append(MediaItemImage(ImageType(item.name), item.path, self.instance_id)) + images.append( + MediaItemImage( + type=ImageType(item.name), path=item.path, provider=self.instance_id + ) + ) except ValueError: for filename in ("folder", "cover", "albumart", "artist"): if item.name.lower().startswith(filename): images.append( - MediaItemImage(ImageType.THUMB, item.path, self.instance_id) + MediaItemImage( + type=ImageType.THUMB, path=item.path, provider=self.instance_id + ) ) break return images diff --git a/music_assistant/server/providers/plex/__init__.py b/music_assistant/server/providers/plex/__init__.py index 278efbf1c..585858b90 100644 --- a/music_assistant/server/providers/plex/__init__.py +++ b/music_assistant/server/providers/plex/__init__.py @@ -211,10 +211,10 @@ async def _get_data(self, key, cls=None): def _get_item_mapping(self, media_type: MediaType, key: str, name: str) -> ItemMapping: return ItemMapping( - media_type, - key, - self.instance_id, - name, + media_type=media_type, + item_id=key, + provider=self.instance_id, + name=name, ) async def _get_or_create_artist_by_name(self, artist_name) -> Artist: @@ -318,12 +318,16 @@ async def _parse_album(self, plex_album: PlexAlbum) -> Album: if plex_album.year: album.year = plex_album.year if thumb := plex_album.firstAttr("thumb", "parentThumb", "grandparentThumb"): - album.metadata.images = [MediaItemImage(ImageType.THUMB, thumb, self.instance_id)] + album.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, url=thumb, provider=self.instance_id) + ] if plex_album.summary: album.metadata.description = plex_album.summary album.artists.append( - self._get_item_mapping(MediaType.ARTIST, plex_album.parentKey, plex_album.parentTitle) + self._get_item_mapping( + type=MediaType.ARTIST, url=plex_album.parentKey, provider=plex_album.parentTitle + ) ) return album @@ -348,7 +352,9 @@ async def _parse_artist(self, plex_artist: PlexArtist) -> Artist: if plex_artist.summary: artist.metadata.description = plex_artist.summary if thumb := plex_artist.firstAttr("thumb", "parentThumb", "grandparentThumb"): - artist.metadata.images = [MediaItemImage(ImageType.THUMB, thumb, self.instance_id)] + artist.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=thumb, url=self.instance_id) + ] return artist async def _parse_playlist(self, plex_playlist: PlexPlaylist) -> Playlist: @@ -369,7 +375,9 @@ async def _parse_playlist(self, plex_playlist: PlexPlaylist) -> Playlist: if plex_playlist.summary: playlist.metadata.description = plex_playlist.summary if thumb := plex_playlist.firstAttr("thumb", "parentThumb", "grandparentThumb"): - playlist.metadata.images = [MediaItemImage(ImageType.THUMB, thumb, self.instance_id)] + playlist.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, url=thumb, provider=self.instance_id) + ] playlist.is_editable = True return playlist @@ -429,7 +437,9 @@ async def _parse_track( raise InvalidDataError("No artist was found for track") if thumb := plex_track.firstAttr("thumb", "parentThumb", "grandparentThumb"): - track.metadata.images = [MediaItemImage(ImageType.THUMB, thumb, self.instance_id)] + track.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, url=thumb, provider=self.instance_id) + ] if plex_track.parentKey: track.album = self._get_item_mapping( MediaType.ALBUM, plex_track.parentKey, plex_track.parentKey @@ -439,7 +449,10 @@ async def _parse_track( if plex_track.chapters: track.metadata.chapters = [ MediaItemChapter( - plex_chapter.id, plex_chapter.start, plex_chapter.end, plex_chapter.title + chapter_id=plex_chapter.id, + position_start=plex_chapter.start, + position_end=plex_chapter.end, + title=plex_chapter.title, ) for plex_chapter in plex_track.chapters ] diff --git a/music_assistant/server/providers/qobuz/__init__.py b/music_assistant/server/providers/qobuz/__init__.py index b77f543a8..3e3d63d92 100644 --- a/music_assistant/server/providers/qobuz/__init__.py +++ b/music_assistant/server/providers/qobuz/__init__.py @@ -454,7 +454,7 @@ async def _parse_artist(self, artist_obj: dict): artist.mbid = VARIOUS_ARTISTS_ID_MBID artist.name = VARIOUS_ARTISTS_NAME if img := self.__get_image(artist_obj): - artist.metadata.images = [MediaItemImage(ImageType.THUMB, img)] + artist.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img)] if artist_obj.get("biography"): artist.metadata.description = artist_obj["biography"].get("content") return artist @@ -504,7 +504,7 @@ async def _parse_album(self, album_obj: dict, artist_obj: dict = None): if "genre" in album_obj: album.metadata.genres = {album_obj["genre"]["name"]} if img := self.__get_image(album_obj): - album.metadata.images = [MediaItemImage(ImageType.THUMB, img)] + album.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img)] if "label" in album_obj: album.metadata.label = album_obj["label"]["name"] if (released_at := album_obj.get("released_at")) and released_at != 0: @@ -592,7 +592,7 @@ async def _parse_track(self, track_obj: dict) -> Track | AlbumTrack | PlaylistTr if track_obj.get("parental_warning"): track.metadata.explicit = True if img := self.__get_image(track_obj): - track.metadata.images = [MediaItemImage(ImageType.THUMB, img)] + track.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img)] return track @@ -619,7 +619,7 @@ async def _parse_playlist(self, playlist_obj): or playlist_obj["is_collaborative"] ) if img := self.__get_image(playlist_obj): - playlist.metadata.images = [MediaItemImage(ImageType.THUMB, img)] + playlist.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img)] playlist.metadata.checksum = str(playlist_obj["updated_at"]) return playlist diff --git a/music_assistant/server/providers/radiobrowser/__init__.py b/music_assistant/server/providers/radiobrowser/__init__.py index 3be46a9ef..db693583e 100644 --- a/music_assistant/server/providers/radiobrowser/__init__.py +++ b/music_assistant/server/providers/radiobrowser/__init__.py @@ -199,7 +199,9 @@ async def browse(self, path: str) -> BrowseFolder: name="", label=country.name, ) - folder.metadata.images = [MediaItemImage(ImageType.THUMB, country.favicon)] + folder.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=country.favicon) + ] sub_items.append(folder) return BrowseFolder( item_id="country", @@ -313,8 +315,8 @@ async def _parse_radio(self, radio_obj: dict) -> Radio: ) radio.metadata.label = radio_obj.tags radio.metadata.popularity = radio_obj.votes - radio.metadata.links = [MediaItemLink(LinkType.WEBSITE, radio_obj.homepage)] - radio.metadata.images = [MediaItemImage(ImageType.THUMB, radio_obj.favicon)] + radio.metadata.links = [MediaItemLink(type=LinkType.WEBSITE, url=radio_obj.homepage)] + radio.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=radio_obj.favicon)] return radio diff --git a/music_assistant/server/providers/soundcloud/__init__.py b/music_assistant/server/providers/soundcloud/__init__.py index bbb1c6a1f..0a8021bbb 100644 --- a/music_assistant/server/providers/soundcloud/__init__.py +++ b/music_assistant/server/providers/soundcloud/__init__.py @@ -318,7 +318,7 @@ async def _parse_artist(self, artist_obj: dict) -> Artist: artist.metadata.description = artist_obj["description"] if artist_obj.get("avatar_url"): img_url = artist_obj["avatar_url"] - artist.metadata.images = [MediaItemImage(ImageType.THUMB, img_url)] + artist.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img_url)] return artist async def _parse_playlist(self, playlist_obj: dict) -> Playlist: @@ -340,7 +340,7 @@ async def _parse_playlist(self, playlist_obj: dict) -> Playlist: playlist.metadata.description = playlist_obj["description"] if playlist_obj.get("artwork_url"): playlist.metadata.images = [ - MediaItemImage(ImageType.THUMB, playlist_obj["artwork_url"]) + MediaItemImage(type=ImageType.THUMB, path=playlist_obj["artwork_url"]) ] if playlist_obj.get("genre"): playlist.metadata.genres = playlist_obj["genre"] @@ -380,7 +380,9 @@ async def _parse_track( track.artists.append(artist) if track_obj.get("artwork_url"): - track.metadata.images = [MediaItemImage(ImageType.THUMB, track_obj["artwork_url"])] + track.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=track_obj["artwork_url"]) + ] if track_obj.get("description"): track.metadata.description = track_obj["description"] if track_obj.get("genre"): diff --git a/music_assistant/server/providers/spotify/__init__.py b/music_assistant/server/providers/spotify/__init__.py index da95d07b3..96ad65f01 100644 --- a/music_assistant/server/providers/spotify/__init__.py +++ b/music_assistant/server/providers/spotify/__init__.py @@ -422,7 +422,7 @@ async def _parse_artist(self, artist_obj): for img in artist_obj["images"]: img_url = img["url"] if "2a96cbd8b46e442fc41c2b86b821562f" not in img_url: - artist.metadata.images = [MediaItemImage(ImageType.THUMB, img_url)] + artist.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img_url)] break return artist @@ -459,7 +459,9 @@ async def _parse_album(self, album_obj: dict): if "genres" in album_obj: album.metadata.genre = set(album_obj["genres"]) if album_obj.get("images"): - album.metadata.images = [MediaItemImage(ImageType.THUMB, album_obj["images"][0]["url"])] + album.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=album_obj["images"][0]["url"]) + ] if "label" in album_obj: album.metadata.label = album_obj["label"] if album_obj.get("release_date"): @@ -527,7 +529,9 @@ async def _parse_track( track.album = await self._parse_album(track_obj["album"]) if track_obj["album"].get("images"): track.metadata.images = [ - MediaItemImage(ImageType.THUMB, track_obj["album"]["images"][0]["url"]) + MediaItemImage( + type=ImageType.THUMB, path=track_obj["album"]["images"][0]["url"] + ) ] if track_obj.get("copyright"): track.metadata.copyright = track_obj["copyright"] @@ -558,7 +562,7 @@ async def _parse_playlist(self, playlist_obj): ) if playlist_obj.get("images"): playlist.metadata.images = [ - MediaItemImage(ImageType.THUMB, playlist_obj["images"][0]["url"]) + MediaItemImage(type=ImageType.THUMB, path=playlist_obj["images"][0]["url"]) ] playlist.metadata.checksum = str(playlist_obj["snapshot_id"]) return playlist diff --git a/music_assistant/server/providers/theaudiodb/__init__.py b/music_assistant/server/providers/theaudiodb/__init__.py index 82bdb2ab7..9c53a9cf5 100644 --- a/music_assistant/server/providers/theaudiodb/__init__.py +++ b/music_assistant/server/providers/theaudiodb/__init__.py @@ -237,7 +237,7 @@ def __parse_artist(self, artist_obj: dict[str, Any]) -> MediaItemMetadata: metadata.links = set() for key, link_type in LINK_MAPPING.items(): if link := artist_obj.get(key): - metadata.links.add(MediaItemLink(link_type, link)) + metadata.links.add(MediaItemLink(type=link_type, url=link)) # description/biography if desc := artist_obj.get(f"strBiography{self.mass.metadata.preferred_language}"): metadata.description = desc @@ -248,7 +248,7 @@ def __parse_artist(self, artist_obj: dict[str, Any]) -> MediaItemMetadata: for key, img_type in IMG_MAPPING.items(): for postfix in ("", "2", "3", "4", "5", "6", "7", "8", "9", "10"): if img := artist_obj.get(f"{key}{postfix}"): - metadata.images.append(MediaItemImage(img_type, img)) + metadata.images.append(MediaItemImage(type=img_type, path=img)) else: break return metadata @@ -266,11 +266,11 @@ def __parse_album(self, album_obj: dict[str, Any]) -> MediaItemMetadata: metadata.links = set() if link := album_obj.get("strWikipediaID"): metadata.links.add( - MediaItemLink(LinkType.WIKIPEDIA, f"https://wikipedia.org/wiki/{link}") + MediaItemLink(type=LinkType.WIKIPEDIA, url=f"https://wikipedia.org/wiki/{link}") ) if link := album_obj.get("strAllMusicID"): metadata.links.add( - MediaItemLink(LinkType.ALLMUSIC, f"https://www.allmusic.com/album/{link}") + MediaItemLink(type=LinkType.ALLMUSIC, url=f"https://www.allmusic.com/album/{link}") ) # description @@ -284,7 +284,7 @@ def __parse_album(self, album_obj: dict[str, Any]) -> MediaItemMetadata: for key, img_type in IMG_MAPPING.items(): for postfix in ("", "2", "3", "4", "5", "6", "7", "8", "9", "10"): if img := album_obj.get(f"{key}{postfix}"): - metadata.images.append(MediaItemImage(img_type, img)) + metadata.images.append(MediaItemImage(type=img_type, path=img)) else: break return metadata @@ -308,7 +308,7 @@ def __parse_track(self, track_obj: dict[str, Any]) -> MediaItemMetadata: for key, img_type in IMG_MAPPING.items(): for postfix in ("", "2", "3", "4", "5", "6", "7", "8", "9", "10"): if img := track_obj.get(f"{key}{postfix}"): - metadata.images.append(MediaItemImage(img_type, img)) + metadata.images.append(MediaItemImage(type=img_type, path=img)) else: break return metadata diff --git a/music_assistant/server/providers/tidal/__init__.py b/music_assistant/server/providers/tidal/__init__.py index 96f0899b2..9e020e222 100644 --- a/music_assistant/server/providers/tidal/__init__.py +++ b/music_assistant/server/providers/tidal/__init__.py @@ -494,8 +494,8 @@ async def _parse_artist(self, artist_obj: TidalArtist, full_details: bool = Fals image_url = await self._get_image_url(artist_obj, 750) artist.metadata.images = [ MediaItemImage( - ImageType.THUMB, - image_url, + type=ImageType.THUMB, + path=image_url, ) ] except Exception: @@ -548,8 +548,8 @@ async def _parse_album(self, album_obj: TidalAlbum, full_details: bool = False) image_url = await self._get_image_url(album_obj, 1280) album.metadata.images = [ MediaItemImage( - ImageType.THUMB, - image_url, + type=ImageType.THUMB, + path=image_url, ) ] except Exception: @@ -649,8 +649,8 @@ async def _parse_playlist( image_url = await self._get_image_url(playlist_obj, 1080) playlist.metadata.images = [ MediaItemImage( - ImageType.THUMB, - image_url, + type=ImageType.THUMB, + path=image_url, ) ] except Exception: diff --git a/music_assistant/server/providers/tunein/__init__.py b/music_assistant/server/providers/tunein/__init__.py index 46379fc0e..a10e7f3bf 100644 --- a/music_assistant/server/providers/tunein/__init__.py +++ b/music_assistant/server/providers/tunein/__init__.py @@ -203,9 +203,9 @@ async def _parse_radio( radio.metadata.description = details["text"] # images if img := details.get("image"): - radio.metadata.images = [MediaItemImage(ImageType.THUMB, img)] + radio.metadata.images = [MediaItemImage(type=ImageType.THUMB, path=img)] if img := details.get("logo"): - radio.metadata.images = [MediaItemImage(ImageType.LOGO, img)] + radio.metadata.images = [MediaItemImage(type=ImageType.LOGO, path=img)] return radio async def get_stream_details(self, item_id: str) -> StreamDetails: diff --git a/music_assistant/server/providers/url/__init__.py b/music_assistant/server/providers/url/__init__.py index 65bdd12f3..abe85c53b 100644 --- a/music_assistant/server/providers/url/__init__.py +++ b/music_assistant/server/providers/url/__init__.py @@ -83,7 +83,12 @@ async def get_artist(self, prov_artist_id: str) -> Track: provider=self.domain, name=artist, provider_mappings={ - ProviderMapping(artist, self.domain, self.instance_id, available=False) + ProviderMapping( + item_id=artist, + provider_domain=self.domain, + provider_instance=self.instance_id, + available=False, + ) }, ) @@ -137,7 +142,9 @@ async def parse_item( ) if media_info.has_cover_image: - media_item.metadata.images = [MediaItemImage(ImageType.THUMB, url, True)] + media_item.metadata.images = [ + MediaItemImage(type=ImageType.THUMB, path=url, provider="embedded") + ] return media_item async def _get_media_info( diff --git a/music_assistant/server/providers/ytmusic/__init__.py b/music_assistant/server/providers/ytmusic/__init__.py index e215ce871..f2385e0da 100644 --- a/music_assistant/server/providers/ytmusic/__init__.py +++ b/music_assistant/server/providers/ytmusic/__init__.py @@ -848,7 +848,7 @@ def _get_artist_item_mapping(self, artist_obj: dict) -> ItemMapping: async def _parse_thumbnails(cls, thumbnails_obj: dict) -> list[MediaItemImage]: """Parse and sort a list of thumbnails and return the highest quality.""" thumb = sorted(thumbnails_obj, key=itemgetter("width"), reverse=True)[0] - return [MediaItemImage(ImageType.THUMB, thumb["url"])] + return [MediaItemImage(type=ImageType.THUMB, path=thumb["url"])] @classmethod async def _parse_stream_format(cls, track_obj: dict) -> dict: