Skip to content

Commit

Permalink
fix: Subsonic: Fix album art missing from playlist display
Browse files Browse the repository at this point in the history
In order to display album art in the playlist view, we need to have an
album associated with each track. Mappings do not seem to be sufficient
here. Allow any caller of _parse_track() to optionally provide an Album
that should be used for this track and ensure that the playlist display
queries that album and uses it.

Fixes: https://github.com/music-assistant/hass-music-assistant/issues/3215

Signed-off-by: Eric B Munson <[email protected]>
  • Loading branch information
khers committed Dec 16, 2024
1 parent c33e766 commit f7930a4
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions music_assistant/providers/opensubsonic/sonic_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,23 @@ def _parse_album(self, sonic_album: SonicAlbum, sonic_info: SonicAlbumInfo = Non

return album

def _parse_track(self, sonic_song: SonicSong) -> Track:
mapping = None
if sonic_song.album_id is not None and sonic_song.album is not None:
mapping = self._get_item_mapping(MediaType.ALBUM, sonic_song.album_id, sonic_song.album)
def _parse_track(self, sonic_song: SonicSong, album: Album = None) -> Track:
# Unfortunately, the Song response type is not defined in the open subsonic spec so we have
# implementations which disagree about where the album id for this song should be stored.
# We accept either song.ablum_id or song.parent but prefer album_id.
if not album:
if sonic_song.album_id and sonic_song.album:
album = self._get_item_mapping(
MediaType.ALBUM, sonic_song.album_id, sonic_song.album
)
elif sonic_song.parent and sonic_song.album:
album = self._get_item_mapping(MediaType.ALBUM, sonic_song.parent, sonic_song.album)

track = Track(
item_id=sonic_song.id,
provider=self.instance_id,
name=sonic_song.title,
album=mapping,
album=album,
duration=sonic_song.duration if sonic_song.duration is not None else 0,
disc_number=sonic_song.disc_number or 0,
favorite=bool(sonic_song.starred),
Expand Down Expand Up @@ -486,8 +493,11 @@ async def get_library_tracks(self) -> AsyncGenerator[Track, None]:
songCount=count,
)
while results["songs"]:
album = None
for entry in results["songs"]:
yield self._parse_track(entry)
if album is None or album.item_id != entry.parent:
album = await self._run_async(self.get_album, prov_album_id=entry.parent)
yield self._parse_track(entry, album=album)
offset += count
results = await self._run_async(
self._conn.search3,
Expand Down Expand Up @@ -568,7 +578,8 @@ async def get_track(self, prov_track_id: str) -> Track:
except (ParameterError, DataNotFoundError) as e:
msg = f"Item {prov_track_id} not found"
raise MediaNotFoundError(msg) from e
return self._parse_track(sonic_song)
album = await self._run_async(self.get_album, prov_ablum_id=sonic_song.parent)
return self._parse_track(sonic_song, album=album)

async def get_artist_albums(self, prov_artist_id: str) -> list[Album]:
"""Return a list of all Albums by specified Artist."""
Expand Down Expand Up @@ -610,9 +621,11 @@ async def get_playlist_tracks(self, prov_playlist_id: str, page: int = 0) -> lis
msg = f"Playlist {prov_playlist_id} not found"
raise MediaNotFoundError(msg) from e

# TODO: figure out if subsonic supports paging here
album = None
for index, sonic_song in enumerate(sonic_playlist.songs, 1):
track = self._parse_track(sonic_song)
if not album or album.item_id != sonic_song.parent:
album = await self._run_async(self.get_album, prov_album_id=sonic_song.parent)
track = self._parse_track(sonic_song, album=album)
track.position = index
result.append(track)
return result
Expand Down

0 comments on commit f7930a4

Please sign in to comment.