From 664286a3b64d6b1c8c8b4fc25795b1fbe1a7f4e9 Mon Sep 17 00:00:00 2001 From: Doug Halley Date: Wed, 14 Feb 2024 23:31:17 -0500 Subject: [PATCH] Updated to use `netloc` comparison Signed-off-by: Doug Halley --- .../opentimelineio/url_utils.py | 30 ++++++++++++------- tests/test_url_conversions.py | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/py-opentimelineio/opentimelineio/url_utils.py b/src/py-opentimelineio/opentimelineio/url_utils.py index 31081e021..52cec058f 100644 --- a/src/py-opentimelineio/opentimelineio/url_utils.py +++ b/src/py-opentimelineio/opentimelineio/url_utils.py @@ -4,6 +4,7 @@ """Utilities for conversion between urls and file paths""" import os +import sys from urllib import ( parse as urlparse, request @@ -52,18 +53,18 @@ def filepath_from_url(urlstr): .. _ongoing discussions: https://discuss.python.org/t/file-uris-in-python/15600 """ - # De-encode the URL - decoded_url_str = urlparse.unquote(urlstr) - # Parse provided URL - parsed_result = urlparse.urlparse(decoded_url_str) + parsed_result = urlparse.urlparse(urlstr) + + # De-encode the parsed path + decoded_parsed_path = urlparse.unquote(parsed_result.path) # Convert the parsed URL to a path - filepath = Path(request.url2pathname(parsed_result.path)) + filepath = Path(request.url2pathname(decoded_parsed_path)) # If the network location is a window drive, reassemble the path if PureWindowsPath(parsed_result.netloc).drive: - filepath = Path(parsed_result.netloc + parsed_result.path) + filepath = Path(parsed_result.netloc + decoded_parsed_path) # Check if the specified index has a specified `drive`, if so then do nothing elif filepath.drive: @@ -74,9 +75,18 @@ def filepath_from_url(urlstr): # Remove leading "/" if/when `request.url2pathname` yields "/S:/path/file.ext" filepath = filepath.relative_to(filepath.root) - # Last resort, strip the "file:" prefix - else: - filepath = Path(decoded_url_str.strip('file:')) + # Should catch UNC paths, + # as parsing "file:///some/path/to/file.ext" doesn't provide a netloc + elif parsed_result.netloc and parsed_result.netloc != 'localhost': + # Paths of type: "file://host/share/path/to/file.ext" provide "host" as netloc + filepath = Path('//', parsed_result.netloc + decoded_parsed_path) # Convert "\" to "/" if needed - return filepath.as_posix() + path = filepath.as_posix() + + # Since the previous code handles Windows drive letter, we can assume that any path + # starting with a "/" is a UNC path if executed is run on Windows. + if path.startswith('/') and sys.platform == 'win32': + path = '/' + path + + return path diff --git a/tests/test_url_conversions.py b/tests/test_url_conversions.py index 405553345..38c769b9d 100644 --- a/tests/test_url_conversions.py +++ b/tests/test_url_conversions.py @@ -32,7 +32,7 @@ MEDIA_EXAMPLE_PATH_ABS ) -ENCODED_WINDOWS_URL = "file://localhost/S%3a/path/file.ext" +ENCODED_WINDOWS_URL = "file://host/S%3a/path/file.ext" WINDOWS_DRIVE_URL = "file://S:/path/file.ext" CORRECTED_WINDOWS_DRIVE_PATH = "S:/path/file.ext"