From 5b963de2ea64058e5a1ff04b24ef27a1e56e1873 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 13:19:45 +0100 Subject: [PATCH] STAR-322: Checking if response changed before updating cluster --- .../src/Cloud/CloudOutputDevice.py | 21 ++++++++++++------- .../src/Cloud/Models/BaseCloudModel.py | 17 +++++++++++++++ .../src/Cloud/Models/CloudCluster.py | 4 ++-- .../src/Cloud/Models/CloudClusterPrintJob.py | 4 ++-- .../Models/CloudClusterPrintJobConstraint.py | 4 ++-- .../src/Cloud/Models/CloudClusterPrinter.py | 4 ++-- .../CloudClusterPrinterConfiguration.py | 4 ++-- ...loudClusterPrinterConfigurationMaterial.py | 4 ++-- .../src/Cloud/Models/CloudClusterStatus.py | 10 +++++++-- .../src/Cloud/Models/CloudErrorObject.py | 4 ++-- .../src/Cloud/Models/CloudJobResponse.py | 4 ++-- .../src/Cloud/Models/CloudJobUploadRequest.py | 4 ++-- .../src/Cloud/Models/CloudPrintResponse.py | 4 ++-- 13 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 108fb0040c..321c40bc74 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os +from datetime import datetime from time import time from typing import Dict, List, Optional @@ -116,6 +117,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: handle progress messages in another class. self._progress_message = None # type: Optional[Message] + # Keep server string of the last generated time to avoid updating models more than once for the same response + self._received_printers = None # type: Optional[List[CloudClusterPrinter]] + self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJob]] + ## Gets the host name of this device @property def host_name(self) -> str: @@ -188,8 +193,13 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: # Update all data from the cluster. - self._updatePrinters(status.printers) - self._updatePrintJobs(status.print_jobs) + if self._received_printers != status.printers: + self._received_printers = status.printers + self._updatePrinters(status.printers) + + if status.print_jobs != self._received_print_jobs: + self._received_print_jobs = status.print_jobs + self._updatePrintJobs(status.print_jobs) ## Updates the local list of printers with the list received from the cloud. # \param jobs: The printers received from the cloud. @@ -214,7 +224,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if not self._active_printer: self.setActivePrinter(self._printers[0]) - self.printersChanged.emit() + self.printersChanged.emit() # TODO: Make this more efficient by not updating every request ## Updates the local list of print jobs with the list received from the cloud. # \param jobs: The print jobs received from the cloud. @@ -224,11 +234,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) - # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. - # TODO: we need to fix this here somehow by updating the correct output models. - # TODO: the configuration drop down in the slice window is not populated because we are missing some data. - # TODO: to fix this we need to implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel - for removed_job in removed_jobs: self._print_jobs.remove(removed_job) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py new file mode 100644 index 0000000000..1176c4374a --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py @@ -0,0 +1,17 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from datetime import datetime, timezone + +from ...Models import BaseModel + + +class BaseCloudModel(BaseModel): + def __eq__(self, other): + return type(self) == type(other) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return type(self) != type(other) or self.__dict__ != other.__dict__ + + @staticmethod + def parseDate(date_str: str) -> datetime: + return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py index 28e95a097a..e6e2af1466 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud connected cluster. -class CloudCluster(BaseModel): +class CloudCluster(BaseCloudModel): def __init__(self, **kwargs): self.cluster_id = None # type: str self.host_guid = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index 22c66ddfab..15d256e7d5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -6,14 +6,14 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a print job from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel -class CloudClusterPrintJob(BaseModel): +class CloudClusterPrintJob(BaseCloudModel): def __init__(self, **kwargs) -> None: self.assigned_to = None # type: str self.configuration = [] # type: List[CloudClusterPrinterConfiguration] diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py index 884ff8f0c2..f13e3098fc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster print job constraint -class CloudClusterPrintJobConstraint(BaseModel): +class CloudClusterPrintJobConstraint(BaseCloudModel): def __init__(self, **kwargs) -> None: self.require_printer_name = None # type: str super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py index 78aa8e3a31..9057743621 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py @@ -6,11 +6,11 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cluster printer -class CloudClusterPrinter(BaseModel): +class CloudClusterPrinter(BaseCloudModel): def __init__(self, **kwargs) -> None: self.configuration = [] # type: List[CloudClusterPrinterConfiguration] self.enabled = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index d60395f6ab..aa382136d0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -6,11 +6,11 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfiguration(BaseModel): +class CloudClusterPrinterConfiguration(BaseCloudModel): def __init__(self, **kwargs) -> None: self.extruder_index = None # type: int self.material = None # type: CloudClusterPrinterConfigurationMaterial diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py index 8023784925..e5f52ac630 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py @@ -1,11 +1,11 @@ from UM.Logger import Logger from cura.CuraApplication import CuraApplication from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfigurationMaterial(BaseModel): +class CloudClusterPrinterConfigurationMaterial(BaseCloudModel): def __init__(self, **kwargs) -> None: self.guid = None # type: str self.brand = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py index a44b665973..77ed979dbc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py @@ -1,15 +1,17 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from datetime import datetime from typing import List from .CloudClusterPrinter import CloudClusterPrinter from .CloudClusterPrintJob import CloudClusterPrintJob -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the status of the cluster for the cloud -class CloudClusterStatus(BaseModel): +class CloudClusterStatus(BaseCloudModel): def __init__(self, **kwargs) -> None: + self.generated_time = None # type: datetime # a list of the printers self.printers = [] # type: List[CloudClusterPrinter] # a list of the print jobs @@ -20,3 +22,7 @@ class CloudClusterStatus(BaseModel): # converting any dictionaries into models 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] + + # converting generated time into datetime + if isinstance(self.generated_time, str): + self.generated_time = self.parseDate(self.generated_time) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py index 813ef957e4..9696cbcb7a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py @@ -2,11 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Dict -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing errors generated by the cloud servers, according to the json-api standard. -class CloudErrorObject(BaseModel): +class CloudErrorObject(BaseCloudModel): def __init__(self, **kwargs) -> None: self.id = None # type: str self.code = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py index 0b611dd2d3..e3161449a5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the response received from the cloud after requesting to upload a print job -class CloudJobResponse(BaseModel): +class CloudJobResponse(BaseCloudModel): def __init__(self, **kwargs) -> None: self.download_url = None # type: str self.job_id = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py index 3e038b343e..07a781e2d6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the request to upload a print job to the cloud -class CloudJobUploadRequest(BaseModel): +class CloudJobUploadRequest(BaseCloudModel): def __init__(self, **kwargs) -> None: self.file_size = None # type: int self.job_name = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py index ff05ad5b19..3e9ad584dc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the responses received from the cloud after requesting a job to be printed. -class CloudPrintResponse(BaseModel): +class CloudPrintResponse(BaseCloudModel): def __init__(self, **kwargs) -> None: self.cluster_job_id = None # type: str self.job_id = None # type: str