Use new media player enums (#78264)

This commit is contained in:
epenet 2022-09-12 20:06:27 +02:00 committed by GitHub
parent 5e9c0399eb
commit 5c8e8e4860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 445 additions and 609 deletions

View File

@ -3,11 +3,7 @@ from __future__ import annotations
from typing import Optional, cast from typing import Optional, cast
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass
MEDIA_CLASS_APP,
MEDIA_CLASS_VIDEO,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -97,7 +93,7 @@ class CameraMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=camera.entity_id, identifier=camera.entity_id,
media_class=MEDIA_CLASS_VIDEO, media_class=MediaClass.VIDEO,
media_content_type=content_type, media_content_type=content_type,
title=camera.name, title=camera.name,
thumbnail=f"/api/camera_proxy/{camera.entity_id}", thumbnail=f"/api/camera_proxy/{camera.entity_id}",
@ -109,12 +105,12 @@ class CameraMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_type="", media_content_type="",
title="Camera", title="Camera",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
children=children, children=children,
not_shown=not_shown, not_shown=not_shown,
) )

View File

@ -17,8 +17,7 @@ from didl_lite import didl_lite
from homeassistant.backports.enum import StrEnum from homeassistant.backports.enum import StrEnum
from homeassistant.components import ssdp from homeassistant.components import ssdp
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY from homeassistant.components.media_player import BrowseError, MediaClass
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import BrowseMediaSource, PlayMedia from homeassistant.components.media_source.models import BrowseMediaSource, PlayMedia
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -518,7 +517,7 @@ class DmsDeviceSource:
media_source = BrowseMediaSource( media_source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=self._make_identifier(Action.SEARCH, query), identifier=self._make_identifier(Action.SEARCH, query),
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title="Search results", title="Search results",
can_play=False, can_play=False,

View File

@ -12,13 +12,7 @@ Media identifiers can look like:
from __future__ import annotations from __future__ import annotations
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_DIRECTORY,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_CHANNELS,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -82,20 +76,20 @@ class DmsMediaSource(MediaSource):
base = BrowseMediaSource( base = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_CHANNELS, media_content_type=MediaType.CHANNELS,
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_CHANNEL, children_media_class=MediaClass.CHANNEL,
) )
base.children = [ base.children = [
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{source_id}/{PATH_OBJECT_ID_FLAG}{ROOT_OBJECT_ID}", identifier=f"{source_id}/{PATH_OBJECT_ID_FLAG}{ROOT_OBJECT_ID}",
media_class=MEDIA_CLASS_CHANNEL, media_class=MediaClass.CHANNEL,
media_content_type=MEDIA_TYPE_CHANNEL, media_content_type=MediaType.CHANNEL,
title=source.name, title=source.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,

View File

@ -28,7 +28,7 @@ from homeassistant.components import (
from homeassistant.components.climate import const as climate from homeassistant.components.climate import const as climate
from homeassistant.components.humidifier import const as humidifier from homeassistant.components.humidifier import const as humidifier
from homeassistant.components.lock import STATE_JAMMED, STATE_UNLOCKING 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 ( from homeassistant.const import (
ATTR_ASSUMED_STATE, ATTR_ASSUMED_STATE,
ATTR_BATTERY_LEVEL, ATTR_BATTERY_LEVEL,
@ -2347,7 +2347,7 @@ class ChannelTrait(_Trait):
{ {
ATTR_ENTITY_ID: self.state.entity_id, ATTR_ENTITY_ID: self.state.entity_id,
media_player.ATTR_MEDIA_CONTENT_ID: channel_number, 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, blocking=not self.config.should_report_state,
context=data.context, context=data.context,

View File

@ -8,14 +8,7 @@ from typing import Any
from jellyfin_apiclient_python.api import jellyfin_url from jellyfin_apiclient_python.api import jellyfin_url
from jellyfin_apiclient_python.client import JellyfinClient from jellyfin_apiclient_python.client import JellyfinClient
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass
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_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
MediaSource, MediaSource,
@ -113,12 +106,12 @@ class JellyfinSource(MediaSource):
base = BrowseMediaSource( base = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_NONE, media_content_type=MEDIA_TYPE_NONE,
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
libraries = await self._get_libraries() libraries = await self._get_libraries()
@ -164,7 +157,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=library_id, identifier=library_id,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_NONE, media_content_type=MEDIA_TYPE_NONE,
title=library_name, title=library_name,
can_play=False, can_play=False,
@ -172,10 +165,10 @@ class JellyfinSource(MediaSource):
) )
if include_children: if include_children:
result.children_media_class = MEDIA_CLASS_ARTIST result.children_media_class = MediaClass.ARTIST
result.children = await self._build_artists(library_id) result.children = await self._build_artists(library_id)
if not result.children: 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) result.children = await self._build_albums(library_id)
return result return result
@ -197,7 +190,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=artist_id, identifier=artist_id,
media_class=MEDIA_CLASS_ARTIST, media_class=MediaClass.ARTIST,
media_content_type=MEDIA_TYPE_NONE, media_content_type=MEDIA_TYPE_NONE,
title=artist_name, title=artist_name,
can_play=False, can_play=False,
@ -206,7 +199,7 @@ class JellyfinSource(MediaSource):
) )
if include_children: if include_children:
result.children_media_class = MEDIA_CLASS_ALBUM result.children_media_class = MediaClass.ALBUM
result.children = await self._build_albums(artist_id) result.children = await self._build_albums(artist_id)
return result return result
@ -228,7 +221,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=album_id, identifier=album_id,
media_class=MEDIA_CLASS_ALBUM, media_class=MediaClass.ALBUM,
media_content_type=MEDIA_TYPE_NONE, media_content_type=MEDIA_TYPE_NONE,
title=album_title, title=album_title,
can_play=False, can_play=False,
@ -237,7 +230,7 @@ class JellyfinSource(MediaSource):
) )
if include_children: if include_children:
result.children_media_class = MEDIA_CLASS_TRACK result.children_media_class = MediaClass.TRACK
result.children = await self._build_tracks(album_id) result.children = await self._build_tracks(album_id)
return result return result
@ -264,7 +257,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=track_id, identifier=track_id,
media_class=MEDIA_CLASS_TRACK, media_class=MediaClass.TRACK,
media_content_type=mime_type, media_content_type=mime_type,
title=track_title, title=track_title,
can_play=True, can_play=True,
@ -284,7 +277,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=library_id, identifier=library_id,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_NONE, media_content_type=MEDIA_TYPE_NONE,
title=library_name, title=library_name,
can_play=False, can_play=False,
@ -292,7 +285,7 @@ class JellyfinSource(MediaSource):
) )
if include_children: if include_children:
result.children_media_class = MEDIA_CLASS_MOVIE result.children_media_class = MediaClass.MOVIE
result.children = await self._build_movies(library_id) result.children = await self._build_movies(library_id)
return result return result
@ -313,7 +306,7 @@ class JellyfinSource(MediaSource):
result = BrowseMediaSource( result = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=movie_id, identifier=movie_id,
media_class=MEDIA_CLASS_MOVIE, media_class=MediaClass.MOVIE,
media_content_type=mime_type, media_content_type=mime_type,
title=movie_title, title=movie_title,
can_play=True, can_play=True,

View File

@ -4,54 +4,37 @@ import contextlib
import logging import logging
from homeassistant.components import media_source from homeassistant.components import media_source
from homeassistant.components.media_player import BrowseError, BrowseMedia from homeassistant.components.media_player import (
from homeassistant.components.media_player.const import ( BrowseError,
MEDIA_CLASS_ALBUM, BrowseMedia,
MEDIA_CLASS_ARTIST, MediaClass,
MEDIA_CLASS_CHANNEL, MediaType,
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,
) )
PLAYABLE_MEDIA_TYPES = [ PLAYABLE_MEDIA_TYPES = [
MEDIA_TYPE_ALBUM, MediaType.ALBUM,
MEDIA_TYPE_ARTIST, MediaType.ARTIST,
MEDIA_TYPE_TRACK, MediaType.TRACK,
] ]
CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = { CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = {
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, MediaType.ALBUM: MediaClass.ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, MediaType.ARTIST: MediaClass.ARTIST,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, MediaType.PLAYLIST: MediaClass.PLAYLIST,
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, MediaType.SEASON: MediaClass.SEASON,
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, MediaType.TVSHOW: MediaClass.TV_SHOW,
} }
CHILD_TYPE_MEDIA_CLASS = { CHILD_TYPE_MEDIA_CLASS = {
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, MediaType.SEASON: MediaClass.SEASON,
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, MediaType.ALBUM: MediaClass.ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, MediaType.ARTIST: MediaClass.ARTIST,
MEDIA_TYPE_MOVIE: MEDIA_CLASS_MOVIE, MediaType.MOVIE: MediaClass.MOVIE,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, MediaType.PLAYLIST: MediaClass.PLAYLIST,
MEDIA_TYPE_TRACK: MEDIA_CLASS_TRACK, MediaType.TRACK: MediaClass.TRACK,
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, MediaType.TVSHOW: MediaClass.TV_SHOW,
MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL, MediaType.CHANNEL: MediaClass.CHANNEL,
MEDIA_TYPE_EPISODE: MEDIA_CLASS_EPISODE, MediaType.EPISODE: MediaClass.EPISODE,
} }
_LOGGER = logging.getLogger(__name__) _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) *(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) children.sort(key=lambda x: x.title.replace("The ", "", 1), reverse=False)
response = BrowseMedia( response = BrowseMedia(
media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get( media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get(
search_type, MEDIA_CLASS_DIRECTORY search_type, MediaClass.DIRECTORY
), ),
media_content_id=search_id, media_content_id=search_id,
media_content_type=search_type, 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": if search_type == "library_music":
response.children_media_class = MEDIA_CLASS_MUSIC response.children_media_class = MediaClass.MUSIC
else: else:
response.calculate_children_class() response.calculate_children_class()
@ -111,42 +94,42 @@ async def item_payload(item, get_thumbnail_url=None):
media_class = None media_class = None
if "songid" in item: if "songid" in item:
media_content_type = MEDIA_TYPE_TRACK media_content_type = MediaType.TRACK
media_content_id = f"{item['songid']}" media_content_id = f"{item['songid']}"
can_play = True can_play = True
can_expand = False can_expand = False
elif "albumid" in item: elif "albumid" in item:
media_content_type = MEDIA_TYPE_ALBUM media_content_type = MediaType.ALBUM
media_content_id = f"{item['albumid']}" media_content_id = f"{item['albumid']}"
can_play = True can_play = True
can_expand = True can_expand = True
elif "artistid" in item: elif "artistid" in item:
media_content_type = MEDIA_TYPE_ARTIST media_content_type = MediaType.ARTIST
media_content_id = f"{item['artistid']}" media_content_id = f"{item['artistid']}"
can_play = True can_play = True
can_expand = True can_expand = True
elif "movieid" in item: elif "movieid" in item:
media_content_type = MEDIA_TYPE_MOVIE media_content_type = MediaType.MOVIE
media_content_id = f"{item['movieid']}" media_content_id = f"{item['movieid']}"
can_play = True can_play = True
can_expand = False can_expand = False
elif "episodeid" in item: elif "episodeid" in item:
media_content_type = MEDIA_TYPE_EPISODE media_content_type = MediaType.EPISODE
media_content_id = f"{item['episodeid']}" media_content_id = f"{item['episodeid']}"
can_play = True can_play = True
can_expand = False can_expand = False
elif "seasonid" in item: elif "seasonid" in item:
media_content_type = MEDIA_TYPE_SEASON media_content_type = MediaType.SEASON
media_content_id = f"{item['tvshowid']}/{item['season']}" media_content_id = f"{item['tvshowid']}/{item['season']}"
can_play = False can_play = False
can_expand = True can_expand = True
elif "tvshowid" in item: elif "tvshowid" in item:
media_content_type = MEDIA_TYPE_TVSHOW media_content_type = MediaType.TVSHOW
media_content_id = f"{item['tvshowid']}" media_content_id = f"{item['tvshowid']}"
can_play = False can_play = False
can_expand = True can_expand = True
elif "channelid" in item: elif "channelid" in item:
media_content_type = MEDIA_TYPE_CHANNEL media_content_type = MediaType.CHANNEL
media_content_id = f"{item['channelid']}" media_content_id = f"{item['channelid']}"
if broadcasting := item.get("broadcastnow"): if broadcasting := item.get("broadcastnow"):
show = broadcasting.get("title") show = broadcasting.get("title")
@ -156,7 +139,7 @@ async def item_payload(item, get_thumbnail_url=None):
else: else:
# this case is for the top folder of each type # this case is for the top folder of each type
# possible content types: album, artist, movie, library_music, tvshow, channel # 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_type = item["type"]
media_content_id = "" media_content_id = ""
can_play = False can_play = False
@ -202,7 +185,7 @@ async def library_payload(hass):
Used by async_browse_media. Used by async_browse_media.
""" """
library_info = BrowseMedia( library_info = BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="library", media_content_id="library",
media_content_type="library", media_content_type="library",
title="Media Library", title="Media Library",
@ -213,9 +196,9 @@ async def library_payload(hass):
library = { library = {
"library_music": "Music", "library_music": "Music",
MEDIA_TYPE_MOVIE: "Movies", MediaType.MOVIE: "Movies",
MEDIA_TYPE_TVSHOW: "TV shows", MediaType.TVSHOW: "TV shows",
MEDIA_TYPE_CHANNEL: "Channels", MediaType.CHANNEL: "Channels",
} }
library_info.children = await asyncio.gather( library_info.children = await asyncio.gather(
@ -256,7 +239,7 @@ async def get_media_info(media_library, search_id, search_type):
media = None media = None
properties = ["thumbnail"] properties = ["thumbnail"]
if search_type == MEDIA_TYPE_ALBUM: if search_type == MediaType.ALBUM:
if search_id: if search_id:
album = await media_library.get_album_details( album = await media_library.get_album_details(
album_id=int(search_id), properties=properties 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") media = media.get("albums")
title = "Albums" title = "Albums"
elif search_type == MEDIA_TYPE_ARTIST: elif search_type == MediaType.ARTIST:
if search_id: if search_id:
media = await media_library.get_albums( media = await media_library.get_albums(
artist_id=int(search_id), properties=properties artist_id=int(search_id), properties=properties
@ -301,11 +284,11 @@ async def get_media_info(media_library, search_id, search_type):
title = "Artists" title = "Artists"
elif search_type == "library_music": 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()] media = [{"label": name, "type": type_} for type_, name in library.items()]
title = "Music Library" title = "Music Library"
elif search_type == MEDIA_TYPE_MOVIE: elif search_type == MediaType.MOVIE:
if search_id: if search_id:
movie = await media_library.get_movie_details( movie = await media_library.get_movie_details(
movie_id=int(search_id), properties=properties 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") media = media.get("movies")
title = "Movies" title = "Movies"
elif search_type == MEDIA_TYPE_TVSHOW: elif search_type == MediaType.TVSHOW:
if search_id: if search_id:
media = await media_library.get_seasons( media = await media_library.get_seasons(
tv_show_id=int(search_id), 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") media = media.get("tvshows")
title = "TV Shows" title = "TV Shows"
elif search_type == MEDIA_TYPE_SEASON: elif search_type == MediaType.SEASON:
tv_show_id, season_id = search_id.split("/", 1) tv_show_id, season_id = search_id.split("/", 1)
media = await media_library.get_episodes( media = await media_library.get_episodes(
tv_show_id=int(tv_show_id), 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"] title = season["seasondetails"]["label"]
elif search_type == MEDIA_TYPE_CHANNEL: elif search_type == MediaType.CHANNEL:
media = await media_library.get_channels( media = await media_library.get_channels(
channel_group_id="alltv", channel_group_id="alltv",
properties=["thumbnail", "channeltype", "channel", "broadcastnow"], properties=["thumbnail", "channeltype", "channel", "broadcastnow"],

View File

@ -1,18 +1,14 @@
"""Constants for the media_source integration.""" """Constants for the media_source integration."""
import re import re
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaClass
MEDIA_CLASS_IMAGE,
MEDIA_CLASS_MUSIC,
MEDIA_CLASS_VIDEO,
)
DOMAIN = "media_source" DOMAIN = "media_source"
MEDIA_MIME_TYPES = ("audio", "video", "image") MEDIA_MIME_TYPES = ("audio", "video", "image")
MEDIA_CLASS_MAP = { MEDIA_CLASS_MAP = {
"audio": MEDIA_CLASS_MUSIC, "audio": MediaClass.MUSIC,
"video": MEDIA_CLASS_VIDEO, "video": MediaClass.VIDEO,
"image": MEDIA_CLASS_IMAGE, "image": MediaClass.IMAGE,
} }
URI_SCHEME = "media-source://" URI_SCHEME = "media-source://"
URI_SCHEME_REGEX = re.compile( URI_SCHEME_REGEX = re.compile(

View File

@ -11,8 +11,7 @@ from aiohttp.web_request import FileField
import voluptuous as vol import voluptuous as vol
from homeassistant.components import http, websocket_api from homeassistant.components import http, websocket_api
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY from homeassistant.components.media_player import BrowseError, MediaClass
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import Unauthorized from homeassistant.exceptions import Unauthorized
from homeassistant.util import raise_if_invalid_filename, raise_if_invalid_path from homeassistant.util import raise_if_invalid_filename, raise_if_invalid_path
@ -109,12 +108,12 @@ class LocalSource(MediaSource):
base = BrowseMediaSource( base = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=None, media_content_type=None,
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
base.children = [ base.children = [
@ -158,10 +157,10 @@ class LocalSource(MediaSource):
title = path.name title = path.name
media_class = MEDIA_CLASS_DIRECTORY media_class = MediaClass.DIRECTORY
if mime_type: if mime_type:
media_class = MEDIA_CLASS_MAP.get( media_class = MEDIA_CLASS_MAP.get(
mime_type.split("/")[0], MEDIA_CLASS_DIRECTORY mime_type.split("/")[0], MediaClass.DIRECTORY
) )
media = BrowseMediaSource( media = BrowseMediaSource(

View File

@ -5,12 +5,7 @@ from abc import ABC
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, cast from typing import Any, cast
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
from homeassistant.components.media_player.const import (
MEDIA_CLASS_APP,
MEDIA_TYPE_APP,
MEDIA_TYPE_APPS,
)
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from .const import DOMAIN, URI_SCHEME, URI_SCHEME_REGEX from .const import DOMAIN, URI_SCHEME, URI_SCHEME_REGEX
@ -56,20 +51,20 @@ class MediaSourceItem:
base = BrowseMediaSource( base = BrowseMediaSource(
domain=None, domain=None,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_type=MEDIA_TYPE_APPS, media_content_type=MediaType.APPS,
title="Media Sources", title="Media Sources",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_APP, children_media_class=MediaClass.APP,
) )
base.children = sorted( base.children = sorted(
( (
BrowseMediaSource( BrowseMediaSource(
domain=source.domain, domain=source.domain,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_type=MEDIA_TYPE_APP, media_content_type=MediaType.APP,
thumbnail=f"https://brands.home-assistant.io/_/{source.domain}/logo.png", thumbnail=f"https://brands.home-assistant.io/_/{source.domain}/logo.png",
title=source.name, title=source.name,
can_play=False, can_play=False,

View File

@ -7,13 +7,7 @@ from typing import Optional, cast
from motioneye_client.const import KEY_MEDIA_LIST, KEY_MIME_TYPE, KEY_PATH from motioneye_client.const import KEY_MEDIA_LIST, KEY_MIME_TYPE, KEY_PATH
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaClass, MediaType
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_IMAGE,
MEDIA_CLASS_VIDEO,
MEDIA_TYPE_IMAGE,
MEDIA_TYPE_VIDEO,
)
from homeassistant.components.media_source.error import MediaSourceError, Unresolvable from homeassistant.components.media_source.error import MediaSourceError, Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -34,8 +28,8 @@ MIME_TYPE_MAP = {
} }
MEDIA_CLASS_MAP = { MEDIA_CLASS_MAP = {
"movies": MEDIA_CLASS_VIDEO, "movies": MediaClass.VIDEO,
"images": MEDIA_CLASS_IMAGE, "images": MediaClass.IMAGE,
} }
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -172,12 +166,12 @@ class MotionEyeMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=config.entry_id, identifier=config.entry_id,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=config.title, title=config.title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
def _build_media_configs(self) -> BrowseMediaSource: def _build_media_configs(self) -> BrowseMediaSource:
@ -185,7 +179,7 @@ class MotionEyeMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title="motionEye Media", title="motionEye Media",
can_play=False, can_play=False,
@ -194,7 +188,7 @@ class MotionEyeMediaSource(MediaSource):
self._build_media_config(entry) self._build_media_config(entry)
for entry in self.hass.config_entries.async_entries(DOMAIN) for entry in self.hass.config_entries.async_entries(DOMAIN)
], ],
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
@classmethod @classmethod
@ -207,12 +201,12 @@ class MotionEyeMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{config.entry_id}#{device.id}", identifier=f"{config.entry_id}#{device.id}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=f"{config.title} {device.name}" if full_title else device.name, title=f"{config.title} {device.name}" if full_title else device.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
def _build_media_devices(self, config: ConfigEntry) -> BrowseMediaSource: def _build_media_devices(self, config: ConfigEntry) -> BrowseMediaSource:
@ -238,9 +232,9 @@ class MotionEyeMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{config.entry_id}#{device.id}#{kind}", identifier=f"{config.entry_id}#{device.id}#{kind}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=( media_content_type=(
MEDIA_TYPE_VIDEO if kind == "movies" else MEDIA_TYPE_IMAGE MediaType.VIDEO if kind == "movies" else MediaType.IMAGE
), ),
title=( title=(
f"{config.title} {device.name} {kind.title()}" f"{config.title} {device.name} {kind.title()}"
@ -250,7 +244,7 @@ class MotionEyeMediaSource(MediaSource):
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=( 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"{config.entry_id}#{device.id}"
f"#{kind}#{full_child_path}" f"#{kind}#{full_child_path}"
), ),
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=( media_content_type=(
MEDIA_TYPE_VIDEO MediaType.VIDEO
if kind == "movies" if kind == "movies"
else MEDIA_TYPE_IMAGE else MediaType.IMAGE
), ),
title=display_child_path, title=display_child_path,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
) )
return base return base

View File

@ -36,14 +36,7 @@ from google_nest_sdm.google_nest_subscriber import GoogleNestSubscriber
from google_nest_sdm.transcoder import Transcoder from google_nest_sdm.transcoder import Transcoder
from homeassistant.components.ffmpeg import get_ffmpeg_manager from homeassistant.components.ffmpeg import get_ffmpeg_manager
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
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_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -450,9 +443,9 @@ def _browse_root() -> BrowseMediaSource:
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_VIDEO, media_content_type=MediaType.VIDEO,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
title=MEDIA_SOURCE_TITLE, title=MEDIA_SOURCE_TITLE,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -482,9 +475,9 @@ def _browse_device(device_id: MediaId, device: Device) -> BrowseMediaSource:
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=device_id.identifier, identifier=device_id.identifier,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_VIDEO, media_content_type=MediaType.VIDEO,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
title=DEVICE_TITLE_FORMAT.format(device_name=device_info.device_name), title=DEVICE_TITLE_FORMAT.format(device_name=device_info.device_name),
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -503,8 +496,8 @@ def _browse_clip_preview(
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=event_id.identifier, identifier=event_id.identifier,
media_class=MEDIA_CLASS_IMAGE, media_class=MediaClass.IMAGE,
media_content_type=MEDIA_TYPE_IMAGE, media_content_type=MediaType.IMAGE,
title=CLIP_TITLE_FORMAT.format( title=CLIP_TITLE_FORMAT.format(
event_name=", ".join(types), event_name=", ".join(types),
event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT), event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT),
@ -525,8 +518,8 @@ def _browse_image_event(
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=event_id.identifier, identifier=event_id.identifier,
media_class=MEDIA_CLASS_IMAGE, media_class=MediaClass.IMAGE,
media_content_type=MEDIA_TYPE_IMAGE, media_content_type=MediaType.IMAGE,
title=CLIP_TITLE_FORMAT.format( title=CLIP_TITLE_FORMAT.format(
event_name=MEDIA_SOURCE_EVENT_TITLE_MAP.get(event.event_type, "Event"), event_name=MEDIA_SOURCE_EVENT_TITLE_MAP.get(event.event_type, "Event"),
event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT), event_time=dt_util.as_local(event.timestamp).strftime(DATE_STR_FORMAT),

View File

@ -5,12 +5,7 @@ import datetime as dt
import logging import logging
import re import re
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_VIDEO,
MEDIA_TYPE_VIDEO,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import MediaSourceError, Unresolvable from homeassistant.components.media_source.error import MediaSourceError, Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -102,13 +97,13 @@ class NetatmoSource(MediaSource):
else: else:
path = f"{source}/{camera_id}" 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( media = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=path, identifier=path,
media_class=media_class, media_class=media_class,
media_content_type=MEDIA_TYPE_VIDEO, media_content_type=MediaType.VIDEO,
title=title, title=title,
can_play=bool( can_play=bool(
event_id and self.events[camera_id][event_id].get("media_url") event_id and self.events[camera_id][event_id].get("media_url")

View File

@ -3,20 +3,7 @@ from __future__ import annotations
from yarl import URL from yarl import URL
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import BrowseError, BrowseMedia, MediaClass
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 .const import DOMAIN, SERVERS from .const import DOMAIN, SERVERS
from .errors import MediaNotFound from .errors import MediaNotFound
@ -29,18 +16,18 @@ class UnknownMediaType(BrowseError):
EXPANDABLES = ["album", "artist", "playlist", "season", "show"] EXPANDABLES = ["album", "artist", "playlist", "season", "show"]
ITEM_TYPE_MEDIA_CLASS = { ITEM_TYPE_MEDIA_CLASS = {
"album": MEDIA_CLASS_ALBUM, "album": MediaClass.ALBUM,
"artist": MEDIA_CLASS_ARTIST, "artist": MediaClass.ARTIST,
"clip": MEDIA_CLASS_VIDEO, "clip": MediaClass.VIDEO,
"episode": MEDIA_CLASS_EPISODE, "episode": MediaClass.EPISODE,
"mixed": MEDIA_CLASS_DIRECTORY, "mixed": MediaClass.DIRECTORY,
"movie": MEDIA_CLASS_MOVIE, "movie": MediaClass.MOVIE,
"playlist": MEDIA_CLASS_PLAYLIST, "playlist": MediaClass.PLAYLIST,
"season": MEDIA_CLASS_SEASON, "season": MediaClass.SEASON,
"show": MEDIA_CLASS_TV_SHOW, "show": MediaClass.TV_SHOW,
"station": MEDIA_CLASS_ARTIST, "station": MediaClass.ARTIST,
"track": MEDIA_CLASS_TRACK, "track": MediaClass.TRACK,
"video": MEDIA_CLASS_VIDEO, "video": MediaClass.VIDEO,
} }
@ -99,13 +86,13 @@ def browse_media( # noqa: C901
"""Create response payload to describe libraries of the Plex server.""" """Create response payload to describe libraries of the Plex server."""
server_info = BrowseMedia( server_info = BrowseMedia(
title=plex_server.friendly_name, 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_id=generate_plex_uri(server_id, "server"),
media_content_type="server", media_content_type="server",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[], children=[],
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
thumbnail="https://brands.home-assistant.io/_/plex/logo.png", thumbnail="https://brands.home-assistant.io/_/plex/logo.png",
) )
if platform != "sonos": if platform != "sonos":
@ -136,7 +123,7 @@ def browse_media( # noqa: C901
"""Create response payload for all available playlists.""" """Create response payload for all available playlists."""
playlists_info = { playlists_info = {
"title": "Playlists", "title": "Playlists",
"media_class": MEDIA_CLASS_DIRECTORY, "media_class": MediaClass.DIRECTORY,
"media_content_id": generate_plex_uri(server_id, "all"), "media_content_id": generate_plex_uri(server_id, "all"),
"media_content_type": "playlists", "media_content_type": "playlists",
"can_play": False, "can_play": False,
@ -151,7 +138,7 @@ def browse_media( # noqa: C901
except UnknownMediaType: except UnknownMediaType:
continue continue
response = BrowseMedia(**playlists_info) response = BrowseMedia(**playlists_info)
response.children_media_class = MEDIA_CLASS_PLAYLIST response.children_media_class = MediaClass.PLAYLIST
return response return response
def build_item_response(payload): def build_item_response(payload):
@ -197,7 +184,7 @@ def browse_media( # noqa: C901
raise UnknownMediaType(f"Unknown type received: {hub.type}") from err raise UnknownMediaType(f"Unknown type received: {hub.type}") from err
payload = { payload = {
"title": hub.title, "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_id": generate_plex_uri(server_id, media_content_id),
"media_content_type": "hub", "media_content_type": "hub",
"can_play": False, "can_play": False,
@ -223,7 +210,7 @@ def browse_media( # noqa: C901
if special_folder: if special_folder:
if media_content_type == "server": if media_content_type == "server":
library_or_section = plex_server.library library_or_section = plex_server.library
children_media_class = MEDIA_CLASS_DIRECTORY children_media_class = MediaClass.DIRECTORY
title = plex_server.friendly_name title = plex_server.friendly_name
elif media_content_type == "library": elif media_content_type == "library":
library_or_section = plex_server.library.sectionByID(int(media_content_id)) library_or_section = plex_server.library.sectionByID(int(media_content_id))
@ -241,7 +228,7 @@ def browse_media( # noqa: C901
payload = { payload = {
"title": title, "title": title,
"media_class": MEDIA_CLASS_DIRECTORY, "media_class": MediaClass.DIRECTORY,
"media_content_id": generate_plex_uri( "media_content_id": generate_plex_uri(
server_id, f"{media_content_id}/{special_folder}" server_id, f"{media_content_id}/{special_folder}"
), ),
@ -323,7 +310,7 @@ def root_payload(hass, is_internal, platform=None):
return BrowseMedia( return BrowseMedia(
title="Plex", title="Plex",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="plex_root", media_content_type="plex_root",
can_play=False, can_play=False,
@ -341,7 +328,7 @@ def library_section_payload(section):
server_id = section._server.machineIdentifier # pylint: disable=protected-access server_id = section._server.machineIdentifier # pylint: disable=protected-access
return BrowseMedia( return BrowseMedia(
title=section.title, title=section.title,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id=generate_plex_uri(server_id, section.key), media_content_id=generate_plex_uri(server_id, section.key),
media_content_type="library", media_content_type="library",
can_play=False, can_play=False,
@ -374,7 +361,7 @@ def hub_payload(hub):
server_id = hub._server.machineIdentifier # pylint: disable=protected-access server_id = hub._server.machineIdentifier # pylint: disable=protected-access
payload = { payload = {
"title": hub.title, "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_id": generate_plex_uri(server_id, media_content_id),
"media_content_type": "hub", "media_content_type": "hub",
"can_play": False, "can_play": False,

View File

@ -1,12 +1,7 @@
"""Models to represent various Plex objects used in the integration.""" """Models to represent various Plex objects used in the integration."""
import logging import logging
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaType
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
MEDIA_TYPE_VIDEO,
)
from homeassistant.helpers.template import result_as_boolean from homeassistant.helpers.template import result_as_boolean
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -92,19 +87,19 @@ class PlexSession:
) )
if media.type == "episode": if media.type == "episode":
self.media_content_type = MEDIA_TYPE_TVSHOW self.media_content_type = MediaType.TVSHOW
self.media_season = media.seasonNumber self.media_season = media.seasonNumber
self.media_series_title = media.grandparentTitle self.media_series_title = media.grandparentTitle
if media.index is not None: if media.index is not None:
self.media_episode = media.index self.media_episode = media.index
self.sensor_title = f"{self.media_series_title} - {media.seasonEpisode} - {self.media_title}" self.sensor_title = f"{self.media_series_title} - {media.seasonEpisode} - {self.media_title}"
elif media.type == "movie": 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: if media.year is not None and media.title is not None:
self.media_title += f" ({media.year!s})" self.media_title += f" ({media.year!s})"
self.sensor_title = self.media_title self.sensor_title = self.media_title
elif media.type == "track": 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_name = media.parentTitle
self.media_album_artist = media.grandparentTitle self.media_album_artist = media.grandparentTitle
self.media_track = media.index self.media_track = media.index
@ -113,7 +108,7 @@ class PlexSession:
f"{self.media_artist} - {self.media_album_name} - {self.media_title}" f"{self.media_artist} - {self.media_album_name} - {self.media_title}"
) )
elif media.type == "clip": elif media.type == "clip":
self.media_content_type = MEDIA_TYPE_VIDEO self.media_content_type = MediaType.VIDEO
self.sensor_title = media.title self.sensor_title = media.title
else: else:
self.sensor_title = "Unknown" self.sensor_title = "Unknown"

View File

@ -12,8 +12,7 @@ import plexapi.server
from requests import Session from requests import Session
import requests.exceptions import requests.exceptions
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN from homeassistant.components.media_player import DOMAIN as MP_DOMAIN, MediaType
from homeassistant.components.media_player.const import MEDIA_TYPE_PLAYLIST
from homeassistant.const import CONF_CLIENT_ID, CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL from homeassistant.const import CONF_CLIENT_ID, CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.debounce import Debouncer
@ -627,7 +626,7 @@ class PlexServer:
except NotFound as err: except NotFound as err:
raise MediaNotFound(f"Media for key {key} not found") from err raise MediaNotFound(f"Media for key {key} not found") from err
if media_type == MEDIA_TYPE_PLAYLIST: if media_type == MediaType.PLAYLIST:
try: try:
playlist_name = kwargs["playlist_name"] playlist_name = kwargs["playlist_name"]
return self.playlist(playlist_name) return self.playlist(playlist_name)

View File

@ -7,10 +7,10 @@ from pyps4_2ndscreen.media_art import COUNTRIES
import voluptuous as vol import voluptuous as vol
from homeassistant.components import persistent_notification 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_CONTENT_TYPE,
ATTR_MEDIA_TITLE, ATTR_MEDIA_TITLE,
MEDIA_TYPE_GAME, MediaType,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
@ -206,7 +206,7 @@ def _reformat_data(hass: HomeAssistant, games: dict, unique_id: str) -> dict:
ATTR_LOCKED: False, ATTR_LOCKED: False,
ATTR_MEDIA_TITLE: data, ATTR_MEDIA_TITLE: data,
ATTR_MEDIA_IMAGE_URL: None, ATTR_MEDIA_IMAGE_URL: None,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_GAME, ATTR_MEDIA_CONTENT_TYPE: MediaType.GAME,
} }
data_reformatted = True data_reformatted = True

View File

@ -5,13 +5,7 @@ import mimetypes
from radios import FilterBy, Order, RadioBrowser, Station from radios import FilterBy, Order, RadioBrowser, Station
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass, MediaType
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_MUSIC,
MEDIA_TYPE_MUSIC,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -88,12 +82,12 @@ class RadioMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_CHANNEL, media_class=MediaClass.CHANNEL,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title=self.entry.title, title=self.entry.title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
children=[ children=[
*await self._async_build_popular(radios, item), *await self._async_build_popular(radios, item),
*await self._async_build_by_tag(radios, item), *await self._async_build_by_tag(radios, item),
@ -128,7 +122,7 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=station.uuid, identifier=station.uuid,
media_class=MEDIA_CLASS_MUSIC, media_class=MediaClass.MUSIC,
media_content_type=mime_type, media_content_type=mime_type,
title=station.name, title=station.name,
can_play=True, can_play=True,
@ -161,8 +155,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"country/{country.code}", identifier=f"country/{country.code}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title=country.name, title=country.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -194,8 +188,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"language/{language.code}", identifier=f"language/{language.code}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title=language.name, title=language.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -209,8 +203,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="language", identifier="language",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title="By Language", title="By Language",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -237,8 +231,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="popular", identifier="popular",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title="Popular", title="Popular",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -277,8 +271,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"tag/{tag.name}", identifier=f"tag/{tag.name}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title=tag.name.title(), title=tag.name.title(),
can_play=False, can_play=False,
can_expand=True, can_expand=True,
@ -291,8 +285,8 @@ class RadioMediaSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="tag", identifier="tag",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=MEDIA_TYPE_MUSIC, media_content_type=MediaType.MUSIC,
title="By Category", title="By Category",
can_play=False, can_play=False,
can_expand=True, can_expand=True,

View File

@ -5,17 +5,12 @@ from collections.abc import Callable
from functools import partial from functools import partial
from homeassistant.components import media_source from homeassistant.components import media_source
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import (
from homeassistant.components.media_player.const import ( BrowseError,
MEDIA_CLASS_APP, BrowseMedia,
MEDIA_CLASS_CHANNEL, MediaClass,
MEDIA_CLASS_DIRECTORY, MediaType,
MEDIA_TYPE_APP,
MEDIA_TYPE_APPS,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_CHANNELS,
) )
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.network import is_internal_request from homeassistant.helpers.network import is_internal_request
@ -23,25 +18,25 @@ from .coordinator import RokuDataUpdateCoordinator
from .helpers import format_channel_name from .helpers import format_channel_name
CONTENT_TYPE_MEDIA_CLASS = { CONTENT_TYPE_MEDIA_CLASS = {
MEDIA_TYPE_APP: MEDIA_CLASS_APP, MediaType.APP: MediaClass.APP,
MEDIA_TYPE_APPS: MEDIA_CLASS_APP, MediaType.APPS: MediaClass.APP,
MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL, MediaType.CHANNEL: MediaClass.CHANNEL,
MEDIA_TYPE_CHANNELS: MEDIA_CLASS_CHANNEL, MediaType.CHANNELS: MediaClass.CHANNEL,
} }
CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = { CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = {
MEDIA_TYPE_APPS: MEDIA_CLASS_DIRECTORY, MediaType.APPS: MediaClass.DIRECTORY,
MEDIA_TYPE_CHANNELS: MEDIA_CLASS_DIRECTORY, MediaType.CHANNELS: MediaClass.DIRECTORY,
} }
PLAYABLE_MEDIA_TYPES = [ PLAYABLE_MEDIA_TYPES = [
MEDIA_TYPE_APP, MediaType.APP,
MEDIA_TYPE_CHANNEL, MediaType.CHANNEL,
] ]
EXPANDABLE_MEDIA_TYPES = [ EXPANDABLE_MEDIA_TYPES = [
MEDIA_TYPE_APPS, MediaType.APPS,
MEDIA_TYPE_CHANNELS, MediaType.CHANNELS,
] ]
GetBrowseImageUrlType = Callable[[str, str, "str | None"], str] GetBrowseImageUrlType = Callable[[str, str, "str | None"], str]
@ -57,7 +52,7 @@ def get_thumbnail_url_full(
) -> str | None: ) -> str | None:
"""Get thumbnail URL.""" """Get thumbnail URL."""
if is_internal: 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 coordinator.roku.app_icon_url(media_content_id)
return None return None
@ -119,7 +114,7 @@ async def root_payload(
children = [ children = [
item_payload( item_payload(
{"title": "Apps", "type": MEDIA_TYPE_APPS}, {"title": "Apps", "type": MediaType.APPS},
coordinator, coordinator,
get_browse_image_url, get_browse_image_url,
) )
@ -128,7 +123,7 @@ async def root_payload(
if device.info.device_type == "tv" and len(device.channels) > 0: if device.info.device_type == "tv" and len(device.channels) > 0:
children.append( children.append(
item_payload( item_payload(
{"title": "TV Channels", "type": MEDIA_TYPE_CHANNELS}, {"title": "TV Channels", "type": MediaType.CHANNELS},
coordinator, coordinator,
get_browse_image_url, get_browse_image_url,
) )
@ -160,7 +155,7 @@ async def root_payload(
return BrowseMedia( return BrowseMedia(
title="Roku", title="Roku",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="root", media_content_type="root",
can_play=False, can_play=False,
@ -183,31 +178,31 @@ def build_item_response(
media = None media = None
children_media_class = None children_media_class = None
if search_type == MEDIA_TYPE_APPS: if search_type == MediaType.APPS:
title = "Apps" title = "Apps"
media = [ 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 for item in coordinator.data.apps
] ]
children_media_class = MEDIA_CLASS_APP children_media_class = MediaClass.APP
elif search_type == MEDIA_TYPE_CHANNELS: elif search_type == MediaType.CHANNELS:
title = "TV Channels" title = "TV Channels"
media = [ media = [
{ {
"channel_number": channel.number, "channel_number": channel.number,
"title": format_channel_name(channel.number, channel.name), "title": format_channel_name(channel.number, channel.name),
"type": MEDIA_TYPE_CHANNEL, "type": MediaType.CHANNEL,
} }
for channel in coordinator.data.channels 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: if title is None or media is None:
return None return None
return BrowseMedia( return BrowseMedia(
media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get( media_class=CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS.get(
search_type, MEDIA_CLASS_DIRECTORY search_type, MediaClass.DIRECTORY
), ),
media_content_id=search_id, media_content_id=search_id,
media_content_type=search_type, media_content_type=search_type,
@ -235,11 +230,11 @@ def item_payload(
thumbnail = None thumbnail = None
if "app_id" in item: if "app_id" in item:
media_content_type = MEDIA_TYPE_APP media_content_type = MediaType.APP
media_content_id = item["app_id"] media_content_id = item["app_id"]
thumbnail = get_browse_image_url(media_content_type, media_content_id, None) thumbnail = get_browse_image_url(media_content_type, media_content_id, None)
elif "channel_number" in item: elif "channel_number" in item:
media_content_type = MEDIA_TYPE_CHANNEL media_content_type = MediaType.CHANNEL
media_content_id = item["channel_number"] media_content_id = item["channel_number"]
else: else:
media_content_type = item["type"] media_content_type = item["type"]

View File

@ -1,12 +1,7 @@
"""Support to interface with the Roon API.""" """Support to interface with the Roon API."""
import logging import logging
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import BrowseMedia, MediaClass
from homeassistant.components.media_player.const import (
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_TRACK,
)
from homeassistant.components.media_player.errors import BrowseError 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") hint = item.get("hint")
if hint == "list": if hint == "list":
media_class = MEDIA_CLASS_DIRECTORY media_class = MediaClass.DIRECTORY
can_expand = True can_expand = True
elif hint == "action_list": elif hint == "action_list":
media_class = MEDIA_CLASS_PLAYLIST media_class = MediaClass.PLAYLIST
can_expand = False can_expand = False
elif hint == "action": elif hint == "action":
media_content_type = "track" media_content_type = "track"
media_class = MEDIA_CLASS_TRACK media_class = MediaClass.TRACK
can_expand = False can_expand = False
else: else:
# Roon API says to treat unknown as a list # Roon API says to treat unknown as a list
media_class = MEDIA_CLASS_DIRECTORY media_class = MediaClass.DIRECTORY
can_expand = True can_expand = True
_LOGGER.warning("Unknown hint %s - %s", title, hint) _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, title=list_title,
media_content_id=content_id, media_content_id=content_id,
media_content_type="library", media_content_type="library",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[], children=[],

View File

@ -1,22 +1,9 @@
"""Const for Sonos.""" """Const for Sonos."""
from __future__ import annotations
import datetime import datetime
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaClass, MediaType
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.const import Platform from homeassistant.const import Platform
UPNP_ST = "urn:schemas-upnp-org:device:ZonePlayer:1" UPNP_ST = "urn:schemas-upnp-org:device:ZonePlayer:1"
@ -46,11 +33,11 @@ SONOS_STATE_PLAYING = "PLAYING"
SONOS_STATE_TRANSITIONING = "TRANSITIONING" SONOS_STATE_TRANSITIONING = "TRANSITIONING"
EXPANDABLE_MEDIA_TYPES = [ EXPANDABLE_MEDIA_TYPES = [
MEDIA_TYPE_ALBUM, MediaType.ALBUM,
MEDIA_TYPE_ARTIST, MediaType.ARTIST,
MEDIA_TYPE_COMPOSER, MediaType.COMPOSER,
MEDIA_TYPE_GENRE, MediaType.GENRE,
MEDIA_TYPE_PLAYLIST, MediaType.PLAYLIST,
SONOS_ALBUM, SONOS_ALBUM,
SONOS_ALBUM_ARTIST, SONOS_ALBUM_ARTIST,
SONOS_ARTIST, SONOS_ARTIST,
@ -60,49 +47,49 @@ EXPANDABLE_MEDIA_TYPES = [
] ]
SONOS_TO_MEDIA_CLASSES = { SONOS_TO_MEDIA_CLASSES = {
SONOS_ALBUM: MEDIA_CLASS_ALBUM, SONOS_ALBUM: MediaClass.ALBUM,
SONOS_ALBUM_ARTIST: MEDIA_CLASS_ARTIST, SONOS_ALBUM_ARTIST: MediaClass.ARTIST,
SONOS_ARTIST: MEDIA_CLASS_CONTRIBUTING_ARTIST, SONOS_ARTIST: MediaClass.CONTRIBUTING_ARTIST,
SONOS_COMPOSER: MEDIA_CLASS_COMPOSER, SONOS_COMPOSER: MediaClass.COMPOSER,
SONOS_GENRE: MEDIA_CLASS_GENRE, SONOS_GENRE: MediaClass.GENRE,
SONOS_PLAYLISTS: MEDIA_CLASS_PLAYLIST, SONOS_PLAYLISTS: MediaClass.PLAYLIST,
SONOS_TRACKS: MEDIA_CLASS_TRACK, SONOS_TRACKS: MediaClass.TRACK,
"object.container.album.musicAlbum": MEDIA_CLASS_ALBUM, "object.container.album.musicAlbum": MediaClass.ALBUM,
"object.container.genre.musicGenre": MEDIA_CLASS_PLAYLIST, "object.container.genre.musicGenre": MediaClass.PLAYLIST,
"object.container.person.composer": MEDIA_CLASS_PLAYLIST, "object.container.person.composer": MediaClass.PLAYLIST,
"object.container.person.musicArtist": MEDIA_CLASS_ARTIST, "object.container.person.musicArtist": MediaClass.ARTIST,
"object.container.playlistContainer.sameArtist": MEDIA_CLASS_ARTIST, "object.container.playlistContainer.sameArtist": MediaClass.ARTIST,
"object.container.playlistContainer": MEDIA_CLASS_PLAYLIST, "object.container.playlistContainer": MediaClass.PLAYLIST,
"object.item": MEDIA_CLASS_TRACK, "object.item": MediaClass.TRACK,
"object.item.audioItem.musicTrack": MEDIA_CLASS_TRACK, "object.item.audioItem.musicTrack": MediaClass.TRACK,
"object.item.audioItem.audioBroadcast": MEDIA_CLASS_GENRE, "object.item.audioItem.audioBroadcast": MediaClass.GENRE,
} }
SONOS_TO_MEDIA_TYPES = { SONOS_TO_MEDIA_TYPES = {
SONOS_ALBUM: MEDIA_TYPE_ALBUM, SONOS_ALBUM: MediaType.ALBUM,
SONOS_ALBUM_ARTIST: MEDIA_TYPE_ARTIST, SONOS_ALBUM_ARTIST: MediaType.ARTIST,
SONOS_ARTIST: MEDIA_TYPE_CONTRIBUTING_ARTIST, SONOS_ARTIST: MediaType.CONTRIBUTING_ARTIST,
SONOS_COMPOSER: MEDIA_TYPE_COMPOSER, SONOS_COMPOSER: MediaType.COMPOSER,
SONOS_GENRE: MEDIA_TYPE_GENRE, SONOS_GENRE: MediaType.GENRE,
SONOS_PLAYLISTS: MEDIA_TYPE_PLAYLIST, SONOS_PLAYLISTS: MediaType.PLAYLIST,
SONOS_TRACKS: MEDIA_TYPE_TRACK, SONOS_TRACKS: MediaType.TRACK,
"object.container.album.musicAlbum": MEDIA_TYPE_ALBUM, "object.container.album.musicAlbum": MediaType.ALBUM,
"object.container.genre.musicGenre": MEDIA_TYPE_PLAYLIST, "object.container.genre.musicGenre": MediaType.PLAYLIST,
"object.container.person.composer": MEDIA_TYPE_PLAYLIST, "object.container.person.composer": MediaType.PLAYLIST,
"object.container.person.musicArtist": MEDIA_TYPE_ARTIST, "object.container.person.musicArtist": MediaType.ARTIST,
"object.container.playlistContainer.sameArtist": MEDIA_TYPE_ARTIST, "object.container.playlistContainer.sameArtist": MediaType.ARTIST,
"object.container.playlistContainer": MEDIA_TYPE_PLAYLIST, "object.container.playlistContainer": MediaType.PLAYLIST,
"object.item.audioItem.musicTrack": MEDIA_TYPE_TRACK, "object.item.audioItem.musicTrack": MediaType.TRACK,
} }
MEDIA_TYPES_TO_SONOS = { MEDIA_TYPES_TO_SONOS: dict[MediaType | str, str] = {
MEDIA_TYPE_ALBUM: SONOS_ALBUM, MediaType.ALBUM: SONOS_ALBUM,
MEDIA_TYPE_ARTIST: SONOS_ALBUM_ARTIST, MediaType.ARTIST: SONOS_ALBUM_ARTIST,
MEDIA_TYPE_CONTRIBUTING_ARTIST: SONOS_ARTIST, MediaType.CONTRIBUTING_ARTIST: SONOS_ARTIST,
MEDIA_TYPE_COMPOSER: SONOS_COMPOSER, MediaType.COMPOSER: SONOS_COMPOSER,
MEDIA_TYPE_GENRE: SONOS_GENRE, MediaType.GENRE: SONOS_GENRE,
MEDIA_TYPE_PLAYLIST: SONOS_PLAYLISTS, MediaType.PLAYLIST: SONOS_PLAYLISTS,
MEDIA_TYPE_TRACK: SONOS_TRACKS, MediaType.TRACK: SONOS_TRACKS,
} }
SONOS_TYPES_MAPPING = { SONOS_TYPES_MAPPING = {
@ -135,13 +122,13 @@ LIBRARY_TITLES_MAPPING = {
} }
PLAYABLE_MEDIA_TYPES = [ PLAYABLE_MEDIA_TYPES = [
MEDIA_TYPE_ALBUM, MediaType.ALBUM,
MEDIA_TYPE_ARTIST, MediaType.ARTIST,
MEDIA_TYPE_COMPOSER, MediaType.COMPOSER,
MEDIA_TYPE_CONTRIBUTING_ARTIST, MediaType.CONTRIBUTING_ARTIST,
MEDIA_TYPE_GENRE, MediaType.GENRE,
MEDIA_TYPE_PLAYLIST, MediaType.PLAYLIST,
MEDIA_TYPE_TRACK, MediaType.TRACK,
] ]
SONOS_CHECK_ACTIVITY = "sonos_check_activity" SONOS_CHECK_ACTIVITY = "sonos_check_activity"

View File

@ -12,12 +12,7 @@ from soco.ms_data_structures import MusicServiceItem
from soco.music_library import MusicLibrary from soco.music_library import MusicLibrary
from homeassistant.components import media_source, plex, spotify from homeassistant.components import media_source, plex, spotify
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
from homeassistant.components.media_player.const import (
MEDIA_CLASS_APP,
MEDIA_CLASS_DIRECTORY,
MEDIA_TYPE_ALBUM,
)
from homeassistant.components.media_player.errors import BrowseError from homeassistant.components.media_player.errors import BrowseError
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.network import is_internal_request 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 media_library: MusicLibrary, payload: dict[str, str], get_thumbnail_url=None
) -> BrowseMedia | None: ) -> BrowseMedia | None:
"""Create response payload for the provided media query.""" """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") ("A:GENRE", "A:COMPOSER")
): ):
payload["idstring"] = "A:ALBUMARTIST/" + "/".join( payload["idstring"] = "A:ALBUMARTIST/" + "/".join(
@ -191,7 +186,7 @@ def build_item_response(
# Fetch album info for titles and thumbnails # Fetch album info for titles and thumbnails
# Can't be extracted from track info # Can't be extracted from track info
if ( if (
payload["search_type"] == MEDIA_TYPE_ALBUM payload["search_type"] == MediaType.ALBUM
and media[0].item_class == "object.item.audioItem.musicTrack" and media[0].item_class == "object.item.audioItem.musicTrack"
): ):
item = get_media(media_library, payload["idstring"], SONOS_ALBUM_ARTIST) item = get_media(media_library, payload["idstring"], SONOS_ALBUM_ARTIST)
@ -271,7 +266,7 @@ async def root_payload(
children.append( children.append(
BrowseMedia( BrowseMedia(
title="Favorites", title="Favorites",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="favorites", media_content_type="favorites",
thumbnail="https://brands.home-assistant.io/_/sonos/logo.png", thumbnail="https://brands.home-assistant.io/_/sonos/logo.png",
@ -286,7 +281,7 @@ async def root_payload(
children.append( children.append(
BrowseMedia( BrowseMedia(
title="Music Library", title="Music Library",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="library", media_content_type="library",
thumbnail="https://brands.home-assistant.io/_/sonos/logo.png", thumbnail="https://brands.home-assistant.io/_/sonos/logo.png",
@ -299,7 +294,7 @@ async def root_payload(
children.append( children.append(
BrowseMedia( BrowseMedia(
title="Plex", title="Plex",
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_id="", media_content_id="",
media_content_type="plex", media_content_type="plex",
thumbnail="https://brands.home-assistant.io/_/plex/logo.png", thumbnail="https://brands.home-assistant.io/_/plex/logo.png",
@ -337,7 +332,7 @@ async def root_payload(
return BrowseMedia( return BrowseMedia(
title="Sonos", title="Sonos",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="root", media_content_type="root",
can_play=False, can_play=False,
@ -359,7 +354,7 @@ def library_payload(media_library: MusicLibrary, get_thumbnail_url=None) -> Brow
return BrowseMedia( return BrowseMedia(
title="Music Library", title="Music Library",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="library", media_content_id="library",
media_content_type="library", media_content_type="library",
can_play=False, can_play=False,
@ -397,7 +392,7 @@ def favorites_payload(favorites: list[DidlFavorite]) -> BrowseMedia:
return BrowseMedia( return BrowseMedia(
title="Favorites", title="Favorites",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="favorites", media_content_type="favorites",
can_play=False, can_play=False,
@ -433,7 +428,7 @@ def favorites_folder_payload(
return BrowseMedia( return BrowseMedia(
title=content_type.title(), title=content_type.title(),
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="", media_content_id="",
media_content_type="favorites", media_content_type="favorites",
can_play=False, can_play=False,

View File

@ -9,22 +9,11 @@ from spotipy import Spotify
import yarl import yarl
from homeassistant.backports.enum import StrEnum from homeassistant.backports.enum import StrEnum
from homeassistant.components.media_player import BrowseError, BrowseMedia from homeassistant.components.media_player import (
from homeassistant.components.media_player.const import ( BrowseError,
MEDIA_CLASS_ALBUM, BrowseMedia,
MEDIA_CLASS_APP, MediaClass,
MEDIA_CLASS_ARTIST, MediaType,
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.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
@ -70,62 +59,62 @@ LIBRARY_MAP = {
CONTENT_TYPE_MEDIA_CLASS: dict[str, Any] = { CONTENT_TYPE_MEDIA_CLASS: dict[str, Any] = {
BrowsableMedia.CURRENT_USER_PLAYLISTS.value: { BrowsableMedia.CURRENT_USER_PLAYLISTS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_PLAYLIST, "children": MediaClass.PLAYLIST,
}, },
BrowsableMedia.CURRENT_USER_FOLLOWED_ARTISTS.value: { BrowsableMedia.CURRENT_USER_FOLLOWED_ARTISTS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_ARTIST, "children": MediaClass.ARTIST,
}, },
BrowsableMedia.CURRENT_USER_SAVED_ALBUMS.value: { BrowsableMedia.CURRENT_USER_SAVED_ALBUMS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_ALBUM, "children": MediaClass.ALBUM,
}, },
BrowsableMedia.CURRENT_USER_SAVED_TRACKS.value: { BrowsableMedia.CURRENT_USER_SAVED_TRACKS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_TRACK, "children": MediaClass.TRACK,
}, },
BrowsableMedia.CURRENT_USER_SAVED_SHOWS.value: { BrowsableMedia.CURRENT_USER_SAVED_SHOWS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_PODCAST, "children": MediaClass.PODCAST,
}, },
BrowsableMedia.CURRENT_USER_RECENTLY_PLAYED.value: { BrowsableMedia.CURRENT_USER_RECENTLY_PLAYED.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_TRACK, "children": MediaClass.TRACK,
}, },
BrowsableMedia.CURRENT_USER_TOP_ARTISTS.value: { BrowsableMedia.CURRENT_USER_TOP_ARTISTS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_ARTIST, "children": MediaClass.ARTIST,
}, },
BrowsableMedia.CURRENT_USER_TOP_TRACKS.value: { BrowsableMedia.CURRENT_USER_TOP_TRACKS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_TRACK, "children": MediaClass.TRACK,
}, },
BrowsableMedia.FEATURED_PLAYLISTS.value: { BrowsableMedia.FEATURED_PLAYLISTS.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_PLAYLIST, "children": MediaClass.PLAYLIST,
}, },
BrowsableMedia.CATEGORIES.value: { BrowsableMedia.CATEGORIES.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_GENRE, "children": MediaClass.GENRE,
}, },
"category_playlists": { "category_playlists": {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_PLAYLIST, "children": MediaClass.PLAYLIST,
}, },
BrowsableMedia.NEW_RELEASES.value: { BrowsableMedia.NEW_RELEASES.value: {
"parent": MEDIA_CLASS_DIRECTORY, "parent": MediaClass.DIRECTORY,
"children": MEDIA_CLASS_ALBUM, "children": MediaClass.ALBUM,
}, },
MEDIA_TYPE_PLAYLIST: { MediaType.PLAYLIST: {
"parent": MEDIA_CLASS_PLAYLIST, "parent": MediaClass.PLAYLIST,
"children": MEDIA_CLASS_TRACK, "children": MediaClass.TRACK,
}, },
MEDIA_TYPE_ALBUM: {"parent": MEDIA_CLASS_ALBUM, "children": MEDIA_CLASS_TRACK}, MediaType.ALBUM: {"parent": MediaClass.ALBUM, "children": MediaClass.TRACK},
MEDIA_TYPE_ARTIST: {"parent": MEDIA_CLASS_ARTIST, "children": MEDIA_CLASS_ALBUM}, MediaType.ARTIST: {"parent": MediaClass.ARTIST, "children": MediaClass.ALBUM},
MEDIA_TYPE_EPISODE: {"parent": MEDIA_CLASS_EPISODE, "children": None}, MediaType.EPISODE: {"parent": MediaClass.EPISODE, "children": None},
MEDIA_TYPE_SHOW: {"parent": MEDIA_CLASS_PODCAST, "children": MEDIA_CLASS_EPISODE}, MEDIA_TYPE_SHOW: {"parent": MediaClass.PODCAST, "children": MediaClass.EPISODE},
MEDIA_TYPE_TRACK: {"parent": MEDIA_CLASS_TRACK, "children": None}, MediaType.TRACK: {"parent": MediaClass.TRACK, "children": None},
} }
@ -157,7 +146,7 @@ async def async_browse_media(
children.append( children.append(
BrowseMedia( BrowseMedia(
title=config_entry.title, 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_id=f"{MEDIA_PLAYER_PREFIX}{config_entry_id}",
media_content_type=f"{MEDIA_PLAYER_PREFIX}library", media_content_type=f"{MEDIA_PLAYER_PREFIX}library",
thumbnail="https://brands.home-assistant.io/_/spotify/logo.png", thumbnail="https://brands.home-assistant.io/_/spotify/logo.png",
@ -167,7 +156,7 @@ async def async_browse_media(
) )
return BrowseMedia( return BrowseMedia(
title="Spotify", title="Spotify",
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_id=MEDIA_PLAYER_PREFIX, media_content_id=MEDIA_PLAYER_PREFIX,
media_content_type="spotify", media_content_type="spotify",
thumbnail="https://brands.home-assistant.io/_/spotify/logo.png", 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: elif media_content_type == BrowsableMedia.NEW_RELEASES:
if media := spotify.new_releases(country=user["country"], limit=BROWSE_LIMIT): if media := spotify.new_releases(country=user["country"], limit=BROWSE_LIMIT):
items = media.get("albums", {}).get("items", []) 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): if media := spotify.playlist(media_content_id):
items = [item["track"] for item in media.get("tracks", {}).get("items", [])] 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): if media := spotify.album(media_content_id):
items = media.get("tracks", {}).get("items", []) 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 ( if (media := spotify.artist_albums(media_content_id, limit=BROWSE_LIMIT)) and (
artist := spotify.artist(media_content_id) artist := spotify.artist(media_content_id)
): ):
@ -364,8 +353,8 @@ def build_item_response( # noqa: C901
BrowseMedia( BrowseMedia(
can_expand=True, can_expand=True,
can_play=False, can_play=False,
children_media_class=MEDIA_CLASS_TRACK, children_media_class=MediaClass.TRACK,
media_class=MEDIA_CLASS_PLAYLIST, media_class=MediaClass.PLAYLIST,
media_content_id=item_id, media_content_id=item_id,
media_content_type=f"{MEDIA_PLAYER_PREFIX}category_playlists", media_content_type=f"{MEDIA_PLAYER_PREFIX}category_playlists",
thumbnail=fetch_image_url(item, key="icons"), thumbnail=fetch_image_url(item, key="icons"),
@ -380,7 +369,7 @@ def build_item_response( # noqa: C901
title = media["name"] title = media["name"]
can_play = media_content_type in PLAYABLE_MEDIA_TYPES and ( 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( browse_media = BrowseMedia(
@ -429,12 +418,12 @@ def item_payload(item: dict[str, Any], *, can_play_artist: bool) -> BrowseMedia:
raise UnknownMediaType from err raise UnknownMediaType from err
can_expand = media_type not in [ can_expand = media_type not in [
MEDIA_TYPE_TRACK, MediaType.TRACK,
MEDIA_TYPE_EPISODE, MediaType.EPISODE,
] ]
can_play = media_type in PLAYABLE_MEDIA_TYPES and ( 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( browse_media = BrowseMedia(
@ -449,8 +438,8 @@ def item_payload(item: dict[str, Any], *, can_play_artist: bool) -> BrowseMedia:
if "images" in item: if "images" in item:
browse_media.thumbnail = fetch_image_url(item) browse_media.thumbnail = fetch_image_url(item)
elif MEDIA_TYPE_ALBUM in item: elif MediaType.ALBUM in item:
browse_media.thumbnail = fetch_image_url(item[MEDIA_TYPE_ALBUM]) browse_media.thumbnail = fetch_image_url(item[MediaType.ALBUM])
return browse_media return browse_media
@ -464,8 +453,8 @@ def library_payload(*, can_play_artist: bool) -> BrowseMedia:
browse_media = BrowseMedia( browse_media = BrowseMedia(
can_expand=True, can_expand=True,
can_play=False, can_play=False,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="library", media_content_id="library",
media_content_type=f"{MEDIA_PLAYER_PREFIX}library", media_content_type=f"{MEDIA_PLAYER_PREFIX}library",
title="Media Library", title="Media Library",

View File

@ -2,13 +2,7 @@
import logging import logging
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaType
MEDIA_TYPE_ALBUM,
MEDIA_TYPE_ARTIST,
MEDIA_TYPE_EPISODE,
MEDIA_TYPE_PLAYLIST,
MEDIA_TYPE_TRACK,
)
DOMAIN = "spotify" DOMAIN = "spotify"
@ -35,10 +29,10 @@ MEDIA_PLAYER_PREFIX = "spotify://"
MEDIA_TYPE_SHOW = "show" MEDIA_TYPE_SHOW = "show"
PLAYABLE_MEDIA_TYPES = [ PLAYABLE_MEDIA_TYPES = [
MEDIA_TYPE_PLAYLIST, MediaType.PLAYLIST,
MEDIA_TYPE_ALBUM, MediaType.ALBUM,
MEDIA_TYPE_ARTIST, MediaType.ARTIST,
MEDIA_TYPE_EPISODE, MediaType.EPISODE,
MEDIA_TYPE_SHOW, MEDIA_TYPE_SHOW,
MEDIA_TYPE_TRACK, MediaType.TRACK,
] ]

View File

@ -2,19 +2,11 @@
import contextlib import contextlib
from homeassistant.components import media_source from homeassistant.components import media_source
from homeassistant.components.media_player import BrowseError, BrowseMedia from homeassistant.components.media_player import (
from homeassistant.components.media_player.const import ( BrowseError,
MEDIA_CLASS_ALBUM, BrowseMedia,
MEDIA_CLASS_ARTIST, MediaClass,
MEDIA_CLASS_DIRECTORY, MediaType,
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.helpers.network import is_internal_request from homeassistant.helpers.network import is_internal_request
@ -26,44 +18,44 @@ MEDIA_TYPE_TO_SQUEEZEBOX = {
"Tracks": "titles", "Tracks": "titles",
"Playlists": "playlists", "Playlists": "playlists",
"Genres": "genres", "Genres": "genres",
MEDIA_TYPE_ALBUM: "album", MediaType.ALBUM: "album",
MEDIA_TYPE_ARTIST: "artist", MediaType.ARTIST: "artist",
MEDIA_TYPE_TRACK: "title", MediaType.TRACK: "title",
MEDIA_TYPE_PLAYLIST: "playlist", MediaType.PLAYLIST: "playlist",
MEDIA_TYPE_GENRE: "genre", MediaType.GENRE: "genre",
} }
SQUEEZEBOX_ID_BY_TYPE = { SQUEEZEBOX_ID_BY_TYPE = {
MEDIA_TYPE_ALBUM: "album_id", MediaType.ALBUM: "album_id",
MEDIA_TYPE_ARTIST: "artist_id", MediaType.ARTIST: "artist_id",
MEDIA_TYPE_TRACK: "track_id", MediaType.TRACK: "track_id",
MEDIA_TYPE_PLAYLIST: "playlist_id", MediaType.PLAYLIST: "playlist_id",
MEDIA_TYPE_GENRE: "genre_id", MediaType.GENRE: "genre_id",
} }
CONTENT_TYPE_MEDIA_CLASS = { CONTENT_TYPE_MEDIA_CLASS = {
"Artists": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_ARTIST}, "Artists": {"item": MediaClass.DIRECTORY, "children": MediaClass.ARTIST},
"Albums": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_ALBUM}, "Albums": {"item": MediaClass.DIRECTORY, "children": MediaClass.ALBUM},
"Tracks": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_TRACK}, "Tracks": {"item": MediaClass.DIRECTORY, "children": MediaClass.TRACK},
"Playlists": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_PLAYLIST}, "Playlists": {"item": MediaClass.DIRECTORY, "children": MediaClass.PLAYLIST},
"Genres": {"item": MEDIA_CLASS_DIRECTORY, "children": MEDIA_CLASS_GENRE}, "Genres": {"item": MediaClass.DIRECTORY, "children": MediaClass.GENRE},
MEDIA_TYPE_ALBUM: {"item": MEDIA_CLASS_ALBUM, "children": MEDIA_CLASS_TRACK}, MediaType.ALBUM: {"item": MediaClass.ALBUM, "children": MediaClass.TRACK},
MEDIA_TYPE_ARTIST: {"item": MEDIA_CLASS_ARTIST, "children": MEDIA_CLASS_ALBUM}, MediaType.ARTIST: {"item": MediaClass.ARTIST, "children": MediaClass.ALBUM},
MEDIA_TYPE_TRACK: {"item": MEDIA_CLASS_TRACK, "children": None}, MediaType.TRACK: {"item": MediaClass.TRACK, "children": None},
MEDIA_TYPE_GENRE: {"item": MEDIA_CLASS_GENRE, "children": MEDIA_CLASS_ARTIST}, MediaType.GENRE: {"item": MediaClass.GENRE, "children": MediaClass.ARTIST},
MEDIA_TYPE_PLAYLIST: {"item": MEDIA_CLASS_PLAYLIST, "children": MEDIA_CLASS_TRACK}, MediaType.PLAYLIST: {"item": MediaClass.PLAYLIST, "children": MediaClass.TRACK},
} }
CONTENT_TYPE_TO_CHILD_TYPE = { CONTENT_TYPE_TO_CHILD_TYPE = {
MEDIA_TYPE_ALBUM: MEDIA_TYPE_TRACK, MediaType.ALBUM: MediaType.TRACK,
MEDIA_TYPE_PLAYLIST: MEDIA_TYPE_PLAYLIST, MediaType.PLAYLIST: MediaType.PLAYLIST,
MEDIA_TYPE_ARTIST: MEDIA_TYPE_ALBUM, MediaType.ARTIST: MediaType.ALBUM,
MEDIA_TYPE_GENRE: MEDIA_TYPE_ARTIST, MediaType.GENRE: MediaType.ARTIST,
"Artists": MEDIA_TYPE_ARTIST, "Artists": MediaType.ARTIST,
"Albums": MEDIA_TYPE_ALBUM, "Albums": MediaType.ALBUM,
"Tracks": MEDIA_TYPE_TRACK, "Tracks": MediaType.TRACK,
"Playlists": MEDIA_TYPE_PLAYLIST, "Playlists": MediaType.PLAYLIST,
"Genres": MEDIA_TYPE_GENRE, "Genres": MediaType.GENRE,
} }
BROWSE_LIMIT = 1000 BROWSE_LIMIT = 1000
@ -141,7 +133,7 @@ async def library_payload(hass, player):
"""Create response payload to describe contents of library.""" """Create response payload to describe contents of library."""
library_info = { library_info = {
"title": "Music Library", "title": "Music Library",
"media_class": MEDIA_CLASS_DIRECTORY, "media_class": MediaClass.DIRECTORY,
"media_content_id": "library", "media_content_id": "library",
"media_content_type": "library", "media_content_type": "library",
"can_play": False, "can_play": False,

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from systembridgeconnector.models.media_directories import MediaDirectories from systembridgeconnector.models.media_directories import MediaDirectories
from systembridgeconnector.models.media_files import File as MediaFile, MediaFiles 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 ( from homeassistant.components.media_source.const import (
MEDIA_CLASS_MAP, MEDIA_CLASS_MAP,
MEDIA_MIME_TYPES, MEDIA_MIME_TYPES,
@ -97,26 +97,26 @@ class SystemBridgeSource(MediaSource):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=entry.entry_id, identifier=entry.entry_id,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=entry.title, title=entry.title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[], children=[],
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
) )
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=children, children=children,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
@ -138,7 +138,7 @@ def _build_root_paths(
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=entry.title, title=entry.title,
can_play=False, can_play=False,
@ -147,17 +147,17 @@ def _build_root_paths(
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{entry.entry_id}~~{directory.key}", identifier=f"{entry.entry_id}~~{directory.key}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=f"{directory.key[:1].capitalize()}{directory.key[1:]}", title=f"{directory.key[:1].capitalize()}{directory.key[1:]}",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[], children=[],
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
) )
for directory in media_directories.directories 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( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=identifier, identifier=identifier,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=f"{entry.title} - {path}", title=f"{entry.title} - {path}",
can_play=False, can_play=False,
@ -199,7 +199,7 @@ def _build_media_item(
ext = f"~~{media_file.mime_type}" ext = f"~~{media_file.mime_type}"
if media_file.is_directory or media_file.mime_type is None: if media_file.is_directory or media_file.mime_type is None:
media_class = MEDIA_CLASS_DIRECTORY media_class = MediaClass.DIRECTORY
else: else:
media_class = MEDIA_CLASS_MAP[media_file.mime_type.split("/", 1)[0]] media_class = MEDIA_CLASS_MAP[media_file.mime_type.split("/", 1)[0]]

View File

@ -20,13 +20,13 @@ import voluptuous as vol
import yarl import yarl
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import (
ATTR_MEDIA_ANNOUNCE, ATTR_MEDIA_ANNOUNCE,
ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_ID,
ATTR_MEDIA_CONTENT_TYPE, ATTR_MEDIA_CONTENT_TYPE,
DOMAIN as DOMAIN_MP, DOMAIN as DOMAIN_MP,
MEDIA_TYPE_MUSIC,
SERVICE_PLAY_MEDIA, SERVICE_PLAY_MEDIA,
MediaType,
) )
from homeassistant.components.media_source import generate_media_source_id from homeassistant.components.media_source import generate_media_source_id
from homeassistant.const import ( from homeassistant.const import (
@ -224,7 +224,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
DOMAIN, DOMAIN,
str(yarl.URL.build(path=p_type, query=params)), 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, ATTR_MEDIA_ANNOUNCE: True,
}, },
blocking=True, blocking=True,

View File

@ -6,8 +6,7 @@ from typing import TYPE_CHECKING, Any
from yarl import URL from yarl import URL
from homeassistant.components.media_player.const import MEDIA_CLASS_APP from homeassistant.components.media_player import BrowseError, MediaClass
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable from homeassistant.components.media_source.error import Unresolvable
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
@ -85,12 +84,12 @@ class TTSMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_type="", media_content_type="",
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_APP, children_media_class=MediaClass.APP,
children=children, children=children,
) )
@ -111,7 +110,7 @@ class TTSMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{provider_domain}{params}", identifier=f"{provider_domain}{params}",
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_type="provider", media_content_type="provider",
title=provider.name, title=provider.name,
thumbnail=f"https://brands.home-assistant.io/_/{provider_domain}/logo.png", thumbnail=f"https://brands.home-assistant.io/_/{provider_domain}/logo.png",

View File

@ -19,12 +19,7 @@ from pyunifiprotect.utils import from_js_time
from yarl import URL from yarl import URL
from homeassistant.components.camera import CameraImageView from homeassistant.components.camera import CameraImageView
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import BrowseError, MediaClass
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_IMAGE,
MEDIA_CLASS_VIDEO,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
MediaSource, MediaSource,
@ -422,7 +417,7 @@ class ProtectMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{nvr.id}:eventthumb:{event_id}", identifier=f"{nvr.id}:eventthumb:{event_id}",
media_class=MEDIA_CLASS_IMAGE, media_class=MediaClass.IMAGE,
media_content_type="image/jpeg", media_content_type="image/jpeg",
title=title, title=title,
can_play=True, can_play=True,
@ -435,7 +430,7 @@ class ProtectMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{nvr.id}:event:{event_id}", identifier=f"{nvr.id}:event:{event_id}",
media_class=MEDIA_CLASS_VIDEO, media_class=MediaClass.VIDEO,
media_content_type="video/mp4", media_content_type="video/mp4",
title=title, title=title,
can_play=True, can_play=True,
@ -506,12 +501,12 @@ class ProtectMediaSource(MediaSource):
source = BrowseMediaSource( source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{base_id}:recent:{days}", identifier=f"{base_id}:recent:{days}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="video/mp4", media_content_type="video/mp4",
title=title, title=title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
) )
if not build_children: if not build_children:
@ -560,12 +555,12 @@ class ProtectMediaSource(MediaSource):
source = BrowseMediaSource( source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{base_id}:range:{start.year}:{start.month}", identifier=f"{base_id}:range:{start.year}:{start.month}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=title, title=title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
) )
if not build_children: if not build_children:
@ -622,12 +617,12 @@ class ProtectMediaSource(MediaSource):
source = BrowseMediaSource( source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=identifier, identifier=identifier,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=title, title=title,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
) )
if not build_children: if not build_children:
@ -692,12 +687,12 @@ class ProtectMediaSource(MediaSource):
source = BrowseMediaSource( source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=base_id, identifier=base_id,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=title, title=title,
can_play=False, can_play=False,
can_expand=True, 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: if not build_children or data.api.bootstrap.recording_start is None:
@ -781,13 +776,13 @@ class ProtectMediaSource(MediaSource):
source = BrowseMediaSource( source = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{data.api.bootstrap.nvr.id}:browse:{camera_id}", identifier=f"{data.api.bootstrap.nvr.id}:browse:{camera_id}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=name, title=name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
thumbnail=thumbnail_url, thumbnail=thumbnail_url,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
) )
if not build_children: if not build_children:
@ -837,12 +832,12 @@ class ProtectMediaSource(MediaSource):
base = BrowseMediaSource( base = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{data.api.bootstrap.nvr.id}:browse", identifier=f"{data.api.bootstrap.nvr.id}:browse",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=data.api.bootstrap.nvr.name, title=data.api.bootstrap.nvr.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
children=await self._build_cameras(data), children=await self._build_cameras(data),
) )
@ -864,11 +859,11 @@ class ProtectMediaSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=None, identifier=None,
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type=VIDEO_FORMAT, media_content_type=VIDEO_FORMAT,
title=self.name, title=self.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_VIDEO, children_media_class=MediaClass.VIDEO,
children=consoles, children=consoles,
) )

View File

@ -1,16 +1,11 @@
"""Support for media browsing.""" """Support for media browsing."""
import json import json
from homeassistant.components.media_player import BrowseError, BrowseMedia from homeassistant.components.media_player import (
from homeassistant.components.media_player.const import ( BrowseError,
MEDIA_CLASS_ALBUM, BrowseMedia,
MEDIA_CLASS_ARTIST, MediaClass,
MEDIA_CLASS_CHANNEL, MediaType,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_GENRE,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_TRACK,
MEDIA_TYPE_MUSIC,
) )
PLAYABLE_ITEM_TYPES = [ PLAYABLE_ITEM_TYPES = [
@ -48,52 +43,52 @@ FAVOURITES_URI = "favourites"
def _item_to_children_media_class(item, info=None): def _item_to_children_media_class(item, info=None):
if info and "album" in info and "artist" in info: if info and "album" in info and "artist" in info:
return MEDIA_CLASS_TRACK return MediaClass.TRACK
if item["uri"].startswith(PLAYLISTS_URI_PREFIX): if item["uri"].startswith(PLAYLISTS_URI_PREFIX):
return MEDIA_CLASS_PLAYLIST return MediaClass.PLAYLIST
if item["uri"].startswith(ARTISTS_URI_PREFIX): if item["uri"].startswith(ARTISTS_URI_PREFIX):
if len(item["uri"]) > len(ARTISTS_URI_PREFIX): if len(item["uri"]) > len(ARTISTS_URI_PREFIX):
return MEDIA_CLASS_ALBUM return MediaClass.ALBUM
return MEDIA_CLASS_ARTIST return MediaClass.ARTIST
if item["uri"].startswith(ALBUMS_URI_PREFIX): if item["uri"].startswith(ALBUMS_URI_PREFIX):
if len(item["uri"]) > len(ALBUMS_URI_PREFIX): if len(item["uri"]) > len(ALBUMS_URI_PREFIX):
return MEDIA_CLASS_TRACK return MediaClass.TRACK
return MEDIA_CLASS_ALBUM return MediaClass.ALBUM
if item["uri"].startswith(GENRES_URI_PREFIX): if item["uri"].startswith(GENRES_URI_PREFIX):
if len(item["uri"]) > len(GENRES_URI_PREFIX): if len(item["uri"]) > len(GENRES_URI_PREFIX):
return MEDIA_CLASS_ALBUM return MediaClass.ALBUM
return MEDIA_CLASS_GENRE return MediaClass.GENRE
if item["uri"].startswith(LAST_100_URI_PREFIX) or item["uri"] == FAVOURITES_URI: 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): if item["uri"].startswith(RADIO_URI_PREFIX):
return MEDIA_CLASS_CHANNEL return MediaClass.CHANNEL
return MEDIA_CLASS_DIRECTORY return MediaClass.DIRECTORY
def _item_to_media_class(item, parent_item=None): def _item_to_media_class(item, parent_item=None):
if "type" not in item: if "type" not in item:
return MEDIA_CLASS_DIRECTORY return MediaClass.DIRECTORY
if item["type"] in ("webradio", "mywebradio"): if item["type"] in ("webradio", "mywebradio"):
return MEDIA_CLASS_CHANNEL return MediaClass.CHANNEL
if item["type"] in ("song", "cuesong"): if item["type"] in ("song", "cuesong"):
return MEDIA_CLASS_TRACK return MediaClass.TRACK
if item.get("artist"): if item.get("artist"):
return MEDIA_CLASS_ALBUM return MediaClass.ALBUM
if item["uri"].startswith(ARTISTS_URI_PREFIX) and len(item["uri"]) > len( if item["uri"].startswith(ARTISTS_URI_PREFIX) and len(item["uri"]) > len(
ARTISTS_URI_PREFIX ARTISTS_URI_PREFIX
): ):
return MEDIA_CLASS_ARTIST return MediaClass.ARTIST
if parent_item: if parent_item:
return _item_to_children_media_class(parent_item) return _item_to_children_media_class(parent_item)
return MEDIA_CLASS_DIRECTORY return MediaClass.DIRECTORY
def _list_payload(item, children=None): def _list_payload(item, children=None):
return BrowseMedia( return BrowseMedia(
title=item["name"], title=item["name"],
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
children_media_class=_item_to_children_media_class(item), 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), media_content_id=json.dumps(item),
can_play=False, can_play=False,
can_expand=True, 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"): if thumbnail := item.get("albumart"):
item_hash = str(hash(thumbnail)) item_hash = str(hash(thumbnail))
entity.thumbnail_cache.setdefault(item_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: else:
# don't use the built-in volumio white-on-white icons # don't use the built-in volumio white-on-white icons
thumbnail = None 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"), "title": title or item.get("title"),
"media_class": _item_to_media_class(item, parent_item), "media_class": _item_to_media_class(item, parent_item),
"children_media_class": _item_to_children_media_class(item, info), "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), "media_content_id": json.dumps(item),
"can_play": item.get("type") in PLAYABLE_ITEM_TYPES, "can_play": item.get("type") in PLAYABLE_ITEM_TYPES,
"can_expand": item.get("type") not in NON_EXPANDABLE_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() navigation = await media_library.browse()
children = [_list_payload(item) for item in navigation["lists"]] children = [_list_payload(item) for item in navigation["lists"]]
return BrowseMedia( return BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="library", media_content_id="library",
media_content_type="library", media_content_type="library",
title="Media Library", title="Media Library",

View File

@ -16,14 +16,7 @@ from xbox.webapi.api.provider.smartglass.models import (
InstalledPackagesList, InstalledPackagesList,
) )
from homeassistant.components.media_player import BrowseMedia from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
from homeassistant.components.media_player.const import (
MEDIA_CLASS_APP,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_GAME,
MEDIA_TYPE_APP,
MEDIA_TYPE_GAME,
)
class MediaTypeDetails(NamedTuple): class MediaTypeDetails(NamedTuple):
@ -35,12 +28,12 @@ class MediaTypeDetails(NamedTuple):
TYPE_MAP = { TYPE_MAP = {
"App": MediaTypeDetails( "App": MediaTypeDetails(
type=MEDIA_TYPE_APP, type=MediaType.APP,
cls=MEDIA_CLASS_APP, cls=MediaClass.APP,
), ),
"Game": MediaTypeDetails( "Game": MediaTypeDetails(
type=MEDIA_TYPE_GAME, type=MediaType.GAME,
cls=MEDIA_CLASS_GAME, cls=MediaClass.GAME,
), ),
} }
@ -58,7 +51,7 @@ async def build_item_response(
if media_content_type in (None, "library"): if media_content_type in (None, "library"):
children: list[BrowseMedia] = [] children: list[BrowseMedia] = []
library_info = BrowseMedia( library_info = BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id="library", media_content_id="library",
media_content_type="library", media_content_type="library",
title="Installed Applications", title="Installed Applications",
@ -79,9 +72,9 @@ async def build_item_response(
) )
children.append( children.append(
BrowseMedia( BrowseMedia(
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_id="Home", media_content_id="Home",
media_content_type=MEDIA_TYPE_APP, media_content_type=MediaType.APP,
title="Home", title="Home",
can_play=True, can_play=True,
can_expand=False, can_expand=False,
@ -102,9 +95,9 @@ async def build_item_response(
) )
children.append( children.append(
BrowseMedia( BrowseMedia(
media_class=MEDIA_CLASS_APP, media_class=MediaClass.APP,
media_content_id="TV", media_content_id="TV",
media_content_type=MEDIA_TYPE_APP, media_content_type=MediaType.APP,
title="Live TV", title="Live TV",
can_play=True, can_play=True,
can_expand=False, can_expand=False,
@ -118,7 +111,7 @@ async def build_item_response(
for c_type in content_types: for c_type in content_types:
children.append( children.append(
BrowseMedia( BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id=c_type, media_content_id=c_type,
media_content_type=TYPE_MAP[c_type].type, media_content_type=TYPE_MAP[c_type].type,
title=f"{c_type}s", title=f"{c_type}s",
@ -145,7 +138,7 @@ async def build_item_response(
} }
return BrowseMedia( return BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_id=media_content_id, media_content_id=media_content_id,
media_content_type=media_content_type, media_content_type=media_content_type,
title=f"{media_content_id}s", title=f"{media_content_id}s",

View File

@ -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.screenshots.models import ScreenshotResponse
from xbox.webapi.api.provider.smartglass.models import InstalledPackage from xbox.webapi.api.provider.smartglass.models import InstalledPackage
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player import MediaClass
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_GAME,
MEDIA_CLASS_IMAGE,
MEDIA_CLASS_VIDEO,
)
from homeassistant.components.media_source.models import ( from homeassistant.components.media_source.models import (
BrowseMediaSource, BrowseMediaSource,
MediaSource, MediaSource,
@ -35,8 +30,8 @@ MIME_TYPE_MAP = {
} }
MEDIA_CLASS_MAP = { MEDIA_CLASS_MAP = {
"gameclips": MEDIA_CLASS_VIDEO, "gameclips": MediaClass.VIDEO,
"screenshots": MEDIA_CLASS_IMAGE, "screenshots": MediaClass.IMAGE,
} }
@ -120,13 +115,13 @@ class XboxSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier="", identifier="",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title="Xbox Game Media", title="Xbox Game Media",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[_build_game_item(game, images) for game in games.values()], 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): async def _build_media_items(self, title, category):
@ -157,7 +152,7 @@ class XboxSource(MediaSource):
).strftime("%b. %d, %Y %I:%M %p"), ).strftime("%b. %d, %Y %I:%M %p"),
item.thumbnails[0].uri, item.thumbnails[0].uri,
item.game_clip_uris[0].uri, item.game_clip_uris[0].uri,
MEDIA_CLASS_VIDEO, MediaClass.VIDEO,
) )
for item in response.game_clips for item in response.game_clips
] ]
@ -182,7 +177,7 @@ class XboxSource(MediaSource):
), ),
item.thumbnails[0].uri, item.thumbnails[0].uri,
item.screenshot_uris[0].uri, item.screenshot_uris[0].uri,
MEDIA_CLASS_IMAGE, MediaClass.IMAGE,
) )
for item in response.screenshots for item in response.screenshots
] ]
@ -190,7 +185,7 @@ class XboxSource(MediaSource):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{title}~~{category}", identifier=f"{title}~~{category}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=f"{owner.title()} {kind.title()}", title=f"{owner.title()} {kind.title()}",
can_play=False, can_play=False,
@ -213,12 +208,12 @@ def _build_game_item(item: InstalledPackage, images: dict[str, list[Image]]):
return BrowseMediaSource( return BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{item.title_id}#{item.name}#{thumbnail}", identifier=f"{item.title_id}#{item.name}#{thumbnail}",
media_class=MEDIA_CLASS_GAME, media_class=MediaClass.GAME,
media_content_type="", media_content_type="",
title=item.name, title=item.name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
thumbnail=thumbnail, thumbnail=thumbnail,
) )
@ -229,13 +224,13 @@ def _build_categories(title):
base = BrowseMediaSource( base = BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{title}", identifier=f"{title}",
media_class=MEDIA_CLASS_GAME, media_class=MediaClass.GAME,
media_content_type="", media_content_type="",
title=name, title=name,
can_play=False, can_play=False,
can_expand=True, can_expand=True,
children=[], children=[],
children_media_class=MEDIA_CLASS_DIRECTORY, children_media_class=MediaClass.DIRECTORY,
thumbnail=thumbnail, thumbnail=thumbnail,
) )
@ -247,7 +242,7 @@ def _build_categories(title):
BrowseMediaSource( BrowseMediaSource(
domain=DOMAIN, domain=DOMAIN,
identifier=f"{title}~~{owner}#{kind}", identifier=f"{title}~~{owner}#{kind}",
media_class=MEDIA_CLASS_DIRECTORY, media_class=MediaClass.DIRECTORY,
media_content_type="", media_content_type="",
title=f"{owner.title()} {kind.title()}", title=f"{owner.title()} {kind.title()}",
can_play=False, can_play=False,