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 Radio mode for Subsonic and remove Podcast hacks #1774

Merged
merged 1 commit into from
Nov 8, 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
105 changes: 1 addition & 104 deletions music_assistant/providers/opensubsonic/sonic_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
SonicError,
)
from music_assistant_models.enums import (
AlbumType,
ContentType,
ImageType,
MediaType,
Expand Down Expand Up @@ -52,8 +51,6 @@
from libopensonic.media import Artist as SonicArtist
from libopensonic.media import ArtistInfo as SonicArtistInfo
from libopensonic.media import Playlist as SonicPlaylist
from libopensonic.media import PodcastChannel as SonicPodcastChannel
from libopensonic.media import PodcastEpisode as SonicPodcastEpisode
from libopensonic.media import Song as SonicSong

CONF_BASE_URL = "baseURL"
Expand Down Expand Up @@ -155,85 +152,6 @@ def _get_item_mapping(self, media_type: MediaType, key: str, name: str) -> ItemM
name=name,
)

def _parse_podcast_artist(self, sonic_channel: SonicPodcastChannel) -> Artist:
artist = Artist(
item_id=sonic_channel.id,
name=sonic_channel.title,
provider=self.instance_id,
favorite=bool(sonic_channel.starred),
provider_mappings={
ProviderMapping(
item_id=sonic_channel.id,
provider_domain=self.domain,
provider_instance=self.instance_id,
)
},
)
if sonic_channel.description is not None:
artist.metadata.description = sonic_channel.description
if sonic_channel.original_image_url:
artist.metadata.images = [
MediaItemImage(
type=ImageType.THUMB,
path=sonic_channel.original_image_url,
provider=self.instance_id,
remotely_accessible=True,
)
]
return artist

def _parse_podcast_album(self, sonic_channel: SonicPodcastChannel) -> Album:
return Album(
item_id=sonic_channel.id,
provider=self.instance_id,
name=sonic_channel.title,
provider_mappings={
ProviderMapping(
item_id=sonic_channel.id,
provider_domain=self.domain,
provider_instance=self.instance_id,
available=True,
)
},
album_type=AlbumType.PODCAST,
)

def _parse_podcast_episode(
self, sonic_episode: SonicPodcastEpisode, sonic_channel: SonicPodcastChannel
) -> Track:
return Track(
item_id=sonic_episode.id,
provider=self.instance_id,
name=sonic_episode.title,
album=self._parse_podcast_album(sonic_channel=sonic_channel),
artists=[self._parse_podcast_artist(sonic_channel=sonic_channel)],
duration=sonic_episode.duration if sonic_episode.duration is not None else 0,
favorite=bool(sonic_episode.starred),
provider_mappings={
ProviderMapping(
item_id=sonic_episode.id,
provider_domain=self.domain,
provider_instance=self.instance_id,
available=True,
)
},
)

async def _get_podcast_artists(self) -> list[Artist]:
if not self._enable_podcasts:
return []

sonic_channels = await self._run_async(self._conn.getPodcasts, incEpisodes=False)
artists = []
for channel in sonic_channels:
artists.append(self._parse_podcast_artist(channel))
return artists

async def _get_podcasts(self) -> list[SonicPodcastChannel]:
if not self._enable_podcasts:
return []
return await self._run_async(self._conn.getPodcasts, incEpisodes=True)

def _parse_artist(
self, sonic_artist: SonicArtist, sonic_info: SonicArtistInfo = None
) -> Artist:
Expand Down Expand Up @@ -361,9 +279,6 @@ def _parse_track(self, sonic_song: SonicSong) -> Track:
name=sonic_song.title,
album=mapping,
duration=sonic_song.duration if sonic_song.duration is not None else 0,
# We are setting disc number to 0 because the standard for what is part of
# a Open Subsonic Song is not yet set and the implementations I have checked
# do not contain this field. We should revisit this when the spec is finished
disc_number=sonic_song.disc_number or 0,
favorite=bool(sonic_song.starred),
provider_mappings={
Expand Down Expand Up @@ -586,15 +501,6 @@ async def get_album(self, prov_album_id: str) -> Album:
sonic_album: SonicAlbum = await self._run_async(self._conn.getAlbum, prov_album_id)
sonic_info = await self._run_async(self._conn.getAlbumInfo2, aid=prov_album_id)
except (ParameterError, DataNotFoundError) as e:
if self._enable_podcasts:
# This might actually be a 'faked' album from podcasts, try that before giving up
try:
sonic_channel = await self._run_async(
self._conn.getPodcasts, incEpisodes=False, pid=prov_album_id
)
return self._parse_podcast_album(sonic_channel=sonic_channel)
except SonicError:
pass
msg = f"Album {prov_album_id} not found"
raise MediaNotFoundError(msg) from e

Expand Down Expand Up @@ -648,15 +554,6 @@ async def get_artist(self, prov_artist_id: str) -> Artist:
)
sonic_info = await self._run_async(self._conn.getArtistInfo2, aid=prov_artist_id)
except (ParameterError, DataNotFoundError) as e:
if self._enable_podcasts:
# This might actually be a 'faked' artist from podcasts, try that before giving up
try:
sonic_channel = await self._run_async(
self._conn.getPodcasts, incEpisodes=False, pid=prov_artist_id
)
return self._parse_podcast_artist(sonic_channel=sonic_channel[0])
except SonicError:
pass
msg = f"Artist {prov_artist_id} not found"
raise MediaNotFoundError(msg) from e
return self._parse_artist(sonic_artist, sonic_info)
Expand Down Expand Up @@ -734,7 +631,7 @@ async def get_artist_toptracks(self, prov_artist_id: str) -> list[Track]:
async def get_similar_tracks(self, prov_track_id: str, limit: int = 25) -> list[Track]:
"""Get tracks similar to selected track."""
songs: list[SonicSong] = await self._run_async(
self._conn.getSimilarSongs2, iid=prov_track_id, count=limit
self._conn.getSimilarSongs2, id=prov_track_id, count=limit
)
return [self._parse_track(entry) for entry in songs]

Expand Down
Loading