diff --git a/src/Mod/AddonManager/addonmanager_connection_checker.py b/src/Mod/AddonManager/addonmanager_connection_checker.py index 76cf14a574de..ac3c08aa1439 100644 --- a/src/Mod/AddonManager/addonmanager_connection_checker.py +++ b/src/Mod/AddonManager/addonmanager_connection_checker.py @@ -45,8 +45,7 @@ def __init__(self): # Check the connection in a new thread, so FreeCAD stays responsive self.connection_checker = ConnectionChecker() - self.connection_checker.success.connect(self._check_succeeded) - self.connection_checker.failure.connect(self._network_connection_failed) + self.signals_connected = False self.connection_message_timer = None self.connection_check_message = None @@ -54,6 +53,9 @@ def __init__(self): def start(self): """Start the connection check""" self.connection_checker.start() + self.connection_checker.success.connect(self._check_succeeded) + self.connection_checker.failure.connect(self._network_connection_failed) + self.signals_connected = True # If it takes longer than a half second to check the connection, show a message: self.connection_message_timer = QtCore.QTimer.singleShot( @@ -75,8 +77,7 @@ def _show_connection_check_message(self): def cancel_network_check(self, _): """Cancel the check""" if not self.connection_checker.isFinished(): - self.connection_checker.success.disconnect(self._check_succeeded) - self.connection_checker.failure.disconnect(self._network_connection_failed) + self._disconnect_signals() self.connection_checker.requestInterruption() self.connection_checker.wait(500) self.connection_check_message.close() @@ -99,10 +100,12 @@ def _network_connection_failed(self, message: str) -> None: translate("AddonsInstaller", "Missing dependency"), translate( "AddonsInstaller", - "Could not import QtNetwork -- see Report View for details. Addon Manager unavailable.", + "Could not import QtNetwork -- see Report View for details. Addon Manager " + "unavailable.", ), ) + self._disconnect_signals() self.check_complete.emit() def _check_succeeded(self): @@ -112,4 +115,11 @@ def _check_succeeded(self): self.connection_check_message.close() self.connection_available.emit() + self._disconnect_signals() self.check_complete.emit() + + def _disconnect_signals(self): + if self.signals_connected: + self.connection_checker.success.disconnect(self._check_succeeded) + self.connection_checker.failure.disconnect(self._network_connection_failed) + self.signals_connected = False diff --git a/src/Mod/AddonManager/addonmanager_workers_utility.py b/src/Mod/AddonManager/addonmanager_workers_utility.py index e25912c76f29..c0c72f7066dd 100644 --- a/src/Mod/AddonManager/addonmanager_workers_utility.py +++ b/src/Mod/AddonManager/addonmanager_workers_utility.py @@ -27,7 +27,8 @@ import FreeCAD from PySide import QtCore -import addonmanager_utilities as utils +import NetworkManager +import time translate = FreeCAD.Qt.translate @@ -42,32 +43,49 @@ class ConnectionChecker(QtCore.QThread): def __init__(self): QtCore.QThread.__init__(self) + self.done = False + self.request_id = 0 + self.data = None def run(self): - """Not generally called directly: create a new ConnectionChecker object and - call start() on it to spawn a child thread.""" + """Not generally called directly: create a new ConnectionChecker object and call start() + on it to spawn a child thread.""" FreeCAD.Console.PrintLog("Checking network connection...\n") - result = self.check_network_connection() - if QtCore.QThread.currentThread().isInterruptionRequested(): - FreeCAD.Console.PrintLog("Connection check cancelled\n") - return - if not result: + url = "https://api.github.com/zen" + self.done = False + NetworkManager.AM_NETWORK_MANAGER.completed.connect(self.connection_data_received) + self.request_id = NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get(url) + while not self.done: + if QtCore.QThread.currentThread().isInterruptionRequested(): + FreeCAD.Console.PrintLog("Connection check cancelled\n") + NetworkManager.AM_NETWORK_MANAGER.abort(self.request_id) + self.disconnect_network_manager() + return + QtCore.QCoreApplication.processEvents() + time.sleep(0.1) + if not self.data: self.failure.emit( translate( "AddonsInstaller", - "Unable to read data from GitHub: check your internet connection and proxy settings and try again.", + "Unable to read data from GitHub: check your internet connection and proxy " + "settings and try again.", ) ) + self.disconnect_network_manager() return - FreeCAD.Console.PrintLog(f"GitHub's zen message response: {result}\n") + FreeCAD.Console.PrintLog(f"GitHub's zen message response: {self.data.decode}\n") + self.disconnect_network_manager() self.success.emit() - def check_network_connection(self) -> Optional[str]: - """The main work of this object: returns the decoded result of the connection request, or - None if the request failed""" - url = "https://api.github.com/zen" - result = utils.blocking_get(url) - if result: - return result.decode("utf8") - return None + def connection_data_received(self, id: int, status: int, data: QtCore.QByteArray): + if self.request_id and self.request_id == id: + if status == 200: + self.data = data + else: + FreeCAD.Console.PrintWarning(f"No data received: status returned was {status}\n") + self.data = None + self.done = True + + def disconnect_network_manager(self): + NetworkManager.AM_NETWORK_MANAGER.completed.disconnect(self.connection_data_received)