From 9bb5490c330bb394694b19c57de9aea9ce299c2b Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Wed, 28 Oct 2026 11:39:17 +0100 Subject: [PATCH] feat(music-assistant): Pocket Casts Up Next as a Top Pick Pocket Casts now serves an Up Next recommendation row whose single item is the Up Next playlist, titled with the episode at the head of the queue (podcast as subtitle, podcast artwork). The frontend builds Top Picks for You from the first items of the visible recommendation rows, so the head of Up Next shows there; clicking or playing it loads the whole playlist. An empty Up Next yields an empty row, which the frontend hides together with the pick. Co-Authored-By: Claude Opus 5.5 --- .../pocketcasts-up-next/__init__.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/kubernetes/apps/music-assistant/pocketcasts-up-next/__init__.py b/kubernetes/apps/music-assistant/pocketcasts-up-next/__init__.py index 01cbdb31..a3cc2fac 100644 --- a/kubernetes/apps/music-assistant/pocketcasts-up-next/__init__.py +++ b/kubernetes/apps/music-assistant/pocketcasts-up-next/__init__.py @@ -32,6 +32,7 @@ from music_assistant_models.media_items import ( Podcast, PodcastEpisode, ProviderMapping, + RecommendationFolder, SearchResults, UniqueList, ) @@ -62,6 +63,7 @@ UP_NEXT_PLAYLIST_ID = "up_next" SUPPORTED_FEATURES = { ProviderFeature.LIBRARY_PODCASTS, ProviderFeature.LIBRARY_PLAYLISTS, + ProviderFeature.RECOMMENDATIONS, ProviderFeature.BROWSE, ProviderFeature.SEARCH, ProviderFeature.LIBRARY_PODCASTS_EDIT, @@ -282,6 +284,38 @@ class PocketCastsProvider(MusicProvider): ) return self._get_up_next_playlist() + async def get_recommendations(self) -> list[RecommendationFolder]: + """Get the Up Next row, without items.""" + return [ + RecommendationFolder( + item_id=UP_NEXT_PLAYLIST_ID, + provider=self.instance_id, + name="Up Next", + icon="mdi-playlist-play", + ) + ] + + async def get_recommendation_items( + self, item_id: str + ) -> UniqueList[MediaItemType | ItemMapping | BrowseFolder]: + """ + Get the Up Next playlist, shown as the episode at the head of the queue. + + :param item_id: The item_id of the row, as returned by get_recommendations. + """ + if item_id != UP_NEXT_PLAYLIST_ID: + return UniqueList() + episodes = await self._get_special_folder_episodes(UP_NEXT_PLAYLIST_ID) + if not episodes: + return UniqueList() + first = episodes[0] + playlist = self._get_up_next_playlist() + playlist.name = first.name + playlist.owner = first.podcast.name + if first.metadata.images: + playlist.metadata.images = first.metadata.images + return UniqueList([playlist]) + async def get_playlist_tracks( self, prov_playlist_id: str, page: int = 0 ) -> list[PodcastEpisode]: -- 2.54.0