diff options
author | Jaime van Kessel <nallath@gmail.com> | 2021-09-13 15:57:40 +0300 |
---|---|---|
committer | Jaime van Kessel <nallath@gmail.com> | 2021-09-13 15:57:40 +0300 |
commit | cfb147853ef82534e2b1a8f7106565477955107e (patch) | |
tree | cb6ad3b50457b0cf65d2cce5b23a467ebc53116b /cura | |
parent | 9f3aef02a2314e9039e931bb0edabaffd4ab8fea (diff) | |
parent | 8ed2e7bd447cb1d19a74e71481f10838340c6758 (diff) |
Merge branch 'master' of github.com:Ultimaker/Cura into libArachne_rebased
Diffstat (limited to 'cura')
23 files changed, 136 insertions, 38 deletions
diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py index 2c3ecbc856..6911132f55 100644 --- a/cura/ApplicationMetadata.py +++ b/cura/ApplicationMetadata.py @@ -13,7 +13,7 @@ DEFAULT_CURA_DEBUG_MODE = False # Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for # example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the # CuraVersion.py.in template. -CuraSDKVersion = "7.6.0" +CuraSDKVersion = "7.7.0" try: from cura.CuraVersion import CuraAppName # type: ignore diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 29c0d05e86..5c5f083491 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -471,7 +471,8 @@ class CuraApplication(QtApplication): ("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"), ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"), ("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"), - ("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer") + ("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), + ("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer") } ) @@ -1311,9 +1312,9 @@ class CuraApplication(QtApplication): if not isinstance(node, SceneNode): continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent().callDecoration("isSliceable"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is reset) if not node.isSelectable(): continue # i.e. node with layer data if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"): @@ -1331,9 +1332,9 @@ class CuraApplication(QtApplication): if not isinstance(node, SceneNode): continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is reset) if not node.isSelectable(): continue # i.e. node with layer data nodes.append(node) @@ -1360,9 +1361,9 @@ class CuraApplication(QtApplication): if not isinstance(node, SceneNode): continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is reset) if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"): continue # i.e. node with layer data nodes.append(node) @@ -1389,7 +1390,7 @@ class CuraApplication(QtApplication): continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. parent_node = node.getParent() if parent_node and parent_node.callDecoration("isGroup"): @@ -1417,11 +1418,11 @@ class CuraApplication(QtApplication): continue if not node.getMeshData() and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. parent_node = node.getParent() if parent_node and parent_node.callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is reset) if not node.isSelectable(): continue # i.e. node with layer data @@ -2038,11 +2039,11 @@ class CuraApplication(QtApplication): if not node.isEnabled(): continue if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"): - continue # Node that doesnt have a mesh and is not a group. + continue # Node that doesn't have a mesh and is not a group. if only_selectable and not node.isSelectable(): continue # Only remove nodes that are selectable. if not node.callDecoration("isSliceable") and not node.callDecoration("getLayerData") and not node.callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + continue # Grouped nodes don't need resetting as their parent (the group) is reset) nodes.append(node) if nodes: from UM.Operations.GroupedOperation import GroupedOperation diff --git a/cura/CuraView.py b/cura/CuraView.py index d594ea9571..86d4254a7d 100644 --- a/cura/CuraView.py +++ b/cura/CuraView.py @@ -12,7 +12,7 @@ from cura.CuraApplication import CuraApplication # Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure # to indicate this. # MainComponent works in the same way the MainComponent of a stage. -# the stageMenuComponent returns an item that should be used somehwere in the stage menu. It's up to the active stage +# the stageMenuComponent returns an item that should be used somewhere in the stage menu. It's up to the active stage # to actually do something with this. class CuraView(View): def __init__(self, parent = None, use_empty_menu_placeholder: bool = False) -> None: diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 7f62a0a8fa..2c3b432b1d 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -59,7 +59,7 @@ class LayerPolygon: self._vertex_count = self._mesh_line_count + numpy.sum(self._types[1:] == self._types[:-1]) # Buffering the colors shouldn't be necessary as it is not - # re-used and can save alot of memory usage. + # re-used and can save a lot of memory usage. self._color_map = LayerPolygon.getColorMap() self._colors = self._color_map[self._types] # type: numpy.ndarray @@ -146,7 +146,7 @@ class LayerPolygon: # When the line type changes the index needs to be increased by 2. indices[self._index_begin:self._index_end, :] += numpy.cumsum(needed_points_list[line_mesh_mask.ravel(), 0], dtype = numpy.int32).reshape((-1, 1)) # Each line segment goes from it's starting point p to p+1, offset by the vertex index. - # The -1 is to compensate for the neccecarily True value of needed_points_list[0,0] which causes an unwanted +1 in cumsum above. + # The -1 is to compensate for the necessarily True value of needed_points_list[0,0] which causes an unwanted +1 in cumsum above. indices[self._index_begin:self._index_end, :] += numpy.array([self._vertex_begin - 1, self._vertex_begin]) self._build_cache_line_mesh_mask = None diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py index 818d62de7c..8213734348 100644 --- a/cura/Machines/MachineErrorChecker.py +++ b/cura/Machines/MachineErrorChecker.py @@ -97,8 +97,7 @@ class MachineErrorChecker(QObject): def startErrorCheckPropertyChanged(self, key: str, property_name: str) -> None: """Start the error check for property changed - - this is seperate from the startErrorCheck because it ignores a number property types + this is separate from the startErrorCheck because it ignores a number property types :param key: :param property_name: diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index d268774850..2ca0960de4 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -33,7 +33,7 @@ class SettingVisibilityPresetsModel(QObject): if basic_item is not None: basic_visibile_settings = ";".join(basic_item.settings) else: - Logger.log("w", "Unable to find the basic visiblity preset.") + Logger.log("w", "Unable to find the basic visibility preset.") basic_visibile_settings = "" self._preferences = preferences diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py index 5b95b3a3bb..d6f4980fe4 100644 --- a/cura/OAuth2/AuthorizationHelpers.py +++ b/cura/OAuth2/AuthorizationHelpers.py @@ -3,7 +3,7 @@ from datetime import datetime import json -import random +import secrets from hashlib import sha512 from base64 import b64encode from typing import Optional @@ -48,8 +48,8 @@ class AuthorizationHelpers: } try: return self.parseTokenResponse(requests.post(self._token_url, data = data)) # type: ignore - except requests.exceptions.ConnectionError: - return AuthenticationResponse(success=False, err_message="Unable to connect to remote server") + except requests.exceptions.ConnectionError as connection_error: + return AuthenticationResponse(success = False, err_message = f"Unable to connect to remote server: {connection_error}") def getAccessTokenUsingRefreshToken(self, refresh_token: str) -> "AuthenticationResponse": """Request the access token from the authorization server using a refresh token. @@ -139,11 +139,11 @@ class AuthorizationHelpers: def generateVerificationCode(code_length: int = 32) -> str: """Generate a verification code of arbitrary length. - :param code_length:: How long should the code be? This should never be lower than 16, but it's probably + :param code_length:: How long should the code be in bytes? This should never be lower than 16, but it's probably better to leave it at 32 """ - return "".join(random.choice("0123456789ABCDEF") for i in range(code_length)) + return secrets.token_hex(code_length) @staticmethod def generateVerificationCodeChallenge(verification_code: str) -> str: diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 46fe1be656..9bff497c17 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -120,7 +120,7 @@ class AuthorizationService: return self._auth_helpers.parseJWT(self._auth_data.access_token) def getAccessToken(self) -> Optional[str]: - """Get the access token as provided by the repsonse data.""" + """Get the access token as provided by the response data.""" if self._auth_data is None: Logger.log("d", "No auth data to retrieve the access_token from") diff --git a/cura/OAuth2/KeyringAttribute.py b/cura/OAuth2/KeyringAttribute.py index b8864e31e0..a8c60de994 100644 --- a/cura/OAuth2/KeyringAttribute.py +++ b/cura/OAuth2/KeyringAttribute.py @@ -14,13 +14,18 @@ if TYPE_CHECKING: # Need to do some extra workarounds on windows: import sys from UM.Platform import Platform -if Platform.isWindows() and hasattr(sys, "frozen"): - import win32timezone +if Platform.isWindows(): + if hasattr(sys, "frozen"): + import win32timezone from keyring.backends.Windows import WinVaultKeyring keyring.set_keyring(WinVaultKeyring()) -if Platform.isOSX() and hasattr(sys, "frozen"): +if Platform.isOSX(): from keyring.backends.macOS import Keyring keyring.set_keyring(Keyring()) +if Platform.isLinux(): + # We do not support the keyring on Linux, so make sure no Keyring backend is loaded, even if there is a system one. + from keyring.backends.fail import Keyring as NoKeyringBackend + keyring.set_keyring(NoKeyringBackend()) # Even if errors happen, we don't want this stored locally: DONT_EVER_STORE_LOCALLY: List[str] = ["refresh_token"] diff --git a/cura/PickingPass.py b/cura/PickingPass.py index eb190be16d..54e886fe62 100644 --- a/cura/PickingPass.py +++ b/cura/PickingPass.py @@ -79,7 +79,7 @@ class PickingPass(RenderPass): return -1 distance = output.pixel(px, py) # distance in micron, from in r, g & b channels - distance = (distance & 0x00ffffff) / 1000. # drop the alpha channel and covert to mm + distance = (distance & 0x00ffffff) / 1000. # drop the alpha channel and convert to mm return distance def getPickedPosition(self, x: int, y: int) -> Vector: diff --git a/cura/PrinterOutput/FirmwareUpdater.py b/cura/PrinterOutput/FirmwareUpdater.py index c4f3948c20..cfcfb2204f 100644 --- a/cura/PrinterOutput/FirmwareUpdater.py +++ b/cura/PrinterOutput/FirmwareUpdater.py @@ -49,7 +49,7 @@ class FirmwareUpdater(QObject): raise NotImplementedError("_updateFirmware needs to be implemented") def _cleanupAfterUpdate(self) -> None: - """Cleanup after a succesful update""" + """Cleanup after a successful update""" # Clean up for next attempt. self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread") diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 2690c2651f..9979354dba 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -414,6 +414,6 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): @pyqtProperty(str, constant = True) def ipAddress(self) -> str: - """IP adress of this printer""" + """IP address of this printer""" return self._address diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 45f2edab20..09c9a7a3dc 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -319,7 +319,7 @@ class ContainerManager(QObject): stack.qualityChanges = quality_changes if not quality_changes or container_registry.isReadOnly(quality_changes.getId()): - Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId()) + Logger.log("e", "Could not update quality of a nonexistent or read only quality profile in stack %s", stack.getId()) continue self._performMerge(quality_changes, stack.getTop()) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 295d843fd7..6130019f4d 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -32,6 +32,10 @@ from cura.Machines.ContainerTree import ContainerTree from cura.ReaderWriters.ProfileReader import NoProfileException, ProfileReader from UM.i18n import i18nCatalog +from .DatabaseHandlers.IntentDatabaseHandler import IntentDatabaseHandler +from .DatabaseHandlers.QualityDatabaseHandler import QualityDatabaseHandler +from .DatabaseHandlers.VariantDatabaseHandler import VariantDatabaseHandler + catalog = i18nCatalog("cura") @@ -44,6 +48,10 @@ class CuraContainerRegistry(ContainerRegistry): # is added, we check to see if an extruder stack needs to be added. self.containerAdded.connect(self._onContainerAdded) + self._database_handlers["variant"] = VariantDatabaseHandler() + self._database_handlers["quality"] = QualityDatabaseHandler() + self._database_handlers["intent"] = IntentDatabaseHandler() + @override(ContainerRegistry) def addContainer(self, container: ContainerInterface) -> bool: """Overridden from ContainerRegistry diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index efc447b2cf..7ede6950d7 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -66,7 +66,7 @@ class CuraStackBuilder: Logger.logException("e", "Failed to create an extruder stack for position {pos}: {err}".format(pos = position, err = str(e))) return None - # If given, set the machine_extruder_count when creating the machine, or else the extruderList used bellow will + # If given, set the machine_extruder_count when creating the machine, or else the extruderList used below will # not return the correct extruder list (since by default, the machine_extruder_count is 1) in machines with # settable number of extruders. if machine_extruder_count and 0 <= machine_extruder_count <= len(extruder_dict): diff --git a/cura/Settings/DatabaseHandlers/IntentDatabaseHandler.py b/cura/Settings/DatabaseHandlers/IntentDatabaseHandler.py new file mode 100644 index 0000000000..cd6c662591 --- /dev/null +++ b/cura/Settings/DatabaseHandlers/IntentDatabaseHandler.py @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Settings.SQLQueryFactory import SQLQueryFactory +from UM.Settings.DatabaseContainerMetadataController import DatabaseMetadataContainerController +from UM.Settings.InstanceContainer import InstanceContainer + + +class IntentDatabaseHandler(DatabaseMetadataContainerController): + """The Database handler for Intent containers""" + + def __init__(self) -> None: + super().__init__(SQLQueryFactory(table = "intent", + fields = { + "id": "text", + "name": "text", + "quality_type": "text", + "intent_category": "text", + "variant": "text", + "definition": "text", + "material": "text", + "version": "text", + "setting_version": "text" + })) + self._container_type = InstanceContainer diff --git a/cura/Settings/DatabaseHandlers/QualityDatabaseHandler.py b/cura/Settings/DatabaseHandlers/QualityDatabaseHandler.py new file mode 100644 index 0000000000..477bb56465 --- /dev/null +++ b/cura/Settings/DatabaseHandlers/QualityDatabaseHandler.py @@ -0,0 +1,38 @@ +# Copyright (c) 2021 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Settings.SQLQueryFactory import SQLQueryFactory, metadata_type +from UM.Settings.DatabaseContainerMetadataController import DatabaseMetadataContainerController +from UM.Settings.InstanceContainer import InstanceContainer + + +class QualityDatabaseHandler(DatabaseMetadataContainerController): + """The Database handler for Quality containers""" + + def __init__(self): + super().__init__(SQLQueryFactory(table = "quality", + fields = { + "id": "text", + "name": "text", + "quality_type": "text", + "material": "text", + "variant": "text", + "global_quality": "bool", + "definition": "text", + "version": "text", + "setting_version": "text" + })) + self._container_type = InstanceContainer + + def groomMetadata(self, metadata: metadata_type) -> metadata_type: + """ + Ensures that the metadata is in the order of the field keys and has the right size. + if the metadata doesn't contains a key which is stored in the DB it will add it as + an empty string. Key, value pairs that are not stored in the DB are dropped. + If the `global_quality` isn't set it well default to 'False' + + :param metadata: The container metadata + """ + if "global_quality" not in metadata: + metadata["global_quality"] = "False" + return super().groomMetadata(metadata) diff --git a/cura/Settings/DatabaseHandlers/VariantDatabaseHandler.py b/cura/Settings/DatabaseHandlers/VariantDatabaseHandler.py new file mode 100644 index 0000000000..4b1deae356 --- /dev/null +++ b/cura/Settings/DatabaseHandlers/VariantDatabaseHandler.py @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Settings.SQLQueryFactory import SQLQueryFactory +from UM.Settings.DatabaseContainerMetadataController import DatabaseMetadataContainerController +from UM.Settings.InstanceContainer import InstanceContainer + + +class VariantDatabaseHandler(DatabaseMetadataContainerController): + """The Database handler for Variant containers""" + + def __init__(self): + super().__init__(SQLQueryFactory(table = "variant", + fields = { + "id": "text", + "name": "text", + "hardware_type": "text", + "definition": "text", + "version": "text", + "setting_version": "text" + })) + self._container_type = InstanceContainer diff --git a/cura/Settings/DatabaseHandlers/__init__.py b/cura/Settings/DatabaseHandlers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/cura/Settings/DatabaseHandlers/__init__.py diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 70a8a6aae7..ac9d704afd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -627,7 +627,7 @@ class MachineManager(QObject): return "" return global_container_stack.getIntentCategory() - # Provies a list of extruder positions that have a different intent from the active one. + # Provides a list of extruder positions that have a different intent from the active one. @pyqtProperty("QStringList", notify=activeIntentChanged) def extruderPositionsWithNonActiveIntent(self): global_container_stack = self._application.getGlobalContainerStack() diff --git a/cura/SingleInstance.py b/cura/SingleInstance.py index 6fcf0da6cf..fa82ceb104 100644 --- a/cura/SingleInstance.py +++ b/cura/SingleInstance.py @@ -68,7 +68,7 @@ class SingleInstance: Logger.log("e", "Single instance server was not created.") def _onClientConnected(self) -> None: - Logger.log("i", "New connection recevied on our single-instance server") + Logger.log("i", "New connection received on our single-instance server") connection = None #type: Optional[QLocalSocket] if self._single_instance_server: connection = self._single_instance_server.nextPendingConnection() diff --git a/cura/TaskManagement/OnExitCallbackManager.py b/cura/TaskManagement/OnExitCallbackManager.py index 2e8e42595b..7894931e9c 100644 --- a/cura/TaskManagement/OnExitCallbackManager.py +++ b/cura/TaskManagement/OnExitCallbackManager.py @@ -56,8 +56,8 @@ class OnExitCallbackManager: self._application.callLater(self._application.closeApplication) # This is the callback function which an on-exit callback should call when it finishes, it should provide the - # "should_proceed" flag indicating whether this check has "passed", or in other words, whether quiting the - # application should be blocked. If the last on-exit callback doesn't block the quiting, it will call the next + # "should_proceed" flag indicating whether this check has "passed", or in other words, whether quitting the + # application should be blocked. If the last on-exit callback doesn't block the quitting, it will call the next # registered on-exit callback if available. def onCurrentCallbackFinished(self, should_proceed: bool = True) -> None: if not should_proceed: diff --git a/cura/UI/ObjectsModel.py b/cura/UI/ObjectsModel.py index 0c109d7a4a..64a6e89054 100644 --- a/cura/UI/ObjectsModel.py +++ b/cura/UI/ObjectsModel.py @@ -90,7 +90,7 @@ class ObjectsModel(ListModel): parent = node.getParent() if parent and parent.callDecoration("isGroup"): - return False # Grouped nodes don't need resetting as their parent (the group) is resetted) + return False # Grouped nodes don't need resetting as their parent (the group) is reset) node_build_plate_number = node.callDecoration("getBuildPlateNumber") if Application.getInstance().getPreferences().getValue("view/filter_current_build_plate") and node_build_plate_number != self._build_plate_number: |