1 """Support for media browsing."""
12 PLAYABLE_ITEM_TYPES = [
21 "folder-with-favourites",
25 NON_EXPANDABLE_ITEM_TYPES = [
36 PLAYLISTS_URI_PREFIX =
"playlists"
37 ARTISTS_URI_PREFIX =
"artists://"
38 ALBUMS_URI_PREFIX =
"albums://"
39 GENRES_URI_PREFIX =
"genres://"
40 RADIO_URI_PREFIX =
"radio"
41 LAST_100_URI_PREFIX =
"Last_100"
42 FAVOURITES_URI =
"favourites"
46 if info
and "album" in info
and "artist" in info:
47 return MediaClass.TRACK
48 if item[
"uri"].startswith(PLAYLISTS_URI_PREFIX):
49 return MediaClass.PLAYLIST
50 if item[
"uri"].startswith(ARTISTS_URI_PREFIX):
51 if len(item[
"uri"]) > len(ARTISTS_URI_PREFIX):
52 return MediaClass.ALBUM
53 return MediaClass.ARTIST
54 if item[
"uri"].startswith(ALBUMS_URI_PREFIX):
55 if len(item[
"uri"]) > len(ALBUMS_URI_PREFIX):
56 return MediaClass.TRACK
57 return MediaClass.ALBUM
58 if item[
"uri"].startswith(GENRES_URI_PREFIX):
59 if len(item[
"uri"]) > len(GENRES_URI_PREFIX):
60 return MediaClass.ALBUM
61 return MediaClass.GENRE
62 if item[
"uri"].startswith(LAST_100_URI_PREFIX)
or item[
"uri"] == FAVOURITES_URI:
63 return MediaClass.TRACK
64 if item[
"uri"].startswith(RADIO_URI_PREFIX):
65 return MediaClass.CHANNEL
66 return MediaClass.DIRECTORY
70 if "type" not in item:
71 return MediaClass.DIRECTORY
72 if item[
"type"]
in (
"webradio",
"mywebradio"):
73 return MediaClass.CHANNEL
74 if item[
"type"]
in (
"song",
"cuesong"):
75 return MediaClass.TRACK
76 if item.get(
"artist"):
77 return MediaClass.ALBUM
78 if item[
"uri"].startswith(ARTISTS_URI_PREFIX)
and len(item[
"uri"]) > len(
81 return MediaClass.ARTIST
84 return MediaClass.DIRECTORY
90 media_class=MediaClass.DIRECTORY,
92 media_content_type=MediaType.MUSIC,
93 media_content_id=json.dumps(item),
101 if thumbnail := item.get(
"albumart"):
102 item_hash =
str(hash(thumbnail))
103 entity.thumbnail_cache.setdefault(item_hash, thumbnail)
104 thumbnail = entity.get_browse_image_url(MediaType.MUSIC, item_hash)
110 "title": title
or item.get(
"title"),
113 "media_content_type": MediaType.MUSIC,
114 "media_content_id": json.dumps(item),
115 "can_play": item.get(
"type")
in PLAYABLE_ITEM_TYPES,
116 "can_expand": item.get(
"type")
not in NON_EXPANDABLE_ITEM_TYPES,
117 "thumbnail": thumbnail,
126 """Browse the top-level of a Volumio media hierarchy."""
127 navigation = await media_library.browse()
128 children = [
_list_payload(item)
for item
in navigation[
"lists"]]
130 media_class=MediaClass.DIRECTORY,
131 media_content_id=
"library",
132 media_content_type=
"library",
133 title=
"Media Library",
140 async
def browse_node(entity, media_library, media_content_type, media_content_id):
141 """Browse a node of a Volumio media hierarchy."""
142 json_item = json.loads(media_content_id)
143 navigation = await media_library.browse(json_item[
"uri"])
144 if "lists" not in navigation:
145 raise BrowseError(f
"Media not found: {media_content_type} / {media_content_id}")
148 first_list = navigation[
"lists"][0]
151 for item
in first_list[
"items"]
153 info = navigation.get(
"info")
154 if not (title := first_list.get(
"title")):
156 title = f
"{info.get('album')} ({info.get('artist')})"
158 title =
"Media Library"