Fix using network shares for extensions on WIN32

- Support UNC paths.
- Normalize URL's to account for differences between browsers.
This commit is contained in:
Campbell Barton 2024-07-02 12:53:00 +10:00
parent e8a3537ffb
commit 33fb83ae74
2 changed files with 37 additions and 3 deletions

View File

@ -70,6 +70,26 @@ def url_append_defaults(url):
return url_append_query_for_blender(url, blender_version=bpy.app.version)
def url_normalize(url):
# Ensure consistent use of `file://` so multiple representations aren't considered different repositories.
# Currently this only makes changes for UNC paths on WIN32.
import sys
import re
prefix = "file://"
if url.startswith(prefix):
if sys.platform == "win32":
# Not a drive, e.g. `file:///C:/path`.
path_lstrip = url[len(prefix):].lstrip("/")
if re.match("[A-Za-z]:", path_lstrip) is None:
# Ensure:
# MS-Edge uses: `file://HOST/share/path`
# Firefox uses: `file://///HOST/share/path`
# Both can work prefer the shorter one.
url = prefix + path_lstrip
return url
def rna_prop_repo_enum_valid_only_itemf(_self, context):
if context is None:
result = []
@ -2589,6 +2609,9 @@ class EXTENSIONS_OT_package_install(Operator, _ExtCmdMixIn):
url = self.url
print("DROP URL:", url)
# Needed for UNC paths on WIN32.
url = self.url = url_normalize(url)
url, url_params = url_parse_for_blender(url)
# Check if the extension is compatible with the current platform.

View File

@ -373,9 +373,20 @@ def path_from_url(path: str) -> str:
if sys.platform == "win32":
# MS-Windows needs special handling for drive letters.
# `file:///C:/test` is converted to `/C:/test` which must skip the leading slash.
if re.match("/[A-Za-z]:", path_unquote):
path_unquote = path_unquote[1:]
return os.path.join(p.netloc, path_unquote)
if (p.netloc == "") and re.match("/[A-Za-z]:", path_unquote):
result = path_unquote[1:]
else:
# Handle UNC paths: `\\HOST\share\path` as a URL on MS-Windows.
# - MS-Edge: `file://HOST/share/path` where `netloc="HOST"`, `path="/share/path"`.
# - Firefox: `file://///HOST/share/path` where `netloc=""`, `path="///share/path"`.
if p.netloc:
result = "//{:s}/{:s}".format(p.netloc, path_unquote.lstrip("/"))
else:
result = "//{:s}".format(path_unquote.lstrip("/"))
else:
result = os.path.join(p.netloc, path_unquote)
return result
def random_acii_lines(*, seed: Union[int, str], width: int) -> Generator[str, None, None]: