diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index caffa64a95..c478f15ade 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -22,8 +22,10 @@ from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel -from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, \ - CloudClusterPrintJob, CloudClusterPrintJobConstraint, JobUploadRequest, JobUploadResponse, PrintResponse +from .Models import ( + CloudClusterPrinter, CloudClusterPrintJob, JobUploadRequest, JobUploadResponse, PrintResponse, CloudClusterStatus, + CloudClusterPrinterConfigurationMaterial +) ## The cloud output device is a network output device that works remotely but has limited functionality. @@ -209,58 +211,21 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict): + if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to get cloud cluster data: %s, %s", status_code, response) return Logger.log("d", "Got response form the cloud cluster %s, %s", status_code, response) - printers, print_jobs = self._parseStatusResponse(response) - if not printers and not print_jobs: - return - + status = CloudClusterStatus(**response["data"]) + # Update all data from the cluster. - self._updatePrinters(printers) - self._updatePrintJobs(print_jobs) - - @staticmethod - def _parseStatusResponse(response: dict) -> Tuple[List[CloudClusterPrinter], List[CloudClusterPrintJob]]: - printers = [] - print_jobs = [] - - data = response["data"] - for p in data["printers"]: - printer = CloudClusterPrinter(**p) - configuration = printer.configuration - printer.configuration = [] - for c in configuration: - extruder = CloudClusterPrinterConfiguration(**c) - extruder.material = CloudClusterPrinterConfigurationMaterial(material=extruder.material) - printer.configuration.append(extruder) - - printers.append(printer) - - for j in data["print_jobs"]: - job = CloudClusterPrintJob(**j) - constraints = job.constraints - job.constraints = [] - for c in constraints: - job.constraints.append(CloudClusterPrintJobConstraint(**c)) - - configuration = job.configuration - job.configuration = [] - for c in configuration: - configuration = CloudClusterPrinterConfiguration(**c) - configuration.material = CloudClusterPrinterConfigurationMaterial(material=configuration.material) - job.configuration.append(configuration) - - print_jobs.append(job) - - return printers, print_jobs + self._updatePrinters(status.printers) + self._updatePrintJobs(status.print_jobs) def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - current_printers = {p.key: p for p in self._printers} + remote_printers: Dict[str, CloudClusterPrinter] = {p.uuid: p for p in printers} + current_printers: Dict[str, PrinterOutputModel] = {p.key: p for p in self._printers} removed_printer_ids = set(current_printers).difference(remote_printers) new_printer_ids = set(remote_printers).difference(current_printers) @@ -337,8 +302,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - remote_jobs = {j.uuid: j for j in jobs} - current_jobs = {j.key: j for j in self._print_jobs} + remote_jobs: Dict[str, CloudClusterPrintJob] = {j.uuid: j for j in jobs} + current_jobs: Dict[str, UM3PrintJobOutputModel] = {j.key: j for j in self._print_jobs} removed_job_ids = set(current_jobs).difference(set(remote_jobs)) new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) @@ -368,7 +333,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._print_jobs.append(model) @staticmethod - def _updateUM3PrintJobOutputModel(model: PrinterOutputModel, job: CloudClusterPrintJob) -> None: + def _updateUM3PrintJobOutputModel(model: UM3PrintJobOutputModel, job: CloudClusterPrintJob) -> None: model.updateTimeTotal(job.time_total) model.updateTimeElapsed(job.time_elapsed) model.updateOwner(job.owner) @@ -411,10 +376,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobRequested(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict): + if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", status_code, response) return - print_response = PrintResponse(**response.get("data")) + print_response = PrintResponse(**response["data"]) Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 435f265300..780fa06172 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -8,11 +8,11 @@ from ..Models import BaseModel ## Class representing a cloud connected cluster. class CloudCluster(BaseModel): def __init__(self, **kwargs): - self.cluster_id = None # type: str - self.host_guid = None # type: str - self.host_name = None # type: str - self.host_version = None # type: str - self.status = None # type: str + self.cluster_id: str = None + self.host_guid: str = None + self.host_name: str = None + self.host_version: str = None + self.status: str = None super().__init__(**kwargs) def validate(self): @@ -23,81 +23,102 @@ class CloudCluster(BaseModel): ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfigurationMaterial(BaseModel): def __init__(self, **kwargs): - self.guid = None # type: str - self.brand = None # type: str - self.color = None # type: str - self.material = None # type: str + self.guid: str = None + self.brand: str = None + self.color: str = None + self.material: str = None super().__init__(**kwargs) ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfiguration(BaseModel): def __init__(self, **kwargs): - self.extruder_index = None # type: str - self.material = None # type: CloudClusterPrinterConfigurationMaterial - self.nozzle_diameter = None # type: str - self.print_core_id = None # type: str + self.extruder_index: str = None + self.material: CloudClusterPrinterConfigurationMaterial = None + self.nozzle_diameter: str = None + self.print_core_id: str = None super().__init__(**kwargs) + if isinstance(self.material, dict): + self.material = CloudClusterPrinterConfigurationMaterial(**self.material) + ## Class representing a cluster printer class CloudClusterPrinter(BaseModel): def __init__(self, **kwargs): - self.configuration = None # type: List[CloudClusterPrinterConfiguration] - self.enabled = None # type: str - self.firmware_version = None # type: str - self.friendly_name = None # type: str - self.ip_address = None # type: str - self.machine_variant = None # type: str - self.status = None # type: str - self.unique_name = None # type: str - self.uuid = None # type: str + self.configuration: List[CloudClusterPrinterConfiguration] = [] + self.enabled: str = None + self.firmware_version: str = None + self.friendly_name: str = None + self.ip_address: str = None + self.machine_variant: str = None + self.status: str = None + self.unique_name: str = None + self.uuid: str = None super().__init__(**kwargs) + self.configuration = [CloudClusterPrinterConfiguration(**c) + if isinstance(c, dict) else c for c in self.configuration] + ## Class representing a cloud cluster print job constraint class CloudClusterPrintJobConstraint(BaseModel): def __init__(self, **kwargs): - self.require_printer_name = None # type: str + self.require_printer_name: str = None super().__init__(**kwargs) + ## Class representing a print job class CloudClusterPrintJob(BaseModel): def __init__(self, **kwargs): - self.assigned_to = None # type: str - self.configuration = None # type: str - self.constraints = None # type: str - self.created_at = None # type: str - self.force = None # type: str - self.last_seen = None # type: str - self.machine_variant = None # type: str - self.name = None # type: str - self.network_error_count = None # type: str - self.owner = None # type: str - self.printer_uuid = None # type: str - self.started = None # type: str - self.status = None # type: str - self.time_elapsed = None # type: str - self.time_total = None # type: str - self.uuid = None # type: str + self.assigned_to: str = None + self.configuration: List[CloudClusterPrinterConfiguration] = [] + self.constraints: List[CloudClusterPrintJobConstraint] = [] + self.created_at: str = None + self.force: str = None + self.last_seen: str = None + self.machine_variant: str = None + self.name: str = None + self.network_error_count: int = None + self.owner: str = None + self.printer_uuid: str = None + self.started: str = None + self.status: str = None + self.time_elapsed: str = None + self.time_total: str = None + self.uuid: str = None super().__init__(**kwargs) + self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c + for c in self.configuration] + self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p + for p in self.constraints] + + +class CloudClusterStatus(BaseModel): + def __init__(self, **kwargs): + self.printers: List[CloudClusterPrinter] = [] + self.print_jobs: List[CloudClusterPrintJob] = [] + super().__init__(**kwargs) + + self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] + self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] class JobUploadRequest(BaseModel): def __init__(self, **kwargs): - self.file_size = None # type: int - self.job_name = None # type: str + self.file_size: int = None + self.job_name: str = None super().__init__(**kwargs) class JobUploadResponse(BaseModel): def __init__(self, **kwargs): - self.download_url = None # type: str - self.job_id = None # type: str - self.job_name = None # type: str - self.slicing_details = None # type: str - self.status = None # type: str - self.upload_url = None # type: str + self.download_url: str = None + self.job_id: str = None + self.job_name: str = None + self.slicing_details: str = None + self.status: str = None + self.upload_url: str = None super().__init__(**kwargs)