mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 17:04:04 -04:00
Fix Sonos browse album art lookup for multi-segment A:ALBUM IDs (#163786)
This commit is contained in:
@@ -585,10 +585,30 @@ def get_media(
|
||||
item_id = "A:ALBUMARTIST/" + "/".join(item_id.split("/")[2:])
|
||||
|
||||
if item_id.startswith("A:ALBUM/") or search_type == "tracks":
|
||||
search_term = urllib.parse.unquote(item_id.split("/")[-1])
|
||||
# Some Sonos libraries return album ids in the shape:
|
||||
# A:ALBUM/<album>/<artist>, where the artist part disambiguates results.
|
||||
# Use the album segment for searching.
|
||||
if item_id.startswith("A:ALBUM/"):
|
||||
splits = item_id.split("/")
|
||||
search_term = urllib.parse.unquote(splits[1]) if len(splits) > 1 else ""
|
||||
album_title: str | None = search_term
|
||||
else:
|
||||
search_term = urllib.parse.unquote(item_id.split("/")[-1])
|
||||
album_title = None
|
||||
|
||||
matches = media_library.get_music_library_information(
|
||||
search_type, search_term=search_term, full_album_art_uri=True
|
||||
)
|
||||
if item_id.startswith("A:ALBUM/") and len(matches) > 1:
|
||||
if result := next(
|
||||
(item for item in matches if item_id == item.item_id), None
|
||||
):
|
||||
matches = [result]
|
||||
elif album_title:
|
||||
if result := next(
|
||||
(item for item in matches if album_title == item.title), None
|
||||
):
|
||||
matches = [result]
|
||||
elif search_type == SONOS_SHARE:
|
||||
# In order to get the MusicServiceItem, we browse the parent folder
|
||||
# and find one that matches on item_id.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Tests for the Sonos Media Browser."""
|
||||
|
||||
from functools import partial
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
@@ -15,6 +16,7 @@ from homeassistant.components.media_player import (
|
||||
from homeassistant.components.sonos.const import MEDIA_TYPE_DIRECTORY
|
||||
from homeassistant.components.sonos.media_browser import (
|
||||
build_item_response,
|
||||
get_media,
|
||||
get_thumbnail_url_full,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
@@ -109,6 +111,81 @@ async def test_build_item_response(
|
||||
)
|
||||
|
||||
|
||||
def test_get_media_multisegment_album_id_uses_album_segment() -> None:
|
||||
"""Test `A:ALBUM/<album>/<artist>` uses album name as lookup search term."""
|
||||
music_library = MagicMock()
|
||||
music_library.get_music_library_information.return_value = []
|
||||
result = get_media(
|
||||
music_library,
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles",
|
||||
"album",
|
||||
)
|
||||
|
||||
assert result is None
|
||||
assert music_library.get_music_library_information.call_count == 1
|
||||
assert music_library.get_music_library_information.call_args.args == ("albums",)
|
||||
assert music_library.get_music_library_information.call_args.kwargs == {
|
||||
"search_term": "Abbey Road",
|
||||
"full_album_art_uri": True,
|
||||
}
|
||||
|
||||
|
||||
def test_get_media_multisegment_album_id_prefers_exact_item_id_match() -> None:
|
||||
"""Test multi-match disambiguation prefers exact `item_id`."""
|
||||
music_library = MagicMock()
|
||||
exact_item = MockMusicServiceItem(
|
||||
"Abbey Road (Remaster)",
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles",
|
||||
"A:ALBUM",
|
||||
"object.container.album.musicAlbum",
|
||||
)
|
||||
music_library.get_music_library_information.return_value = [
|
||||
MockMusicServiceItem(
|
||||
"Abbey Road",
|
||||
"A:ALBUM/Abbey%20Road/Someone%20Else",
|
||||
"A:ALBUM",
|
||||
"object.container.album.musicAlbum",
|
||||
),
|
||||
exact_item,
|
||||
]
|
||||
|
||||
result = get_media(
|
||||
music_library,
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles",
|
||||
"album",
|
||||
)
|
||||
|
||||
assert result is exact_item
|
||||
|
||||
|
||||
def test_get_media_multisegment_album_id_falls_back_to_exact_title_match() -> None:
|
||||
"""Test multi-match disambiguation falls back to exact title match."""
|
||||
music_library = MagicMock()
|
||||
title_match_item = MockMusicServiceItem(
|
||||
"Abbey Road",
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles%20(Remaster)",
|
||||
"A:ALBUM",
|
||||
"object.container.album.musicAlbum",
|
||||
)
|
||||
music_library.get_music_library_information.return_value = [
|
||||
MockMusicServiceItem(
|
||||
"Abbey Road (Live)",
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles%20(Live)",
|
||||
"A:ALBUM",
|
||||
"object.container.album.musicAlbum",
|
||||
),
|
||||
title_match_item,
|
||||
]
|
||||
|
||||
result = get_media(
|
||||
music_library,
|
||||
"A:ALBUM/Abbey%20Road/The%20Beatles",
|
||||
"album",
|
||||
)
|
||||
|
||||
assert result is title_match_item
|
||||
|
||||
|
||||
async def test_browse_media_root(
|
||||
hass: HomeAssistant,
|
||||
soco_factory: SoCoMockFactory,
|
||||
|
||||
Reference in New Issue
Block a user