from __future__ import annotations
from json import JSONDecodeError
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Any, cast
import aiohttp.client_exceptions
from music_assistant_models.config_entries import ConfigEntry
from music_assistant_models.enums import ConfigEntryType, ExternalID, ImageType, ProviderFeature
-from music_assistant_models.media_items import MediaItemImage, MediaItemMetadata
+from music_assistant_models.media_items import MediaItemImage, MediaItemMetadata, UniqueList
from music_assistant.controllers.cache import use_cache
-from music_assistant.helpers.app_vars import app_var
+from music_assistant.helpers.app_vars import app_var # type: ignore[attr-defined]
from music_assistant.helpers.throttle_retry import Throttler
from music_assistant.models.metadata_provider import MetadataProvider
from music_assistant_models.media_items import Album, Artist
from music_assistant_models.provider import ProviderManifest
- from music_assistant import MusicAssistant
+ from music_assistant.mass import MusicAssistant
from music_assistant.models import ProviderInstanceType
SUPPORTED_FEATURES = {
self.logger.debug("Fetching metadata for Artist %s on Fanart.tv", artist.name)
if data := await self._get_data(f"music/{artist.mbid}"):
metadata = MediaItemMetadata()
- metadata.images = []
for key, img_type in IMG_MAPPING.items():
items = data.get(key)
if not items:
continue
for item in items:
- metadata.images.append(
+ metadata.add_image(
MediaItemImage(
type=img_type,
path=item["url"],
self.logger.debug("Fetching metadata for Album %s on Fanart.tv", album.name)
if data := await self._get_data(f"music/albums/{mbid}"):
if data and data.get("albums"):
- data = data["albums"][mbid]
- metadata = MediaItemMetadata()
- metadata.images = []
- for key, img_type in IMG_MAPPING.items():
- items = data.get(key)
- if not items:
- continue
- for item in items:
- metadata.images.append(
- MediaItemImage(
- type=img_type,
- path=item["url"],
- provider=self.domain,
- remotely_accessible=True,
+ if album := data["albums"][mbid]:
+ metadata = MediaItemMetadata()
+ metadata.images = UniqueList()
+ for key, img_type in IMG_MAPPING.items():
+ items = album.get(key)
+ if not items:
+ continue
+ for item in items:
+ metadata.images.append(
+ MediaItemImage(
+ type=img_type,
+ path=item["url"],
+ provider=self.domain,
+ remotely_accessible=True,
+ )
)
- )
- return metadata
+ return metadata
return None
@use_cache(86400 * 30)
- async def _get_data(self, endpoint, **kwargs) -> dict | None:
+ async def _get_data(self, endpoint: str, **kwargs: str) -> dict[str, Any] | None:
"""Get data from api."""
url = f"http://webservice.fanart.tv/v3/{endpoint}"
headers = {
if "error" in result and "limit" in result["error"]:
self.logger.warning(result["error"])
return None
- return result
+ return cast(dict[str, Any], result)
"mashumaro==3.14",
"memory-tempfile==2.2.3",
"music-assistant-frontend==2.10.4",
- "music-assistant-models==1.1.15",
+ "music-assistant-models==1.1.16",
"orjson==3.10.12",
"pillow==11.1.0",
"podcastparser==0.6.10",
'^music_assistant/providers/chromecast/.*$',
'^music_assistant/providers/deezer/.*$',
'^music_assistant/providers/dlna/.*$',
- '^music_assistant/providers/fanarttv/.*$',
'^music_assistant/providers/hass/.*$',
'^music_assistant/providers/hass_players/.*$',
'^music_assistant/providers/player_group/.*$',