Addon Manager: Create NetworkManager class

To enable single-login authenticated proxy use, and simplified multi-threaded
network accesses, this commit adds a new wrapper around a QNetworkAccessManager
and includes a global instantiation of the class intended to exist for the
lifetime of the program. This instance can be used to enqueue any number of
network requests, which the manager will send out to the networking subsystem
in an appropriate manner.
This commit is contained in:
Chris Hennes
2022-01-14 11:52:31 -06:00
parent cad0d01883
commit e9d6a2c4a4
8 changed files with 1055 additions and 660 deletions

View File

@@ -25,7 +25,7 @@ import os
import re
import ctypes
import ssl
from typing import Union
from typing import Union, Optional
import urllib
from urllib.request import Request
@@ -53,7 +53,6 @@ else:
except AttributeError:
pass
# @package AddonManager_utilities
# \ingroup ADDONMANAGER
# \brief Utilities to work across different platforms, providers and python versions
@@ -72,7 +71,7 @@ def translate(context, text, disambig=None):
def symlink(source, link_name):
"creates a symlink of a file, if possible"
"""Creates a symlink of a file, if possible. Note that it fails on most modern Windows installations"""
if os.path.exists(link_name) or os.path.lexists(link_name):
pass
@@ -81,6 +80,8 @@ def symlink(source, link_name):
if callable(os_symlink):
os_symlink(source, link_name)
else:
# NOTE: This does not work on most normal Windows 10 and later installations, unless developer
# mode is turned on. Make sure to catch any exception thrown and have a fallback plan.
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
@@ -92,47 +93,6 @@ def symlink(source, link_name):
raise ctypes.WinError()
def urlopen(url: str) -> Union[None, HTTPResponse]:
"""Opens an url with urllib and streams it to a temp file"""
timeout = 5
# Proxy an ssl configuration
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons")
if pref.GetBool("NoProxyCheck", True):
proxies = {}
else:
if pref.GetBool("SystemProxyCheck", False):
proxy = urllib.request.getproxies()
proxies = {"http": proxy.get("http"), "https": proxy.get("http")}
elif pref.GetBool("UserProxyCheck", False):
proxy = pref.GetString("ProxyUrl", "")
proxies = {"http": proxy, "https": proxy}
if ssl_ctx:
handler = urllib.request.HTTPSHandler(context=ssl_ctx)
else:
handler = {}
proxy_support = urllib.request.ProxyHandler(proxies)
opener = urllib.request.build_opener(proxy_support, handler)
urllib.request.install_opener(opener)
# Url opening
req = urllib.request.Request(
url, headers={"User-Agent": "Mozilla/5.0 Magic Browser"}
)
try:
u = urllib.request.urlopen(req, timeout=timeout)
except URLError as e:
FreeCAD.Console.PrintLog(f"Error loading {url}:\n {e.reason}\n")
return None
except Exception:
return None
else:
return u
def getserver(url):
"""returns the server part of an url"""
@@ -207,6 +167,19 @@ def get_zip_url(repo):
return None
def recognized_git_location(repo) -> bool:
parsed_url = urlparse(repo.url)
if (
parsed_url.netloc == "github.com"
or parsed_url.netloc == "framagit.com"
or parsed_url.netloc == "gitlab.com"
or parsed_url.netloc == "salsa.debian.org"
):
return True
else:
return False
def construct_git_url(repo, filename):
"Returns a direct download link to a file in an online Git repo: works with github, gitlab, and framagit"