def test_getStoragePathForType_Linux(self): with pytest.raises(ResourceTypeError): # No types have been added, so this should break! Resources.getAllResourcesOfType(0) with pytest.raises(UnsupportedStorageTypeError): # We still haven't added it, so it should fail (again) Resources.getStoragePathForType(0) Resources.addStorageType(0, "/test") assert Resources.getStoragePathForType(0) == "/test"
def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) engine.rootContext().setContextProperty("CuraApplication", self) self._print_information = PrintInformation.PrintInformation() engine.rootContext().setContextProperty("PrintInformation", self._print_information) self._cura_actions = CuraActions.CuraActions(self) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") qmlRegisterType(cura.Settings.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterSingletonType(cura.Settings.ProfilesModel, "Cura", 1, 0, "ProfilesModel", cura.Settings.ProfilesModel.createProfilesModel) qmlRegisterType(cura.Settings.QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") qmlRegisterType(cura.Settings.UserProfilesModel, "Cura", 1, 0, "UserProfilesModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterType(cura.Settings.MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager) # As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work. actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml"))) qmlRegisterSingletonType(actions_url, "Cura", 1, 0, "Actions") engine.rootContext().setContextProperty("ExtruderManager", cura.Settings.ExtruderManager.getInstance()) for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): continue qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name)
def _populate(self) -> None: from cura.CuraApplication import CuraApplication items = [] # type: List[SettingVisibilityPreset] items.append(self._custom_preset) for file_path in Resources.getAllResourcesOfType( CuraApplication.ResourceTypes.SettingVisibilityPreset): setting_visibility_preset = SettingVisibilityPreset() try: setting_visibility_preset.loadFromFile(file_path) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) items.append(setting_visibility_preset) # Add the "all" visibility: all_setting_visibility_preset = SettingVisibilityPreset( preset_id="all", name="All", weight=9001) all_setting_visibility_preset.setSettings( list(CuraApplication.getInstance().getMachineManager(). getAllSettingKeys())) items.append(all_setting_visibility_preset) # Sort them on weight (and if that fails, use ID) items.sort(key=lambda k: (int(k.weight), k.presetId)) self.setItems(items)
def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) engine.rootContext().setContextProperty("CuraApplication", self) self._print_information = PrintInformation.PrintInformation() engine.rootContext().setContextProperty("PrintInformation", self._print_information) self._cura_actions = CuraActions.CuraActions(self) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") qmlRegisterType(cura.Settings.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager) qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") engine.rootContext().setContextProperty("ExtruderManager", cura.Settings.ExtruderManager.getInstance()) for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): continue qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name)
def _updatePathCache(self) -> None: """Updates the cache of paths to containers. This way we can more easily load the container files we want lazily. """ self._id_to_path = {} # Clear cache first. self._id_to_mime = {} old_file_expression = re.compile( r"\{sep}old\{sep}\d+\{sep}".format(sep=os.sep) ) # To detect files that are back-ups. Matches on .../old/#/... all_resources = set() # type: Set[str] for resource_type in ContainerRegistry.getInstance().getResourceTypes( ).values(): all_resources |= set( Resources.getAllResourcesOfType(resource_type) ) # Remove duplicates, since the Resources only finds resources by their directories. for filename in all_resources: if re.search(old_file_expression, filename): continue # This is a back-up file from an old version. container_id = self._pathToId(filename) if not container_id: continue mime = self._pathToMime(filename) if not mime: continue self._id_to_path[container_id] = filename self._id_to_mime[container_id] = mime
def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) engine.rootContext().setContextProperty("CuraApplication", self) self._print_information = PrintInformation.PrintInformation() engine.rootContext().setContextProperty("PrintInformation", self._print_information) self._cura_actions = CuraActions.CuraActions(self) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") qmlRegisterType(cura.Settings.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager) qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") engine.rootContext().setContextProperty("ExtruderManager", cura.Settings.ExtruderManager.getInstance()) for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): continue qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name)
def load(self): files = [] for resource_type in self._resource_types: resources = Resources.getAllResourcesOfType(resource_type) try: resource_storage_path = Resources.getStoragePathForType(resource_type) except UnsupportedStorageTypeError: resource_storage_path = "" # Pre-process the list of files to insert relevant data # Most importantly, we need to ensure the loading order is DefinitionContainer, InstanceContainer, ContainerStack for path in resources: mime = MimeTypeDatabase.getMimeTypeForFile(path) container_type = self.__mime_type_map.get(mime.name) if not container_type: Logger.log("w", "Could not determine container type for file %s, ignoring", path) continue type_priority = 2 if issubclass(container_type, DefinitionContainer.DefinitionContainer): type_priority = 0 if issubclass(container_type, InstanceContainer.InstanceContainer): type_priority = 1 # Since we have the mime type and resource type here, process these two properties so we do not # need to look up mime types etc. again. container_id = urllib.parse.unquote_plus(mime.stripExtension(os.path.basename(path))) read_only = os.path.dirname(path) != resource_storage_path files.append((type_priority, container_id, path, read_only, container_type)) # Sort the list of files by type_priority so we can ensure correct loading order. files = sorted(files, key = lambda i: i[0]) for _, container_id, file_path, read_only, container_type in files: if container_id in self._id_container_cache: continue try: if issubclass(container_type, DefinitionContainer.DefinitionContainer): definition = self._loadCachedDefinition(container_id, file_path) if definition: self.addContainer(definition) continue new_container = container_type(container_id) with open(file_path, encoding = "utf-8") as f: new_container.deserialize(f.read()) new_container.setReadOnly(read_only) if issubclass(container_type, DefinitionContainer.DefinitionContainer): self._saveCachedDefinition(new_container) self.addContainer(new_container) except Exception as e: Logger.logException("e", "Could not deserialize container %s", container_id)
def _populate(self): from cura.CuraApplication import CuraApplication items = [] for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeNotFoundError: Logger.log("e", "Could not determine mime type of file %s", file_path) continue item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path))) if not os.path.isfile(file_path): Logger.log("e", "[%s] is not a file", file_path) continue parser = ConfigParser(allow_no_value = True) # accept options without any value, try: parser.read([file_path]) if not parser.has_option("general", "name") or not parser.has_option("general", "weight"): continue settings = [] for section in parser.sections(): if section == 'general': continue settings.append(section) for option in parser[section].keys(): settings.append(option) items.append({ "id": item_id, "name": catalog.i18nc("@action:inmenu", parser["general"]["name"]), "weight": parser["general"]["weight"], "settings": settings, }) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) items.sort(key = lambda k: (int(k["weight"]), k["id"])) # Put "custom" at the top items.insert(0, {"id": "custom", "name": "Custom selection", "weight": -100, "settings": []}) self.setItems(items)
def write(self, stream: StringIO, *unused_args, **unused_kwargs): machine = CuraApplication.getInstance().getMachineManager( ).activeMachine # type: GlobalStack extruders = list(machine.extruders.values()) extruder = extruders[0] # type: ExtruderStack dumper = Dumper() dumper.add_comment('date', datetime.now().ctime()) dumper.add_comment('version', CuraVersion) dumper.add_comment( 'quality', machine.quality.getMetaData().get('name', '[UNDEFINED QUALITY]')) dumper.add_comment( 'profile', machine.qualityChanges.getMetaData().get('name', '[UNDEFINED PROFILE]')) material_metadata = extruder.material.getMetaData() brand = material_metadata.get('brand', '[UNDEFINED BRAND]') material = material_metadata.get('material', '[UNDEFINED MATERIAL]') dumper.add_comment( 'filament', '{brand}/{material}'.format(brand=brand, material=material)) machine_section = 'machine_settings' sections = {machine_section} excluded_sections = {'dual', 'general'} for file_path in Resources.getAllResourcesOfType( CuraApplication.ResourceTypes.SettingVisibilityPreset): try: with open(file_path, mode='rt') as preset_file: parser = ConfigParser(interpolation=None, allow_no_value=True) parser.read_file(preset_file) sections.update(name for name in parser.sections() if name not in excluded_sections) except FileNotFoundError: pass for section in sections: self.__dump_profile(dumper, extruder, section) self.__dump_machine(dumper, extruder, machine_section) dumper.save(stream) return True
def _populate(self) -> None: from cura.CuraApplication import CuraApplication items = [] # type: List[Dict[str, Union[str, int, List[str]]]] for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeNotFoundError: Logger.log("e", "Could not determine mime type of file %s", file_path) continue item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path))) if not os.path.isfile(file_path): Logger.log("e", "[%s] is not a file", file_path) continue parser = ConfigParser(allow_no_value = True) # accept options without any value, try: parser.read([file_path]) if not parser.has_option("general", "name") or not parser.has_option("general", "weight"): continue settings = [] # type: List[str] for section in parser.sections(): if section == 'general': continue settings.append(section) for option in parser[section].keys(): settings.append(option) items.append({ "id": item_id, "name": catalog.i18nc("@action:inmenu", parser["general"]["name"]), "weight": parser["general"]["weight"], "settings": settings, }) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) items.sort(key = lambda k: (int(k["weight"]), k["id"])) # type: ignore # Put "custom" at the top items.insert(0, {"id": "custom", "name": "Custom selection", "weight": -100, "settings": []}) self.setItems(items)
def _sendMaterials(self, materials_to_send: Set[str]) -> None: file_paths = Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer) # Find all local material files and send them if needed. for file_path in file_paths: try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeDatabase.MimeTypeNotFoundError: continue file_name = os.path.basename(file_path) material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)) if material_id not in materials_to_send: # If the material does not have to be sent we skip it. continue self._sendMaterialFile(file_path, file_name, material_id)
def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) self._print_information = PrintInformation.PrintInformation() engine.rootContext().setContextProperty("PrintInformation", self._print_information) self._cura_actions = CuraActions.CuraActions(self) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): continue qmlRegisterType(QUrl.fromLocalFile(path), "Cura", 1, 0, type_name)
def _populate(self) -> None: from cura.CuraApplication import CuraApplication items = [] # type: List[SettingVisibilityPreset] items.append(self._custom_preset) for file_path in Resources.getAllResourcesOfType( CuraApplication.ResourceTypes.SettingVisibilityPreset): setting_visibility_preset = SettingVisibilityPreset() try: setting_visibility_preset.loadFromFile(file_path) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) items.append(setting_visibility_preset) # Sort them on weight (and if that fails, use ID) items.sort(key=lambda k: (int(k.weight), k.presetId)) self.setItems(items)
def _sendMaterials(self, materials_to_send: Set[str]) -> None: file_paths = Resources.getAllResourcesOfType( CuraApplication.ResourceTypes.MaterialInstanceContainer) # Find all local material files and send them if needed. for file_path in file_paths: try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeDatabase.MimeTypeNotFoundError: continue file_name = os.path.basename(file_path) material_id = urllib.parse.unquote_plus( mime_type.stripExtension(file_name)) if material_id not in materials_to_send: # If the material does not have to be sent we skip it. continue self._sendMaterialFile(file_path, file_name, material_id)
def _updatePathCache(self) -> None: self._id_to_path = {} # Clear cache first. self._id_to_mime = {} old_file_expression = re.compile(r"\{sep}old\{sep}\d+\{sep}".format(sep = os.sep)) # To detect files that are back-ups. Matches on .../old/#/... all_resources = set() # type: Set[str] for resource_type in ContainerRegistry.getInstance().getResourceTypes().values(): all_resources |= set(Resources.getAllResourcesOfType(resource_type)) # Remove duplicates, since the Resources only finds resources by their directories. for filename in all_resources: if re.search(old_file_expression, filename): continue # This is a back-up file from an old version. container_id = self._pathToId(filename) if not container_id: continue mime = self._pathToMime(filename) if not mime: continue self._id_to_path[container_id] = filename self._id_to_mime[container_id] = mime
def _populate(self) -> None: from steslicer.SteSlicerApplication import SteSlicerApplication items = [] # type: List[SettingVisibilityPreset] custom_preset = SettingVisibilityPreset(preset_id="custom", name="Custom selection", weight=-100) items.append(custom_preset) for file_path in Resources.getAllResourcesOfType( SteSlicerApplication.ResourceTypes.SettingVisibilityPreset): setting_visibility_preset = SettingVisibilityPreset() try: setting_visibility_preset.loadFromFile(file_path) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) items.append(setting_visibility_preset) # Sort them on weight (and if that fails, use ID) items.sort(key=lambda k: (int(k.weight), k.presetId)) self.setItems(items)
def load(self): files = [] files_resource_type = [] for resource_type in self._resource_types: resources = Resources.getAllResourcesOfType(resource_type) files.extend(resources) files_resource_type.extend([resource_type] * len(resources)) for file_path, resource_type in zip(files, files_resource_type): try: mime = MimeTypeDatabase.getMimeTypeForFile(file_path) container_type = self.__mime_type_map.get(mime.name) container_id = mime.stripExtension(os.path.basename(file_path)) ## Ensure that all special characters are encoded back. container_id = urllib.parse.unquote_plus(container_id) read_only = True try: read_only = os.path.dirname(file_path) != ( Resources.getStoragePathForType(resource_type)) except UnsupportedStorageTypeError: pass if container_type is None: Logger.log("w", "Unable to detect container type for %s", mime.name) continue new_container = container_type(container_id) with open(file_path, encoding="utf-8") as f: new_container.deserialize(f.read()) new_container.setReadOnly(read_only) self._containers.append(new_container) except Exception as e: Logger.logException("e", "Could not deserialize container %s", container_id)
def load(self) -> None: files = [] for resource_type in self._resource_types: resources = Resources.getAllResourcesOfType(resource_type) try: resource_storage_path = Resources.getStoragePathForType( resource_type) except UnsupportedStorageTypeError: resource_storage_path = "" # Pre-process the list of files to insert relevant data # Most importantly, we need to ensure the loading order is DefinitionContainer, InstanceContainer, ContainerStack for path in resources: try: mime = MimeTypeDatabase.getMimeTypeForFile(path) except MimeTypeDatabase.MimeTypeNotFoundError: # No valid mime type found for file, ignore it. continue container_type = self.__mime_type_map.get(mime.name) if not container_type: Logger.log( "w", "Could not determine container type for file %s, ignoring", path) continue type_priority = container_type.getLoadingPriority() # Since we have the mime type and resource type here, process these two properties so we do not # need to look up mime types etc. again. container_id = urllib.parse.unquote_plus( mime.stripExtension(os.path.basename(path))) read_only = os.path.realpath(os.path.dirname( path)) != os.path.realpath(resource_storage_path) files.append((type_priority, container_id, path, read_only, container_type)) # Sort the list of files by type_priority so we can ensure correct loading order. files = sorted(files, key=lambda i: i[0]) resource_start_time = time.time() for _, container_id, file_path, read_only, container_type in files: if container_id in self._id_container_cache: Logger.log("c", "Found a container with a duplicate ID: %s", container_id) Logger.log( "c", "Existing container is %s, trying to load %s from %s", self._id_container_cache[container_id], container_type, file_path) continue try: if issubclass(container_type, DefinitionContainer): definition = self._loadCachedDefinition( container_id, file_path) if definition: self.addContainer(definition) continue new_container = container_type(container_id) with open(file_path, encoding="utf-8") as f: new_container.deserialize(f.read()) new_container.setReadOnly(read_only) new_container.setPath(file_path) if issubclass(container_type, DefinitionContainer): self._saveCachedDefinition(new_container) self.addContainer(new_container) except Exception as e: Logger.logException("e", "Could not deserialize container %s", container_id) Logger.log("d", "Loading data into container registry took %s seconds", time.time() - resource_start_time)
def test_getAllResourcesOfType(self): resouce_folder = tempfile.mkdtemp("test_folder_origin") resource_file = tempfile.mkstemp(dir=str(resouce_folder)) Resources.addStorageType(111, resouce_folder) assert Resources.getAllResourcesOfType(111) == [resource_file[1]]
def load(self) -> None: # We disable the garbage collection while loading, as this speeds up the loading. # Since there is so much going on (lots of objects being created), it's better to have it wait a bit until # the dust settles down. gc.disable() files = [] old_file_expression = re.compile( r"\{sep}old\{sep}\d+\{sep}".format(sep=os.sep)) for resource_type in self._resource_types: resources = Resources.getAllResourcesOfType(resource_type) try: resource_storage_path = Resources.getStoragePathForType( resource_type) except UnsupportedStorageTypeError: resource_storage_path = "" # Pre-process the list of files to insert relevant data # Most importantly, we need to ensure the loading order is DefinitionContainer, InstanceContainer, ContainerStack for path in resources: if old_file_expression.search(path): # This is a backup file, ignore it. continue try: mime = MimeTypeDatabase.getMimeTypeForFile(path) except MimeTypeDatabase.MimeTypeNotFoundError: # No valid mime type found for file, ignore it. continue container_type = self.__mime_type_map.get(mime.name) if not container_type: Logger.log( "w", "Could not determine container type for file %s, ignoring", path) continue type_priority = container_type.getLoadingPriority() # Since we have the mime type and resource type here, process these two properties so we do not # need to look up mime types etc. again. container_id = urllib.parse.unquote_plus( mime.stripExtension(os.path.basename(path))) read_only = os.path.realpath(os.path.dirname( path)) != os.path.realpath(resource_storage_path) files.append((type_priority, container_id, path, read_only, container_type)) # Sort the list of files by type_priority so we can ensure correct loading order. files = sorted(files, key=lambda i: i[0]) resource_start_time = time.time() with self.lockCache(): #Because we might be writing cache files. for _, container_id, file_path, read_only, container_type in files: # Enable the rest of the application to get UI updates. UM.Qt.QtApplication.QtApplication.processEvents() if container_id in self._id_container_cache: Logger.log("c", "Found a container with a duplicate ID: %s", container_id) Logger.log( "c", "Existing container is %s, trying to load %s from %s", self._id_container_cache[container_id], container_type, file_path) continue try: if issubclass(container_type, DefinitionContainer): definition = self._loadCachedDefinition( container_id, file_path) if definition: self.addContainer(definition) continue new_container = container_type(container_id) with open(file_path, encoding="utf-8") as f: new_container.deserialize(f.read()) new_container.setReadOnly(read_only) new_container.setPath(file_path) if issubclass(container_type, DefinitionContainer): self._saveCachedDefinition(new_container) self.addContainer(new_container) except Exception as e: Logger.logException("e", "Could not deserialize container %s", container_id) Logger.log("d", "Loading data into container registry took %s seconds", time.time() - resource_start_time) gc.enable()
def sendMissingMaterials(self, reply: QNetworkReply) -> None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute ) != 200: #Got an error from the HTTP request. Logger.log( "e", "Couldn't request current material storage on printer. Not syncing materials." ) return remote_materials_list = reply.readAll().data().decode("utf-8") try: remote_materials_list = json.loads(remote_materials_list) except json.JSONDecodeError: Logger.log( "e", "Current material storage on printer was a corrupted reply.") return try: remote_materials_by_guid = { material["guid"]: material for material in remote_materials_list } #Index by GUID. except KeyError: Logger.log( "e", "Current material storage on printer was an invalid reply (missing GUIDs)." ) return container_registry = ContainerRegistry.getInstance() local_materials_list = filter( lambda material: ("GUID" in material and "version" in material and "id" in material), container_registry.findContainersMetadata(type="material")) local_materials_by_guid = { material["GUID"]: material for material in local_materials_list if material["id"] == material["base_file"] } for material in local_materials_list: #For each GUID get the material with the highest version number. try: if int(material["version"]) > local_materials_by_guid[ material["GUID"]]["version"]: local_materials_by_guid[material["GUID"]] = material except ValueError: Logger.log( "e", "Material {material_id} has invalid version number {number}." .format(material_id=material["id"], number=material["version"])) continue materials_to_send = set() #type: Set[Dict[str, Any]] for guid, material in local_materials_by_guid.items(): if guid not in remote_materials_by_guid: materials_to_send.add(material["id"]) continue try: if int(material["version"] ) > remote_materials_by_guid[guid]["version"]: materials_to_send.add(material["id"]) continue except KeyError: Logger.log( "e", "Current material storage on printer was an invalid reply (missing version)." ) return for file_path in Resources.getAllResourcesOfType( CuraApplication.ResourceTypes.MaterialInstanceContainer): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeDatabase.MimeTypeNotFoundError: continue #Not the sort of file we'd like to send then. _, file_name = os.path.split(file_path) material_id = urllib.parse.unquote_plus( mime_type.stripExtension(file_name)) if material_id not in materials_to_send: continue parts = [] with open(file_path, "rb") as f: parts.append( self.device._createFormPart( "name=\"file\"; filename=\"{file_name}\"".format( file_name=file_name), f.read())) signature_file_path = file_path + ".sig" if os.path.exists(signature_file_path): _, signature_file_name = os.path.split(signature_file_path) with open(signature_file_path, "rb") as f: parts.append( self.device._createFormPart( "name=\"signature_file\"; filename=\"{file_name}\"" .format(file_name=signature_file_name), f.read())) Logger.log( "d", "Syncing material {material_id} with cluster.".format( material_id=material_id)) self.device.postFormWithParts(target="materials/", parts=parts, on_finished=self.sendingFinished)
def load(self) -> None: files = [] old_file_expression = re.compile(r"\{sep}old\{sep}\d+\{sep}".format(sep = os.sep)) for resource_type in self._resource_types: resources = Resources.getAllResourcesOfType(resource_type) try: resource_storage_path = Resources.getStoragePathForType(resource_type) except UnsupportedStorageTypeError: resource_storage_path = "" # Pre-process the list of files to insert relevant data # Most importantly, we need to ensure the loading order is DefinitionContainer, InstanceContainer, ContainerStack for path in resources: if old_file_expression.search(path): # This is a backup file, ignore it. continue try: mime = MimeTypeDatabase.getMimeTypeForFile(path) except MimeTypeDatabase.MimeTypeNotFoundError: # No valid mime type found for file, ignore it. continue container_type = self.__mime_type_map.get(mime.name) if not container_type: Logger.log("w", "Could not determine container type for file %s, ignoring", path) continue type_priority = container_type.getLoadingPriority() # Since we have the mime type and resource type here, process these two properties so we do not # need to look up mime types etc. again. container_id = urllib.parse.unquote_plus(mime.stripExtension(os.path.basename(path))) read_only = os.path.realpath(os.path.dirname(path)) != os.path.realpath(resource_storage_path) files.append((type_priority, container_id, path, read_only, container_type)) # Sort the list of files by type_priority so we can ensure correct loading order. files = sorted(files, key = lambda i: i[0]) resource_start_time = time.time() for _, container_id, file_path, read_only, container_type in files: if container_id in self._id_container_cache: Logger.log("c", "Found a container with a duplicate ID: %s", container_id) Logger.log("c", "Existing container is %s, trying to load %s from %s", self._id_container_cache[container_id], container_type, file_path) continue try: if issubclass(container_type, DefinitionContainer): definition = self._loadCachedDefinition(container_id, file_path) if definition: self.addContainer(definition) continue new_container = container_type(container_id) with open(file_path, encoding = "utf-8") as f: new_container.deserialize(f.read()) new_container.setReadOnly(read_only) new_container.setPath(file_path) if issubclass(container_type, DefinitionContainer): self._saveCachedDefinition(new_container) self.addContainer(new_container) except Exception as e: Logger.logException("e", "Could not deserialize container %s", container_id) Logger.log("d", "Loading data into container registry took %s seconds", time.time() - resource_start_time)