Add workaround for unavailable provider items
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 20 Jul 2023 12:44:21 +0000 (14:44 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 20 Jul 2023 12:44:21 +0000 (14:44 +0200)
music_assistant/common/models/media_items.py
music_assistant/server/controllers/media/base.py

index f8a3d377f205064f17a98be7dd026e138d7d8615..b881896d1e2bde277347bc6fdcfbcc30eccd5e11 100755 (executable)
@@ -268,6 +268,12 @@ class MediaItem(DataClassDictMixin):
         """Return (calculated) availability."""
         return any(x.available for x in self.provider_mappings)
 
+    @available.setter
+    def available(self, available: bool):
+        """Set availability."""
+        for provider_mapping in self.provider_mappings:
+            provider_mapping.available = available
+
     @property
     def image(self) -> MediaItemImage | None:
         """Return (first/random) image/thumb from metadata (if any)."""
index b084675357b58c99b5b2c10aefd0ce64907ce808..d81b80f3ca4fecda0eff53927d8639977258dada 100644 (file)
@@ -409,14 +409,29 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         # There is a possibility that the (streaming) provider changed the id of the item
         # so we return the previous details (if we have any) marked as unavailable, so
         # at least we have the possibility to sort out the new id through matching logic.
-        if not fallback:
-            fallback = await self.get_library_item_by_prov_id(
-                item_id, provider_instance_id_or_domain
+        fallback = fallback or await self.get_library_item_by_prov_id(
+            item_id, provider_instance_id_or_domain
+        )
+        if fallback and isinstance(fallback, ItemMapping):
+            # create a fake item on the fly from the ItemMapping details
+            fallback_item: MediaItemType = self.item_cls(
+                item_id=fallback.item_id, provider=fallback.provider, name=fallback.name
             )
-        if fallback:
-            fallback_item = ItemMapping.from_item(fallback)
-            fallback_item.available = False
-            return fallback_item
+            if provider := self.mass.get_provider(fallback_item.provider):
+                fallback_item.provider_mappings.add(
+                    ProviderMapping(
+                        item_id=fallback_item.item_id,
+                        provider_domain=provider.domain,
+                        provider_instance=provider.instance_id,
+                        available=False,
+                    )
+                )
+                return fallback_item
+        elif fallback:
+            # simply return the fallback item (marked as unavailable)
+            fallback.available = False
+            return fallback
+        # all options exhausted, we really can not find this item
         raise MediaNotFoundError(
             f"{self.media_type.value}://{item_id} not "
             f"found on provider {provider_instance_id_or_domain}"