Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Subsonic: Fix album art missing from playlist display #1796

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading