Skip to content

Commit eafedeb

Browse files
authored
Add more information to music assistant get_queue (home-assistant#155242)
1 parent ce93de7 commit eafedeb

File tree

4 files changed

+112
-16
lines changed

4 files changed

+112
-16
lines changed

homeassistant/components/music_assistant/const.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@
6464
ATTR_STREAM_TITLE = "stream_title"
6565
ATTR_PROVIDER = "provider"
6666
ATTR_ITEM_ID = "item_id"
67+
ATTR_EXPLICIT = "explicit"
68+
ATTR_BITRATE = "bit_rate"
69+
ATTR_DISCART_IMAGE = "discart_image"
70+
ATTR_FANART_IMAGE = "fanart_image"
6771

6872
ATTR_CONF_EXPOSE_PLAYER_TO_HA = "expose_player_to_ha"
6973

homeassistant/components/music_assistant/schemas.py

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from typing import TYPE_CHECKING, Any
66

7-
from music_assistant_models.enums import MediaType
7+
from music_assistant_models.enums import ImageType, MediaType
8+
from music_assistant_models.media_items import ItemMapping
89
import voluptuous as vol
910

1011
from homeassistant.const import ATTR_NAME
@@ -17,11 +18,16 @@
1718
ATTR_ARTISTS,
1819
ATTR_AUDIOBOOKS,
1920
ATTR_BIT_DEPTH,
21+
ATTR_BITRATE,
2022
ATTR_CONTENT_TYPE,
2123
ATTR_CURRENT_INDEX,
2224
ATTR_CURRENT_ITEM,
25+
ATTR_DISCART_IMAGE,
2326
ATTR_DURATION,
2427
ATTR_ELAPSED_TIME,
28+
ATTR_EXPLICIT,
29+
ATTR_FANART_IMAGE,
30+
ATTR_FAVORITE,
2531
ATTR_IMAGE,
2632
ATTR_ITEM_ID,
2733
ATTR_ITEMS,
@@ -49,7 +55,7 @@
4955

5056
if TYPE_CHECKING:
5157
from music_assistant_client import MusicAssistantClient
52-
from music_assistant_models.media_items import ItemMapping, MediaItemType
58+
from music_assistant_models.media_items import MediaItemType
5359
from music_assistant_models.queue_item import QueueItem
5460

5561
MEDIA_ITEM_SCHEMA = vol.Schema(
@@ -58,7 +64,11 @@
5864
vol.Required(ATTR_URI): cv.string,
5965
vol.Required(ATTR_NAME): cv.string,
6066
vol.Required(ATTR_VERSION): cv.string,
61-
vol.Optional(ATTR_IMAGE, default=None): vol.Any(None, cv.string),
67+
vol.Required(ATTR_IMAGE, default=None): vol.Any(None, cv.string),
68+
vol.Optional(ATTR_FAVORITE): bool,
69+
vol.Optional(ATTR_EXPLICIT): vol.Any(None, bool),
70+
vol.Optional(ATTR_DISCART_IMAGE): vol.Any(None, cv.string),
71+
vol.Optional(ATTR_FANART_IMAGE): vol.Any(None, cv.string),
6272
vol.Optional(ATTR_ARTISTS): [vol.Self],
6373
vol.Optional(ATTR_ALBUM): vol.Self,
6474
}
@@ -70,20 +80,39 @@ def media_item_dict_from_mass_item(
7080
item: MediaItemType | ItemMapping,
7181
) -> dict[str, Any]:
7282
"""Parse a Music Assistant MediaItem."""
73-
base: dict[str, Any] = {
83+
result: dict[str, Any] = {
7484
ATTR_MEDIA_TYPE: item.media_type,
7585
ATTR_URI: item.uri,
7686
ATTR_NAME: item.name,
7787
ATTR_VERSION: item.version,
7888
ATTR_IMAGE: mass.get_media_item_image_url(item),
7989
}
90+
91+
if isinstance(item, ItemMapping):
92+
return result
93+
94+
result[ATTR_FAVORITE] = item.favorite
95+
result[ATTR_EXPLICIT] = item.metadata.explicit
96+
97+
if item.media_type is MediaType.ALBUM:
98+
result[ATTR_DISCART_IMAGE] = mass.get_media_item_image_url(
99+
item, type=ImageType.DISCART
100+
)
101+
if item.media_type is MediaType.ARTIST:
102+
result[ATTR_FANART_IMAGE] = mass.get_media_item_image_url(
103+
item, type=ImageType.FANART
104+
)
105+
80106
artists: list[ItemMapping] | None
81107
if artists := getattr(item, "artists", None):
82-
base[ATTR_ARTISTS] = [media_item_dict_from_mass_item(mass, x) for x in artists]
108+
result[ATTR_ARTISTS] = [
109+
media_item_dict_from_mass_item(mass, x) for x in artists
110+
]
83111
album: ItemMapping | None
84112
if album := getattr(item, "album", None):
85-
base[ATTR_ALBUM] = media_item_dict_from_mass_item(mass, album)
86-
return base
113+
result[ATTR_ALBUM] = media_item_dict_from_mass_item(mass, album)
114+
115+
return result
87116

88117

89118
SEARCH_RESULT_SCHEMA = vol.Schema(
@@ -126,11 +155,12 @@ def media_item_dict_from_mass_item(
126155

127156
AUDIO_FORMAT_SCHEMA = vol.Schema(
128157
{
158+
vol.Required(ATTR_PROVIDER): str,
159+
vol.Required(ATTR_ITEM_ID): str,
129160
vol.Required(ATTR_CONTENT_TYPE): str,
130161
vol.Required(ATTR_SAMPLE_RATE): int,
131162
vol.Required(ATTR_BIT_DEPTH): int,
132-
vol.Required(ATTR_PROVIDER): str,
133-
vol.Required(ATTR_ITEM_ID): str,
163+
vol.Optional(ATTR_BITRATE): int,
134164
}
135165
)
136166

@@ -142,8 +172,8 @@ def media_item_dict_from_mass_item(
142172
vol.Optional(ATTR_MEDIA_ITEM, default=None): vol.Any(
143173
None, vol.Schema(MEDIA_ITEM_SCHEMA)
144174
),
145-
vol.Optional(ATTR_STREAM_DETAILS): vol.Schema(AUDIO_FORMAT_SCHEMA),
146175
vol.Optional(ATTR_STREAM_TITLE, default=None): vol.Any(None, cv.string),
176+
vol.Optional(ATTR_STREAM_DETAILS): vol.Schema(AUDIO_FORMAT_SCHEMA),
147177
}
148178
)
149179

@@ -155,7 +185,7 @@ def queue_item_dict_from_mass_item(
155185
"""Parse a Music Assistant QueueItem."""
156186
if not item:
157187
return None
158-
base = {
188+
result = {
159189
ATTR_QUEUE_ITEM_ID: item.queue_item_id,
160190
ATTR_NAME: item.name,
161191
ATTR_DURATION: item.duration,
@@ -166,16 +196,19 @@ def queue_item_dict_from_mass_item(
166196
),
167197
}
168198
if streamdetails := item.streamdetails:
169-
base[ATTR_STREAM_TITLE] = streamdetails.stream_title
170-
base[ATTR_STREAM_DETAILS] = {
199+
result[ATTR_STREAM_TITLE] = streamdetails.stream_title
200+
stream_details_dict: dict[str, Any] = {
201+
ATTR_PROVIDER: streamdetails.provider,
202+
ATTR_ITEM_ID: streamdetails.item_id,
171203
ATTR_CONTENT_TYPE: streamdetails.audio_format.content_type.value,
172204
ATTR_SAMPLE_RATE: streamdetails.audio_format.sample_rate,
173205
ATTR_BIT_DEPTH: streamdetails.audio_format.bit_depth,
174-
ATTR_PROVIDER: streamdetails.provider,
175-
ATTR_ITEM_ID: streamdetails.item_id,
176206
}
207+
if streamdetails.audio_format.bit_rate is not None:
208+
stream_details_dict[ATTR_BITRATE] = streamdetails.audio_format.bit_rate
209+
result[ATTR_STREAM_DETAILS] = stream_details_dict
177210

178-
return base
211+
return result
179212

180213

181214
QUEUE_DETAILS_SCHEMA = vol.Schema(

tests/components/music_assistant/snapshots/test_actions.ambr

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
'version': '',
1313
}),
1414
]),
15+
'discart_image': None,
16+
'explicit': False,
17+
'favorite': False,
1518
'image': None,
1619
'media_type': <MediaType.ALBUM: 'album'>,
1720
'name': 'Synth Punk EP',
@@ -28,6 +31,9 @@
2831
'version': '',
2932
}),
3033
]),
34+
'discart_image': None,
35+
'explicit': False,
36+
'favorite': False,
3137
'image': None,
3238
'media_type': <MediaType.ALBUM: 'album'>,
3339
'name': 'Synthwave (The 80S Revival)',
@@ -45,6 +51,9 @@
4551
dict({
4652
'items': list([
4753
dict({
54+
'explicit': None,
55+
'fanart_image': None,
56+
'favorite': False,
4857
'image': None,
4958
'media_type': <MediaType.ARTIST: 'artist'>,
5059
'name': 'W O L F C L U B',
@@ -62,41 +71,53 @@
6271
dict({
6372
'items': list([
6473
dict({
74+
'explicit': None,
75+
'favorite': False,
6576
'image': None,
6677
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
6778
'name': 'Test Audiobook',
6879
'uri': 'library://audiobook/1',
6980
'version': '',
7081
}),
7182
dict({
83+
'explicit': None,
84+
'favorite': False,
7285
'image': None,
7386
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
7487
'name': 'Test Audiobook 0',
7588
'uri': 'library://audiobook/11',
7689
'version': '',
7790
}),
7891
dict({
92+
'explicit': None,
93+
'favorite': False,
7994
'image': None,
8095
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
8196
'name': 'Test Audiobook 1',
8297
'uri': 'library://audiobook/12',
8398
'version': '',
8499
}),
85100
dict({
101+
'explicit': None,
102+
'favorite': False,
86103
'image': None,
87104
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
88105
'name': 'Test Audiobook 2',
89106
'uri': 'library://audiobook/13',
90107
'version': '',
91108
}),
92109
dict({
110+
'explicit': None,
111+
'favorite': False,
93112
'image': None,
94113
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
95114
'name': 'Test Audiobook 3',
96115
'uri': 'library://audiobook/14',
97116
'version': '',
98117
}),
99118
dict({
119+
'explicit': None,
120+
'favorite': False,
100121
'image': None,
101122
'media_type': <MediaType.AUDIOBOOK: 'audiobook'>,
102123
'name': 'Test Audiobook 4',
@@ -114,6 +135,8 @@
114135
dict({
115136
'items': list([
116137
dict({
138+
'explicit': None,
139+
'favorite': True,
117140
'image': None,
118141
'media_type': <MediaType.PLAYLIST: 'playlist'>,
119142
'name': '1970s Rock Hits',
@@ -131,34 +154,44 @@
131154
dict({
132155
'items': list([
133156
dict({
157+
'explicit': None,
158+
'favorite': False,
134159
'image': None,
135160
'media_type': <MediaType.PODCAST: 'podcast'>,
136161
'name': 'Test Podcast 0',
137162
'uri': 'library://podcast/6',
138163
'version': '',
139164
}),
140165
dict({
166+
'explicit': None,
167+
'favorite': False,
141168
'image': None,
142169
'media_type': <MediaType.PODCAST: 'podcast'>,
143170
'name': 'Test Podcast 1',
144171
'uri': 'library://podcast/7',
145172
'version': '',
146173
}),
147174
dict({
175+
'explicit': None,
176+
'favorite': False,
148177
'image': None,
149178
'media_type': <MediaType.PODCAST: 'podcast'>,
150179
'name': 'Test Podcast 2',
151180
'uri': 'library://podcast/8',
152181
'version': '',
153182
}),
154183
dict({
184+
'explicit': None,
185+
'favorite': False,
155186
'image': None,
156187
'media_type': <MediaType.PODCAST: 'podcast'>,
157188
'name': 'Test Podcast 3',
158189
'uri': 'library://podcast/9',
159190
'version': '',
160191
}),
161192
dict({
193+
'explicit': None,
194+
'favorite': False,
162195
'image': None,
163196
'media_type': <MediaType.PODCAST: 'podcast'>,
164197
'name': 'Test Podcast 4',
@@ -176,6 +209,8 @@
176209
dict({
177210
'items': list([
178211
dict({
212+
'explicit': None,
213+
'favorite': True,
179214
'image': None,
180215
'media_type': <MediaType.RADIO: 'radio'>,
181216
'name': 'fm4 | ORF | HQ',
@@ -209,6 +244,8 @@
209244
'version': '',
210245
}),
211246
]),
247+
'explicit': False,
248+
'favorite': True,
212249
'image': None,
213250
'media_type': <MediaType.TRACK: 'track'>,
214251
'name': 'Tennessee Whiskey',
@@ -232,6 +269,8 @@
232269
'version': '',
233270
}),
234271
]),
272+
'explicit': False,
273+
'favorite': True,
235274
'image': None,
236275
'media_type': <MediaType.TRACK: 'track'>,
237276
'name': 'Thelma + Louise',
@@ -255,6 +294,8 @@
255294
'version': '',
256295
}),
257296
]),
297+
'explicit': False,
298+
'favorite': True,
258299
'image': None,
259300
'media_type': <MediaType.TRACK: 'track'>,
260301
'name': "They Don't Care About Us",
@@ -285,6 +326,8 @@
285326
'version': '',
286327
}),
287328
]),
329+
'explicit': True,
330+
'favorite': True,
288331
'image': None,
289332
'media_type': <MediaType.TRACK: 'track'>,
290333
'name': "They Don't Give A F**** About Us",
@@ -308,6 +351,8 @@
308351
'version': '',
309352
}),
310353
]),
354+
'explicit': False,
355+
'favorite': True,
311356
'image': None,
312357
'media_type': <MediaType.TRACK: 'track'>,
313358
'name': 'Things We Lost In The Fire',
@@ -331,6 +376,8 @@
331376
'version': '',
332377
}),
333378
]),
379+
'explicit': False,
380+
'favorite': True,
334381
'image': None,
335382
'media_type': <MediaType.TRACK: 'track'>,
336383
'name': 'Those Nights',
@@ -357,6 +404,9 @@
357404
'version': '',
358405
}),
359406
]),
407+
'discart_image': None,
408+
'explicit': False,
409+
'favorite': False,
360410
'image': None,
361411
'media_type': <MediaType.ALBUM: 'album'>,
362412
'name': 'Synth Punk EP',
@@ -373,6 +423,9 @@
373423
'version': '',
374424
}),
375425
]),
426+
'discart_image': None,
427+
'explicit': False,
428+
'favorite': False,
376429
'image': None,
377430
'media_type': <MediaType.ALBUM: 'album'>,
378431
'name': 'Synthwave (The 80S Revival)',

0 commit comments

Comments
 (0)