Use new media player enums (#78264)
This commit is contained in:
parent
5e9c0399eb
commit
5c8e8e4860
31 changed files with 445 additions and 609 deletions
|
@ -3,11 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import Optional, cast
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -97,7 +93,7 @@ class CameraMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=camera.entity_id,
|
||||
media_class=MEDIA_CLASS_VIDEO,
|
||||
media_class=MediaClass.VIDEO,
|
||||
media_content_type=content_type,
|
||||
title=camera.name,
|
||||
thumbnail=f"/api/camera_proxy/{camera.entity_id}",
|
||||
|
@ -109,12 +105,12 @@ class CameraMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_type="",
|
||||
title="Camera",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
children=children,
|
||||
not_shown=not_shown,
|
||||
)
|
||||
|
|
|
@ -17,8 +17,7 @@ from didl_lite import didl_lite
|
|||
|
||||
from homeassistant.backports.enum import StrEnum
|
||||
from homeassistant.components import ssdp
|
||||
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import BrowseMediaSource, PlayMedia
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -518,7 +517,7 @@ class DmsDeviceSource:
|
|||
media_source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=self._make_identifier(Action.SEARCH, query),
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title="Search results",
|
||||
can_play=False,
|
||||
|
|
|
@ -12,13 +12,7 @@ Media identifiers can look like:
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_TYPE_CHANNEL,
|
||||
MEDIA_TYPE_CHANNELS,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -82,20 +76,20 @@ class DmsMediaSource(MediaSource):
|
|||
base = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_CHANNELS,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.CHANNELS,
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_CHANNEL,
|
||||
children_media_class=MediaClass.CHANNEL,
|
||||
)
|
||||
|
||||
base.children = [
|
||||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{source_id}/{PATH_OBJECT_ID_FLAG}{ROOT_OBJECT_ID}",
|
||||
media_class=MEDIA_CLASS_CHANNEL,
|
||||
media_content_type=MEDIA_TYPE_CHANNEL,
|
||||
media_class=MediaClass.CHANNEL,
|
||||
media_content_type=MediaType.CHANNEL,
|
||||
title=source.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
|
|
@ -28,7 +28,7 @@ from homeassistant.components import (
|
|||
from homeassistant.components.climate import const as climate
|
||||
from homeassistant.components.humidifier import const as humidifier
|
||||
from homeassistant.components.lock import STATE_JAMMED, STATE_UNLOCKING
|
||||
from homeassistant.components.media_player.const import MEDIA_TYPE_CHANNEL
|
||||
from homeassistant.components.media_player import MediaType
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
ATTR_BATTERY_LEVEL,
|
||||
|
@ -2347,7 +2347,7 @@ class ChannelTrait(_Trait):
|
|||
{
|
||||
ATTR_ENTITY_ID: self.state.entity_id,
|
||||
media_player.ATTR_MEDIA_CONTENT_ID: channel_number,
|
||||
media_player.ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
|
||||
media_player.ATTR_MEDIA_CONTENT_TYPE: MediaType.CHANNEL,
|
||||
},
|
||||
blocking=not self.config.should_report_state,
|
||||
context=data.context,
|
||||
|
|
|
@ -8,14 +8,7 @@ from typing import Any
|
|||
from jellyfin_apiclient_python.api import jellyfin_url
|
||||
from jellyfin_apiclient_python.client import JellyfinClient
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_MOVIE,
|
||||
MEDIA_CLASS_TRACK,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
MediaSource,
|
||||
|
@ -113,12 +106,12 @@ class JellyfinSource(MediaSource):
|
|||
base = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_NONE,
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
libraries = await self._get_libraries()
|
||||
|
@ -164,7 +157,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=library_id,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_NONE,
|
||||
title=library_name,
|
||||
can_play=False,
|
||||
|
@ -172,10 +165,10 @@ class JellyfinSource(MediaSource):
|
|||
)
|
||||
|
||||
if include_children:
|
||||
result.children_media_class = MEDIA_CLASS_ARTIST
|
||||
result.children_media_class = MediaClass.ARTIST
|
||||
result.children = await self._build_artists(library_id)
|
||||
if not result.children:
|
||||
result.children_media_class = MEDIA_CLASS_ALBUM
|
||||
result.children_media_class = MediaClass.ALBUM
|
||||
result.children = await self._build_albums(library_id)
|
||||
|
||||
return result
|
||||
|
@ -197,7 +190,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=artist_id,
|
||||
media_class=MEDIA_CLASS_ARTIST,
|
||||
media_class=MediaClass.ARTIST,
|
||||
media_content_type=MEDIA_TYPE_NONE,
|
||||
title=artist_name,
|
||||
can_play=False,
|
||||
|
@ -206,7 +199,7 @@ class JellyfinSource(MediaSource):
|
|||
)
|
||||
|
||||
if include_children:
|
||||
result.children_media_class = MEDIA_CLASS_ALBUM
|
||||
result.children_media_class = MediaClass.ALBUM
|
||||
result.children = await self._build_albums(artist_id)
|
||||
|
||||
return result
|
||||
|
@ -228,7 +221,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=album_id,
|
||||
media_class=MEDIA_CLASS_ALBUM,
|
||||
media_class=MediaClass.ALBUM,
|
||||
media_content_type=MEDIA_TYPE_NONE,
|
||||
title=album_title,
|
||||
can_play=False,
|
||||
|
@ -237,7 +230,7 @@ class JellyfinSource(MediaSource):
|
|||
)
|
||||
|
||||
if include_children:
|
||||
result.children_media_class = MEDIA_CLASS_TRACK
|
||||
result.children_media_class = MediaClass.TRACK
|
||||
result.children = await self._build_tracks(album_id)
|
||||
|
||||
return result
|
||||
|
@ -264,7 +257,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=track_id,
|
||||
media_class=MEDIA_CLASS_TRACK,
|
||||
media_class=MediaClass.TRACK,
|
||||
media_content_type=mime_type,
|
||||
title=track_title,
|
||||
can_play=True,
|
||||
|
@ -284,7 +277,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=library_id,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_NONE,
|
||||
title=library_name,
|
||||
can_play=False,
|
||||
|
@ -292,7 +285,7 @@ class JellyfinSource(MediaSource):
|
|||
)
|
||||
|
||||
if include_children:
|
||||
result.children_media_class = MEDIA_CLASS_MOVIE
|
||||
result.children_media_class = MediaClass.MOVIE
|
||||
result.children = await self._build_movies(library_id)
|
||||
|
||||
return result
|
||||
|
@ -313,7 +306,7 @@ class JellyfinSource(MediaSource):
|
|||
result = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=movie_id,
|
||||
media_class=MEDIA_CLASS_MOVIE,
|
||||
media_class=MediaClass.MOVIE,
|
||||
media_content_type=mime_type,
|
||||
title=movie_title,
|
||||
can_play=True,
|
||||
|
|
|
@ -4,54 +4,37 @@ import contextlib
|
|||
import logging
|
||||
|
||||
from homeassistant.components import media_source
|
||||
from homeassistant.components.media_player import BrowseError, BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_EPISODE,
|
||||
MEDIA_CLASS_MOVIE,
|
||||
MEDIA_CLASS_MUSIC,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_SEASON,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_CLASS_TV_SHOW,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_CHANNEL,
|
||||
MEDIA_TYPE_EPISODE,
|
||||
MEDIA_TYPE_MOVIE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_SEASON,
|
||||
MEDIA_TYPE_TRACK,
|
||||
MEDIA_TYPE_TVSHOW,
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseError,
|
||||
BrowseMedia,
|
||||
MediaClass,
|
||||
MediaType,
|
||||
)
|
||||
|
||||
PLAYABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
MediaType.ALBUM,
|
||||
MediaType.ARTIST,
|
||||
MediaType.TRACK,
|
||||
]
|
||||
|
||||
CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = {
|
||||
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM,
|
||||
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST,
|
||||
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON,
|
||||
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW,
|
||||
MediaType.ALBUM: MediaClass.ALBUM,
|
||||
MediaType.ARTIST: MediaClass.ARTIST,
|
||||
MediaType.PLAYLIST: MediaClass.PLAYLIST,
|
||||
MediaType.SEASON: MediaClass.SEASON,
|
||||
MediaType.TVSHOW: MediaClass.TV_SHOW,
|
||||
}
|
||||
|
||||
CHILD_TYPE_MEDIA_CLASS = {
|
||||
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON,
|
||||
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM,
|
||||
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST,
|
||||
MEDIA_TYPE_MOVIE: MEDIA_CLASS_MOVIE,
|
||||
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK: MEDIA_CLASS_TRACK,
|
||||
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW,
|
||||
MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_TYPE_EPISODE: MEDIA_CLASS_EPISODE,
|
||||
MediaType.SEASON: MediaClass.SEASON,
|
||||
MediaType.ALBUM: MediaClass.ALBUM,
|
||||
MediaType.ARTIST: MediaClass.ARTIST,
|
||||
MediaType.MOVIE: MediaClass.MOVIE,
|
||||
MediaType.PLAYLIST: MediaClass.PLAYLIST,
|
||||
MediaType.TRACK: MediaClass.TRACK,
|
||||
MediaType.TVSHOW: MediaClass.TV_SHOW,
|
||||
MediaType.CHANNEL: MediaClass.CHANNEL,
|
||||
MediaType.EPISODE: MediaClass.EPISODE,
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -76,12 +59,12 @@ async def build_item_response(media_library, payload, get_thumbnail_url=None):
|
|||
*(item_payload(item, get_thumbnail_url) for item in media)
|
||||
)
|
||||
|
||||
if search_type in (MEDIA_TYPE_TVSHOW, MEDIA_TYPE_MOVIE) and search_id == "":
|
||||
if search_type in (MediaType.TVSHOW, MediaType.MOVIE) and search_id == "":
|
||||
children.sort(key=lambda x: x.title.replace("The ", "", 1), reverse=False)
|
||||
|
||||
response = BrowseMedia(
|
||||
media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get(
|
||||
search_type, MEDIA_CLASS_DIRECTORY
|
||||
search_type, MediaClass.DIRECTORY
|
||||
),
|
||||
media_content_id=search_id,
|
||||
media_content_type=search_type,
|
||||
|
@ -93,7 +76,7 @@ async def build_item_response(media_library, payload, get_thumbnail_url=None):
|
|||
)
|
||||
|
||||
if search_type == "library_music":
|
||||
response.children_media_class = MEDIA_CLASS_MUSIC
|
||||
response.children_media_class = MediaClass.MUSIC
|
||||
else:
|
||||
response.calculate_children_class()
|
||||
|
||||
|
@ -111,42 +94,42 @@ async def item_payload(item, get_thumbnail_url=None):
|
|||
media_class = None
|
||||
|
||||
if "songid" in item:
|
||||
media_content_type = MEDIA_TYPE_TRACK
|
||||
media_content_type = MediaType.TRACK
|
||||
media_content_id = f"{item['songid']}"
|
||||
can_play = True
|
||||
can_expand = False
|
||||
elif "albumid" in item:
|
||||
media_content_type = MEDIA_TYPE_ALBUM
|
||||
media_content_type = MediaType.ALBUM
|
||||
media_content_id = f"{item['albumid']}"
|
||||
can_play = True
|
||||
can_expand = True
|
||||
elif "artistid" in item:
|
||||
media_content_type = MEDIA_TYPE_ARTIST
|
||||
media_content_type = MediaType.ARTIST
|
||||
media_content_id = f"{item['artistid']}"
|
||||
can_play = True
|
||||
can_expand = True
|
||||
elif "movieid" in item:
|
||||
media_content_type = MEDIA_TYPE_MOVIE
|
||||
media_content_type = MediaType.MOVIE
|
||||
media_content_id = f"{item['movieid']}"
|
||||
can_play = True
|
||||
can_expand = False
|
||||
elif "episodeid" in item:
|
||||
media_content_type = MEDIA_TYPE_EPISODE
|
||||
media_content_type = MediaType.EPISODE
|
||||
media_content_id = f"{item['episodeid']}"
|
||||
can_play = True
|
||||
can_expand = False
|
||||
elif "seasonid" in item:
|
||||
media_content_type = MEDIA_TYPE_SEASON
|
||||
media_content_type = MediaType.SEASON
|
||||
media_content_id = f"{item['tvshowid']}/{item['season']}"
|
||||
can_play = False
|
||||
can_expand = True
|
||||
elif "tvshowid" in item:
|
||||
media_content_type = MEDIA_TYPE_TVSHOW
|
||||
media_content_type = MediaType.TVSHOW
|
||||
media_content_id = f"{item['tvshowid']}"
|
||||
can_play = False
|
||||
can_expand = True
|
||||
elif "channelid" in item:
|
||||
media_content_type = MEDIA_TYPE_CHANNEL
|
||||
media_content_type = MediaType.CHANNEL
|
||||
media_content_id = f"{item['channelid']}"
|
||||
if broadcasting := item.get("broadcastnow"):
|
||||
show = broadcasting.get("title")
|
||||
|
@ -156,7 +139,7 @@ async def item_payload(item, get_thumbnail_url=None):
|
|||
else:
|
||||
# this case is for the top folder of each type
|
||||
# possible content types: album, artist, movie, library_music, tvshow, channel
|
||||
media_class = MEDIA_CLASS_DIRECTORY
|
||||
media_class = MediaClass.DIRECTORY
|
||||
media_content_type = item["type"]
|
||||
media_content_id = ""
|
||||
can_play = False
|
||||
|
@ -202,7 +185,7 @@ async def library_payload(hass):
|
|||
Used by async_browse_media.
|
||||
"""
|
||||
library_info = BrowseMedia(
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="library",
|
||||
media_content_type="library",
|
||||
title="Media Library",
|
||||
|
@ -213,9 +196,9 @@ async def library_payload(hass):
|
|||
|
||||
library = {
|
||||
"library_music": "Music",
|
||||
MEDIA_TYPE_MOVIE: "Movies",
|
||||
MEDIA_TYPE_TVSHOW: "TV shows",
|
||||
MEDIA_TYPE_CHANNEL: "Channels",
|
||||
MediaType.MOVIE: "Movies",
|
||||
MediaType.TVSHOW: "TV shows",
|
||||
MediaType.CHANNEL: "Channels",
|
||||
}
|
||||
|
||||
library_info.children = await asyncio.gather(
|
||||
|
@ -256,7 +239,7 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
media = None
|
||||
|
||||
properties = ["thumbnail"]
|
||||
if search_type == MEDIA_TYPE_ALBUM:
|
||||
if search_type == MediaType.ALBUM:
|
||||
if search_id:
|
||||
album = await media_library.get_album_details(
|
||||
album_id=int(search_id), properties=properties
|
||||
|
@ -282,7 +265,7 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
media = media.get("albums")
|
||||
title = "Albums"
|
||||
|
||||
elif search_type == MEDIA_TYPE_ARTIST:
|
||||
elif search_type == MediaType.ARTIST:
|
||||
if search_id:
|
||||
media = await media_library.get_albums(
|
||||
artist_id=int(search_id), properties=properties
|
||||
|
@ -301,11 +284,11 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
title = "Artists"
|
||||
|
||||
elif search_type == "library_music":
|
||||
library = {MEDIA_TYPE_ALBUM: "Albums", MEDIA_TYPE_ARTIST: "Artists"}
|
||||
library = {MediaType.ALBUM: "Albums", MediaType.ARTIST: "Artists"}
|
||||
media = [{"label": name, "type": type_} for type_, name in library.items()]
|
||||
title = "Music Library"
|
||||
|
||||
elif search_type == MEDIA_TYPE_MOVIE:
|
||||
elif search_type == MediaType.MOVIE:
|
||||
if search_id:
|
||||
movie = await media_library.get_movie_details(
|
||||
movie_id=int(search_id), properties=properties
|
||||
|
@ -319,7 +302,7 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
media = media.get("movies")
|
||||
title = "Movies"
|
||||
|
||||
elif search_type == MEDIA_TYPE_TVSHOW:
|
||||
elif search_type == MediaType.TVSHOW:
|
||||
if search_id:
|
||||
media = await media_library.get_seasons(
|
||||
tv_show_id=int(search_id),
|
||||
|
@ -338,7 +321,7 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
media = media.get("tvshows")
|
||||
title = "TV Shows"
|
||||
|
||||
elif search_type == MEDIA_TYPE_SEASON:
|
||||
elif search_type == MediaType.SEASON:
|
||||
tv_show_id, season_id = search_id.split("/", 1)
|
||||
media = await media_library.get_episodes(
|
||||
tv_show_id=int(tv_show_id),
|
||||
|
@ -355,7 +338,7 @@ async def get_media_info(media_library, search_id, search_type):
|
|||
)
|
||||
title = season["seasondetails"]["label"]
|
||||
|
||||
elif search_type == MEDIA_TYPE_CHANNEL:
|
||||
elif search_type == MediaType.CHANNEL:
|
||||
media = await media_library.get_channels(
|
||||
channel_group_id="alltv",
|
||||
properties=["thumbnail", "channeltype", "channel", "broadcastnow"],
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
"""Constants for the media_source integration."""
|
||||
import re
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MEDIA_CLASS_MUSIC,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaClass
|
||||
|
||||
DOMAIN = "media_source"
|
||||
MEDIA_MIME_TYPES = ("audio", "video", "image")
|
||||
MEDIA_CLASS_MAP = {
|
||||
"audio": MEDIA_CLASS_MUSIC,
|
||||
"video": MEDIA_CLASS_VIDEO,
|
||||
"image": MEDIA_CLASS_IMAGE,
|
||||
"audio": MediaClass.MUSIC,
|
||||
"video": MediaClass.VIDEO,
|
||||
"image": MediaClass.IMAGE,
|
||||
}
|
||||
URI_SCHEME = "media-source://"
|
||||
URI_SCHEME_REGEX = re.compile(
|
||||
|
|
|
@ -11,8 +11,7 @@ from aiohttp.web_request import FileField
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import http, websocket_api
|
||||
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import Unauthorized
|
||||
from homeassistant.util import raise_if_invalid_filename, raise_if_invalid_path
|
||||
|
@ -109,12 +108,12 @@ class LocalSource(MediaSource):
|
|||
base = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=None,
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
base.children = [
|
||||
|
@ -158,10 +157,10 @@ class LocalSource(MediaSource):
|
|||
|
||||
title = path.name
|
||||
|
||||
media_class = MEDIA_CLASS_DIRECTORY
|
||||
media_class = MediaClass.DIRECTORY
|
||||
if mime_type:
|
||||
media_class = MEDIA_CLASS_MAP.get(
|
||||
mime_type.split("/")[0], MEDIA_CLASS_DIRECTORY
|
||||
mime_type.split("/")[0], MediaClass.DIRECTORY
|
||||
)
|
||||
|
||||
media = BrowseMediaSource(
|
||||
|
|
|
@ -5,12 +5,7 @@ from abc import ABC
|
|||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_TYPE_APP,
|
||||
MEDIA_TYPE_APPS,
|
||||
)
|
||||
from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
from .const import DOMAIN, URI_SCHEME, URI_SCHEME_REGEX
|
||||
|
@ -56,20 +51,20 @@ class MediaSourceItem:
|
|||
base = BrowseMediaSource(
|
||||
domain=None,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_content_type=MEDIA_TYPE_APPS,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_type=MediaType.APPS,
|
||||
title="Media Sources",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_APP,
|
||||
children_media_class=MediaClass.APP,
|
||||
)
|
||||
base.children = sorted(
|
||||
(
|
||||
BrowseMediaSource(
|
||||
domain=source.domain,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_content_type=MEDIA_TYPE_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_type=MediaType.APP,
|
||||
thumbnail=f"https://brands.home-assistant.io/_/{source.domain}/logo.png",
|
||||
title=source.name,
|
||||
can_play=False,
|
||||
|
|
|
@ -7,13 +7,7 @@ from typing import Optional, cast
|
|||
|
||||
from motioneye_client.const import KEY_MEDIA_LIST, KEY_MIME_TYPE, KEY_PATH
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
MEDIA_TYPE_IMAGE,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaClass, MediaType
|
||||
from homeassistant.components.media_source.error import MediaSourceError, Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -34,8 +28,8 @@ MIME_TYPE_MAP = {
|
|||
}
|
||||
|
||||
MEDIA_CLASS_MAP = {
|
||||
"movies": MEDIA_CLASS_VIDEO,
|
||||
"images": MEDIA_CLASS_IMAGE,
|
||||
"movies": MediaClass.VIDEO,
|
||||
"images": MediaClass.IMAGE,
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -172,12 +166,12 @@ class MotionEyeMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=config.entry_id,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=config.title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
def _build_media_configs(self) -> BrowseMediaSource:
|
||||
|
@ -185,7 +179,7 @@ class MotionEyeMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title="motionEye Media",
|
||||
can_play=False,
|
||||
|
@ -194,7 +188,7 @@ class MotionEyeMediaSource(MediaSource):
|
|||
self._build_media_config(entry)
|
||||
for entry in self.hass.config_entries.async_entries(DOMAIN)
|
||||
],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -207,12 +201,12 @@ class MotionEyeMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{config.entry_id}#{device.id}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=f"{config.title} {device.name}" if full_title else device.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
def _build_media_devices(self, config: ConfigEntry) -> BrowseMediaSource:
|
||||
|
@ -238,9 +232,9 @@ class MotionEyeMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{config.entry_id}#{device.id}#{kind}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=(
|
||||
MEDIA_TYPE_VIDEO if kind == "movies" else MEDIA_TYPE_IMAGE
|
||||
MediaType.VIDEO if kind == "movies" else MediaType.IMAGE
|
||||
),
|
||||
title=(
|
||||
f"{config.title} {device.name} {kind.title()}"
|
||||
|
@ -250,7 +244,7 @@ class MotionEyeMediaSource(MediaSource):
|
|||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=(
|
||||
MEDIA_CLASS_VIDEO if kind == "movies" else MEDIA_CLASS_IMAGE
|
||||
MediaClass.VIDEO if kind == "movies" else MediaClass.IMAGE
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -340,16 +334,16 @@ class MotionEyeMediaSource(MediaSource):
|
|||
f"{config.entry_id}#{device.id}"
|
||||
f"#{kind}#{full_child_path}"
|
||||
),
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=(
|
||||
MEDIA_TYPE_VIDEO
|
||||
MediaType.VIDEO
|
||||
if kind == "movies"
|
||||
else MEDIA_TYPE_IMAGE
|
||||
else MediaType.IMAGE
|
||||
),
|
||||
title=display_child_path,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
)
|
||||
return base
|
||||
|
|
|
@ -36,14 +36,7 @@ from google_nest_sdm.google_nest_subscriber import GoogleNestSubscriber
|
|||
from google_nest_sdm.transcoder import Transcoder
|
||||
|
||||
from homeassistant.components.ffmpeg import get_ffmpeg_manager
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
MEDIA_TYPE_IMAGE,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -450,9 +443,9 @@ def _browse_root() -> BrowseMediaSource:
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_VIDEO,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
title=MEDIA_SOURCE_TITLE,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -482,9 +475,9 @@ def _browse_device(device_id: MediaId, device: Device) -> BrowseMediaSource:
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=device_id.identifier,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_VIDEO,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
title=DEVICE_TITLE_FORMAT.format(device_name=device_info.device_name),
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -503,8 +496,8 @@ def _browse_clip_preview(
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=event_id.identifier,
|
||||
media_class=MEDIA_CLASS_IMAGE,
|
||||
media_content_type=MEDIA_TYPE_IMAGE,
|
||||
media_class=MediaClass.IMAGE,
|
||||
media_content_type=MediaType.IMAGE,
|
||||
title=CLIP_TITLE_FORMAT.format(
|
||||
event_name=", ".join(types),
|
||||
event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT),
|
||||
|
@ -525,8 +518,8 @@ def _browse_image_event(
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=event_id.identifier,
|
||||
media_class=MEDIA_CLASS_IMAGE,
|
||||
media_content_type=MEDIA_TYPE_IMAGE,
|
||||
media_class=MediaClass.IMAGE,
|
||||
media_content_type=MediaType.IMAGE,
|
||||
title=CLIP_TITLE_FORMAT.format(
|
||||
event_name=MEDIA_SOURCE_EVENT_TITLE_MAP.get(event.event_type, "Event"),
|
||||
event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT),
|
||||
|
|
|
@ -5,12 +5,7 @@ import datetime as dt
|
|||
import logging
|
||||
import re
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
|
||||
from homeassistant.components.media_source.error import MediaSourceError, Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -102,13 +97,13 @@ class NetatmoSource(MediaSource):
|
|||
else:
|
||||
path = f"{source}/{camera_id}"
|
||||
|
||||
media_class = MEDIA_CLASS_DIRECTORY if event_id is None else MEDIA_CLASS_VIDEO
|
||||
media_class = MediaClass.DIRECTORY if event_id is None else MediaClass.VIDEO
|
||||
|
||||
media = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=path,
|
||||
media_class=media_class,
|
||||
media_content_type=MEDIA_TYPE_VIDEO,
|
||||
media_content_type=MediaType.VIDEO,
|
||||
title=title,
|
||||
can_play=bool(
|
||||
event_id and self.events[camera_id][event_id].get("media_url")
|
||||
|
|
|
@ -3,20 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from yarl import URL
|
||||
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_EPISODE,
|
||||
MEDIA_CLASS_MOVIE,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_SEASON,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_CLASS_TV_SHOW,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, BrowseMedia, MediaClass
|
||||
|
||||
from .const import DOMAIN, SERVERS
|
||||
from .errors import MediaNotFound
|
||||
|
@ -29,18 +16,18 @@ class UnknownMediaType(BrowseError):
|
|||
|
||||
EXPANDABLES = ["album", "artist", "playlist", "season", "show"]
|
||||
ITEM_TYPE_MEDIA_CLASS = {
|
||||
"album": MEDIA_CLASS_ALBUM,
|
||||
"artist": MEDIA_CLASS_ARTIST,
|
||||
"clip": MEDIA_CLASS_VIDEO,
|
||||
"episode": MEDIA_CLASS_EPISODE,
|
||||
"mixed": MEDIA_CLASS_DIRECTORY,
|
||||
"movie": MEDIA_CLASS_MOVIE,
|
||||
"playlist": MEDIA_CLASS_PLAYLIST,
|
||||
"season": MEDIA_CLASS_SEASON,
|
||||
"show": MEDIA_CLASS_TV_SHOW,
|
||||
"station": MEDIA_CLASS_ARTIST,
|
||||
"track": MEDIA_CLASS_TRACK,
|
||||
"video": MEDIA_CLASS_VIDEO,
|
||||
"album": MediaClass.ALBUM,
|
||||
"artist": MediaClass.ARTIST,
|
||||
"clip": MediaClass.VIDEO,
|
||||
"episode": MediaClass.EPISODE,
|
||||
"mixed": MediaClass.DIRECTORY,
|
||||
"movie": MediaClass.MOVIE,
|
||||
"playlist": MediaClass.PLAYLIST,
|
||||
"season": MediaClass.SEASON,
|
||||
"show": MediaClass.TV_SHOW,
|
||||
"station": MediaClass.ARTIST,
|
||||
"track": MediaClass.TRACK,
|
||||
"video": MediaClass.VIDEO,
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,13 +86,13 @@ def browse_media( # noqa: C901
|
|||
"""Create response payload to describe libraries of the Plex server."""
|
||||
server_info = BrowseMedia(
|
||||
title=plex_server.friendly_name,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id=generate_plex_uri(server_id, "server"),
|
||||
media_content_type="server",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
thumbnail="https://brands.home-assistant.io/_/plex/logo.png",
|
||||
)
|
||||
if platform != "sonos":
|
||||
|
@ -136,7 +123,7 @@ def browse_media( # noqa: C901
|
|||
"""Create response payload for all available playlists."""
|
||||
playlists_info = {
|
||||
"title": "Playlists",
|
||||
"media_class": MEDIA_CLASS_DIRECTORY,
|
||||
"media_class": MediaClass.DIRECTORY,
|
||||
"media_content_id": generate_plex_uri(server_id, "all"),
|
||||
"media_content_type": "playlists",
|
||||
"can_play": False,
|
||||
|
@ -151,7 +138,7 @@ def browse_media( # noqa: C901
|
|||
except UnknownMediaType:
|
||||
continue
|
||||
response = BrowseMedia(**playlists_info)
|
||||
response.children_media_class = MEDIA_CLASS_PLAYLIST
|
||||
response.children_media_class = MediaClass.PLAYLIST
|
||||
return response
|
||||
|
||||
def build_item_response(payload):
|
||||
|
@ -197,7 +184,7 @@ def browse_media( # noqa: C901
|
|||
raise UnknownMediaType(f"Unknown type received: {hub.type}") from err
|
||||
payload = {
|
||||
"title": hub.title,
|
||||
"media_class": MEDIA_CLASS_DIRECTORY,
|
||||
"media_class": MediaClass.DIRECTORY,
|
||||
"media_content_id": generate_plex_uri(server_id, media_content_id),
|
||||
"media_content_type": "hub",
|
||||
"can_play": False,
|
||||
|
@ -223,7 +210,7 @@ def browse_media( # noqa: C901
|
|||
if special_folder:
|
||||
if media_content_type == "server":
|
||||
library_or_section = plex_server.library
|
||||
children_media_class = MEDIA_CLASS_DIRECTORY
|
||||
children_media_class = MediaClass.DIRECTORY
|
||||
title = plex_server.friendly_name
|
||||
elif media_content_type == "library":
|
||||
library_or_section = plex_server.library.sectionByID(int(media_content_id))
|
||||
|
@ -241,7 +228,7 @@ def browse_media( # noqa: C901
|
|||
|
||||
payload = {
|
||||
"title": title,
|
||||
"media_class": MEDIA_CLASS_DIRECTORY,
|
||||
"media_class": MediaClass.DIRECTORY,
|
||||
"media_content_id": generate_plex_uri(
|
||||
server_id, f"{media_content_id}/{special_folder}"
|
||||
),
|
||||
|
@ -323,7 +310,7 @@ def root_payload(hass, is_internal, platform=None):
|
|||
|
||||
return BrowseMedia(
|
||||
title="Plex",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="plex_root",
|
||||
can_play=False,
|
||||
|
@ -341,7 +328,7 @@ def library_section_payload(section):
|
|||
server_id = section._server.machineIdentifier # pylint: disable=protected-access
|
||||
return BrowseMedia(
|
||||
title=section.title,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id=generate_plex_uri(server_id, section.key),
|
||||
media_content_type="library",
|
||||
can_play=False,
|
||||
|
@ -374,7 +361,7 @@ def hub_payload(hub):
|
|||
server_id = hub._server.machineIdentifier # pylint: disable=protected-access
|
||||
payload = {
|
||||
"title": hub.title,
|
||||
"media_class": MEDIA_CLASS_DIRECTORY,
|
||||
"media_class": MediaClass.DIRECTORY,
|
||||
"media_content_id": generate_plex_uri(server_id, media_content_id),
|
||||
"media_content_type": "hub",
|
||||
"can_play": False,
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
"""Models to represent various Plex objects used in the integration."""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_TYPE_MOVIE,
|
||||
MEDIA_TYPE_MUSIC,
|
||||
MEDIA_TYPE_TVSHOW,
|
||||
MEDIA_TYPE_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaType
|
||||
from homeassistant.helpers.template import result_as_boolean
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
|
@ -92,19 +87,19 @@ class PlexSession:
|
|||
)
|
||||
|
||||
if media.type == "episode":
|
||||
self.media_content_type = MEDIA_TYPE_TVSHOW
|
||||
self.media_content_type = MediaType.TVSHOW
|
||||
self.media_season = media.seasonNumber
|
||||
self.media_series_title = media.grandparentTitle
|
||||
if media.index is not None:
|
||||
self.media_episode = media.index
|
||||
self.sensor_title = f"{self.media_series_title} - {media.seasonEpisode} - {self.media_title}"
|
||||
elif media.type == "movie":
|
||||
self.media_content_type = MEDIA_TYPE_MOVIE
|
||||
self.media_content_type = MediaType.MOVIE
|
||||
if media.year is not None and media.title is not None:
|
||||
self.media_title += f" ({media.year!s})"
|
||||
self.sensor_title = self.media_title
|
||||
elif media.type == "track":
|
||||
self.media_content_type = MEDIA_TYPE_MUSIC
|
||||
self.media_content_type = MediaType.MUSIC
|
||||
self.media_album_name = media.parentTitle
|
||||
self.media_album_artist = media.grandparentTitle
|
||||
self.media_track = media.index
|
||||
|
@ -113,7 +108,7 @@ class PlexSession:
|
|||
f"{self.media_artist} - {self.media_album_name} - {self.media_title}"
|
||||
)
|
||||
elif media.type == "clip":
|
||||
self.media_content_type = MEDIA_TYPE_VIDEO
|
||||
self.media_content_type = MediaType.VIDEO
|
||||
self.sensor_title = media.title
|
||||
else:
|
||||
self.sensor_title = "Unknown"
|
||||
|
|
|
@ -12,8 +12,7 @@ import plexapi.server
|
|||
from requests import Session
|
||||
import requests.exceptions
|
||||
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.components.media_player.const import MEDIA_TYPE_PLAYLIST
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN, MediaType
|
||||
from homeassistant.const import CONF_CLIENT_ID, CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.debounce import Debouncer
|
||||
|
@ -627,7 +626,7 @@ class PlexServer:
|
|||
except NotFound as err:
|
||||
raise MediaNotFound(f"Media for key {key} not found") from err
|
||||
|
||||
if media_type == MEDIA_TYPE_PLAYLIST:
|
||||
if media_type == MediaType.PLAYLIST:
|
||||
try:
|
||||
playlist_name = kwargs["playlist_name"]
|
||||
return self.playlist(playlist_name)
|
||||
|
|
|
@ -7,10 +7,10 @@ from pyps4_2ndscreen.media_art import COUNTRIES
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import persistent_notification
|
||||
from homeassistant.components.media_player.const import (
|
||||
from homeassistant.components.media_player import (
|
||||
ATTR_MEDIA_CONTENT_TYPE,
|
||||
ATTR_MEDIA_TITLE,
|
||||
MEDIA_TYPE_GAME,
|
||||
MediaType,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
|
@ -206,7 +206,7 @@ def _reformat_data(hass: HomeAssistant, games: dict, unique_id: str) -> dict:
|
|||
ATTR_LOCKED: False,
|
||||
ATTR_MEDIA_TITLE: data,
|
||||
ATTR_MEDIA_IMAGE_URL: None,
|
||||
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_GAME,
|
||||
ATTR_MEDIA_CONTENT_TYPE: MediaType.GAME,
|
||||
}
|
||||
data_reformatted = True
|
||||
|
||||
|
|
|
@ -5,13 +5,7 @@ import mimetypes
|
|||
|
||||
from radios import FilterBy, Order, RadioBrowser, Station
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_MUSIC,
|
||||
MEDIA_TYPE_MUSIC,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -88,12 +82,12 @@ class RadioMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_CHANNEL,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.CHANNEL,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title=self.entry.title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
children=[
|
||||
*await self._async_build_popular(radios, item),
|
||||
*await self._async_build_by_tag(radios, item),
|
||||
|
@ -128,7 +122,7 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=station.uuid,
|
||||
media_class=MEDIA_CLASS_MUSIC,
|
||||
media_class=MediaClass.MUSIC,
|
||||
media_content_type=mime_type,
|
||||
title=station.name,
|
||||
can_play=True,
|
||||
|
@ -161,8 +155,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"country/{country.code}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title=country.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -194,8 +188,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"language/{language.code}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title=language.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -209,8 +203,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="language",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title="By Language",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -237,8 +231,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="popular",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title="Popular",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -277,8 +271,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"tag/{tag.name}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title=tag.name.title(),
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -291,8 +285,8 @@ class RadioMediaSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="tag",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
title="By Category",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
|
|
@ -5,17 +5,12 @@ from collections.abc import Callable
|
|||
from functools import partial
|
||||
|
||||
from homeassistant.components import media_source
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_TYPE_APP,
|
||||
MEDIA_TYPE_APPS,
|
||||
MEDIA_TYPE_CHANNEL,
|
||||
MEDIA_TYPE_CHANNELS,
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseError,
|
||||
BrowseMedia,
|
||||
MediaClass,
|
||||
MediaType,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.network import is_internal_request
|
||||
|
||||
|
@ -23,25 +18,25 @@ from .coordinator import RokuDataUpdateCoordinator
|
|||
from .helpers import format_channel_name
|
||||
|
||||
CONTENT_TYPE_MEDIA_CLASS = {
|
||||
MEDIA_TYPE_APP: MEDIA_CLASS_APP,
|
||||
MEDIA_TYPE_APPS: MEDIA_CLASS_APP,
|
||||
MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_TYPE_CHANNELS: MEDIA_CLASS_CHANNEL,
|
||||
MediaType.APP: MediaClass.APP,
|
||||
MediaType.APPS: MediaClass.APP,
|
||||
MediaType.CHANNEL: MediaClass.CHANNEL,
|
||||
MediaType.CHANNELS: MediaClass.CHANNEL,
|
||||
}
|
||||
|
||||
CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = {
|
||||
MEDIA_TYPE_APPS: MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_TYPE_CHANNELS: MEDIA_CLASS_DIRECTORY,
|
||||
MediaType.APPS: MediaClass.DIRECTORY,
|
||||
MediaType.CHANNELS: MediaClass.DIRECTORY,
|
||||
}
|
||||
|
||||
PLAYABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_APP,
|
||||
MEDIA_TYPE_CHANNEL,
|
||||
MediaType.APP,
|
||||
MediaType.CHANNEL,
|
||||
]
|
||||
|
||||
EXPANDABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_APPS,
|
||||
MEDIA_TYPE_CHANNELS,
|
||||
MediaType.APPS,
|
||||
MediaType.CHANNELS,
|
||||
]
|
||||
|
||||
GetBrowseImageUrlType = Callable[[str, str, "str | None"], str]
|
||||
|
@ -57,7 +52,7 @@ def get_thumbnail_url_full(
|
|||
) -> str | None:
|
||||
"""Get thumbnail URL."""
|
||||
if is_internal:
|
||||
if media_content_type == MEDIA_TYPE_APP and media_content_id:
|
||||
if media_content_type == MediaType.APP and media_content_id:
|
||||
return coordinator.roku.app_icon_url(media_content_id)
|
||||
return None
|
||||
|
||||
|
@ -119,7 +114,7 @@ async def root_payload(
|
|||
|
||||
children = [
|
||||
item_payload(
|
||||
{"title": "Apps", "type": MEDIA_TYPE_APPS},
|
||||
{"title": "Apps", "type": MediaType.APPS},
|
||||
coordinator,
|
||||
get_browse_image_url,
|
||||
)
|
||||
|
@ -128,7 +123,7 @@ async def root_payload(
|
|||
if device.info.device_type == "tv" and len(device.channels) > 0:
|
||||
children.append(
|
||||
item_payload(
|
||||
{"title": "TV Channels", "type": MEDIA_TYPE_CHANNELS},
|
||||
{"title": "TV Channels", "type": MediaType.CHANNELS},
|
||||
coordinator,
|
||||
get_browse_image_url,
|
||||
)
|
||||
|
@ -160,7 +155,7 @@ async def root_payload(
|
|||
|
||||
return BrowseMedia(
|
||||
title="Roku",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="root",
|
||||
can_play=False,
|
||||
|
@ -183,31 +178,31 @@ def build_item_response(
|
|||
media = None
|
||||
children_media_class = None
|
||||
|
||||
if search_type == MEDIA_TYPE_APPS:
|
||||
if search_type == MediaType.APPS:
|
||||
title = "Apps"
|
||||
media = [
|
||||
{"app_id": item.app_id, "title": item.name, "type": MEDIA_TYPE_APP}
|
||||
{"app_id": item.app_id, "title": item.name, "type": MediaType.APP}
|
||||
for item in coordinator.data.apps
|
||||
]
|
||||
children_media_class = MEDIA_CLASS_APP
|
||||
elif search_type == MEDIA_TYPE_CHANNELS:
|
||||
children_media_class = MediaClass.APP
|
||||
elif search_type == MediaType.CHANNELS:
|
||||
title = "TV Channels"
|
||||
media = [
|
||||
{
|
||||
"channel_number": channel.number,
|
||||
"title": format_channel_name(channel.number, channel.name),
|
||||
"type": MEDIA_TYPE_CHANNEL,
|
||||
"type": MediaType.CHANNEL,
|
||||
}
|
||||
for channel in coordinator.data.channels
|
||||
]
|
||||
children_media_class = MEDIA_CLASS_CHANNEL
|
||||
children_media_class = MediaClass.CHANNEL
|
||||
|
||||
if title is None or media is None:
|
||||
return None
|
||||
|
||||
return BrowseMedia(
|
||||
media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get(
|
||||
search_type, MEDIA_CLASS_DIRECTORY
|
||||
search_type, MediaClass.DIRECTORY
|
||||
),
|
||||
media_content_id=search_id,
|
||||
media_content_type=search_type,
|
||||
|
@ -235,11 +230,11 @@ def item_payload(
|
|||
thumbnail = None
|
||||
|
||||
if "app_id" in item:
|
||||
media_content_type = MEDIA_TYPE_APP
|
||||
media_content_type = MediaType.APP
|
||||
media_content_id = item["app_id"]
|
||||
thumbnail = get_browse_image_url(media_content_type, media_content_id, None)
|
||||
elif "channel_number" in item:
|
||||
media_content_type = MEDIA_TYPE_CHANNEL
|
||||
media_content_type = MediaType.CHANNEL
|
||||
media_content_id = item["channel_number"]
|
||||
else:
|
||||
media_content_type = item["type"]
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
"""Support to interface with the Roon API."""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_TRACK,
|
||||
)
|
||||
from homeassistant.components.media_player import BrowseMedia, MediaClass
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
|
||||
|
||||
|
@ -71,18 +66,18 @@ def item_payload(roon_server, item, list_image_id):
|
|||
|
||||
hint = item.get("hint")
|
||||
if hint == "list":
|
||||
media_class = MEDIA_CLASS_DIRECTORY
|
||||
media_class = MediaClass.DIRECTORY
|
||||
can_expand = True
|
||||
elif hint == "action_list":
|
||||
media_class = MEDIA_CLASS_PLAYLIST
|
||||
media_class = MediaClass.PLAYLIST
|
||||
can_expand = False
|
||||
elif hint == "action":
|
||||
media_content_type = "track"
|
||||
media_class = MEDIA_CLASS_TRACK
|
||||
media_class = MediaClass.TRACK
|
||||
can_expand = False
|
||||
else:
|
||||
# Roon API says to treat unknown as a list
|
||||
media_class = MEDIA_CLASS_DIRECTORY
|
||||
media_class = MediaClass.DIRECTORY
|
||||
can_expand = True
|
||||
_LOGGER.warning("Unknown hint %s - %s", title, hint)
|
||||
|
||||
|
@ -135,7 +130,7 @@ def library_payload(roon_server, zone_id, media_content_id):
|
|||
title=list_title,
|
||||
media_content_id=content_id,
|
||||
media_content_type="library",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[],
|
||||
|
|
|
@ -1,22 +1,9 @@
|
|||
"""Const for Sonos."""
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_COMPOSER,
|
||||
MEDIA_CLASS_CONTRIBUTING_ARTIST,
|
||||
MEDIA_CLASS_GENRE,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_COMPOSER,
|
||||
MEDIA_TYPE_CONTRIBUTING_ARTIST,
|
||||
MEDIA_TYPE_GENRE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaClass, MediaType
|
||||
from homeassistant.const import Platform
|
||||
|
||||
UPNP_ST = "urn:schemas-upnp-org:device:ZonePlayer:1"
|
||||
|
@ -46,11 +33,11 @@ SONOS_STATE_PLAYING = "PLAYING"
|
|||
SONOS_STATE_TRANSITIONING = "TRANSITIONING"
|
||||
|
||||
EXPANDABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_COMPOSER,
|
||||
MEDIA_TYPE_GENRE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MediaType.ALBUM,
|
||||
MediaType.ARTIST,
|
||||
MediaType.COMPOSER,
|
||||
MediaType.GENRE,
|
||||
MediaType.PLAYLIST,
|
||||
SONOS_ALBUM,
|
||||
SONOS_ALBUM_ARTIST,
|
||||
SONOS_ARTIST,
|
||||
|
@ -60,49 +47,49 @@ EXPANDABLE_MEDIA_TYPES = [
|
|||
]
|
||||
|
||||
SONOS_TO_MEDIA_CLASSES = {
|
||||
SONOS_ALBUM: MEDIA_CLASS_ALBUM,
|
||||
SONOS_ALBUM_ARTIST: MEDIA_CLASS_ARTIST,
|
||||
SONOS_ARTIST: MEDIA_CLASS_CONTRIBUTING_ARTIST,
|
||||
SONOS_COMPOSER: MEDIA_CLASS_COMPOSER,
|
||||
SONOS_GENRE: MEDIA_CLASS_GENRE,
|
||||
SONOS_PLAYLISTS: MEDIA_CLASS_PLAYLIST,
|
||||
SONOS_TRACKS: MEDIA_CLASS_TRACK,
|
||||
"object.container.album.musicAlbum": MEDIA_CLASS_ALBUM,
|
||||
"object.container.genre.musicGenre": MEDIA_CLASS_PLAYLIST,
|
||||
"object.container.person.composer": MEDIA_CLASS_PLAYLIST,
|
||||
"object.container.person.musicArtist": MEDIA_CLASS_ARTIST,
|
||||
"object.container.playlistContainer.sameArtist": MEDIA_CLASS_ARTIST,
|
||||
"object.container.playlistContainer": MEDIA_CLASS_PLAYLIST,
|
||||
"object.item": MEDIA_CLASS_TRACK,
|
||||
"object.item.audioItem.musicTrack": MEDIA_CLASS_TRACK,
|
||||
"object.item.audioItem.audioBroadcast": MEDIA_CLASS_GENRE,
|
||||
SONOS_ALBUM: MediaClass.ALBUM,
|
||||
SONOS_ALBUM_ARTIST: MediaClass.ARTIST,
|
||||
SONOS_ARTIST: MediaClass.CONTRIBUTING_ARTIST,
|
||||
SONOS_COMPOSER: MediaClass.COMPOSER,
|
||||
SONOS_GENRE: MediaClass.GENRE,
|
||||
SONOS_PLAYLISTS: MediaClass.PLAYLIST,
|
||||
SONOS_TRACKS: MediaClass.TRACK,
|
||||
"object.container.album.musicAlbum": MediaClass.ALBUM,
|
||||
"object.container.genre.musicGenre": MediaClass.PLAYLIST,
|
||||
"object.container.person.composer": MediaClass.PLAYLIST,
|
||||
"object.container.person.musicArtist": MediaClass.ARTIST,
|
||||
"object.container.playlistContainer.sameArtist": MediaClass.ARTIST,
|
||||
"object.container.playlistContainer": MediaClass.PLAYLIST,
|
||||
"object.item": MediaClass.TRACK,
|
||||
"object.item.audioItem.musicTrack": MediaClass.TRACK,
|
||||
"object.item.audioItem.audioBroadcast": MediaClass.GENRE,
|
||||
}
|
||||
|
||||
SONOS_TO_MEDIA_TYPES = {
|
||||
SONOS_ALBUM: MEDIA_TYPE_ALBUM,
|
||||
SONOS_ALBUM_ARTIST: MEDIA_TYPE_ARTIST,
|
||||
SONOS_ARTIST: MEDIA_TYPE_CONTRIBUTING_ARTIST,
|
||||
SONOS_COMPOSER: MEDIA_TYPE_COMPOSER,
|
||||
SONOS_GENRE: MEDIA_TYPE_GENRE,
|
||||
SONOS_PLAYLISTS: MEDIA_TYPE_PLAYLIST,
|
||||
SONOS_TRACKS: MEDIA_TYPE_TRACK,
|
||||
"object.container.album.musicAlbum": MEDIA_TYPE_ALBUM,
|
||||
"object.container.genre.musicGenre": MEDIA_TYPE_PLAYLIST,
|
||||
"object.container.person.composer": MEDIA_TYPE_PLAYLIST,
|
||||
"object.container.person.musicArtist": MEDIA_TYPE_ARTIST,
|
||||
"object.container.playlistContainer.sameArtist": MEDIA_TYPE_ARTIST,
|
||||
"object.container.playlistContainer": MEDIA_TYPE_PLAYLIST,
|
||||
"object.item.audioItem.musicTrack": MEDIA_TYPE_TRACK,
|
||||
SONOS_ALBUM: MediaType.ALBUM,
|
||||
SONOS_ALBUM_ARTIST: MediaType.ARTIST,
|
||||
SONOS_ARTIST: MediaType.CONTRIBUTING_ARTIST,
|
||||
SONOS_COMPOSER: MediaType.COMPOSER,
|
||||
SONOS_GENRE: MediaType.GENRE,
|
||||
SONOS_PLAYLISTS: MediaType.PLAYLIST,
|
||||
SONOS_TRACKS: MediaType.TRACK,
|
||||
"object.container.album.musicAlbum": MediaType.ALBUM,
|
||||
"object.container.genre.musicGenre": MediaType.PLAYLIST,
|
||||
"object.container.person.composer": MediaType.PLAYLIST,
|
||||
"object.container.person.musicArtist": MediaType.ARTIST,
|
||||
"object.container.playlistContainer.sameArtist": MediaType.ARTIST,
|
||||
"object.container.playlistContainer": MediaType.PLAYLIST,
|
||||
"object.item.audioItem.musicTrack": MediaType.TRACK,
|
||||
}
|
||||
|
||||
MEDIA_TYPES_TO_SONOS = {
|
||||
MEDIA_TYPE_ALBUM: SONOS_ALBUM,
|
||||
MEDIA_TYPE_ARTIST: SONOS_ALBUM_ARTIST,
|
||||
MEDIA_TYPE_CONTRIBUTING_ARTIST: SONOS_ARTIST,
|
||||
MEDIA_TYPE_COMPOSER: SONOS_COMPOSER,
|
||||
MEDIA_TYPE_GENRE: SONOS_GENRE,
|
||||
MEDIA_TYPE_PLAYLIST: SONOS_PLAYLISTS,
|
||||
MEDIA_TYPE_TRACK: SONOS_TRACKS,
|
||||
MEDIA_TYPES_TO_SONOS: dict[MediaType | str, str] = {
|
||||
MediaType.ALBUM: SONOS_ALBUM,
|
||||
MediaType.ARTIST: SONOS_ALBUM_ARTIST,
|
||||
MediaType.CONTRIBUTING_ARTIST: SONOS_ARTIST,
|
||||
MediaType.COMPOSER: SONOS_COMPOSER,
|
||||
MediaType.GENRE: SONOS_GENRE,
|
||||
MediaType.PLAYLIST: SONOS_PLAYLISTS,
|
||||
MediaType.TRACK: SONOS_TRACKS,
|
||||
}
|
||||
|
||||
SONOS_TYPES_MAPPING = {
|
||||
|
@ -135,13 +122,13 @@ LIBRARY_TITLES_MAPPING = {
|
|||
}
|
||||
|
||||
PLAYABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_COMPOSER,
|
||||
MEDIA_TYPE_CONTRIBUTING_ARTIST,
|
||||
MEDIA_TYPE_GENRE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
MediaType.ALBUM,
|
||||
MediaType.ARTIST,
|
||||
MediaType.COMPOSER,
|
||||
MediaType.CONTRIBUTING_ARTIST,
|
||||
MediaType.GENRE,
|
||||
MediaType.PLAYLIST,
|
||||
MediaType.TRACK,
|
||||
]
|
||||
|
||||
SONOS_CHECK_ACTIVITY = "sonos_check_activity"
|
||||
|
|
|
@ -12,12 +12,7 @@ from soco.ms_data_structures import MusicServiceItem
|
|||
from soco.music_library import MusicLibrary
|
||||
|
||||
from homeassistant.components import media_source, plex, spotify
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
)
|
||||
from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.network import is_internal_request
|
||||
|
@ -159,7 +154,7 @@ def build_item_response(
|
|||
media_library: MusicLibrary, payload: dict[str, str], get_thumbnail_url=None
|
||||
) -> BrowseMedia | None:
|
||||
"""Create response payload for the provided media query."""
|
||||
if payload["search_type"] == MEDIA_TYPE_ALBUM and payload["idstring"].startswith(
|
||||
if payload["search_type"] == MediaType.ALBUM and payload["idstring"].startswith(
|
||||
("A:GENRE", "A:COMPOSER")
|
||||
):
|
||||
payload["idstring"] = "A:ALBUMARTIST/" + "/".join(
|
||||
|
@ -191,7 +186,7 @@ def build_item_response(
|
|||
# Fetch album info for titles and thumbnails
|
||||
# Can't be extracted from track info
|
||||
if (
|
||||
payload["search_type"] == MEDIA_TYPE_ALBUM
|
||||
payload["search_type"] == MediaType.ALBUM
|
||||
and media[0].item_class == "object.item.audioItem.musicTrack"
|
||||
):
|
||||
item = get_media(media_library, payload["idstring"], SONOS_ALBUM_ARTIST)
|
||||
|
@ -271,7 +266,7 @@ async def root_payload(
|
|||
children.append(
|
||||
BrowseMedia(
|
||||
title="Favorites",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="favorites",
|
||||
thumbnail="https://brands.home-assistant.io/_/sonos/logo.png",
|
||||
|
@ -286,7 +281,7 @@ async def root_payload(
|
|||
children.append(
|
||||
BrowseMedia(
|
||||
title="Music Library",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="library",
|
||||
thumbnail="https://brands.home-assistant.io/_/sonos/logo.png",
|
||||
|
@ -299,7 +294,7 @@ async def root_payload(
|
|||
children.append(
|
||||
BrowseMedia(
|
||||
title="Plex",
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_id="",
|
||||
media_content_type="plex",
|
||||
thumbnail="https://brands.home-assistant.io/_/plex/logo.png",
|
||||
|
@ -337,7 +332,7 @@ async def root_payload(
|
|||
|
||||
return BrowseMedia(
|
||||
title="Sonos",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="root",
|
||||
can_play=False,
|
||||
|
@ -359,7 +354,7 @@ def library_payload(media_library: MusicLibrary, get_thumbnail_url=None) -> Brow
|
|||
|
||||
return BrowseMedia(
|
||||
title="Music Library",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="library",
|
||||
media_content_type="library",
|
||||
can_play=False,
|
||||
|
@ -397,7 +392,7 @@ def favorites_payload(favorites: list[DidlFavorite]) -> BrowseMedia:
|
|||
|
||||
return BrowseMedia(
|
||||
title="Favorites",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="favorites",
|
||||
can_play=False,
|
||||
|
@ -433,7 +428,7 @@ def favorites_folder_payload(
|
|||
|
||||
return BrowseMedia(
|
||||
title=content_type.title(),
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="",
|
||||
media_content_type="favorites",
|
||||
can_play=False,
|
||||
|
|
|
@ -9,22 +9,11 @@ from spotipy import Spotify
|
|||
import yarl
|
||||
|
||||
from homeassistant.backports.enum import StrEnum
|
||||
from homeassistant.components.media_player import BrowseError, BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_EPISODE,
|
||||
MEDIA_CLASS_GENRE,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_PODCAST,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_EPISODE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseError,
|
||||
BrowseMedia,
|
||||
MediaClass,
|
||||
MediaType,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
|
||||
|
@ -70,62 +59,62 @@ LIBRARY_MAP = {
|
|||
|
||||
CONTENT_TYPE_MEDIA_CLASS: dict[str, Any] = {
|
||||
BrowsableMedia.CURRENT_USER_PLAYLISTS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_PLAYLIST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.PLAYLIST,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_FOLLOWED_ARTISTS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_ARTIST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.ARTIST,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_SAVED_ALBUMS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_ALBUM,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.ALBUM,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_SAVED_TRACKS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_TRACK,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.TRACK,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_SAVED_SHOWS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_PODCAST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.PODCAST,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_RECENTLY_PLAYED.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_TRACK,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.TRACK,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_TOP_ARTISTS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_ARTIST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.ARTIST,
|
||||
},
|
||||
BrowsableMedia.CURRENT_USER_TOP_TRACKS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_TRACK,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.TRACK,
|
||||
},
|
||||
BrowsableMedia.FEATURED_PLAYLISTS.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_PLAYLIST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.PLAYLIST,
|
||||
},
|
||||
BrowsableMedia.CATEGORIES.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_GENRE,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.GENRE,
|
||||
},
|
||||
"category_playlists": {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_PLAYLIST,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.PLAYLIST,
|
||||
},
|
||||
BrowsableMedia.NEW_RELEASES.value: {
|
||||
"parent": MEDIA_CLASS_DIRECTORY,
|
||||
"children": MEDIA_CLASS_ALBUM,
|
||||
"parent": MediaClass.DIRECTORY,
|
||||
"children": MediaClass.ALBUM,
|
||||
},
|
||||
MEDIA_TYPE_PLAYLIST: {
|
||||
"parent": MEDIA_CLASS_PLAYLIST,
|
||||
"children": MEDIA_CLASS_TRACK,
|
||||
MediaType.PLAYLIST: {
|
||||
"parent": MediaClass.PLAYLIST,
|
||||
"children": MediaClass.TRACK,
|
||||
},
|
||||
MEDIA_TYPE_ALBUM: {"parent": MEDIA_CLASS_ALBUM, "children": MEDIA_CLASS_TRACK},
|
||||
MEDIA_TYPE_ARTIST: {"parent": MEDIA_CLASS_ARTIST, "children": MEDIA_CLASS_ALBUM},
|
||||
MEDIA_TYPE_EPISODE: {"parent": MEDIA_CLASS_EPISODE, "children": None},
|
||||
MEDIA_TYPE_SHOW: {"parent": MEDIA_CLASS_PODCAST, "children": MEDIA_CLASS_EPISODE},
|
||||
MEDIA_TYPE_TRACK: {"parent": MEDIA_CLASS_TRACK, "children": None},
|
||||
MediaType.ALBUM: {"parent": MediaClass.ALBUM, "children": MediaClass.TRACK},
|
||||
MediaType.ARTIST: {"parent": MediaClass.ARTIST, "children": MediaClass.ALBUM},
|
||||
MediaType.EPISODE: {"parent": MediaClass.EPISODE, "children": None},
|
||||
MEDIA_TYPE_SHOW: {"parent": MediaClass.PODCAST, "children": MediaClass.EPISODE},
|
||||
MediaType.TRACK: {"parent": MediaClass.TRACK, "children": None},
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,7 +146,7 @@ async def async_browse_media(
|
|||
children.append(
|
||||
BrowseMedia(
|
||||
title=config_entry.title,
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_id=f"{MEDIA_PLAYER_PREFIX}{config_entry_id}",
|
||||
media_content_type=f"{MEDIA_PLAYER_PREFIX}library",
|
||||
thumbnail="https://brands.home-assistant.io/_/spotify/logo.png",
|
||||
|
@ -167,7 +156,7 @@ async def async_browse_media(
|
|||
)
|
||||
return BrowseMedia(
|
||||
title="Spotify",
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_id=MEDIA_PLAYER_PREFIX,
|
||||
media_content_type="spotify",
|
||||
thumbnail="https://brands.home-assistant.io/_/spotify/logo.png",
|
||||
|
@ -312,13 +301,13 @@ def build_item_response( # noqa: C901
|
|||
elif media_content_type == BrowsableMedia.NEW_RELEASES:
|
||||
if media := spotify.new_releases(country=user["country"], limit=BROWSE_LIMIT):
|
||||
items = media.get("albums", {}).get("items", [])
|
||||
elif media_content_type == MEDIA_TYPE_PLAYLIST:
|
||||
elif media_content_type == MediaType.PLAYLIST:
|
||||
if media := spotify.playlist(media_content_id):
|
||||
items = [item["track"] for item in media.get("tracks", {}).get("items", [])]
|
||||
elif media_content_type == MEDIA_TYPE_ALBUM:
|
||||
elif media_content_type == MediaType.ALBUM:
|
||||
if media := spotify.album(media_content_id):
|
||||
items = media.get("tracks", {}).get("items", [])
|
||||
elif media_content_type == MEDIA_TYPE_ARTIST:
|
||||
elif media_content_type == MediaType.ARTIST:
|
||||
if (media := spotify.artist_albums(media_content_id, limit=BROWSE_LIMIT)) and (
|
||||
artist := spotify.artist(media_content_id)
|
||||
):
|
||||
|
@ -364,8 +353,8 @@ def build_item_response( # noqa: C901
|
|||
BrowseMedia(
|
||||
can_expand=True,
|
||||
can_play=False,
|
||||
children_media_class=MEDIA_CLASS_TRACK,
|
||||
media_class=MEDIA_CLASS_PLAYLIST,
|
||||
children_media_class=MediaClass.TRACK,
|
||||
media_class=MediaClass.PLAYLIST,
|
||||
media_content_id=item_id,
|
||||
media_content_type=f"{MEDIA_PLAYER_PREFIX}category_playlists",
|
||||
thumbnail=fetch_image_url(item, key="icons"),
|
||||
|
@ -380,7 +369,7 @@ def build_item_response( # noqa: C901
|
|||
title = media["name"]
|
||||
|
||||
can_play = media_content_type in PLAYABLE_MEDIA_TYPES and (
|
||||
media_content_type != MEDIA_TYPE_ARTIST or can_play_artist
|
||||
media_content_type != MediaType.ARTIST or can_play_artist
|
||||
)
|
||||
|
||||
browse_media = BrowseMedia(
|
||||
|
@ -429,12 +418,12 @@ def item_payload(item: dict[str, Any], *, can_play_artist: bool) -> BrowseMedia:
|
|||
raise UnknownMediaType from err
|
||||
|
||||
can_expand = media_type not in [
|
||||
MEDIA_TYPE_TRACK,
|
||||
MEDIA_TYPE_EPISODE,
|
||||
MediaType.TRACK,
|
||||
MediaType.EPISODE,
|
||||
]
|
||||
|
||||
can_play = media_type in PLAYABLE_MEDIA_TYPES and (
|
||||
media_type != MEDIA_TYPE_ARTIST or can_play_artist
|
||||
media_type != MediaType.ARTIST or can_play_artist
|
||||
)
|
||||
|
||||
browse_media = BrowseMedia(
|
||||
|
@ -449,8 +438,8 @@ def item_payload(item: dict[str, Any], *, can_play_artist: bool) -> BrowseMedia:
|
|||
|
||||
if "images" in item:
|
||||
browse_media.thumbnail = fetch_image_url(item)
|
||||
elif MEDIA_TYPE_ALBUM in item:
|
||||
browse_media.thumbnail = fetch_image_url(item[MEDIA_TYPE_ALBUM])
|
||||
elif MediaType.ALBUM in item:
|
||||
browse_media.thumbnail = fetch_image_url(item[MediaType.ALBUM])
|
||||
|
||||
return browse_media
|
||||
|
||||
|
@ -464,8 +453,8 @@ def library_payload(*, can_play_artist: bool) -> BrowseMedia:
|
|||
browse_media = BrowseMedia(
|
||||
can_expand=True,
|
||||
can_play=False,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="library",
|
||||
media_content_type=f"{MEDIA_PLAYER_PREFIX}library",
|
||||
title="Media Library",
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_EPISODE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaType
|
||||
|
||||
DOMAIN = "spotify"
|
||||
|
||||
|
@ -35,10 +29,10 @@ MEDIA_PLAYER_PREFIX = "spotify://"
|
|||
MEDIA_TYPE_SHOW = "show"
|
||||
|
||||
PLAYABLE_MEDIA_TYPES = [
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_EPISODE,
|
||||
MediaType.PLAYLIST,
|
||||
MediaType.ALBUM,
|
||||
MediaType.ARTIST,
|
||||
MediaType.EPISODE,
|
||||
MEDIA_TYPE_SHOW,
|
||||
MEDIA_TYPE_TRACK,
|
||||
MediaType.TRACK,
|
||||
]
|
||||
|
|
|
@ -2,19 +2,11 @@
|
|||
import contextlib
|
||||
|
||||
from homeassistant.components import media_source
|
||||
from homeassistant.components.media_player import BrowseError, BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_GENRE,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_ARTIST,
|
||||
MEDIA_TYPE_GENRE,
|
||||
MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_TRACK,
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseError,
|
||||
BrowseMedia,
|
||||
MediaClass,
|
||||
MediaType,
|
||||
)
|
||||
from homeassistant.helpers.network import is_internal_request
|
||||
|
||||
|
@ -26,44 +18,44 @@ MEDIA_TYPE_TO_SQUEEZEBOX = {
|
|||
"Tracks": "titles",
|
||||
"Playlists": "playlists",
|
||||
"Genres": "genres",
|
||||
MEDIA_TYPE_ALBUM: "album",
|
||||
MEDIA_TYPE_ARTIST: "artist",
|
||||
MEDIA_TYPE_TRACK: "title",
|
||||
MEDIA_TYPE_PLAYLIST: "playlist",
|
||||
MEDIA_TYPE_GENRE: "genre",
|
||||
MediaType.ALBUM: "album",
|
||||
MediaType.ARTIST: "artist",
|
||||
MediaType.TRACK: "title",
|
||||
MediaType.PLAYLIST: "playlist",
|
||||
MediaType.GENRE: "genre",
|
||||
}
|
||||
|
||||
SQUEEZEBOX_ID_BY_TYPE = {
|
||||
MEDIA_TYPE_ALBUM: "album_id",
|
||||
MEDIA_TYPE_ARTIST: "artist_id",
|
||||
MEDIA_TYPE_TRACK: "track_id",
|
||||
MEDIA_TYPE_PLAYLIST: "playlist_id",
|
||||
MEDIA_TYPE_GENRE: "genre_id",
|
||||
MediaType.ALBUM: "album_id",
|
||||
MediaType.ARTIST: "artist_id",
|
||||
MediaType.TRACK: "track_id",
|
||||
MediaType.PLAYLIST: "playlist_id",
|
||||
MediaType.GENRE: "genre_id",
|
||||
}
|
||||
|
||||
CONTENT_TYPE_MEDIA_CLASS = {
|
||||
"Artists": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_ARTIST},
|
||||
"Albums": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_ALBUM},
|
||||
"Tracks": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_TRACK},
|
||||
"Playlists": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_PLAYLIST},
|
||||
"Genres": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_GENRE},
|
||||
MEDIA_TYPE_ALBUM: {"item": MEDIA_CLASS_ALBUM, "children": MEDIA_CLASS_TRACK},
|
||||
MEDIA_TYPE_ARTIST: {"item": MEDIA_CLASS_ARTIST, "children": MEDIA_CLASS_ALBUM},
|
||||
MEDIA_TYPE_TRACK: {"item": MEDIA_CLASS_TRACK, "children": None},
|
||||
MEDIA_TYPE_GENRE: {"item": MEDIA_CLASS_GENRE, "children": MEDIA_CLASS_ARTIST},
|
||||
MEDIA_TYPE_PLAYLIST: {"item": MEDIA_CLASS_PLAYLIST, "children": MEDIA_CLASS_TRACK},
|
||||
"Artists": {"item": MediaClass.DIRECTORY, "children": MediaClass.ARTIST},
|
||||
"Albums": {"item": MediaClass.DIRECTORY, "children": MediaClass.ALBUM},
|
||||
"Tracks": {"item": MediaClass.DIRECTORY, "children": MediaClass.TRACK},
|
||||
"Playlists": {"item": MediaClass.DIRECTORY, "children": MediaClass.PLAYLIST},
|
||||
"Genres": {"item": MediaClass.DIRECTORY, "children": MediaClass.GENRE},
|
||||
MediaType.ALBUM: {"item": MediaClass.ALBUM, "children": MediaClass.TRACK},
|
||||
MediaType.ARTIST: {"item": MediaClass.ARTIST, "children": MediaClass.ALBUM},
|
||||
MediaType.TRACK: {"item": MediaClass.TRACK, "children": None},
|
||||
MediaType.GENRE: {"item": MediaClass.GENRE, "children": MediaClass.ARTIST},
|
||||
MediaType.PLAYLIST: {"item": MediaClass.PLAYLIST, "children": MediaClass.TRACK},
|
||||
}
|
||||
|
||||
CONTENT_TYPE_TO_CHILD_TYPE = {
|
||||
MEDIA_TYPE_ALBUM: MEDIA_TYPE_TRACK,
|
||||
MEDIA_TYPE_PLAYLIST: MEDIA_TYPE_PLAYLIST,
|
||||
MEDIA_TYPE_ARTIST: MEDIA_TYPE_ALBUM,
|
||||
MEDIA_TYPE_GENRE: MEDIA_TYPE_ARTIST,
|
||||
"Artists": MEDIA_TYPE_ARTIST,
|
||||
"Albums": MEDIA_TYPE_ALBUM,
|
||||
"Tracks": MEDIA_TYPE_TRACK,
|
||||
"Playlists": MEDIA_TYPE_PLAYLIST,
|
||||
"Genres": MEDIA_TYPE_GENRE,
|
||||
MediaType.ALBUM: MediaType.TRACK,
|
||||
MediaType.PLAYLIST: MediaType.PLAYLIST,
|
||||
MediaType.ARTIST: MediaType.ALBUM,
|
||||
MediaType.GENRE: MediaType.ARTIST,
|
||||
"Artists": MediaType.ARTIST,
|
||||
"Albums": MediaType.ALBUM,
|
||||
"Tracks": MediaType.TRACK,
|
||||
"Playlists": MediaType.PLAYLIST,
|
||||
"Genres": MediaType.GENRE,
|
||||
}
|
||||
|
||||
BROWSE_LIMIT = 1000
|
||||
|
@ -141,7 +133,7 @@ async def library_payload(hass, player):
|
|||
"""Create response payload to describe contents of library."""
|
||||
library_info = {
|
||||
"title": "Music Library",
|
||||
"media_class": MEDIA_CLASS_DIRECTORY,
|
||||
"media_class": MediaClass.DIRECTORY,
|
||||
"media_content_id": "library",
|
||||
"media_content_type": "library",
|
||||
"can_play": False,
|
||||
|
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
from systembridgeconnector.models.media_directories import MediaDirectories
|
||||
from systembridgeconnector.models.media_files import File as MediaFile, MediaFiles
|
||||
|
||||
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY
|
||||
from homeassistant.components.media_player import MediaClass
|
||||
from homeassistant.components.media_source.const import (
|
||||
MEDIA_CLASS_MAP,
|
||||
MEDIA_MIME_TYPES,
|
||||
|
@ -97,26 +97,26 @@ class SystemBridgeSource(MediaSource):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=entry.entry_id,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=entry.title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
)
|
||||
|
||||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=children,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
|
||||
|
@ -138,7 +138,7 @@ def _build_root_paths(
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=entry.title,
|
||||
can_play=False,
|
||||
|
@ -147,17 +147,17 @@ def _build_root_paths(
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{entry.entry_id}~~{directory.key}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=f"{directory.key[:1].capitalize()}{directory.key[1:]}",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
for directory in media_directories.directories
|
||||
],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
)
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@ def _build_media_items(
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=identifier,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=f"{entry.title} - {path}",
|
||||
can_play=False,
|
||||
|
@ -199,7 +199,7 @@ def _build_media_item(
|
|||
ext = f"~~{media_file.mime_type}"
|
||||
|
||||
if media_file.is_directory or media_file.mime_type is None:
|
||||
media_class = MEDIA_CLASS_DIRECTORY
|
||||
media_class = MediaClass.DIRECTORY
|
||||
else:
|
||||
media_class = MEDIA_CLASS_MAP[media_file.mime_type.split("/", 1)[0]]
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ import voluptuous as vol
|
|||
import yarl
|
||||
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from homeassistant.components.media_player.const import (
|
||||
from homeassistant.components.media_player import (
|
||||
ATTR_MEDIA_ANNOUNCE,
|
||||
ATTR_MEDIA_CONTENT_ID,
|
||||
ATTR_MEDIA_CONTENT_TYPE,
|
||||
DOMAIN as DOMAIN_MP,
|
||||
MEDIA_TYPE_MUSIC,
|
||||
SERVICE_PLAY_MEDIA,
|
||||
MediaType,
|
||||
)
|
||||
from homeassistant.components.media_source import generate_media_source_id
|
||||
from homeassistant.const import (
|
||||
|
@ -224,7 +224,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
DOMAIN,
|
||||
str(yarl.URL.build(path=p_type, query=params)),
|
||||
),
|
||||
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
|
||||
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
||||
ATTR_MEDIA_ANNOUNCE: True,
|
||||
},
|
||||
blocking=True,
|
||||
|
|
|
@ -6,8 +6,7 @@ from typing import TYPE_CHECKING, Any
|
|||
|
||||
from yarl import URL
|
||||
|
||||
from homeassistant.components.media_player.const import MEDIA_CLASS_APP
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.components.media_source.error import Unresolvable
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
|
@ -85,12 +84,12 @@ class TTSMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_type="",
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_APP,
|
||||
children_media_class=MediaClass.APP,
|
||||
children=children,
|
||||
)
|
||||
|
||||
|
@ -111,7 +110,7 @@ class TTSMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{provider_domain}{params}",
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_type="provider",
|
||||
title=provider.name,
|
||||
thumbnail=f"https://brands.home-assistant.io/_/{provider_domain}/logo.png",
|
||||
|
|
|
@ -19,12 +19,7 @@ from pyunifiprotect.utils import from_js_time
|
|||
from yarl import URL
|
||||
|
||||
from homeassistant.components.camera import CameraImageView
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player.errors import BrowseError
|
||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
MediaSource,
|
||||
|
@ -422,7 +417,7 @@ class ProtectMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{nvr.id}:eventthumb:{event_id}",
|
||||
media_class=MEDIA_CLASS_IMAGE,
|
||||
media_class=MediaClass.IMAGE,
|
||||
media_content_type="image/jpeg",
|
||||
title=title,
|
||||
can_play=True,
|
||||
|
@ -435,7 +430,7 @@ class ProtectMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{nvr.id}:event:{event_id}",
|
||||
media_class=MEDIA_CLASS_VIDEO,
|
||||
media_class=MediaClass.VIDEO,
|
||||
media_content_type="video/mp4",
|
||||
title=title,
|
||||
can_play=True,
|
||||
|
@ -506,12 +501,12 @@ class ProtectMediaSource(MediaSource):
|
|||
source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{base_id}:recent:{days}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="video/mp4",
|
||||
title=title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
)
|
||||
|
||||
if not build_children:
|
||||
|
@ -560,12 +555,12 @@ class ProtectMediaSource(MediaSource):
|
|||
source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{base_id}:range:{start.year}:{start.month}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
)
|
||||
|
||||
if not build_children:
|
||||
|
@ -622,12 +617,12 @@ class ProtectMediaSource(MediaSource):
|
|||
source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=identifier,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
)
|
||||
|
||||
if not build_children:
|
||||
|
@ -692,12 +687,12 @@ class ProtectMediaSource(MediaSource):
|
|||
source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=base_id,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=title,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
)
|
||||
|
||||
if not build_children or data.api.bootstrap.recording_start is None:
|
||||
|
@ -781,13 +776,13 @@ class ProtectMediaSource(MediaSource):
|
|||
source = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{data.api.bootstrap.nvr.id}:browse:{camera_id}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
thumbnail=thumbnail_url,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
)
|
||||
|
||||
if not build_children:
|
||||
|
@ -837,12 +832,12 @@ class ProtectMediaSource(MediaSource):
|
|||
base = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{data.api.bootstrap.nvr.id}:browse",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=data.api.bootstrap.nvr.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
children=await self._build_cameras(data),
|
||||
)
|
||||
|
||||
|
@ -864,11 +859,11 @@ class ProtectMediaSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=None,
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type=VIDEO_FORMAT,
|
||||
title=self.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_VIDEO,
|
||||
children_media_class=MediaClass.VIDEO,
|
||||
children=consoles,
|
||||
)
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
"""Support for media browsing."""
|
||||
import json
|
||||
|
||||
from homeassistant.components.media_player import BrowseError, BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_ALBUM,
|
||||
MEDIA_CLASS_ARTIST,
|
||||
MEDIA_CLASS_CHANNEL,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_GENRE,
|
||||
MEDIA_CLASS_PLAYLIST,
|
||||
MEDIA_CLASS_TRACK,
|
||||
MEDIA_TYPE_MUSIC,
|
||||
from homeassistant.components.media_player import (
|
||||
BrowseError,
|
||||
BrowseMedia,
|
||||
MediaClass,
|
||||
MediaType,
|
||||
)
|
||||
|
||||
PLAYABLE_ITEM_TYPES = [
|
||||
|
@ -48,52 +43,52 @@ FAVOURITES_URI = "favourites"
|
|||
|
||||
def _item_to_children_media_class(item, info=None):
|
||||
if info and "album" in info and "artist" in info:
|
||||
return MEDIA_CLASS_TRACK
|
||||
return MediaClass.TRACK
|
||||
if item["uri"].startswith(PLAYLISTS_URI_PREFIX):
|
||||
return MEDIA_CLASS_PLAYLIST
|
||||
return MediaClass.PLAYLIST
|
||||
if item["uri"].startswith(ARTISTS_URI_PREFIX):
|
||||
if len(item["uri"]) > len(ARTISTS_URI_PREFIX):
|
||||
return MEDIA_CLASS_ALBUM
|
||||
return MEDIA_CLASS_ARTIST
|
||||
return MediaClass.ALBUM
|
||||
return MediaClass.ARTIST
|
||||
if item["uri"].startswith(ALBUMS_URI_PREFIX):
|
||||
if len(item["uri"]) > len(ALBUMS_URI_PREFIX):
|
||||
return MEDIA_CLASS_TRACK
|
||||
return MEDIA_CLASS_ALBUM
|
||||
return MediaClass.TRACK
|
||||
return MediaClass.ALBUM
|
||||
if item["uri"].startswith(GENRES_URI_PREFIX):
|
||||
if len(item["uri"]) > len(GENRES_URI_PREFIX):
|
||||
return MEDIA_CLASS_ALBUM
|
||||
return MEDIA_CLASS_GENRE
|
||||
return MediaClass.ALBUM
|
||||
return MediaClass.GENRE
|
||||
if item["uri"].startswith(LAST_100_URI_PREFIX) or item["uri"] == FAVOURITES_URI:
|
||||
return MEDIA_CLASS_TRACK
|
||||
return MediaClass.TRACK
|
||||
if item["uri"].startswith(RADIO_URI_PREFIX):
|
||||
return MEDIA_CLASS_CHANNEL
|
||||
return MEDIA_CLASS_DIRECTORY
|
||||
return MediaClass.CHANNEL
|
||||
return MediaClass.DIRECTORY
|
||||
|
||||
|
||||
def _item_to_media_class(item, parent_item=None):
|
||||
if "type" not in item:
|
||||
return MEDIA_CLASS_DIRECTORY
|
||||
return MediaClass.DIRECTORY
|
||||
if item["type"] in ("webradio", "mywebradio"):
|
||||
return MEDIA_CLASS_CHANNEL
|
||||
return MediaClass.CHANNEL
|
||||
if item["type"] in ("song", "cuesong"):
|
||||
return MEDIA_CLASS_TRACK
|
||||
return MediaClass.TRACK
|
||||
if item.get("artist"):
|
||||
return MEDIA_CLASS_ALBUM
|
||||
return MediaClass.ALBUM
|
||||
if item["uri"].startswith(ARTISTS_URI_PREFIX) and len(item["uri"]) > len(
|
||||
ARTISTS_URI_PREFIX
|
||||
):
|
||||
return MEDIA_CLASS_ARTIST
|
||||
return MediaClass.ARTIST
|
||||
if parent_item:
|
||||
return _item_to_children_media_class(parent_item)
|
||||
return MEDIA_CLASS_DIRECTORY
|
||||
return MediaClass.DIRECTORY
|
||||
|
||||
|
||||
def _list_payload(item, children=None):
|
||||
return BrowseMedia(
|
||||
title=item["name"],
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
children_media_class=_item_to_children_media_class(item),
|
||||
media_content_type=MEDIA_TYPE_MUSIC,
|
||||
media_content_type=MediaType.MUSIC,
|
||||
media_content_id=json.dumps(item),
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
|
@ -105,7 +100,7 @@ def _raw_item_payload(entity, item, parent_item=None, title=None, info=None):
|
|||
if thumbnail := item.get("albumart"):
|
||||
item_hash = str(hash(thumbnail))
|
||||
entity.thumbnail_cache.setdefault(item_hash, thumbnail)
|
||||
thumbnail = entity.get_browse_image_url(MEDIA_TYPE_MUSIC, item_hash)
|
||||
thumbnail = entity.get_browse_image_url(MediaType.MUSIC, item_hash)
|
||||
else:
|
||||
# don't use the built-in volumio white-on-white icons
|
||||
thumbnail = None
|
||||
|
@ -114,7 +109,7 @@ def _raw_item_payload(entity, item, parent_item=None, title=None, info=None):
|
|||
"title": title or item.get("title"),
|
||||
"media_class": _item_to_media_class(item, parent_item),
|
||||
"children_media_class": _item_to_children_media_class(item, info),
|
||||
"media_content_type": MEDIA_TYPE_MUSIC,
|
||||
"media_content_type": MediaType.MUSIC,
|
||||
"media_content_id": json.dumps(item),
|
||||
"can_play": item.get("type") in PLAYABLE_ITEM_TYPES,
|
||||
"can_expand": item.get("type") not in NON_EXPANDABLE_ITEM_TYPES,
|
||||
|
@ -131,7 +126,7 @@ async def browse_top_level(media_library):
|
|||
navigation = await media_library.browse()
|
||||
children = [_list_payload(item) for item in navigation["lists"]]
|
||||
return BrowseMedia(
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="library",
|
||||
media_content_type="library",
|
||||
title="Media Library",
|
||||
|
|
|
@ -16,14 +16,7 @@ from xbox.webapi.api.provider.smartglass.models import (
|
|||
InstalledPackagesList,
|
||||
)
|
||||
|
||||
from homeassistant.components.media_player import BrowseMedia
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_APP,
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_GAME,
|
||||
MEDIA_TYPE_APP,
|
||||
MEDIA_TYPE_GAME,
|
||||
)
|
||||
from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
|
||||
|
||||
|
||||
class MediaTypeDetails(NamedTuple):
|
||||
|
@ -35,12 +28,12 @@ class MediaTypeDetails(NamedTuple):
|
|||
|
||||
TYPE_MAP = {
|
||||
"App": MediaTypeDetails(
|
||||
type=MEDIA_TYPE_APP,
|
||||
cls=MEDIA_CLASS_APP,
|
||||
type=MediaType.APP,
|
||||
cls=MediaClass.APP,
|
||||
),
|
||||
"Game": MediaTypeDetails(
|
||||
type=MEDIA_TYPE_GAME,
|
||||
cls=MEDIA_CLASS_GAME,
|
||||
type=MediaType.GAME,
|
||||
cls=MediaClass.GAME,
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -58,7 +51,7 @@ async def build_item_response(
|
|||
if media_content_type in (None, "library"):
|
||||
children: list[BrowseMedia] = []
|
||||
library_info = BrowseMedia(
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id="library",
|
||||
media_content_type="library",
|
||||
title="Installed Applications",
|
||||
|
@ -79,9 +72,9 @@ async def build_item_response(
|
|||
)
|
||||
children.append(
|
||||
BrowseMedia(
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_id="Home",
|
||||
media_content_type=MEDIA_TYPE_APP,
|
||||
media_content_type=MediaType.APP,
|
||||
title="Home",
|
||||
can_play=True,
|
||||
can_expand=False,
|
||||
|
@ -102,9 +95,9 @@ async def build_item_response(
|
|||
)
|
||||
children.append(
|
||||
BrowseMedia(
|
||||
media_class=MEDIA_CLASS_APP,
|
||||
media_class=MediaClass.APP,
|
||||
media_content_id="TV",
|
||||
media_content_type=MEDIA_TYPE_APP,
|
||||
media_content_type=MediaType.APP,
|
||||
title="Live TV",
|
||||
can_play=True,
|
||||
can_expand=False,
|
||||
|
@ -118,7 +111,7 @@ async def build_item_response(
|
|||
for c_type in content_types:
|
||||
children.append(
|
||||
BrowseMedia(
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id=c_type,
|
||||
media_content_type=TYPE_MAP[c_type].type,
|
||||
title=f"{c_type}s",
|
||||
|
@ -145,7 +138,7 @@ async def build_item_response(
|
|||
}
|
||||
|
||||
return BrowseMedia(
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_id=media_content_id,
|
||||
media_content_type=media_content_type,
|
||||
title=f"{media_content_id}s",
|
||||
|
|
|
@ -11,12 +11,7 @@ from xbox.webapi.api.provider.gameclips.models import GameclipsResponse
|
|||
from xbox.webapi.api.provider.screenshots.models import ScreenshotResponse
|
||||
from xbox.webapi.api.provider.smartglass.models import InstalledPackage
|
||||
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_CLASS_DIRECTORY,
|
||||
MEDIA_CLASS_GAME,
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
)
|
||||
from homeassistant.components.media_player import MediaClass
|
||||
from homeassistant.components.media_source.models import (
|
||||
BrowseMediaSource,
|
||||
MediaSource,
|
||||
|
@ -35,8 +30,8 @@ MIME_TYPE_MAP = {
|
|||
}
|
||||
|
||||
MEDIA_CLASS_MAP = {
|
||||
"gameclips": MEDIA_CLASS_VIDEO,
|
||||
"screenshots": MEDIA_CLASS_IMAGE,
|
||||
"gameclips": MediaClass.VIDEO,
|
||||
"screenshots": MediaClass.IMAGE,
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,13 +115,13 @@ class XboxSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier="",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title="Xbox Game Media",
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[_build_game_item(game, images) for game in games.values()],
|
||||
children_media_class=MEDIA_CLASS_GAME,
|
||||
children_media_class=MediaClass.GAME,
|
||||
)
|
||||
|
||||
async def _build_media_items(self, title, category):
|
||||
|
@ -157,7 +152,7 @@ class XboxSource(MediaSource):
|
|||
).strftime("%b. %d, %Y %I:%M %p"),
|
||||
item.thumbnails[0].uri,
|
||||
item.game_clip_uris[0].uri,
|
||||
MEDIA_CLASS_VIDEO,
|
||||
MediaClass.VIDEO,
|
||||
)
|
||||
for item in response.game_clips
|
||||
]
|
||||
|
@ -182,7 +177,7 @@ class XboxSource(MediaSource):
|
|||
),
|
||||
item.thumbnails[0].uri,
|
||||
item.screenshot_uris[0].uri,
|
||||
MEDIA_CLASS_IMAGE,
|
||||
MediaClass.IMAGE,
|
||||
)
|
||||
for item in response.screenshots
|
||||
]
|
||||
|
@ -190,7 +185,7 @@ class XboxSource(MediaSource):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{title}~~{category}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=f"{owner.title()} {kind.title()}",
|
||||
can_play=False,
|
||||
|
@ -213,12 +208,12 @@ def _build_game_item(item: InstalledPackage, images: dict[str, list[Image]]):
|
|||
return BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{item.title_id}#{item.name}#{thumbnail}",
|
||||
media_class=MEDIA_CLASS_GAME,
|
||||
media_class=MediaClass.GAME,
|
||||
media_content_type="",
|
||||
title=item.name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
thumbnail=thumbnail,
|
||||
)
|
||||
|
||||
|
@ -229,13 +224,13 @@ def _build_categories(title):
|
|||
base = BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{title}",
|
||||
media_class=MEDIA_CLASS_GAME,
|
||||
media_class=MediaClass.GAME,
|
||||
media_content_type="",
|
||||
title=name,
|
||||
can_play=False,
|
||||
can_expand=True,
|
||||
children=[],
|
||||
children_media_class=MEDIA_CLASS_DIRECTORY,
|
||||
children_media_class=MediaClass.DIRECTORY,
|
||||
thumbnail=thumbnail,
|
||||
)
|
||||
|
||||
|
@ -247,7 +242,7 @@ def _build_categories(title):
|
|||
BrowseMediaSource(
|
||||
domain=DOMAIN,
|
||||
identifier=f"{title}~~{owner}#{kind}",
|
||||
media_class=MEDIA_CLASS_DIRECTORY,
|
||||
media_class=MediaClass.DIRECTORY,
|
||||
media_content_type="",
|
||||
title=f"{owner.title()} {kind.title()}",
|
||||
can_play=False,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue