3939 PodMeApiStreamUrlNotFoundError ,
4040 PodMeApiUnauthorizedError ,
4141)
42+ from podme_api .helpers import async_cache
4243from podme_api .models import (
4344 PodMeApiPlatform ,
4445 PodMeCategory ,
4546 PodMeCategoryPage ,
4647 PodMeDownloadProgressTask ,
4748 PodMeEpisode ,
49+ PodMeEpisodeData ,
4850 PodMeHomeScreen ,
4951 PodMeLanguage ,
5052 PodMePodcast ,
@@ -76,7 +78,7 @@ class PodMeClient:
7678 auth_client : PodMeAuthClient
7779 """auth_client (PodMeAuthClient): The authentication client."""
7880
79- api_platform : PodMeApiPlatform = PodMeApiPlatform . MOBILE
81+ api_platform : PodMeApiPlatform = "mobile"
8082 """api_platform (PodMeApiPlatform): The API platform to use."""
8183
8284 disable_credentials_storage : bool = False
@@ -158,6 +160,7 @@ async def _request( # noqa: C901
158160 uri : str ,
159161 method : str = METH_GET ,
160162 retry : int = 0 ,
163+ api_platform : PodMeApiPlatform | None = None ,
161164 ** kwargs ,
162165 ) -> str | dict | list | bool | None :
163166 """Make a request to the PodMe API.
@@ -166,6 +169,7 @@ async def _request( # noqa: C901
166169 uri (str): The URI for the API endpoint.
167170 method (str): The HTTP method to use for the request.
168171 retry (int): The number of retries for the request.
172+ api_platform (PodMeApiPlatform): The API platform to use.
169173 **kwargs: Additional keyword arguments for the request.
170174 May include:
171175 - params (dict): Query parameters for the request.
@@ -176,7 +180,9 @@ async def _request( # noqa: C901
176180 The response data from the API.
177181
178182 """
179- base_url = PODME_API_URL .format (platform = self .api_platform )
183+ if api_platform is None :
184+ api_platform = self .api_platform
185+ base_url = PODME_API_URL .format (platform = api_platform )
180186 url = URL (f"{ base_url .strip ('/' )} /" ).join (URL (uri ))
181187
182188 access_token = await self .auth_client .async_get_access_token ()
@@ -224,7 +230,7 @@ async def _request( # noqa: C901
224230 if response .status == HTTPStatus .TOO_MANY_REQUESTS :
225231 raise PodMeApiRateLimitError ("Rate limit error has occurred with the PodMe API" )
226232 if response .status == HTTPStatus .NOT_FOUND :
227- raise PodMeApiNotFoundError ("Resource not found" )
233+ raise PodMeApiNotFoundError (f "Resource not found: < { url } > " )
228234 if response .status == HTTPStatus .BAD_REQUEST :
229235 raise PodMeApiError ("Bad request syntax or unsupported method" )
230236 if response .status == HTTPStatus .UNAUTHORIZED :
@@ -281,6 +287,7 @@ async def _get_pages(
281287 page_size : int | None = None ,
282288 params : dict | None = None ,
283289 items_key : str | None = None ,
290+ ** kwargs ,
284291 ):
285292 """Retrieve multiple pages of data from the API.
286293
@@ -291,6 +298,7 @@ async def _get_pages(
291298 page_size: The number of items per page.
292299 params: Additional parameters for the request.
293300 items_key: The key for the items in the response.
301+ **kwargs: Additional keyword arguments which will be passed on to the request.
294302
295303 Returns:
296304 list: The retrieved data.
@@ -311,6 +319,7 @@ async def _get_pages(
311319 "getByOldest" : "true" if get_by_oldest else None ,
312320 ** params ,
313321 },
322+ ** kwargs ,
314323 )
315324 if not isinstance (new_results , list ) and items_key is not None :
316325 new_results = new_results .get (items_key , [])
@@ -484,11 +493,11 @@ async def download_files(
484493 on_finished = on_finished ,
485494 )
486495
487- async def get_episode_download_url (self , episode : PodMeEpisode | int ) -> tuple [int , URL ]:
496+ async def get_episode_download_url (self , episode : PodMeEpisodeData | int ) -> tuple [int , URL ]:
488497 """Get the download URL for an episode.
489498
490499 Args:
491- episode (PodMeEpisode | int): The episode object or episode ID to get the download URL for.
500+ episode (PodMeEpisodeData | int): The episode object or episode ID to get the download URL for.
492501
493502 Returns:
494503 tuple[int, URL]: The episode ID and the download URL.
@@ -500,22 +509,24 @@ async def get_episode_download_url(self, episode: PodMeEpisode | int) -> tuple[i
500509 episode_data = episode
501510 if isinstance (episode_data , int ):
502511 episode_data = await self .get_episode_info (episode )
512+ if episode_data .url is not None :
513+ return episode_data .id , URL (episode_data .url )
503514 if episode_data .stream_url is None :
504515 raise PodMeApiStreamUrlError (f"No stream URL found for episode { episode_data .id } " )
505516 info = await self .resolve_stream_url (URL (episode_data .stream_url ))
506517 return episode_data .id , URL (info ["url" ])
507518
508519 async def get_episode_download_url_bulk (
509520 self ,
510- episodes : list [PodMeEpisode | int ],
521+ episodes : list [PodMeEpisodeData | int ],
511522 ) -> list [tuple [int , URL ]]:
512523 """Get download URLs for a list of episodes.
513524
514525 This method fetches download URLs for multiple episodes concurrently and
515526 ensures that only unique episode IDs are included in the result.
516527
517528 Args:
518- episodes (list[PodMeEpisode | int]): A list of PodMeEpisode objects
529+ episodes (list[PodMeEpisodeData | int]): A list of PodMeEpisode objects
519530 or episode IDs for which to fetch download URLs.
520531
521532 Returns:
@@ -793,6 +804,7 @@ async def get_currently_playing(self) -> list[PodMeEpisode]:
793804 )
794805 return [PodMeEpisode .from_dict (data ) for data in episodes ]
795806
807+ @async_cache
796808 async def get_podcast_info (self , podcast_slug : str ) -> PodMePodcast :
797809 """Get information about a podcast.
798810
@@ -815,19 +827,19 @@ async def get_podcasts_info(self, podcast_slugs: list[str]) -> list[PodMePodcast
815827 podcasts = await asyncio .gather (* [self .get_podcast_info (slug ) for slug in podcast_slugs ])
816828 return list (podcasts )
817829
818- async def get_episode_info (self , episode_id : int ) -> PodMeEpisode :
830+ async def get_episode_info (self , episode_id : int ) -> PodMeEpisodeData :
819831 """Get information about an episode.
820832
821833 Args:
822834 episode_id (int): The ID of the episode.
823835
824836 """
825837 data = await self ._request (
826- f"episode /{ episode_id } " ,
838+ f"episodes /{ episode_id } " ,
827839 )
828- return PodMeEpisode .from_dict (data )
840+ return PodMeEpisodeData .from_dict (data )
829841
830- async def get_episodes_info (self , episode_ids : list [int ]) -> list [PodMeEpisode ]:
842+ async def get_episodes_info (self , episode_ids : list [int ]) -> list [PodMeEpisodeData ]:
831843 """Get information about multiple episodes.
832844
833845 Args:
@@ -862,22 +874,25 @@ async def search_podcast(
862874 )
863875 return [PodMeSearchResult .from_dict (data ) for data in podcasts ]
864876
865- async def get_episode_list (self , podcast_slug : str ) -> list [PodMeEpisode ]:
877+ async def get_episode_list (self , podcast_slug : str ) -> list [PodMeEpisodeData ]:
866878 """Get the full list of episodes for a podcast.
867879
868880 Args:
869881 podcast_slug (str): The slug of the podcast.
870882
871883 """
884+ podcast_info = await self .get_podcast_info (podcast_slug )
872885 episodes = await self ._get_pages (
873- f"episode/slug/ { podcast_slug } " ,
886+ f"episodes/podcast/ { podcast_info . id } " ,
874887 get_by_oldest = True ,
875888 )
876889 _LOGGER .debug ("Retrieved full episode list, containing %s episodes" , len (episodes ))
877890
878- return [PodMeEpisode .from_dict (data ) for data in episodes ]
891+ return [PodMeEpisodeData .from_dict (data ) for data in episodes ]
879892
880- async def get_latest_episodes (self , podcast_slug : str , episodes_limit : int = 20 ) -> list [PodMeEpisode ]:
893+ async def get_latest_episodes (
894+ self , podcast_slug : str , episodes_limit : int = 20
895+ ) -> list [PodMeEpisodeData ]:
881896 """Get the latest episodes for a podcast.
882897
883898 Args:
@@ -888,9 +903,10 @@ async def get_latest_episodes(self, podcast_slug: str, episodes_limit: int = 20)
888903 max_per_page = 50
889904 pages = math .ceil (episodes_limit / max_per_page )
890905 page_size = min (max_per_page , episodes_limit )
906+ podcast_info = await self .get_podcast_info (podcast_slug )
891907
892908 episodes = await self ._get_pages (
893- f"episode/slug/ { podcast_slug } " ,
909+ f"episodes/podcast/ { podcast_info . id } " ,
894910 get_pages = pages ,
895911 page_size = page_size ,
896912 )
@@ -900,7 +916,7 @@ async def get_latest_episodes(self, podcast_slug: str, episodes_limit: int = 20)
900916 episodes_limit ,
901917 len (episodes ),
902918 )
903- return [PodMeEpisode .from_dict (data ) for data in episodes ]
919+ return [PodMeEpisodeData .from_dict (data ) for data in episodes ]
904920
905921 async def get_episode_ids (self , podcast_slug ) -> list [int ]:
906922 """Get the IDs of all episodes for a podcast.
0 commit comments