Add media class browse media attribute (#39770)

This commit is contained in:
Martin Hjelmare 2020-09-08 16:42:01 +02:00 committed by GitHub
parent f075823529
commit 586d7eaba6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 248 additions and 18 deletions

View file

@ -7,6 +7,8 @@ from arcam.fmj.state import State
from homeassistant import config_entries
from homeassistant.components.media_player import BrowseMedia, MediaPlayerEntity
from homeassistant.components.media_player.const import (
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_MUSIC,
MEDIA_TYPE_MUSIC,
SUPPORT_BROWSE_MEDIA,
SUPPORT_PLAY_MEDIA,
@ -255,6 +257,7 @@ class ArcamFmj(MediaPlayerEntity):
radio = [
BrowseMedia(
title=preset.name,
media_class=MEDIA_CLASS_MUSIC,
media_content_id=f"preset:{preset.index}",
media_content_type=MEDIA_TYPE_MUSIC,
can_play=True,
@ -265,6 +268,7 @@ class ArcamFmj(MediaPlayerEntity):
root = BrowseMedia(
title="Root",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id="root",
media_content_type="library",
can_play=False,

View file

@ -2,6 +2,14 @@
from homeassistant.components.media_player import BrowseMedia
from homeassistant.components.media_player.const import (
MEDIA_CLASS_ALBUM,
MEDIA_CLASS_ARTIST,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_MOVIE,
MEDIA_CLASS_MUSIC,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_SEASON,
MEDIA_CLASS_TV_SHOW,
MEDIA_TYPE_ALBUM,
MEDIA_TYPE_ARTIST,
MEDIA_TYPE_EPISODE,
@ -26,6 +34,16 @@ EXPANDABLE_MEDIA_TYPES = [
MEDIA_TYPE_SEASON,
]
CONTENT_TYPE_MEDIA_CLASS = {
"library_music": MEDIA_CLASS_MUSIC,
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON,
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST,
MEDIA_TYPE_MOVIE: MEDIA_CLASS_MOVIE,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST,
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW,
}
async def build_item_response(media_library, payload):
"""Create response payload for the provided media query."""
@ -124,6 +142,7 @@ async def build_item_response(media_library, payload):
return
return BrowseMedia(
media_class=CONTENT_TYPE_MEDIA_CLASS[search_type],
media_content_id=payload["search_id"],
media_content_type=search_type,
title=title,
@ -177,6 +196,7 @@ def item_payload(item, media_library):
return BrowseMedia(
title=title,
media_class=CONTENT_TYPE_MEDIA_CLASS[item["type"]],
media_content_type=media_content_type,
media_content_id=media_content_id,
can_play=can_play,
@ -192,6 +212,7 @@ def library_payload(media_library):
Used by async_browse_media.
"""
library_info = BrowseMedia(
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id="library",
media_content_type="library",
title="Media Library",

View file

@ -822,6 +822,7 @@ class MediaPlayerEntity(Entity):
Payload should follow this format:
{
"title": str - Title of the item
"media_class": str - Media class
"media_content_type": str - see below
"media_content_id": str - see below
- Can be passed back in to browse further
@ -1046,6 +1047,7 @@ class BrowseMedia:
def __init__(
self,
*,
media_class: str,
media_content_id: str,
media_content_type: str,
title: str,
@ -1055,6 +1057,7 @@ class BrowseMedia:
thumbnail: Optional[str] = None,
):
"""Initialize browse media item."""
self.media_class = media_class
self.media_content_id = media_content_id
self.media_content_type = media_content_type
self.title = title
@ -1067,6 +1070,7 @@ class BrowseMedia:
"""Convert Media class to browse media dictionary."""
response = {
"title": self.title,
"media_class": self.media_class,
"media_content_type": self.media_content_type,
"media_content_id": self.media_content_id,
"can_play": self.can_play,

View file

@ -29,6 +29,29 @@ ATTR_SOUND_MODE_LIST = "sound_mode_list"
DOMAIN = "media_player"
MEDIA_CLASS_ALBUM = "album"
MEDIA_CLASS_APP = "app"
MEDIA_CLASS_APPS = "apps"
MEDIA_CLASS_ARTIST = "artist"
MEDIA_CLASS_CHANNEL = "channel"
MEDIA_CLASS_CHANNELS = "channels"
MEDIA_CLASS_COMPOSER = "composer"
MEDIA_CLASS_CONTRIBUTING_ARTIST = "contributing_artist"
MEDIA_CLASS_DIRECTORY = "directory"
MEDIA_CLASS_EPISODE = "episode"
MEDIA_CLASS_GAME = "game"
MEDIA_CLASS_GENRE = "genre"
MEDIA_CLASS_IMAGE = "image"
MEDIA_CLASS_MOVIE = "movie"
MEDIA_CLASS_MUSIC = "music"
MEDIA_CLASS_PLAYLIST = "playlist"
MEDIA_CLASS_PODCAST = "podcast"
MEDIA_CLASS_SEASON = "season"
MEDIA_CLASS_TRACK = "track"
MEDIA_CLASS_TV_SHOW = "tv_show"
MEDIA_CLASS_URL = "url"
MEDIA_CLASS_VIDEO = "video"
MEDIA_TYPE_ALBUM = "album"
MEDIA_TYPE_APP = "app"
MEDIA_TYPE_APPS = "apps"

View file

@ -6,6 +6,7 @@ from typing import Tuple
from aiohttp import web
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.error import Unresolvable
from homeassistant.core import HomeAssistant, callback
@ -114,6 +115,7 @@ class LocalSource(MediaSource):
media = BrowseMediaSource(
domain=DOMAIN,
identifier=f"{source_dir_id}/{path.relative_to(self.hass.config.path('media'))}",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_type="directory",
title=title,
can_play=is_file,

View file

@ -5,6 +5,8 @@ from typing import List, Optional, Tuple
from homeassistant.components.media_player import BrowseMedia
from homeassistant.components.media_player.const import (
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_CHANNELS,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_CHANNELS,
)
@ -52,6 +54,7 @@ class MediaSourceItem:
base = BrowseMediaSource(
domain=None,
identifier=None,
media_class=MEDIA_CLASS_CHANNELS,
media_content_type=MEDIA_TYPE_CHANNELS,
title="Media Sources",
can_play=False,
@ -61,6 +64,7 @@ class MediaSourceItem:
BrowseMediaSource(
domain=source.domain,
identifier=None,
media_class=MEDIA_CLASS_CHANNEL,
media_content_type=MEDIA_TYPE_CHANNEL,
title=source.name,
can_play=False,

View file

@ -4,7 +4,10 @@ import logging
import re
from typing import Optional, Tuple
from homeassistant.components.media_player.const import MEDIA_TYPE_VIDEO
from homeassistant.components.media_player.const import (
MEDIA_CLASS_VIDEO,
MEDIA_TYPE_VIDEO,
)
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source.const import MEDIA_MIME_TYPES
from homeassistant.components.media_source.error import MediaSourceError, Unresolvable
@ -91,6 +94,7 @@ class NetatmoSource(MediaSource):
media = BrowseMediaSource(
domain=DOMAIN,
identifier=path,
media_class=MEDIA_CLASS_VIDEO,
media_content_type=MEDIA_TYPE_VIDEO,
title=title,
can_play=bool(

View file

@ -11,6 +11,8 @@ from homeassistant.components.media_player import (
MediaPlayerEntity,
)
from homeassistant.components.media_player.const import (
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_CHANNELS,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_CHANNELS,
SUPPORT_BROWSE_MEDIA,
@ -288,6 +290,7 @@ class PhilipsTVMediaPlayer(MediaPlayerEntity):
return BrowseMedia(
title="Channels",
media_class=MEDIA_CLASS_CHANNELS,
media_content_id="",
media_content_type=MEDIA_TYPE_CHANNELS,
can_play=False,
@ -295,6 +298,7 @@ class PhilipsTVMediaPlayer(MediaPlayerEntity):
children=[
BrowseMedia(
title=channel,
media_class=MEDIA_CLASS_CHANNEL,
media_content_id=channel,
media_content_type=MEDIA_TYPE_CHANNEL,
can_play=True,

View file

@ -2,13 +2,31 @@
import logging
from homeassistant.components.media_player import BrowseMedia
from homeassistant.components.media_player.const import (
MEDIA_CLASS_ALBUM,
MEDIA_CLASS_ARTIST,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_EPISODE,
MEDIA_CLASS_MOVIE,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_SEASON,
MEDIA_CLASS_TRACK,
MEDIA_CLASS_TV_SHOW,
MEDIA_CLASS_VIDEO,
)
from homeassistant.components.media_player.errors import BrowseError
from .const import DOMAIN
class UnknownMediaType(BrowseError):
"""Unknown media type."""
EXPANDABLES = ["album", "artist", "playlist", "season", "show"]
PLAYLISTS_BROWSE_PAYLOAD = {
"title": "Playlists",
"media_class": MEDIA_CLASS_PLAYLIST,
"media_content_id": "all",
"media_content_type": "playlists",
"can_play": False,
@ -19,6 +37,18 @@ SPECIAL_METHODS = {
"Recently Added": "recentlyAdded",
}
ITEM_TYPE_MEDIA_CLASS = {
"album": MEDIA_CLASS_ALBUM,
"artist": MEDIA_CLASS_ARTIST,
"episode": MEDIA_CLASS_EPISODE,
"movie": MEDIA_CLASS_MOVIE,
"playlist": MEDIA_CLASS_PLAYLIST,
"season": MEDIA_CLASS_SEASON,
"show": MEDIA_CLASS_TV_SHOW,
"track": MEDIA_CLASS_TRACK,
"video": MEDIA_CLASS_VIDEO,
}
_LOGGER = logging.getLogger(__name__)
@ -34,11 +64,17 @@ def browse_media(
if media is None:
return None
media_info = item_payload(media)
try:
media_info = item_payload(media)
except UnknownMediaType:
return None
if media_info.can_expand:
media_info.children = []
for item in media:
media_info.children.append(item_payload(item))
try:
media_info.children.append(item_payload(item))
except UnknownMediaType:
continue
return media_info
if media_content_id and ":" in media_content_id:
@ -65,6 +101,7 @@ def browse_media(
payload = {
"title": title,
"media_class": MEDIA_CLASS_DIRECTORY,
"media_content_id": f"{media_content_id}:{special_folder}",
"media_content_type": media_content_type,
"can_play": False,
@ -75,7 +112,10 @@ def browse_media(
method = SPECIAL_METHODS[special_folder]
items = getattr(library_or_section, method)()
for item in items:
payload["children"].append(item_payload(item))
try:
payload["children"].append(item_payload(item))
except UnknownMediaType:
continue
return BrowseMedia(**payload)
if media_content_type in ["server", None]:
@ -99,8 +139,14 @@ def browse_media(
def item_payload(item):
"""Create response payload for a single media item."""
try:
media_class = ITEM_TYPE_MEDIA_CLASS[item.type]
except KeyError as err:
_LOGGER.debug("Unknown type received: %s", item.type)
raise UnknownMediaType from err
payload = {
"title": item.title,
"media_class": media_class,
"media_content_id": str(item.ratingKey),
"media_content_type": item.type,
"can_play": True,
@ -116,6 +162,7 @@ def library_section_payload(section):
"""Create response payload for a single library section."""
return BrowseMedia(
title=section.title,
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id=section.key,
media_content_type="library",
can_play=False,
@ -128,6 +175,7 @@ def special_library_payload(parent_payload, special_type):
title = f"{special_type} ({parent_payload.title})"
return BrowseMedia(
title=title,
media_class=parent_payload.media_class,
media_content_id=f"{parent_payload.media_content_id}:{special_type}",
media_content_type=parent_payload.media_content_type,
can_play=False,
@ -139,6 +187,7 @@ def server_payload(plex_server):
"""Create response payload to describe libraries of the Plex server."""
server_info = BrowseMedia(
title=plex_server.friendly_name,
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id=plex_server.machine_identifier,
media_content_type="server",
can_play=False,
@ -165,7 +214,10 @@ def library_payload(plex_server, library_id):
special_library_payload(library_info, "Recently Added")
)
for item in library.all():
library_info.children.append(item_payload(item))
try:
library_info.children.append(item_payload(item))
except UnknownMediaType:
continue
return library_info
@ -173,5 +225,8 @@ def playlists_payload(plex_server):
"""Create response payload for all available playlists."""
playlists_info = {**PLAYLISTS_BROWSE_PAYLOAD, "children": []}
for playlist in plex_server.playlists():
playlists_info["children"].append(item_payload(playlist))
try:
playlists_info["children"].append(item_payload(playlist))
except UnknownMediaType:
continue
return BrowseMedia(**playlists_info)

View file

@ -11,6 +11,11 @@ from homeassistant.components.media_player import (
MediaPlayerEntity,
)
from homeassistant.components.media_player.const import (
MEDIA_CLASS_APP,
MEDIA_CLASS_APPS,
MEDIA_CLASS_CHANNEL,
MEDIA_CLASS_CHANNELS,
MEDIA_CLASS_DIRECTORY,
MEDIA_TYPE_APP,
MEDIA_TYPE_APPS,
MEDIA_TYPE_CHANNEL,
@ -79,6 +84,7 @@ def browse_media_library(channels: bool = False) -> BrowseMedia:
"""Create response payload to describe contents of a specific library."""
library_info = BrowseMedia(
title="Media Library",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id="library",
media_content_type="library",
can_play=False,
@ -89,6 +95,7 @@ def browse_media_library(channels: bool = False) -> BrowseMedia:
library_info.children.append(
BrowseMedia(
title="Apps",
media_class=MEDIA_CLASS_APPS,
media_content_id="apps",
media_content_type=MEDIA_TYPE_APPS,
can_expand=True,
@ -100,6 +107,7 @@ def browse_media_library(channels: bool = False) -> BrowseMedia:
library_info.children.append(
BrowseMedia(
title="Channels",
media_class=MEDIA_CLASS_CHANNELS,
media_content_id="channels",
media_content_type=MEDIA_TYPE_CHANNELS,
can_expand=True,
@ -286,6 +294,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
if media_content_type == MEDIA_TYPE_APPS:
response = BrowseMedia(
title="Apps",
media_class=MEDIA_CLASS_APPS,
media_content_id="apps",
media_content_type=MEDIA_TYPE_APPS,
can_expand=True,
@ -294,6 +303,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
BrowseMedia(
title=app.name,
thumbnail=self.coordinator.roku.app_icon_url(app.app_id),
media_class=MEDIA_CLASS_APP,
media_content_id=app.app_id,
media_content_type=MEDIA_TYPE_APP,
can_play=True,
@ -306,6 +316,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
if media_content_type == MEDIA_TYPE_CHANNELS:
response = BrowseMedia(
title="Channels",
media_class=MEDIA_CLASS_CHANNELS,
media_content_id="channels",
media_content_type=MEDIA_TYPE_CHANNELS,
can_expand=True,
@ -313,6 +324,7 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity):
children=[
BrowseMedia(
title=channel.name,
media_class=MEDIA_CLASS_CHANNEL,
media_content_id=channel.number,
media_content_type=MEDIA_TYPE_CHANNEL,
can_play=True,

View file

@ -17,6 +17,14 @@ import voluptuous as vol
from homeassistant.components.media_player import BrowseMedia, MediaPlayerEntity
from homeassistant.components.media_player.const import (
ATTR_MEDIA_ENQUEUE,
MEDIA_CLASS_ALBUM,
MEDIA_CLASS_ARTIST,
MEDIA_CLASS_COMPOSER,
MEDIA_CLASS_CONTRIBUTING_ARTIST,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_GENRE,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_TRACK,
MEDIA_TYPE_ALBUM,
MEDIA_TYPE_ARTIST,
MEDIA_TYPE_COMPOSER,
@ -103,6 +111,23 @@ EXPANDABLE_MEDIA_TYPES = [
SONOS_PLAYLISTS,
]
SONOS_TO_MEDIA_CLASSES = {
SONOS_ALBUM: MEDIA_CLASS_ALBUM,
SONOS_ALBUM_ARTIST: MEDIA_CLASS_ARTIST,
SONOS_ARTIST: MEDIA_CLASS_CONTRIBUTING_ARTIST,
SONOS_COMPOSER: MEDIA_CLASS_COMPOSER,
SONOS_GENRE: MEDIA_CLASS_GENRE,
SONOS_PLAYLISTS: MEDIA_CLASS_PLAYLIST,
SONOS_TRACKS: MEDIA_CLASS_TRACK,
"object.container.album.musicAlbum": MEDIA_CLASS_ALBUM,
"object.container.genre.musicGenre": MEDIA_CLASS_PLAYLIST,
"object.container.person.composer": MEDIA_CLASS_PLAYLIST,
"object.container.person.musicArtist": MEDIA_CLASS_ARTIST,
"object.container.playlistContainer.sameArtist": MEDIA_CLASS_ARTIST,
"object.container.playlistContainer": MEDIA_CLASS_PLAYLIST,
"object.item.audioItem.musicTrack": MEDIA_CLASS_TRACK,
}
SONOS_TO_MEDIA_TYPES = {
SONOS_ALBUM: MEDIA_TYPE_ALBUM,
SONOS_ALBUM_ARTIST: MEDIA_TYPE_ARTIST,
@ -1462,9 +1487,12 @@ def build_item_response(media_library, payload):
except IndexError:
title = LIBRARY_TITLES_MAPPING[payload["idstring"]]
media_class = SONOS_TO_MEDIA_CLASSES[MEDIA_TYPES_TO_SONOS[payload["search_type"]]]
return BrowseMedia(
title=title,
thumbnail=thumbnail,
media_class=media_class,
media_content_id=payload["idstring"],
media_content_type=payload["search_type"],
children=[item_payload(item) for item in media],
@ -1482,6 +1510,7 @@ def item_payload(item):
return BrowseMedia(
title=item.title,
thumbnail=getattr(item, "album_art_uri", None),
media_class=SONOS_TO_MEDIA_CLASSES[get_media_type(item)],
media_content_id=get_content_id(item),
media_content_type=SONOS_TO_MEDIA_TYPES[get_media_type(item)],
can_play=can_play(item.item_class),
@ -1497,6 +1526,7 @@ def library_payload(media_library):
"""
return BrowseMedia(
title="Music Library",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_id="library",
media_content_type="library",
can_play=False,

View file

@ -11,6 +11,12 @@ from yarl import URL
from homeassistant.components.media_player import BrowseMedia, MediaPlayerEntity
from homeassistant.components.media_player.const import (
MEDIA_CLASS_ALBUM,
MEDIA_CLASS_ARTIST,
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_PODCAST,
MEDIA_CLASS_TRACK,
MEDIA_TYPE_ALBUM,
MEDIA_TYPE_ARTIST,
MEDIA_TYPE_EPISODE,
@ -96,6 +102,29 @@ LIBRARY_MAP = {
"new_releases": "New Releases",
}
CONTENT_TYPE_MEDIA_CLASS = {
"current_user_playlists": MEDIA_CLASS_PLAYLIST,
"current_user_followed_artists": MEDIA_CLASS_ARTIST,
"current_user_saved_albums": MEDIA_CLASS_ALBUM,
"current_user_saved_tracks": MEDIA_CLASS_TRACK,
"current_user_saved_shows": MEDIA_CLASS_PODCAST,
"current_user_recently_played": MEDIA_CLASS_TRACK,
"current_user_top_artists": MEDIA_CLASS_ARTIST,
"current_user_top_tracks": MEDIA_CLASS_TRACK,
"featured_playlists": MEDIA_CLASS_PLAYLIST,
"categories": MEDIA_CLASS_DIRECTORY,
"category_playlists": MEDIA_CLASS_PLAYLIST,
"new_releases": MEDIA_CLASS_ALBUM,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST,
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST,
MEDIA_TYPE_SHOW: MEDIA_CLASS_PODCAST,
}
class MissingMediaInformation(BrowseError):
"""Missing media required information."""
async def async_setup_entry(
hass: HomeAssistant,
@ -498,24 +527,32 @@ def build_item_response(spotify, user, payload):
return None
if media_content_type == "categories":
return BrowseMedia(
media_item = BrowseMedia(
title=LIBRARY_MAP.get(media_content_id),
media_class=CONTENT_TYPE_MEDIA_CLASS[media_content_type],
media_content_id=media_content_id,
media_content_type=media_content_type,
can_play=False,
can_expand=True,
children=[
children=[],
)
for item in items:
try:
item_id = item["id"]
except KeyError:
_LOGGER.debug("Missing id for media item: %s", item)
continue
media_item.children.append(
BrowseMedia(
title=item.get("name"),
media_content_id=item["id"],
media_class=MEDIA_CLASS_PLAYLIST,
media_content_id=item_id,
media_content_type="category_playlists",
thumbnail=fetch_image_url(item, key="icons"),
can_play=False,
can_expand=True,
)
for item in items
],
)
)
if title is None:
if "name" in media:
@ -525,12 +562,18 @@ def build_item_response(spotify, user, payload):
response = {
"title": title,
"media_class": CONTENT_TYPE_MEDIA_CLASS[media_content_type],
"media_content_id": media_content_id,
"media_content_type": media_content_type,
"can_play": media_content_type in PLAYABLE_MEDIA_TYPES,
"children": [item_payload(item) for item in items],
"children": [],
"can_expand": True,
}
for item in items:
try:
response["children"].append(item_payload(item))
except MissingMediaInformation:
continue
if "images" in media:
response["thumbnail"] = fetch_image_url(media)
@ -546,20 +589,31 @@ def item_payload(item):
Used by async_browse_media.
"""
try:
media_type = item["type"]
media_id = item["uri"]
except KeyError as err:
_LOGGER.debug("Missing type or uri for media item: %s", item)
raise MissingMediaInformation from err
can_expand = item["type"] not in [
can_expand = media_type not in [
MEDIA_TYPE_TRACK,
MEDIA_TYPE_EPISODE,
]
payload = {
"title": item.get("name"),
"media_content_id": item["uri"],
"media_content_type": item["type"],
"can_play": item["type"] in PLAYABLE_MEDIA_TYPES,
"media_content_id": media_id,
"media_content_type": media_type,
"can_play": media_type in PLAYABLE_MEDIA_TYPES,
"can_expand": can_expand,
}
payload = {
**payload,
"media_class": CONTENT_TYPE_MEDIA_CLASS[media_type],
}
if "images" in item:
payload["thumbnail"] = fetch_image_url(item)
elif MEDIA_TYPE_ALBUM in item:
@ -576,6 +630,7 @@ def library_payload():
"""
library_info = {
"title": "Media Library",
"media_class": MEDIA_CLASS_DIRECTORY,
"media_content_id": "library",
"media_content_type": "library",
"can_play": False,

View file

@ -2,6 +2,7 @@
import pytest
from homeassistant.components import media_source
from homeassistant.components.media_player.const import MEDIA_CLASS_DIRECTORY
from homeassistant.components.media_player.errors import BrowseError
from homeassistant.components.media_source import const
from homeassistant.setup import async_setup_component
@ -77,6 +78,7 @@ async def test_websocket_browse_media(hass, hass_ws_client):
domain=const.DOMAIN,
identifier="/media",
title="Local Media",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_type="listing",
can_play=False,
can_expand=True,

View file

@ -1,5 +1,9 @@
"""Test Media Source model methods."""
from homeassistant.components.media_player.const import MEDIA_TYPE_MUSIC
from homeassistant.components.media_player.const import (
MEDIA_CLASS_DIRECTORY,
MEDIA_CLASS_MUSIC,
MEDIA_TYPE_MUSIC,
)
from homeassistant.components.media_source import const, models
@ -8,6 +12,7 @@ async def test_browse_media_as_dict():
base = models.BrowseMediaSource(
domain=const.DOMAIN,
identifier="media",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_type="folder",
title="media/",
can_play=False,
@ -17,6 +22,7 @@ async def test_browse_media_as_dict():
models.BrowseMediaSource(
domain=const.DOMAIN,
identifier="media/test.mp3",
media_class=MEDIA_CLASS_MUSIC,
media_content_type=MEDIA_TYPE_MUSIC,
title="test.mp3",
can_play=True,
@ -26,12 +32,14 @@ async def test_browse_media_as_dict():
item = base.as_dict()
assert item["title"] == "media/"
assert item["media_class"] == MEDIA_CLASS_DIRECTORY
assert item["media_content_type"] == "folder"
assert item["media_content_id"] == f"{const.URI_SCHEME}{const.DOMAIN}/media"
assert not item["can_play"]
assert item["can_expand"]
assert len(item["children"]) == 1
assert item["children"][0]["title"] == "test.mp3"
assert item["children"][0]["media_class"] == MEDIA_CLASS_MUSIC
async def test_browse_media_parent_no_children():
@ -39,6 +47,7 @@ async def test_browse_media_parent_no_children():
base = models.BrowseMediaSource(
domain=const.DOMAIN,
identifier="media",
media_class=MEDIA_CLASS_DIRECTORY,
media_content_type="folder",
title="media/",
can_play=False,
@ -47,6 +56,7 @@ async def test_browse_media_parent_no_children():
item = base.as_dict()
assert item["title"] == "media/"
assert item["media_class"] == MEDIA_CLASS_DIRECTORY
assert item["media_content_type"] == "folder"
assert item["media_content_id"] == f"{const.URI_SCHEME}{const.DOMAIN}/media"
assert not item["can_play"]