"""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)."""
}
self.provider_mappings.add(prov_mapping)
+ def __hash__(self) -> int:
+ """Return custom hash."""
+ return hash(self.uri)
+
+ def __eq__(self, other: ItemMapping) -> bool:
+ """Check equality of two items."""
+ return self.uri == other.uri
+
@dataclass
class ItemMapping(DataClassDictMixin):
def __hash__(self) -> int:
"""Return custom hash."""
- return hash((self.media_type.value, self.provider, self.item_id))
+ return hash(self.uri)
- def __eq__(self, other: ProviderMapping) -> bool:
+ def __eq__(self, other: ItemMapping) -> bool:
"""Check equality of two items."""
- return self.__hash__() == other.__hash__()
+ return self.uri == other.uri
@dataclass
item_id, provider_instance_id_or_domain
)
if fallback and not (isinstance(fallback, ItemMapping) and self.item_cls in (Track, Album)):
- # simply return the fallback item (marked as unavailable)
+ # simply return the fallback item
# NOTE: we only accept ItemMapping as fallback for flat items
# so not for tracks and albums (which rely on other objects)
- fallback.available = False
return fallback
# all options exhausted, we really can not find this item
raise MediaNotFoundError(
media: MediaItemType | list[MediaItemType] | str | list[str],
option: QueueOption = QueueOption.PLAY,
radio_mode: bool = False,
+ start_item: str | None = None,
) -> None:
"""Play media item(s) on the given queue.
- media: Media that should be played (MediaItem(s) or uri's).
- queue_opt: Which enqueue mode to use.
- radio_mode: Enable radio mode for the given item(s).
+ - start_item: Optional item to start the playlist or album from.
"""
# ruff: noqa: PLR0915,PLR0912
queue = self._queues[queue_id]
# single track or radio item
tracks += [media_item]
+ # handle optional start item (play playlist from here feature)
+ if start_item is not None:
+ prev_items = []
+ next_items = []
+ for track in tracks:
+ if next_items or track.item_id == start_item:
+ next_items.append(track)
+ else:
+ prev_items.append(track)
+ tracks = next_items + prev_items
+
# Use collected media items to calculate the radio if radio mode is on
if radio_mode:
tracks = await self._get_radio_tracks(queue_id)
"python-slugify==8.0.1",
"mashumaro==3.8.1",
"memory-tempfile==2.2.3",
- "music-assistant-frontend==2.0.3",
+ "music-assistant-frontend==2.0.4",
"pillow==9.5.0",
"unidecode==1.3.6",
"xmltodict==0.13.0",
ifaddr==0.2.0
mashumaro==3.8.1
memory-tempfile==2.2.3
-music-assistant-frontend==2.0.3
+music-assistant-frontend==2.0.4
orjson==3.9.2
pillow==9.5.0
plexapi==4.14.0