diff --git a/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py b/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py index b062979271..c1ca9cbddf 100644 --- a/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py +++ b/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py @@ -15,7 +15,6 @@ from plugins.Toolbox.src.CloudSync.SubscribedPackagesModel import SubscribedPack class CloudPackageChecker(QObject): - def __init__(self, application: CuraApplication) -> None: super().__init__() @@ -37,7 +36,7 @@ class CloudPackageChecker(QObject): # check again whenever the login state changes self._application.getCuraAPI().account.loginStateChanged.connect(self._fetchUserSubscribedPackages) - def _fetchUserSubscribedPackages(self): + def _fetchUserSubscribedPackages(self) -> None: if self._application.getCuraAPI().account.isLoggedIn: self._getUserPackages() @@ -57,7 +56,7 @@ class CloudPackageChecker(QObject): if package_discrepancy: self._handlePackageDiscrepancies() - def _handlePackageDiscrepancies(self): + def _handlePackageDiscrepancies(self) -> None: Logger.log("d", "Discrepancy found between Cloud subscribed packages and Cura installed packages") sync_message = Message(self._i18n_catalog.i18nc( "@info:generic", diff --git a/plugins/Toolbox/src/CloudSync/CloudPackageManager.py b/plugins/Toolbox/src/CloudSync/CloudPackageManager.py index a724aa316d..bf3ed02de3 100644 --- a/plugins/Toolbox/src/CloudSync/CloudPackageManager.py +++ b/plugins/Toolbox/src/CloudSync/CloudPackageManager.py @@ -6,12 +6,11 @@ from plugins.Toolbox.src.UltimakerCloudScope import UltimakerCloudScope ## Manages Cloud subscriptions. When a package is added to a user's account, the user is 'subscribed' to that package # Whenever the user logs in on another instance of Cura, these subscriptions can be used to sync the user's plugins class CloudPackageManager: - - def __init__(self, app: CuraApplication): + def __init__(self, app: CuraApplication) -> None: self._request_manager = app.getHttpRequestManager() self._scope = UltimakerCloudScope(app) - def subscribe(self, package_id: str): + def subscribe(self, package_id: str) -> None: data = "{\"data\": {\"package_id\": \"%s\", \"sdk_version\": \"%s\"}}" % (package_id, CloudApiModel.sdk_version) self._request_manager.put(url=CloudApiModel.api_url_user_packages, data=data.encode(), diff --git a/plugins/Toolbox/src/CloudSync/DiscrepanciesPresenter.py b/plugins/Toolbox/src/CloudSync/DiscrepanciesPresenter.py index 55df42879c..4e202fb7b1 100644 --- a/plugins/Toolbox/src/CloudSync/DiscrepanciesPresenter.py +++ b/plugins/Toolbox/src/CloudSync/DiscrepanciesPresenter.py @@ -12,7 +12,7 @@ from plugins.Toolbox.src.CloudSync.SubscribedPackagesModel import SubscribedPack # choices are emitted on the `packageMutations` Signal. class DiscrepanciesPresenter(QObject): - def __init__(self, app: QtApplication): + def __init__(self, app: QtApplication) -> None: super().__init__(app) self.packageMutations = Signal() # Emits SubscribedPackagesModel @@ -22,18 +22,18 @@ class DiscrepanciesPresenter(QObject): self._dialog = None # type: Optional[QObject] self._compatibility_dialog_path = "resources/qml/dialogs/CompatibilityDialog.qml" - def present(self, plugin_path: str, model: SubscribedPackagesModel): + def present(self, plugin_path: str, model: SubscribedPackagesModel) -> None: path = os.path.join(plugin_path, self._compatibility_dialog_path) self._dialog = self._app.createQmlComponent(path, {"subscribedPackagesModel": model, "handler": self}) assert self._dialog self._dialog.accepted.connect(lambda: self._onConfirmClicked(model)) @pyqtSlot("QVariant", str) - def dismissIncompatiblePackage(self, model: SubscribedPackagesModel, package_id: str): + def dismissIncompatiblePackage(self, model: SubscribedPackagesModel, package_id: str) -> None: model.dismissPackage(package_id) # update the model to update the view self._package_manager.dismissPackage(package_id) # adds this package_id as dismissed in the user config file - def _onConfirmClicked(self, model: SubscribedPackagesModel): + def _onConfirmClicked(self, model: SubscribedPackagesModel) -> None: # For now, all compatible packages presented to the user should be installed. # Later, we might remove items for which the user unselected the package model.setItems(model.getCompatiblePackages()) diff --git a/plugins/Toolbox/src/CloudSync/DownloadPresenter.py b/plugins/Toolbox/src/CloudSync/DownloadPresenter.py index 756a42b7ef..2d785549ee 100644 --- a/plugins/Toolbox/src/CloudSync/DownloadPresenter.py +++ b/plugins/Toolbox/src/CloudSync/DownloadPresenter.py @@ -21,7 +21,7 @@ class DownloadPresenter: DISK_WRITE_BUFFER_SIZE = 256 * 1024 # 256 KB - def __init__(self, app: CuraApplication): + def __init__(self, app: CuraApplication) -> None: # Emits (Dict[str, str], List[str]) # (success_items, error_items) # Dict{success_package_id, temp_file_path} # List[errored_package_id] @@ -35,7 +35,7 @@ class DownloadPresenter: self._progress = {} # type: Dict[str, Dict[str, Any]] # package_id, Dict self._error = [] # type: List[str] # package_id - def download(self, model: SubscribedPackagesModel): + def download(self, model: SubscribedPackagesModel) -> None: if self._started: Logger.error("Download already started. Create a new %s instead", self.__class__.__name__) return @@ -70,13 +70,13 @@ class DownloadPresenter: self._started = True self._progress_message.show() - def abort(self): + def abort(self) -> None: manager = HttpRequestManager.getInstance() for item in self._progress.values(): manager.abortRequest(item["request_data"]) # Aborts all current operations and returns a copy with the same settings such as app and scope - def resetCopy(self): + def resetCopy(self) -> "DownloadPresenter": self.abort() self.done.disconnectAll() return DownloadPresenter(self._app) @@ -90,7 +90,7 @@ class DownloadPresenter: progress = 0.0, title = i18n_catalog.i18nc("@info:title", "Changes detected from your Ultimaker account", )) - def _onFinished(self, package_id: str, reply: QNetworkReply): + def _onFinished(self, package_id: str, reply: QNetworkReply) -> None: self._progress[package_id]["received"] = self._progress[package_id]["total"] try: @@ -108,7 +108,7 @@ class DownloadPresenter: self._checkDone() - def _onProgress(self, package_id: str, rx: int, rt: int): + def _onProgress(self, package_id: str, rx: int, rt: int) -> None: self._progress[package_id]["received"] = rx self._progress[package_id]["total"] = rt diff --git a/plugins/Toolbox/src/CloudSync/LicenseModel.py b/plugins/Toolbox/src/CloudSync/LicenseModel.py index 1328383d76..c3b5ee5d31 100644 --- a/plugins/Toolbox/src/CloudSync/LicenseModel.py +++ b/plugins/Toolbox/src/CloudSync/LicenseModel.py @@ -3,13 +3,14 @@ from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") + # Model for the ToolboxLicenseDialog class LicenseModel(QObject): dialogTitleChanged = pyqtSignal() headerChanged = pyqtSignal() licenseTextChanged = pyqtSignal() - def __init__(self): + def __init__(self) -> None: super().__init__() self._current_page_idx = 0 @@ -44,7 +45,7 @@ class LicenseModel(QObject): self._current_page_idx = idx self._updateDialogTitle() - def setPageCount(self, count: int): + def setPageCount(self, count: int) -> None: self._page_count = count self._updateDialogTitle() diff --git a/plugins/Toolbox/src/CloudSync/LicensePresenter.py b/plugins/Toolbox/src/CloudSync/LicensePresenter.py index f05feecabd..bafa57cae3 100644 --- a/plugins/Toolbox/src/CloudSync/LicensePresenter.py +++ b/plugins/Toolbox/src/CloudSync/LicensePresenter.py @@ -15,7 +15,7 @@ from plugins.Toolbox.src.CloudSync.LicenseModel import LicenseModel # licenseAnswers emits a list of Dicts containing answers when the user has made a choice for all provided packages class LicensePresenter(QObject): - def __init__(self, app: CuraApplication): + def __init__(self, app: CuraApplication) -> None: super().__init__() self._dialog = None # type: Optional[QObject] self._package_manager = app.getPackageManager() # type: PackageManager @@ -34,7 +34,7 @@ class LicensePresenter(QObject): ## Show a license dialog for multiple packages where users can read a license and accept or decline them # \param plugin_path: Root directory of the Toolbox plugin # \param packages: Dict[package id, file path] - def present(self, plugin_path: str, packages: Dict[str, str]): + def present(self, plugin_path: str, packages: Dict[str, str]) -> None: path = os.path.join(plugin_path, self._compatibility_dialog_path) self._initState(packages) @@ -51,16 +51,16 @@ class LicensePresenter(QObject): self._present_current_package() @pyqtSlot() - def onLicenseAccepted(self): + def onLicenseAccepted(self) -> None: self._package_models[self._current_package_idx]["accepted"] = True self._check_next_page() @pyqtSlot() - def onLicenseDeclined(self): + def onLicenseDeclined(self) -> None: self._package_models[self._current_package_idx]["accepted"] = False self._check_next_page() - def _initState(self, packages: Dict[str, str]): + def _initState(self, packages: Dict[str, str]) -> None: self._package_models = [ { "package_id" : package_id, @@ -70,26 +70,27 @@ class LicensePresenter(QObject): for package_id, package_path in packages.items() ] - def _present_current_package(self): + def _present_current_package(self) -> None: package_model = self._package_models[self._current_package_idx] license_content = self._package_manager.getPackageLicense(package_model["package_path"]) if license_content is None: - # implicitly accept when there is no license + # Implicitly accept when there is no license self.onLicenseAccepted() return self._license_model.setCurrentPageIdx(self._current_package_idx) self._license_model.setPackageName(package_model["package_id"]) self._license_model.setLicenseText(license_content) + if self._dialog: + self._dialog.open() # Does nothing if already open - self._dialog.open() # does nothing if already open - - def _check_next_page(self): + def _check_next_page(self) -> None: if self._current_package_idx + 1 < len(self._package_models): self._current_package_idx += 1 self._present_current_package() else: - self._dialog.close() + if self._dialog: + self._dialog.close() self.licenseAnswers.emit(self._package_models) diff --git a/plugins/Toolbox/src/CloudSync/RestartApplicationPresenter.py b/plugins/Toolbox/src/CloudSync/RestartApplicationPresenter.py index 6f1c76d0cf..96aa9fea7b 100644 --- a/plugins/Toolbox/src/CloudSync/RestartApplicationPresenter.py +++ b/plugins/Toolbox/src/CloudSync/RestartApplicationPresenter.py @@ -18,17 +18,11 @@ from plugins.Toolbox.src.CloudSync.SubscribedPackagesModel import SubscribedPack ## Presents a dialog telling the user that a restart is required to apply changes # Since we cannot restart Cura, the app is closed instead when the button is clicked class RestartApplicationPresenter: - - def __init__(self, app: CuraApplication): - # Emits (Dict[str, str], List[str]) # (success_items, error_items) - # Dict{success_package_id, temp_file_path} - # List[errored_package_id] - self.done = Signal() - + def __init__(self, app: CuraApplication) -> None: self._app = app self._i18n_catalog = i18nCatalog("cura") - def present(self): + def present(self) -> None: app_name = self._app.getApplicationDisplayName() message = Message(self._i18n_catalog.i18nc( diff --git a/plugins/Toolbox/src/CloudSync/SyncOrchestrator.py b/plugins/Toolbox/src/CloudSync/SyncOrchestrator.py index 2420189d70..2dd1e999ac 100644 --- a/plugins/Toolbox/src/CloudSync/SyncOrchestrator.py +++ b/plugins/Toolbox/src/CloudSync/SyncOrchestrator.py @@ -30,7 +30,7 @@ from plugins.Toolbox.src.CloudSync.SubscribedPackagesModel import SubscribedPack # - The RestartApplicationPresenter notifies the user that a restart is required for changes to take effect class SyncOrchestrator(Extension): - def __init__(self, app: CuraApplication): + def __init__(self, app: CuraApplication) -> None: super().__init__() # Differentiate This PluginObject from the Toolbox. self.getId() includes _name. # getPluginId() will return the same value for The toolbox extension and this one @@ -52,11 +52,11 @@ class SyncOrchestrator(Extension): self._restart_presenter = RestartApplicationPresenter(app) - def _onDiscrepancies(self, model: SubscribedPackagesModel): + def _onDiscrepancies(self, model: SubscribedPackagesModel) -> None: plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) self._discrepancies_presenter.present(plugin_path, model) - def _onPackageMutations(self, mutations: SubscribedPackagesModel): + def _onPackageMutations(self, mutations: SubscribedPackagesModel) -> None: self._download_presenter = self._download_presenter.resetCopy() self._download_presenter.done.connect(self._onDownloadFinished) self._download_presenter.download(mutations) @@ -64,13 +64,13 @@ class SyncOrchestrator(Extension): ## Called when a set of packages have finished downloading # \param success_items: Dict[package_id, file_path] # \param error_items: List[package_id] - def _onDownloadFinished(self, success_items: Dict[str, str], error_items: List[str]): + def _onDownloadFinished(self, success_items: Dict[str, str], error_items: List[str]) -> None: # todo handle error items plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) self._license_presenter.present(plugin_path, success_items) # Called when user has accepted / declined all licenses for the downloaded packages - def _onLicenseAnswers(self, answers: List[Dict[str, Any]]): + def _onLicenseAnswers(self, answers: List[Dict[str, Any]]) -> None: Logger.debug("Got license answers: {}", answers) has_changes = False # True when at least one package is installed @@ -91,9 +91,3 @@ class SyncOrchestrator(Extension): if has_changes: self._restart_presenter.present() - - - - - -