123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- # Copyright (c) 2018 Ultimaker B.V.
- # Cura is released under the terms of the LGPLv3 or higher.
- from typing import Any, Optional, List, Dict, Callable
- from PyQt6.QtNetwork import QNetworkReply
- from UM.Logger import Logger
- from UM.Signal import Signal, signalemitter
- from UM.TaskManagement.HttpRequestManager import HttpRequestManager
- from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
- from UM.i18n import i18nCatalog
- from cura.CuraApplication import CuraApplication
- from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
- from .CreateBackupJob import CreateBackupJob
- from .RestoreBackupJob import RestoreBackupJob
- from .Settings import Settings
- catalog = i18nCatalog("cura")
- @signalemitter
- class DriveApiService:
- """The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling."""
- BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL)
- restoringStateChanged = Signal()
- """Emits signal when restoring backup started or finished."""
- creatingStateChanged = Signal()
- """Emits signal when creating backup started or finished."""
- def __init__(self) -> None:
- self._cura_api = CuraApplication.getInstance().getCuraAPI()
- self._json_cloud_scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
- def getBackups(self, changed: Callable[[List[Dict[str, Any]]], None]) -> None:
- def callback(reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
- if error is not None:
- Logger.log("w", "Could not get backups: " + str(error))
- changed([])
- return
- backup_list_response = HttpRequestManager.readJSON(reply)
- if backup_list_response is None:
- Logger.error("List of back-ups can't be parsed.")
- changed([])
- return
- if "data" not in backup_list_response:
- Logger.log("w", "Could not get backups from remote, actual response body was: %s",
- str(backup_list_response))
- changed([]) # empty list of backups
- return
- changed(backup_list_response["data"])
- HttpRequestManager.getInstance().get(
- self.BACKUP_URL,
- callback= callback,
- error_callback = callback,
- scope=self._json_cloud_scope
- )
- def createBackup(self) -> None:
- self.creatingStateChanged.emit(is_creating = True)
- upload_backup_job = CreateBackupJob(self.BACKUP_URL)
- upload_backup_job.finished.connect(self._onUploadFinished)
- upload_backup_job.start()
- def _onUploadFinished(self, job: "CreateBackupJob") -> None:
- if job.backup_upload_error_message != "":
- # If the job contains an error message we pass it along so the UI can display it.
- self.creatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message)
- else:
- self.creatingStateChanged.emit(is_creating = False)
- def restoreBackup(self, backup: Dict[str, Any]) -> None:
- self.restoringStateChanged.emit(is_restoring = True)
- download_url = backup.get("download_url")
- if not download_url:
- # If there is no download URL, we can't restore the backup.
- Logger.warning("backup download_url is missing. Aborting backup.")
- self.restoringStateChanged.emit(is_restoring = False,
- error_message = catalog.i18nc("@info:backup_status",
- "There was an error trying to restore your backup."))
- return
- restore_backup_job = RestoreBackupJob(backup)
- restore_backup_job.finished.connect(self._onRestoreFinished)
- restore_backup_job.start()
- def _onRestoreFinished(self, job: "RestoreBackupJob") -> None:
- if job.restore_backup_error_message != "":
- # If the job contains an error message we pass it along so the UI can display it.
- self.restoringStateChanged.emit(is_restoring = False)
- else:
- self.restoringStateChanged.emit(is_restoring = False, error_message = job.restore_backup_error_message)
- def deleteBackup(self, backup_id: str, finished_callable: Callable[[bool], None]):
- def finishedCallback(reply: QNetworkReply, ca: Callable[[bool], None] = finished_callable) -> None:
- self._onDeleteRequestCompleted(reply, ca)
- def errorCallback(reply: QNetworkReply, error: QNetworkReply.NetworkError, ca: Callable[[bool], None] = finished_callable) -> None:
- self._onDeleteRequestCompleted(reply, ca, error)
- HttpRequestManager.getInstance().delete(
- url = "{}/{}".format(self.BACKUP_URL, backup_id),
- callback = finishedCallback,
- error_callback = errorCallback,
- scope= self._json_cloud_scope
- )
- @staticmethod
- def _onDeleteRequestCompleted(reply: QNetworkReply, callable: Callable[[bool], None], error: Optional["QNetworkReply.NetworkError"] = None) -> None:
- callable(HttpRequestManager.replyIndicatesSuccess(reply, error))
|