diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f944f4e277..ba42dd2aec 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -489,7 +489,7 @@ class CuraApplication(QtApplication): self._plugin_registry.loadPlugins() - if self.getBackend() == None: + if self.getBackend() is None: raise RuntimeError("Could not load the backend plugin!") self._plugins_loaded = True diff --git a/plugins/XmlMaterialProfile/Upgrader.py b/plugins/XmlMaterialProfile/Upgrader.py new file mode 100644 index 0000000000..7597d81748 --- /dev/null +++ b/plugins/XmlMaterialProfile/Upgrader.py @@ -0,0 +1,62 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import xml.etree.ElementTree as ET + +from UM.VersionUpgrade import VersionUpgrade + + +class Upgrader(VersionUpgrade): + def getXmlVersion(self, serialized): + data = ET.fromstring(serialized) + + # get format version + version = None + metadata = data.iterfind("./um:metadata/*") + for entry in metadata: + tag_name = entry.tag + if tag_name == "version": + try: + version = int(entry.text) + except Exception as e: + raise ValueError("Invalid version string '%s': %s" % (entry.text, e)) + break + if version is None: + raise RuntimeError("Missing version in metadata") + + # get setting version + if "version" in data.attrib: + setting_version = self._xmlVersionToSettingVersion(data.attrib["version"]) + else: + setting_version = self._xmlVersionToSettingVersion("1.2") + + if version is None: + raise RuntimeError("Missing version in metadata") + + return version * 1000000 + setting_version + + def _xmlVersionToSettingVersion(self, xml_version: str) -> int: + if xml_version == "1.3": + return 1 + return 0 #Older than 1.3. + + def upgradeMaterial(self, serialised, filename): + data = ET.fromstring(serialised) + + # update version + metadata = data.iterfind("./um:metadata/*", {"um": "http://www.ultimaker.com/material"}) + for entry in metadata: + if _tag_without_namespace(entry) == "version": + entry.text = "2" + break + + data.attrib["version"] = "1.3" + + # this makes sure that the XML header states encoding="utf-8" + new_serialised = ET.tostring(data, encoding="utf-8").decode("utf-8") + + return [filename], [new_serialised] + + +def _tag_without_namespace(element): + return element.tag[element.tag.rfind("}") + 1:] diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 7bdfaf404d..70a329ef32 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -14,9 +14,13 @@ from cura.CuraApplication import CuraApplication import UM.Dictionary from UM.Settings.InstanceContainer import InstanceContainer, InvalidInstanceError from UM.Settings.ContainerRegistry import ContainerRegistry +from cura.Settings.CuraContainerRegistry import CuraContainerRegistry + ## Handles serializing and deserializing material containers from an XML file class XmlMaterialProfile(InstanceContainer): + Version = 1 + def __init__(self, container_id, *args, **kwargs): super().__init__(container_id, *args, **kwargs) self._inherited_files = [] @@ -386,11 +390,13 @@ class XmlMaterialProfile(InstanceContainer): self._path = "" def getConfigurationTypeFromSerialized(self, serialized: str) -> Optional[str]: - return "material" + return "materials" def getVersionFromSerialized(self, serialized: str) -> Optional[int]: - version = None data = ET.fromstring(serialized) + + # get format version + version = None metadata = data.iterfind("./um:metadata/*", self.__namespaces) for entry in metadata: tag_name = _tag_without_namespace(entry) @@ -402,7 +408,17 @@ class XmlMaterialProfile(InstanceContainer): break if version is None: raise InvalidInstanceError("Missing version in metadata") - return version + + # get setting version + if "version" in data.attrib: + setting_version = self.xmlVersionToSettingVersion(data.attrib["version"]) + else: + setting_version = self.xmlVersionToSettingVersion("1.2") + + if version is None: + raise InvalidInstanceError("Missing version in metadata") + + return version * 1000000 + setting_version ## Overridden from InstanceContainer def deserialize(self, serialized): diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py index 213b9a358a..73965ac8b8 100644 --- a/plugins/XmlMaterialProfile/__init__.py +++ b/plugins/XmlMaterialProfile/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. from . import XmlMaterialProfile +from . import Upgrader from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.i18n import i18nCatalog + + catalog = i18nCatalog("cura") +upgrader = Upgrader.Upgrader() + def getMetaData(): return { @@ -19,15 +24,36 @@ def getMetaData(): "settings_container": { "type": "material", "mimetype": "application/x-ultimaker-material-profile" + }, + "version_upgrade": { + ("materials", 1000000): ("materials", 1000001, upgrader.upgradeMaterial), + }, + "sources": { + "materials": { + "get_version": upgrader.getXmlVersion, + "location": {"./materials"} + }, } } + def register(app): + # add Mime type mime_type = MimeType( name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", suffixes = [ "xml.fdm_material" ] ) MimeTypeDatabase.addMimeType(mime_type) - return { "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile") } + # add upgrade version + from cura.CuraApplication import CuraApplication + from UM.VersionUpgradeManager import VersionUpgradeManager + VersionUpgradeManager.getInstance().setCurrentVersion( + ("materials", XmlMaterialProfile.XmlMaterialProfile.Version * 1000000 + CuraApplication.SettingVersion), + (CuraApplication.ResourceTypes.MaterialInstanceContainer, "application/x-uranium-instancecontainer") + ) + + return {"version_upgrade": upgrader, + "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile"), + }