From a232e12cc3cb12f2f2b37cd71eda19b3b3c3cd01 Mon Sep 17 00:00:00 2001 From: Jeff Rogers Date: Sat, 16 May 2020 14:37:57 -0700 Subject: [PATCH 1/8] Fix extruder and feed rate after extruder-only moves in post stretch script (issue 7755) --- plugins/PostProcessingPlugin/scripts/Stretch.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/PostProcessingPlugin/scripts/Stretch.py b/plugins/PostProcessingPlugin/scripts/Stretch.py index 480ba60606..e56a9f48b1 100644 --- a/plugins/PostProcessingPlugin/scripts/Stretch.py +++ b/plugins/PostProcessingPlugin/scripts/Stretch.py @@ -289,6 +289,13 @@ class Stretcher: self.layergcode = self.layergcode + sout + "\n" ipos = ipos + 1 else: + # The command is intended to be passed through unmodified via + # the comment field. In the case of an extruder only move, though, + # the extruder and potentially the feed rate are modified. + # We need to update self.outpos accordingly so that subsequent calls + # to stepToGcode() knows about the extruder and feed rate change. + self.outpos.step_e = layer_steps[i].step_e + self.outpos.step_f = layer_steps[i].step_f self.layergcode = self.layergcode + layer_steps[i].comment + "\n" def workOnSequence(self, orig_seq, modif_seq): From ba705176fe704323977e211d081513a8d24e4e5c Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Tue, 2 Jun 2020 14:13:04 +0200 Subject: [PATCH 2/8] Remove extraneous logging --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c562f7988e..f9d53b6b65 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -88,8 +88,6 @@ class CloudOutputDeviceManager: if self._syncing: return - Logger.info("Syncing cloud printer clusters") - self._syncing = True self._account.setSyncState(self.SYNC_SERVICE_NAME, SyncState.SYNCING) self._api.getClusters(self._onGetRemoteClustersFinished, self._onGetRemoteClusterFailed) From 80a5b53aadf8ef42fcd6911067d51a66c7f1b975 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Wed, 3 Jun 2020 13:59:51 +0200 Subject: [PATCH 3/8] Store the printer cluster size as a metadata entry on the machine This makes the cluster size also available when the machine is offline. Also fixes an issue where the cluster size is improperly restored once the internet connection comes back online, resulting in the printer showing as a single printer until next sync CURA-7347 --- cura/Settings/MachineManager.py | 6 +++++- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- .../src/Cloud/CloudOutputDeviceManager.py | 1 + .../src/Models/Http/CloudClusterResponse.py | 4 +++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e5286e7032..cbb986010e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -488,7 +488,11 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineIsGroup(self) -> bool: - return bool(self._printer_output_devices) and len(self._printer_output_devices[0].printers) > 1 + if self.activeMachine is None: + return False + + group_size = int(self.activeMachine.getMetaDataEntry("group_size", "-1")) + return group_size > 1 @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasNetworkConnection(self) -> bool: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index b8c5a30524..4abab245e8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -74,7 +74,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): b"name": cluster.friendly_name.encode() if cluster.friendly_name else b"", b"firmware_version": cluster.host_version.encode() if cluster.host_version else b"", b"printer_type": cluster.printer_type.encode() if cluster.printer_type else b"", - b"cluster_size": b"1" # cloud devices are always clusters of at least one + b"cluster_size": str(cluster.printer_count).encode() if cluster.printer_count else b"1" } super().__init__( diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f9d53b6b65..6f2c68e5fb 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -265,6 +265,7 @@ class CloudOutputDeviceManager: machine.setName(device.name) machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) machine.setMetaDataEntry("group_name", device.name) + machine.setMetaDataEntry("group_size", device.clusterSize) machine.setMetaDataEntry("removal_warning", self.I18N_CATALOG.i18nc( "@label ({} is printer name)", "{} will be removed until the next account sync.
To remove {} permanently, " diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py index 94f20b65c6..a9107db3c8 100644 --- a/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py +++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py @@ -11,7 +11,7 @@ class CloudClusterResponse(BaseModel): def __init__(self, cluster_id: str, host_guid: str, host_name: str, is_online: bool, status: str, host_internal_ip: Optional[str] = None, host_version: Optional[str] = None, - friendly_name: Optional[str] = None, printer_type: str = "ultimaker3", **kwargs) -> None: + friendly_name: Optional[str] = None, printer_type: str = "ultimaker3", printer_count: int = 1, **kwargs) -> None: """Creates a new cluster response object. :param cluster_id: The secret unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='. @@ -23,6 +23,7 @@ class CloudClusterResponse(BaseModel): :param host_internal_ip: The internal IP address of the host printer. :param friendly_name: The human readable name of the host printer. :param printer_type: The machine type of the host printer. + :param printer_count: The amount of printers in the print cluster. 1 for a single printer """ self.cluster_id = cluster_id @@ -34,6 +35,7 @@ class CloudClusterResponse(BaseModel): self.host_internal_ip = host_internal_ip self.friendly_name = friendly_name self.printer_type = printer_type + self.printer_count = printer_count super().__init__(**kwargs) # Validates the model, raising an exception if the model is invalid. From f66e723866bad093c789f2061d1b4f75049c382b Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Tue, 9 Jun 2020 15:12:26 +0200 Subject: [PATCH 4/8] Fix Authorization server not properly stopping after flow completes. CURA-7490 --- cura/OAuth2/AuthorizationRequestServer.py | 3 ++- cura/OAuth2/LocalAuthorizationServer.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/OAuth2/AuthorizationRequestServer.py b/cura/OAuth2/AuthorizationRequestServer.py index 74b0b5f012..4ed3975638 100644 --- a/cura/OAuth2/AuthorizationRequestServer.py +++ b/cura/OAuth2/AuthorizationRequestServer.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from http.server import HTTPServer +from socketserver import ThreadingMixIn from typing import Callable, Any, TYPE_CHECKING if TYPE_CHECKING: @@ -9,7 +10,7 @@ if TYPE_CHECKING: from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers -class AuthorizationRequestServer(HTTPServer): +class AuthorizationRequestServer(ThreadingMixIn, HTTPServer): """The authorization request callback handler server. This subclass is needed to be able to pass some data to the request handler. This cannot be done on the request diff --git a/cura/OAuth2/LocalAuthorizationServer.py b/cura/OAuth2/LocalAuthorizationServer.py index a41de2d406..0e017c5318 100644 --- a/cura/OAuth2/LocalAuthorizationServer.py +++ b/cura/OAuth2/LocalAuthorizationServer.py @@ -81,6 +81,7 @@ class LocalAuthorizationServer: if self._web_server: try: + self._web_server.shutdown() self._web_server.server_close() except OSError: # OS error can happen if the socket was already closed. We really don't care about that case. From 8c6a7d30987d3effacbb3c8d3adc11352fadaa6c Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Tue, 9 Jun 2020 15:56:13 +0200 Subject: [PATCH 5/8] Remove definitionChanges before removing a printer When removing a printer, the files in %appdata%/cura// /definition_changes/ remained intact. This commit fixes that by making sure that the definitionChanges are removed before removing the machine. --- cura/Settings/ExtruderManager.py | 1 + cura/Settings/MachineManager.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 2dc01425fc..2cc9ec4631 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -302,6 +302,7 @@ class ExtruderManager(QObject): for extruder in self.getMachineExtruders(machine_id): ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId()) + ContainerRegistry.getInstance().removeContainer(extruder.definitionChanges.getId()) ContainerRegistry.getInstance().removeContainer(extruder.getId()) if machine_id in self._extruder_trains: del self._extruder_trains[machine_id] diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e5286e7032..f98030a7b1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -720,6 +720,8 @@ class MachineManager(QObject): containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id) for container in containers: CuraContainerRegistry.getInstance().removeContainer(container["id"]) + machine_stack = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", name = machine_id)[0] + CuraContainerRegistry.getInstance().removeContainer(machine_stack.definitionChanges.getId()) CuraContainerRegistry.getInstance().removeContainer(machine_id) # If the printer that is being removed is a network printer, the hidden printers have to be also removed From b734830fcf4ca45a517801d8b298fbc55680d063 Mon Sep 17 00:00:00 2001 From: Nino van Hooff Date: Tue, 9 Jun 2020 17:02:21 +0200 Subject: [PATCH 6/8] Sort new_devices on online status first, name second Since the first device might be activated in case there is no active printer yet, it would be nice to prioritize online devices CURA-7493 --- .../src/Cloud/CloudOutputDeviceManager.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 30c26a2c24..ae0e47ad64 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -163,7 +163,11 @@ class CloudOutputDeviceManager: self._connectToActiveMachine() return - new_devices.sort(key = lambda x: x.name.lower()) + # Sort new_devices on online status first, alphabetical (case-sensitive) second. + # Since the first device might be activated in case there is no active printer yet, + # it would be nice to prioritize online devices + online_cluster_names = {c.friendly_name for c in clusters if c.is_online} + new_devices.sort(key = lambda x: "a{}".format(x.name) if x.name in online_cluster_names else "b{}".format(x.name)) image_path = os.path.join( CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "", From 29442e29e4f91e2d08844cf60fb54d8eb7425c44 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 9 Jun 2020 17:28:02 +0200 Subject: [PATCH 7/8] Make printer name sorting case insensitive again. part of CURA-7493 --- .../src/Cloud/CloudOutputDeviceManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index ae0e47ad64..d6868d108b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -163,11 +163,11 @@ class CloudOutputDeviceManager: self._connectToActiveMachine() return - # Sort new_devices on online status first, alphabetical (case-sensitive) second. + # Sort new_devices on online status first, alphabetical second. # Since the first device might be activated in case there is no active printer yet, # it would be nice to prioritize online devices - online_cluster_names = {c.friendly_name for c in clusters if c.is_online} - new_devices.sort(key = lambda x: "a{}".format(x.name) if x.name in online_cluster_names else "b{}".format(x.name)) + online_cluster_names = {c.friendly_name.lower() for c in clusters if c.is_online} + new_devices.sort(key = lambda x: ("a{}" if x.name.lower() in online_cluster_names else "b{}").format(x.name.lower())) image_path = os.path.join( CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "", From a38fac9e6752d36c2d766c165bbf11bab0fd3366 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 9 Jun 2020 17:34:23 +0200 Subject: [PATCH 8/8] Fix typing. --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index d6868d108b..89419c4dd4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -166,7 +166,7 @@ class CloudOutputDeviceManager: # Sort new_devices on online status first, alphabetical second. # Since the first device might be activated in case there is no active printer yet, # it would be nice to prioritize online devices - online_cluster_names = {c.friendly_name.lower() for c in clusters if c.is_online} + online_cluster_names = {c.friendly_name.lower() for c in clusters if c.is_online and not c.friendly_name is None} new_devices.sort(key = lambda x: ("a{}" if x.name.lower() in online_cluster_names else "b{}").format(x.name.lower())) image_path = os.path.join(