示例#1
0
    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"
示例#2
0
    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)
示例#4
0
    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)
示例#5
0
    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
示例#6
0
    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
示例#10
0
    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)
示例#11
0
    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)
示例#12
0
    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)
示例#14
0
    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)
示例#15
0
    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
示例#16
0
    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)
示例#17
0
    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)
示例#18
0
    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)
示例#19
0
 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]]
示例#20
0
    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()
示例#21
0
    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)
示例#22
0
    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)