From b6fd525e1168a850b99a6121d6756939ae04b434 Mon Sep 17 00:00:00 2001 From: Bo Bayles Date: Fri, 11 Oct 2024 17:24:28 -0500 Subject: [PATCH] Issue 387: Support absolute Windows paths (#388) --- m3u8/__init__.py | 3 ++- m3u8/mixins.py | 6 ++++-- tests/playlists.py | 10 ++++++++++ tests/test_loader.py | 16 +++++++++++++++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/m3u8/__init__.py b/m3u8/__init__.py index d11dbf30..f6fc5174 100644 --- a/m3u8/__init__.py +++ b/m3u8/__init__.py @@ -90,7 +90,8 @@ def load( Retrieves the content from a given URI and returns a M3U8 object. Raises ValueError if invalid content or IOError if request fails. """ - if urlsplit(uri).scheme: + base_uri_parts = urlsplit(uri) + if base_uri_parts.scheme and base_uri_parts.netloc: content, base_uri = http_client.download(uri, timeout, headers, verify_ssl) return M3U8(content, base_uri=base_uri, custom_tags_parser=custom_tags_parser) else: diff --git a/m3u8/mixins.py b/m3u8/mixins.py index 162b82a1..40ffb2fc 100644 --- a/m3u8/mixins.py +++ b/m3u8/mixins.py @@ -9,8 +9,10 @@ def absolute_uri(self): return None ret = urljoin(self.base_uri, self.uri) - if self.base_uri and (not urlsplit(self.base_uri).scheme): - return ret + if self.base_uri: + base_uri_parts = urlsplit(self.base_uri) + if (not base_uri_parts.scheme) and (not base_uri_parts.netloc): + return ret if not urlsplit(ret).scheme: raise ValueError("There can not be `absolute_uri` with no `base_uri` set") diff --git a/tests/playlists.py b/tests/playlists.py index 56c05f71..b2435d2e 100755 --- a/tests/playlists.py +++ b/tests/playlists.py @@ -1576,5 +1576,15 @@ content-131.jpg """ +WINDOWS_PLAYLIST = r"""\ +#EXTM3U +#EXT-X-VERSION:3 +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-TARGETDURATION:10 +#EXT-X-MEDIA-SEQUENCE:55119 +#EXT-X-PROGRAM-DATE-TIME:2024-10-11T09:53:30.001Z +#EXTINF:9.600, +C:\HLS Video\test1.ts +""" del abspath, dirname, join diff --git a/tests/test_loader.py b/tests/test_loader.py index 509b7714..db114c4e 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -5,8 +5,11 @@ import os import socket import urllib.parse -import m3u8 +import unittest.mock + import pytest + +import m3u8 import playlists @@ -146,3 +149,14 @@ def test_raise_timeout_exception_if_timeout_happens_when_loading_from_uri(): assert True else: assert False + + +def test_windows_paths(): + file_path = "C:\\HLS Video\test.m3ui8" + with unittest.mock.patch("builtins.open") as mock_open: + mock_open.return_value.__enter__.return_value.read.return_value = ( + playlists.WINDOWS_PLAYLIST + ) + obj = m3u8.load(file_path) + assert obj.segments[0].uri == "C:\\HLS Video\\test1.ts" + assert obj.segments[0].absolute_uri == "C:\\HLS Video\\test1.ts"