Skip to content

Commit

Permalink
fix(client): improve URL handling for acast.com streams
Browse files Browse the repository at this point in the history
- Update stream URL handling to check for '@' in query string
- Replace '@' with '%40' only when necessary
- Adjust HEAD request to allow redirects
- Update error message for non-downloadable stream URLs
- Modify test helpers to support infinite repeat and acast-specific redirects
- Increase max complexity in ruff configuration
  • Loading branch information
bendikrb committed Oct 15, 2024
1 parent 349d51a commit ae81d3c
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 16 deletions.
15 changes: 8 additions & 7 deletions podme_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,14 +820,15 @@ async def check_stream_url(self, stream_url: URL | str) -> FetchedFileInfo:

# Check if the audio URL is directly downloadable
response = await self.session.get(stream_url)
# Needed for acast.com, which redirects to an URL containing @ instead of %40.
final_stream_url = URL(str(response.url).replace("@", "%40"), encoded=True)
# Needed for acast.com, which redirects to an URL containing @ instead of %40.
if "@" in response.url.query_string:
stream_url = URL(str(response.url).replace("@", "%40"), encoded=True)
else:
stream_url = response.url

response = await self.session.head(final_stream_url)
response = await self.session.head(stream_url, allow_redirects=True)
if response.status != HTTPStatus.OK:
raise PodMeApiStreamUrlError(
f"Stream URL is not downloadable: <{stream_url}> ({final_stream_url})"
)
raise PodMeApiStreamUrlError(f"Stream URL is not downloadable: <{stream_url}>")
content_length = response.headers.get("Content-Length")
content_type = response.headers.get("Content-Type")

Expand All @@ -836,7 +837,7 @@ async def check_stream_url(self, stream_url: URL | str) -> FetchedFileInfo:
return {
"content_length": int(content_length),
"content_type": content_type,
"url": final_stream_url,
"url": stream_url,
}

async def resolve_stream_url(self, stream_url: URL | str) -> FetchedFileInfo:
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/episode_currentlyplaying.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"id":4125238,"podcastId":3037,"authorFullName":"Podme ","title":"07.10.24 - Papaya","podcastTitle":"Papaya","length":"01:11:38","description":"I dag inntreffer en maksimal fadese. Men før det rekker vi både å åpne innboksen, gå på vekta og sjokkere med fun facts. Sånne ting. HEI!","htmlDescription":"","imageUrl":"","smallImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/e3ac5d3e0a3748cdabcd5b74bb22bba3_small.jpg","mediumImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/e3ac5d3e0a3748cdabcd5b74bb22bba3_medium.jpg","streamUrl":"https://amd-podme.akamaized.net/2024/10/6703c5aef01da3000864ec4a/master.m3u8","slug":"papaya","currentSpot":"00:01:01","currentSpotSec":61,"dateAdded":"2024-10-07T11:50:46.137+00:00","isPremium":true,"episodeCanBePlayed":true,"onlyAsPackageSubscription":false,"hasCompleted":false,"totalNoOfEpisodes":null,"isRss":false},{"id":1360289,"podcastId":6390,"authorFullName":"Bauer Media","title":"#18 - En Halvorsprat med Stian Blipp","podcastTitle":"Halvorsprat","length":"00:46:28","description":"Halvor og Stian Blipp snakker om å bli gubbe, hvor raskt man kunne lært å fly, totebags og stjæling.","htmlDescription":"Halvor og Stian Blipp snakker om å bli gubbe, hvor raskt man kunne lært å fly, totebags og stjæling.","imageUrl":"","smallImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/60f9a68c14d74e18afc444607d8e8830_small.jpg","mediumImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/60f9a68c14d74e18afc444607d8e8830_medium.jpg","streamUrl":"https://bauernordic-pods.sharp-stream.com/no/699/halvorsprat_040823_23_23_960__38d34c3a_normal.mp3?aw_0_1st.episodeid=209453&aw_0_1st.collectionid=699","slug":"halvorsprat","currentSpot":"00:04:33","currentSpotSec":273,"dateAdded":"2023-08-03T23:09:00+00:00","isPremium":false,"episodeCanBePlayed":true,"onlyAsPackageSubscription":false,"hasCompleted":false,"totalNoOfEpisodes":null,"isRss":true}]
[{"id":4125238,"podcastId":3037,"authorFullName":"Podme ","title":"07.10.24 - Papaya","podcastTitle":"Papaya","length":"01:11:38","description":"I dag inntreffer en maksimal fadese. Men før det rekker vi både å åpne innboksen, gå på vekta og sjokkere med fun facts. Sånne ting. HEI!","htmlDescription":"","imageUrl":"","smallImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/e3ac5d3e0a3748cdabcd5b74bb22bba3_small.jpg","mediumImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/e3ac5d3e0a3748cdabcd5b74bb22bba3_medium.jpg","streamUrl":"https://amd-podme.akamaized.net/2024/10/6703c5aef01da3000864ec4a/master.m3u8","slug":"papaya","currentSpot":"00:01:01","currentSpotSec":61,"dateAdded":"2024-10-07T11:50:46.137+00:00","isPremium":true,"episodeCanBePlayed":true,"onlyAsPackageSubscription":false,"hasCompleted":false,"totalNoOfEpisodes":null,"isRss":false},{"id":1360289,"podcastId":6390,"authorFullName":"Bauer Media","title":"#18 - En Halvorsprat med Stian Blipp","podcastTitle":"Halvorsprat","length":"00:46:28","description":"Halvor og Stian Blipp snakker om å bli gubbe, hvor raskt man kunne lært å fly, totebags og stjæling.","htmlDescription":"Halvor og Stian Blipp snakker om å bli gubbe, hvor raskt man kunne lært å fly, totebags og stjæling.","imageUrl":"","smallImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/60f9a68c14d74e18afc444607d8e8830_small.jpg","mediumImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/60f9a68c14d74e18afc444607d8e8830_medium.jpg","streamUrl":"https://bauernordic-pods.sharp-stream.com/no/699/halvorsprat_040823_23_23_960__38d34c3a_normal.mp3?aw_0_1st.episodeid=209453&aw_0_1st.collectionid=699","slug":"halvorsprat","currentSpot":"00:04:33","currentSpotSec":273,"dateAdded":"2023-08-03T23:09:00+00:00","isPremium":false,"episodeCanBePlayed":true,"onlyAsPackageSubscription":false,"hasCompleted":false,"totalNoOfEpisodes":null,"isRss":true},{"id":1936396,"podcastId":2047,"authorFullName":"PLAN-B & Acast","title":"Tema: Opptak fra Madagaskar med Morten Ramm","podcastTitle":"198 Land med Einar Tørnquist","length":"00:22:04","description":"Einar og Morten Ramm har vært på tur til Madagaskar, og bestemte seg for å spille inn en temaepisode på øya Tsarabanjina. Charterturisme, dyreliv, definisjonen av \"guttetur\" og alt som er farlig på øya de er på er bare noen av temaene som står på menyen.Hvis du er fysen på de nyeste landepisodene, så finner du de eksklusivt hos Podimo: https://go.podimo.com/no/198landProdusert av Martin Oftedal, PLAN-B Hosted on Acast. See acast.com/privacy for more information.","htmlDescription":"<p>Einar og Morten Ramm har vært på tur til Madagaskar, og bestemte seg for å spille inn en temaepisode på øya Tsarabanjina. Charterturisme, dyreliv, definisjonen av \"guttetur\" og alt som er farlig på øya de er på er bare noen av temaene som står på menyen.</p><br><p><br></p><p>Hvis du er fysen på de nyeste landepisodene, så finner du de eksklusivt hos Podimo: https://go.podimo.com/no/198land</p><br><p><br></p><p>Produsert av Martin Oftedal, PLAN-B</p><br><hr><p style=\"color: rgba(128, 128, 128, 1); font-size: 0.75em\"> Hosted on Acast. See <a style=\"color: rgba(128, 128, 128, 1)\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://acast.com/privacy\">acast.com/privacy</a> for more information.</p>","imageUrl":"https://assets.pippa.io/shows/61953d35cb03c875f76170e5/show-cover.jpg","smallImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/83F3D83C4D0BCF4FA62674D0B7CAF4E9_small.jpg","mediumImageUrl":"https://podmestorage.blob.core.windows.net/podcast-images/83F3D83C4D0BCF4FA62674D0B7CAF4E9_medium.jpg","streamUrl":"https://sphinx.acast.com/p/acast/s/198-land-med-einar-tornquist/e/666179d7c0af9f00135fe22c/media.mp3","slug":"198-land-med-einar-trnquist","currentSpot":"00:01:05","currentSpotSec":65,"dateAdded":"2024-06-10T03:00:27+00:00","isPremium":false,"episodeCanBePlayed":true,"onlyAsPackageSubscription":false,"hasCompleted":false,"totalNoOfEpisodes":162,"isRss":true}]
22 changes: 14 additions & 8 deletions tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def setup_stream_mocks(
stream_url.path,
"GET",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -267,7 +267,7 @@ def setup_stream_mocks(
stream_url.with_name("audio_128_pkg.m3u8").path,
"GET",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -285,7 +285,7 @@ def setup_stream_mocks(
stream_url.with_name("audio_128_pkg.mp4").path,
"HEAD",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -302,7 +302,7 @@ def setup_stream_mocks(
stream_url.with_name("audio_128_pkg.mp4").path,
"GET",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)
else:
redirect_url = stream_url.with_name(f"redir_{stream_url.name}")
Expand All @@ -312,14 +312,17 @@ def setup_stream_mocks(
"Location": str(redirect_url),
},
}
if "acast" in redirect_url.path:
resp["headers"]["Location"] = f"{redirect_url.with_query(None)}?pf=rss&sv=sphinx%401.221.1"

if head_request_error:
resp = {"status": 404}
aresponses.add(
stream_url.host,
stream_url.path,
"HEAD",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -334,7 +337,7 @@ def setup_stream_mocks(
redirect_url.path,
"HEAD",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -343,14 +346,17 @@ def setup_stream_mocks(
"Location": str(redirect_url),
},
}
if "acast" in redirect_url.path:
resp["headers"]["Location"] = f"{redirect_url.with_query(None)}?pf=rss&sv=sphinx%401.221.1"

if get_request_error:
resp = {"status": 500}
aresponses.add(
stream_url.host,
stream_url.path,
"GET",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

resp = {
Expand All @@ -365,7 +371,7 @@ def setup_stream_mocks(
redirect_url.path,
"GET",
aresponses.Response(**resp),
repeat=2,
repeat=float("inf"),
)

# Add response for episode info
Expand Down
1 change: 1 addition & 0 deletions tests/ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ lint.extend-ignore = [
]

lint.pylint.max-branches = 13
lint.mccabe.max-complexity = 12

0 comments on commit ae81d3c

Please sign in to comment.