diff options
Diffstat (limited to 'plugins/Toolbox/src/CloudSync/DownloadPresenter.py')
-rw-r--r-- | plugins/Toolbox/src/CloudSync/DownloadPresenter.py | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/plugins/Toolbox/src/CloudSync/DownloadPresenter.py b/plugins/Toolbox/src/CloudSync/DownloadPresenter.py deleted file mode 100644 index 8a5e763f3c..0000000000 --- a/plugins/Toolbox/src/CloudSync/DownloadPresenter.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (c) 2020 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -import tempfile -from typing import Dict, List, Any - -from PyQt5.QtNetwork import QNetworkReply - -from UM.i18n import i18nCatalog -from UM.Logger import Logger -from UM.Message import Message -from UM.Signal import Signal -from UM.TaskManagement.HttpRequestManager import HttpRequestManager -from cura.CuraApplication import CuraApplication -from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope -from .SubscribedPackagesModel import SubscribedPackagesModel - -i18n_catalog = i18nCatalog("cura") - - -class DownloadPresenter: - """Downloads a set of packages from the Ultimaker Cloud Marketplace - - use download() exactly once: should not be used for multiple sets of downloads since this class contains state - """ - - DISK_WRITE_BUFFER_SIZE = 256 * 1024 # 256 KB - - 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] - self.done = Signal() - - self._app = app - self._scope = UltimakerCloudScope(app) - - self._started = False - self._progress_message = self._createProgressMessage() - self._progress = {} # type: Dict[str, Dict[str, Any]] # package_id, Dict - self._error = [] # type: List[str] # package_id - - def download(self, model: SubscribedPackagesModel) -> None: - if self._started: - Logger.error("Download already started. Create a new %s instead", self.__class__.__name__) - return - - manager = HttpRequestManager.getInstance() - for item in model.items: - package_id = item["package_id"] - - def finishedCallback(reply: QNetworkReply, pid = package_id) -> None: - self._onFinished(pid, reply) - - def progressCallback(rx: int, rt: int, pid = package_id) -> None: - self._onProgress(pid, rx, rt) - - def errorCallback(reply: QNetworkReply, error: QNetworkReply.NetworkError, pid = package_id) -> None: - self._onError(pid) - - request_data = manager.get( - item["download_url"], - callback = finishedCallback, - download_progress_callback = progressCallback, - error_callback = errorCallback, - scope = self._scope) - - self._progress[package_id] = { - "received": 0, - "total": 1, # make sure this is not considered done yet. Also divByZero-safe - "file_written": None, - "request_data": request_data, - "package_model": item - } - - self._started = True - self._progress_message.show() - - 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) -> "DownloadPresenter": - self.abort() - self.done.disconnectAll() - return DownloadPresenter(self._app) - - def _createProgressMessage(self) -> Message: - return Message(i18n_catalog.i18nc("@info:generic", "Syncing..."), - lifetime = 0, - use_inactivity_timer = False, - progress = 0.0, - title = i18n_catalog.i18nc("@info:title", "Changes detected from your Ultimaker account")) - - def _onFinished(self, package_id: str, reply: QNetworkReply) -> None: - self._progress[package_id]["received"] = self._progress[package_id]["total"] - - try: - with tempfile.NamedTemporaryFile(mode = "wb+", suffix = ".curapackage", delete = False) as temp_file: - bytes_read = reply.read(self.DISK_WRITE_BUFFER_SIZE) - while bytes_read: - temp_file.write(bytes_read) - bytes_read = reply.read(self.DISK_WRITE_BUFFER_SIZE) - self._app.processEvents() - self._progress[package_id]["file_written"] = temp_file.name - except IOError as e: - Logger.logException("e", "Failed to write downloaded package to temp file", e) - self._onError(package_id) - temp_file.close() - - self._checkDone() - - def _onProgress(self, package_id: str, rx: int, rt: int) -> None: - self._progress[package_id]["received"] = rx - self._progress[package_id]["total"] = rt - - received = 0 - total = 0 - for item in self._progress.values(): - received += item["received"] - total += item["total"] - - if total == 0: # Total download size is 0, or unknown, or there are no progress items at all. - self._progress_message.setProgress(100.0) - return - - self._progress_message.setProgress(100.0 * (received / total)) # [0 .. 100] % - - def _onError(self, package_id: str) -> None: - self._progress.pop(package_id) - self._error.append(package_id) - self._checkDone() - - def _checkDone(self) -> bool: - for item in self._progress.values(): - if not item["file_written"]: - return False - - success_items = { - package_id: - { - "package_path": value["file_written"], - "icon_url": value["package_model"]["icon_url"] - } - for package_id, value in self._progress.items() - } - error_items = [package_id for package_id in self._error] - - self._progress_message.hide() - self.done.emit(success_items, error_items) - return True |