Esempio n. 1
0
    def _onInstanceNameChanged(self, instance, old_name):
        file_name = urllib.parse.quote_plus(old_name)
        try:
            path = Resources.getStoragePath(Resources.MachineInstances, file_name + ".cfg")
            os.remove(path)
            path = Resources.getStoragePath(Resources.MachineInstanceProfiles, file_name + ".curaprofile")
            os.remove(path)
        except FileNotFoundError:
            pass

        #Update machine instance name for all profiles attached to this machine instance
        for profile in self._profiles:
            if profile.isReadOnly() or profile.getMachineInstanceName() != old_name:
                continue

            file_name = urllib.parse.quote_plus(profile.getName()) + ".cfg"
            try:
                path = Resources.getStoragePath(Resources.Profiles, file_name)
                os.remove(path)
            except FileNotFoundError:
                pass

            profile.setMachineInstanceName(instance.getName())

        self.machineInstanceNameChanged.emit(instance)
Esempio n. 2
0
    def initialize(self) -> None:
        self._installation_dirs_dict["materials"] = Resources.getStoragePath(
            CuraApplication.ResourceTypes.MaterialInstanceContainer)
        self._installation_dirs_dict["qualities"] = Resources.getStoragePath(
            CuraApplication.ResourceTypes.QualityInstanceContainer)

        super().initialize()
Esempio n. 3
0
    def removeMachineInstance(self, instance):
        if instance not in self._machine_instances:
            return

        self._machine_instances.remove(instance)
        instance.nameChanged.disconnect(self._onInstanceNameChanged)

        file_name = urllib.parse.quote_plus(instance.getName())
        try:
            path = Resources.getStoragePath(Resources.MachineInstances,
                                            file_name + ".cfg")
            os.remove(path)
            path = Resources.getStoragePath(Resources.MachineInstanceProfiles,
                                            file_name + ".cfg")
            os.remove(path)
        except FileNotFoundError:
            pass

        self.machineInstancesChanged.emit()

        if self._active_machine == instance:
            try:
                self.setActiveMachineInstance(self._machine_instances[0])
            except:
                self.setActiveMachineInstance(None)
Esempio n. 4
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self._installation_dirs_dict["materials"] = Resources.getStoragePath(
            CuraApplication.ResourceTypes.MaterialInstanceContainer)
        self._installation_dirs_dict["qualities"] = Resources.getStoragePath(
            CuraApplication.ResourceTypes.QualityInstanceContainer)
Esempio n. 5
0
    def saveStack(self, stack):
        if not stack.isDirty():
            return
        try:
            data = stack.serialize()
        except NotImplementedError:
            return
        except Exception:
            Logger.logException(
                "e", "An exception occurred when serializing container %s",
                stack.getId())
            return

        mime_type = ContainerRegistry.getMimeTypeForContainer(type(stack))
        file_name = urllib.parse.quote_plus(
            stack.getId()) + "." + mime_type.preferredSuffix
        stack_type = stack.getMetaDataEntry("type", None)
        path = None
        if not stack_type or stack_type == "machine":
            path = Resources.getStoragePath(self.ResourceTypes.MachineStack,
                                            file_name)
        elif stack_type == "extruder_train":
            path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack,
                                            file_name)
        if path:
            stack.setPath(path)
            with SaveFile(path, "wt") as f:
                f.write(data)
Esempio n. 6
0
    def loadAllScripts(self) -> None:
        if self._loaded_scripts:  # Already loaded.
            return

        # The PostProcessingPlugin path is for built-in scripts.
        # The Resources path is where the user should store custom scripts.
        # The Preferences path is legacy, where the user may previously have stored scripts.
        for root in [
                PluginRegistry.getInstance().getPluginPath(
                    "PostProcessingPlugin"),
                Resources.getStoragePath(Resources.Resources),
                Resources.getStoragePath(Resources.Preferences)
        ]:
            if root is None:
                continue
            path = os.path.join(root, "scripts")
            if not os.path.isdir(path):
                try:
                    os.makedirs(path)
                except OSError:
                    Logger.log(
                        "w", "Unable to create a folder for scripts: " + path)
                    continue

            self.loadScripts(path)
Esempio n. 7
0
    def _onInstanceNameChanged(self, instance, old_name):
        file_name = urllib.parse.quote_plus(old_name)
        try:
            path = Resources.getStoragePath(Resources.MachineInstances,
                                            file_name + ".cfg")
            os.remove(path)
            path = Resources.getStoragePath(Resources.MachineInstanceProfiles,
                                            file_name + ".curaprofile")
            os.remove(path)
        except FileNotFoundError:
            pass

        #Update machine instance name for all profiles attached to this machine instance
        for profile in self._profiles:
            if profile.isReadOnly(
            ) or profile.getMachineInstanceName() != old_name:
                continue

            file_name = urllib.parse.quote_plus(profile.getName()) + ".cfg"
            try:
                path = Resources.getStoragePath(Resources.Profiles, file_name)
                os.remove(path)
            except FileNotFoundError:
                pass

            profile.setMachineInstanceName(instance.getName())

        self.machineInstanceNameChanged.emit(instance)
Esempio n. 8
0
    def saveAll(self) -> None:
        for instance in self.findInstanceContainers():
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", instance.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(instance))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(instance.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.InstanceContainers, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)

        for stack in self.findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", stack.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(stack))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.ContainerStacks, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)

        for definition in self.findDefinitionContainers():
            try:
                data = definition.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", definition.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(definition))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(definition.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.DefinitionContainers, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)
Esempio n. 9
0
    def _installPackage(self, installation_package_data: dict):
        package_info = installation_package_data["package_info"]
        filename = installation_package_data["filename"]

        package_id = package_info["package_id"]

        if not os.path.exists(filename):
            Logger.log(
                "w",
                "Package [%s] file '%s' is missing, cannot install this package",
                package_id, filename)
            return

        Logger.log("i", "Installing package [%s] from file [%s]", package_id,
                   filename)

        # If it's installed, remove it first and then install
        if package_id in self._installed_package_dict:
            self._purgePackage(package_id)

        # Install the package
        with zipfile.ZipFile(filename, "r") as archive:

            temp_dir = tempfile.TemporaryDirectory()
            archive.extractall(temp_dir.name)

            from cura.CuraApplication import CuraApplication
            installation_dirs_dict = {
                "materials":
                Resources.getStoragePath(
                    CuraApplication.ResourceTypes.MaterialInstanceContainer),
                "qualities":
                Resources.getStoragePath(
                    CuraApplication.ResourceTypes.QualityInstanceContainer),
                "plugins":
                os.path.abspath(Resources.getStoragePath(Resources.Plugins)),
            }

            for sub_dir_name, installation_root_dir in installation_dirs_dict.items(
            ):
                src_dir_path = os.path.join(temp_dir.name, "files",
                                            sub_dir_name)
                dst_dir_path = os.path.join(installation_root_dir, package_id)

                if not os.path.exists(src_dir_path):
                    continue

                # Need to rename the container files so they don't get ID conflicts
                to_rename_files = sub_dir_name not in ("plugins", )
                self.__installPackageFiles(
                    package_id,
                    src_dir_path,
                    dst_dir_path,
                    need_to_rename_files=to_rename_files)

        # Remove the file
        os.remove(filename)
Esempio n. 10
0
    def saveMachineInstances(self):
        if self._active_machine:
            Preferences.getInstance().setValue("machines/active_instance", self._active_machine.getName())

        for instance in self._machine_instances:
            file_name = urllib.parse.quote_plus(instance.getName()) + ".cfg"
            instance.saveToFile(Resources.getStoragePath(Resources.MachineInstances, file_name))
            file_name = urllib.parse.quote_plus(instance.getName()) + ".curaprofile"
            instance.getWorkingProfile().saveToFile(Resources.getStoragePath(Resources.MachineInstanceProfiles, file_name))
Esempio n. 11
0
    def saveAll(self) -> None:
        for instance in self.findInstanceContainers():
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", instance.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(instance))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(instance.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.InstanceContainers, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)

        for stack in self.findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", stack.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(stack))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.ContainerStacks, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)

        for definition in self.findDefinitionContainers():
            try:
                data = definition.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", definition.getId())
                continue

            mime_type = self.getMimeTypeForContainer(type(definition))
            if mime_type is not None:
                file_name = urllib.parse.quote_plus(definition.getId()) + "." + mime_type.preferredSuffix
                path = Resources.getStoragePath(Resources.DefinitionContainers, file_name)
                with SaveFile(path, "wt") as f:
                    f.write(data)
Esempio n. 12
0
    def _onExit(self):
        for instance in ContainerRegistry.getInstance().findInstanceContainers(
        ):
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException(
                    "e", "An exception occurred when serializing container %s",
                    instance.getId())
                continue

            file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg"
            instance_type = instance.getMetaDataEntry("type")
            path = None
            if instance_type == "material":
                path = Resources.getStoragePath(
                    self.ResourceTypes.MaterialInstanceContainer, file_name)
            elif instance_type == "quality":
                path = Resources.getStoragePath(
                    self.ResourceTypes.QualityInstanceContainer, file_name)
            elif instance_type == "user":
                path = Resources.getStoragePath(
                    self.ResourceTypes.UserInstanceContainer, file_name)
            elif instance_type == "variant":
                path = Resources.getStoragePath(
                    self.ResourceTypes.VariantInstanceContainer, file_name)

            if path:
                with SaveFile(path, "wt", -1, "utf-8") as f:
                    f.write(data)

        for stack in ContainerRegistry.getInstance().findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException(
                    "e", "An exception occurred when serializing container %s",
                    instance.getId())
                continue

            file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg"
            path = Resources.getStoragePath(self.ResourceTypes.MachineStack,
                                            file_name)
            with SaveFile(path, "wt", -1, "utf-8") as f:
                f.write(data)
Esempio n. 13
0
    def saveSettings(self):
        if not self._started:  # Do not do saving during application start
            return

        self.waitConfigLockFile()

        # When starting Cura, we check for the lockFile which is created and deleted here
        with lockFile(self._config_lock_filename):

            for instance in ContainerRegistry.getInstance(
            ).findInstanceContainers():
                if not instance.isDirty():
                    continue

                try:
                    data = instance.serialize()
                except NotImplementedError:
                    continue
                except Exception:
                    Logger.logException(
                        "e",
                        "An exception occurred when serializing container %s",
                        instance.getId())
                    continue

                mime_type = ContainerRegistry.getMimeTypeForContainer(
                    type(instance))
                file_name = urllib.parse.quote_plus(
                    instance.getId()) + "." + mime_type.preferredSuffix
                instance_type = instance.getMetaDataEntry("type")
                path = None
                if instance_type == "material":
                    path = Resources.getStoragePath(
                        self.ResourceTypes.MaterialInstanceContainer,
                        file_name)
                elif instance_type == "quality" or instance_type == "quality_changes":
                    path = Resources.getStoragePath(
                        self.ResourceTypes.QualityInstanceContainer, file_name)
                elif instance_type == "user":
                    path = Resources.getStoragePath(
                        self.ResourceTypes.UserInstanceContainer, file_name)
                elif instance_type == "variant":
                    path = Resources.getStoragePath(
                        self.ResourceTypes.VariantInstanceContainer, file_name)
                elif instance_type == "definition_changes":
                    path = Resources.getStoragePath(
                        self.ResourceTypes.MachineStack, file_name)

                if path:
                    instance.setPath(path)
                    with SaveFile(path, "wt") as f:
                        f.write(data)

            for stack in ContainerRegistry.getInstance().findContainerStacks():
                self.saveStack(stack)
    def saveAll(self):

        for instance in self.findInstanceContainers():
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", instance.getId())
                continue

            file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg"
            path = Resources.getStoragePath(Resources.InstanceContainers, file_name)
            with SaveFile(path, "wt", -1, "utf-8") as f:
                f.write(data)

        for stack in self.findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", stack.getId())
                continue

            file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg"
            path = Resources.getStoragePath(Resources.ContainerStacks, file_name)
            with SaveFile(path, "wt", -1, "utf-8") as f:
                f.write(data)

        for definition in self.findDefinitionContainers():
            try:
                data = definition.serialize()
            except NotImplementedError:
                # Serializing is not supported so skip this container
                continue
            except Exception:
                Logger.logException("e", "An exception occurred trying to serialize container %s", instance.getId())
                continue

            file_name = urllib.parse.quote_plus(definition.getId()) + ".def.cfg"
            path = Resources.getStoragePath(Resources.DefinitionContainers, file_name)
            with SaveFile(path, "wt", -1, "utf-8") as f:
                f.write(data)
Esempio n. 15
0
    def _installPackage(self, installation_package_data: dict):
        package_info = installation_package_data["package_info"]
        filename = installation_package_data["filename"]

        package_id = package_info["package_id"]
        Logger.log("i", "Installing package [%s] from file [%s]", package_id, filename)

        # Load the cached package file and extract all contents to a temporary directory
        if not os.path.exists(filename):
            Logger.log("w", "Package [%s] file '%s' is missing, cannot install this package", package_id, filename)
            return
        try:
            with zipfile.ZipFile(filename, "r") as archive:
                temp_dir = tempfile.TemporaryDirectory()
                archive.extractall(temp_dir.name)
        except Exception:
            Logger.logException("e", "Failed to install package from file [%s]", filename)
            return

        from cura.CuraApplication import CuraApplication
        installation_dirs_dict = {
            "materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer),
            "qualities": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer),
            "plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins)),
        }

        # Remove it first and then install
        try:
            self._purgePackage(package_id)
        except:
            Logger.log("e", "There was an error deleting the package {package} during updating.".format(package = package_id))
            return

        # Copy the folders there
        for sub_dir_name, installation_root_dir in installation_dirs_dict.items():
            src_dir_path = os.path.join(temp_dir.name, "files", sub_dir_name)
            dst_dir_path = os.path.join(installation_root_dir, package_id)

            if not os.path.exists(src_dir_path):
                continue
            self.__installPackageFiles(package_id, src_dir_path, dst_dir_path)

        # Remove the file
        try:
            os.remove(filename)
        except Exception:
            Logger.log("w", "Tried to delete file [%s], but it failed", filename)

        # Move the info to the installed list of packages only when it succeeds
        self._installed_package_dict[package_id] = self._to_install_package_dict[package_id]
Esempio n. 16
0
    def saveMachineInstances(self):
        if self._active_machine:
            Preferences.getInstance().setValue("machines/active_instance",
                                               self._active_machine.getName())

        for instance in self._machine_instances:
            file_name = urllib.parse.quote_plus(instance.getName()) + ".cfg"
            instance.saveToFile(
                Resources.getStoragePath(Resources.MachineInstances,
                                         file_name))
            file_name = urllib.parse.quote_plus(
                instance.getName()) + ".curaprofile"
            instance.getWorkingProfile().saveToFile(
                Resources.getStoragePath(Resources.MachineInstanceProfiles,
                                         file_name))
Esempio n. 17
0
    def saveSettings(self):
        if not self._started: # Do not do saving during application start
            return

        for instance in ContainerRegistry.getInstance().findInstanceContainers():
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException("e", "An exception occurred when serializing container %s", instance.getId())
                continue

            file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg"
            instance_type = instance.getMetaDataEntry("type")
            path = None
            if instance_type == "material":
                path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name)
            elif instance_type == "quality":
                path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name)
            elif instance_type == "user":
                path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name)
            elif instance_type == "variant":
                path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name)

            if path:
                with SaveFile(path, "wt", -1, "utf-8") as f:
                    f.write(data)

        for stack in ContainerRegistry.getInstance().findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException("e", "An exception occurred when serializing container %s", instance.getId())
                continue

            file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg"
            path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name)
            with SaveFile(path, "wt", -1, "utf-8") as f:
                f.write(data)
Esempio n. 18
0
def test_loadLegacyFileRenamed(container_registry):
    #Create a temporary file for the registry to load.
    stacks_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks")
    temp_file = os.path.join(stacks_folder, "temporary.stack.cfg")
    temp_file_source = os.path.join(stacks_folder, "MachineLegacy.stack.cfg")
    shutil.copyfile(temp_file_source, temp_file)

    #Mock some dependencies.
    UM.Settings.ContainerStack.setContainerRegistry(container_registry)
    Resources.getAllResourcesOfType = unittest.mock.MagicMock(return_value = [temp_file]) #Return a temporary file that we'll make for this test.

    def findContainers(container_type = 0, id = None):
        if id == "MachineLegacy":
            return None

        container = UM.Settings.ContainerRegistry._EmptyInstanceContainer(id)
        container.getNextStack = unittest.mock.MagicMock()
        return [container]

    old_find_containers = container_registry.findContainers
    container_registry.findContainers = findContainers

    with unittest.mock.patch("cura.Settings.GlobalStack.GlobalStack.findContainer"):
        container_registry.load()

    container_registry.findContainers = old_find_containers

    container_registry.saveAll()
    print("all containers in registry", container_registry._containers)
    assert not os.path.isfile(temp_file)
    mime_type = container_registry.getMimeTypeForContainer(GlobalStack)
    file_name = urllib.parse.quote_plus("MachineLegacy") + "." + mime_type.preferredSuffix
    path = Resources.getStoragePath(Resources.ContainerStacks, file_name)
    assert os.path.isfile(path)
Esempio n. 19
0
    def _installPlugin(self, plugin_id: str, plugin_path: str) -> None:
        Logger.log("i", "Attempting to install a new plugin %s from file '%s'",
                   plugin_id, plugin_path)

        local_plugin_path = os.path.join(
            Resources.getStoragePath(Resources.Resources), "plugins")

        if plugin_id in self._bundled_plugin_cache:
            del self._bundled_plugin_cache[plugin_id]

        try:
            with zipfile.ZipFile(plugin_path, "r") as zip_ref:
                plugin_folder = os.path.join(local_plugin_path, plugin_id)

                # Overwrite the existing plugin if already installed
                if os.path.isdir(plugin_folder):
                    shutil.rmtree(plugin_folder, ignore_errors=True)
                os.makedirs(plugin_folder, exist_ok=True)

                # Extract all files
                for info in zip_ref.infolist():
                    extracted_path = zip_ref.extract(info.filename,
                                                     path=plugin_folder)
                    permissions = os.stat(extracted_path).st_mode
                    os.chmod(extracted_path, permissions
                             | stat.S_IEXEC)  # Make these files executable.
        except:  # Installing a new plugin should never crash the application.
            Logger.logException(
                "e",
                "An exception occurred while installing plugin {path}".format(
                    path=plugin_path))

        if plugin_id in self._disabled_plugins:
            self._disabled_plugins.remove(plugin_id)
Esempio n. 20
0
    def uninstallPlugin(self, plugin_id: str):
        Logger.log("d", "Uninstall plugin got ID: %s", plugin_id)
        plugin_folder = os.path.join(
            Resources.getStoragePath(Resources.Resources), "plugins")
        plugin_path = os.path.join(plugin_folder, plugin_id)
        Logger.log("i", "Attempting to uninstall %s", plugin_path)
        result = {"status": "error", "message": "", "id": plugin_id}
        success_message = i18n_catalog.i18nc(
            "@info:status",
            "The plugin has been removed.\nPlease re-start the application to finish uninstall."
        )

        try:
            shutil.rmtree(plugin_path)
        except:
            Logger.logException("d",
                                "An exception occurred while uninstalling %s",
                                plugin_path)

            result["message"] = i18n_catalog.i18nc(
                "@info:status", "Failed to uninstall plugin")
            return result

        result["status"] = "ok"
        result["message"] = success_message
        return result
Esempio n. 21
0
    def __init__(self, application, parent=None):
        super().__init__(parent)

        self._application = application
        self._container_registry = self._application.getContainerRegistry()
        self._plugin_registry = self._application.getPluginRegistry()

        #JSON files that keep track of all installed packages.
        self._user_package_management_file_path = None  #type: str
        self._bundled_package_management_file_path = None  #type: str
        for search_path in Resources.getSearchPaths():
            candidate_bundled_path = os.path.join(search_path,
                                                  "bundled_packages.json")
            if os.path.exists(candidate_bundled_path):
                self._bundled_package_management_file_path = candidate_bundled_path
        for search_path in (Resources.getDataStoragePath(),
                            Resources.getConfigStoragePath()):
            candidate_user_path = os.path.join(search_path, "packages.json")
            if os.path.exists(candidate_user_path):
                self._user_package_management_file_path = candidate_user_path
        if self._user_package_management_file_path is None:  #Doesn't exist yet.
            self._user_package_management_file_path = os.path.join(
                Resources.getDataStoragePath(), "packages.json")

        self._installation_dirs_dict = {
            "plugins":
            os.path.abspath(Resources.getStoragePath(Resources.Plugins))
        }  # type: Dict[str, str]

        self._bundled_package_dict = {}  # A dict of all bundled packages
        self._installed_package_dict = {}  # A dict of all installed packages
        self._to_remove_package_set = set(
        )  # A set of packages that need to be removed at the next start
        self._to_install_package_dict = {
        }  # A dict of packages that need to be installed at the next start
Esempio n. 22
0
    def adjust_theme(self):
        """
		Makes the tooltips wider, if displaying articles in the tooltips.
		"""
        # Previous versions of the Settings Guide may create a theme, which may become outdated in newer versions.
        # We need to remove it and widen the tooltips in a different way.
        application = CuraApplication.getInstance()
        preferences = application.getPreferences()
        preferences.addPreference(
            "general/theme",
            application.default_theme)  # May not exist yet at this point.
        current_theme = preferences.getValue("general/theme")
        if current_theme and current_theme.endswith("_settingsguideadjust"):
            preferences.setValue("general/theme",
                                 current_theme[:-len("_settingsguideadjust")])
        # Look for Settings Guide adjusted themes in the resources folder.
        theme_path = os.path.dirname(
            Resources.getStoragePath(Resources.Themes, ""))
        try:
            for theme_folder in os.listdir(theme_path):
                if theme_folder.endswith("_settingsguideadjust"):
                    shutil.rmtree(os.path.join(theme_path, theme_folder))
        except EnvironmentError as e:
            # Perhaps no rights? Well, just leave the extra theme in then. Nothing to be done about it.
            Logger.error(
                "Unable to remove Settings Guide deprecated theme: {err}".
                format(err=str(e)))
Esempio n. 23
0
    def saveContainer(self, container: "ContainerInterface") -> None:
        try:
            data = container.serialize()
        except NotImplementedError:
            return
        except Exception:
            Logger.logException("e", "An exception occurred when serializing container %s", container.getId())
            return

        mime_type = ContainerRegistry.getMimeTypeForContainer(type(container))
        file_name = urllib.parse.quote_plus(container.getId()) + "." + mime_type.preferredSuffix
        container_type = container.getMetaDataEntry("type")
        resource_types = ContainerRegistry.getInstance().getResourceTypes()
        if container_type in resource_types:
            path = Resources.getStoragePath(resource_types[container_type], file_name)
            with SaveFile(path, "wt") as f:
                f.write(data)
            container.setPath(path)
            # Register it internally as being saved
            self._id_to_path[container.getId()] = path
            self._id_to_mime[container.getId()] = self._pathToMime(path)
            base_file = container.getMetaData().get("base_file")
            if base_file:
                for container_md in ContainerRegistry.getInstance().findContainersMetadata(base_file = base_file):
                    self._id_to_path[container_md["id"]] = path
                    self._id_to_mime[container_md["id"]] = self._pathToMime(path)
        else:
            Logger.log("w", "Dirty container [%s] is not saved because the resource type is unknown in ContainerRegistry", container_type)
Esempio n. 24
0
    def _installPlugin(self, plugin_id: str, plugin_path: str) -> None:
        Logger.log("i", "Attempting to install a new plugin %s from file '%s'", plugin_id, plugin_path)

        local_plugin_path = os.path.join(Resources.getStoragePath(Resources.Resources), "plugins")

        if plugin_id in self._bundled_plugin_cache:
            del self._bundled_plugin_cache[plugin_id]

        try:
            with zipfile.ZipFile(plugin_path, "r") as zip_ref:
                plugin_folder = os.path.join(local_plugin_path, plugin_id)

                # Overwrite the existing plugin if already installed
                if os.path.isdir(plugin_folder):
                    shutil.rmtree(plugin_folder, ignore_errors = True)
                os.makedirs(plugin_folder, exist_ok = True)

                # Extract all files
                for info in zip_ref.infolist():
                    extracted_path = zip_ref.extract(info.filename, path = plugin_folder)
                    permissions = os.stat(extracted_path).st_mode
                    os.chmod(extracted_path, permissions | stat.S_IEXEC) # Make these files executable.
        except: # Installing a new plugin should never crash the application.
            Logger.logException("e", "An exception occurred while installing plugin {path}".format(path = plugin_path))

        if plugin_id in self._disabled_plugins:
            self._disabled_plugins.remove(plugin_id)
Esempio n. 25
0
    def __init__(self, image_reader):
        super(CDTUI, self).__init__()
        self.image_reader = image_reader
        self._ui_view = None
        self.show_config_ui_trigger.connect(self._actualShowConfigUI)
        self._aspect = 1

        self.closeTopButtonFace = True
        self.reversePathToration = False
        self.splitWord = False
        self.image_color_invert = False
        self._ui_lock = threading.Lock()
        self._cancelled = False
        self._disable_size_callbacks = False
        pkFile = os.path.join(
            os.path.join(Resources.getStoragePath(Resources.Resources),
                         'plugins'), 'CDTUI.pk')
        self._pkDat = []
        if os.path.exists(pkFile):

            try:
                self._pkDat = pickle.load(open(pkFile, 'rb'))
                if isinstance(self._pkDat, list) and len(self._pkDat) == 6:
                    self.peak_height = self._pkDat[0]
                    self._offset = self._pkDat[1]
                    self._slopeHeight = self._pkDat[2]
                    self.closeTopButtonFace = self._pkDat[3]
                    self.reversePathToration = self._pkDat[4]
                    self.splitWord = self._pkDat[5]
            except:
                None
Esempio n. 26
0
    def _createView(self):
        Logger.log("d", "Creating post processing plugin view.")

        ## Load all scripts in the scripts folders
        for root in [
                PluginRegistry.getInstance().getPluginPath(
                    "PostProcessingPlugin"),
                Resources.getStoragePath(Resources.Preferences)
        ]:
            path = os.path.join(root, "scripts")
            if not os.path.isdir(path):
                try:
                    os.makedirs(path)
                except OSError:
                    Logger.log(
                        "w", "Unable to create a folder for scripts: " + path)
                    continue

            self.loadAllScripts(path)

        # Create the plugin dialog component
        path = os.path.join(
            PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"),
            "PostProcessingPlugin.qml")
        self._view = Application.getInstance().createQmlComponent(
            path, {"manager": self})
        Logger.log("d", "Post processing view created.")

        # Create the save button component
        Application.getInstance().addAdditionalComponent(
            "saveButton",
            self._view.findChild(QObject, "postProcessingSaveAreaButton"))
Esempio n. 27
0
    def loadAllScripts(self) -> None:
        """Load all scripts from all paths where scripts can be found.

        This should probably only be done on init.
        """

        if self._loaded_scripts:  # Already loaded.
            return

        # The PostProcessingPlugin path is for built-in scripts.
        # The Resources path is where the user should store custom scripts.
        # The Preferences path is legacy, where the user may previously have stored scripts.
        resource_folders = [
            PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"),
            Resources.getStoragePath(Resources.Preferences)
        ]
        resource_folders.extend(
            Resources.getAllPathsForType(Resources.Resources))
        for root in resource_folders:
            if root is None:
                continue
            path = os.path.join(root, "scripts")
            if not os.path.isdir(path):
                try:
                    os.makedirs(path)
                except OSError:
                    Logger.log(
                        "w", "Unable to create a folder for scripts: " + path)
                    continue

            self.loadScripts(path)
Esempio n. 28
0
    def windowClosed(self):
        Logger.log("d", "Shutting down %s", self.getApplicationName())
        try:
            self.getMachineManager().saveAll()
        except Exception as e:
            Logger.log("e", "Exception while saving machines: %s", repr(e))

        try:
            Preferences.getInstance().writeToFile(
                Resources.getStoragePath(Resources.Preferences,
                                         self.getApplicationName() + ".cfg"))
        except Exception as e:
            Logger.log("e", "Exception while saving preferences: %s", repr(e))

        try:
            self.applicationShuttingDown.emit()
        except Exception as e:
            Logger.log("e", "Exception while emitting shutdown signal: %s",
                       repr(e))

        try:
            self.getBackend().close()
        except Exception as e:
            Logger.log("e", "Exception while closing backend: %s", repr(e))

        self.quit()
Esempio n. 29
0
def test_loadLegacyFileRenamed(container_registry):
    #Create a temporary file for the registry to load.
    stacks_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks")
    temp_file = os.path.join(stacks_folder, "temporary.stack.cfg")
    temp_file_source = os.path.join(stacks_folder, "MachineLegacy.stack.cfg")
    shutil.copyfile(temp_file_source, temp_file)

    #Mock some dependencies.
    UM.Settings.ContainerStack.setContainerRegistry(container_registry)
    Resources.getAllResourcesOfType = unittest.mock.MagicMock(return_value = [temp_file]) #Return a temporary file that we'll make for this test.

    def findContainers(container_type = 0, id = None):
        if id == "MachineLegacy":
            return None

        container = UM.Settings.ContainerRegistry._EmptyInstanceContainer(id)
        container.getNextStack = unittest.mock.MagicMock()
        return [container]

    old_find_containers = container_registry.findContainers
    container_registry.findContainers = findContainers

    with unittest.mock.patch("cura.Settings.GlobalStack.GlobalStack.findContainer"):
        container_registry.load()

    container_registry.findContainers = old_find_containers

    container_registry.saveAll()
    print("all containers in registry", container_registry._containers)
    assert not os.path.isfile(temp_file)
    mime_type = container_registry.getMimeTypeForContainer(GlobalStack)
    file_name = urllib.parse.quote_plus("MachineLegacy") + "." + mime_type.preferredSuffix
    path = Resources.getStoragePath(Resources.ContainerStacks, file_name)
    assert os.path.isfile(path)
Esempio n. 30
0
    def windowClosed(self, save_data: bool = True) -> None:
        Logger.log("d", "Shutting down %s", self.getApplicationName())
        self._shutting_down = True

        if save_data:
            try:
                Preferences.getInstance().writeToFile(
                    Resources.getStoragePath(
                        Resources.Preferences,
                        self.getApplicationName() + ".cfg"))
            except Exception as e:
                Logger.log("e", "Exception while saving preferences: %s",
                           repr(e))

        try:
            self.applicationShuttingDown.emit()
        except Exception as e:
            Logger.log("e", "Exception while emitting shutdown signal: %s",
                       repr(e))

        try:
            self.getBackend().close()
        except Exception as e:
            Logger.log("e", "Exception while closing backend: %s", repr(e))

        self.quit()
    def _saveCachedDefinition(self, definition: DefinitionContainer) -> None:
        cache_path = Resources.getStoragePath(
            Resources.Cache, "definitions",
            Application.getInstance().getVersion(), definition.id)

        # Ensure the cache path exists.
        try:
            os.makedirs(os.path.dirname(cache_path), exist_ok=True)
        except PermissionError:
            Logger.log(
                "w",
                "The definition cache for definition {definition_id} failed to save because you don't have permissions to write in the cache directory."
                .format(definition_id=definition.getId()))
            return  # No rights to save it. Better give up.

        try:
            with open(cache_path, "wb") as f:
                pickle.dump(definition, f, pickle.HIGHEST_PROTOCOL)
        except RecursionError:
            # Sometimes a recursion error in pickling occurs here.
            # The cause is unknown. It must be some circular reference in the definition instances or definition containers.
            # Instead of saving a partial cache and raising an exception, simply fail to save the cache.
            # See CURA-4024.
            Logger.log(
                "w",
                "The definition cache for definition {definition_id} failed to pickle."
                .format(definition_id=definition.getId()))
            if os.path.exists(cache_path):
                os.remove(
                    cache_path
                )  # The pickling might be half-complete, which causes EOFError in Pickle when you load it later.
Esempio n. 32
0
    def __init__(self,
                 application: "QtApplication",
                 parent: Optional[QObject] = None) -> None:
        super().__init__(parent)

        self._application = application
        self._container_registry = self._application.getContainerRegistry()
        self._plugin_registry = self._application.getPluginRegistry()

        # JSON files that keep track of all installed packages.
        self._user_package_management_file_path = None  # type: Optional[str]
        self._bundled_package_management_file_paths = []  # type: List[str]
        for search_path in Resources.getAllPathsForType(
                Resources.BundledPackages):
            if not os.path.isdir(search_path):
                continue

            # Load all JSON files that are located in the bundled_packages directory.
            for file_name in os.listdir(search_path):
                if not file_name.endswith(".json"):
                    continue
                file_path = os.path.join(search_path, file_name)
                if not os.path.isfile(file_path):
                    continue
                self._bundled_package_management_file_paths.append(file_path)
                Logger.log(
                    "i", "Found bundled packages JSON file: {location}".format(
                        location=file_path))

        for search_path in (Resources.getDataStoragePath(),
                            Resources.getConfigStoragePath()):
            candidate_user_path = os.path.join(search_path, "packages.json")
            if os.path.exists(candidate_user_path):
                self._user_package_management_file_path = candidate_user_path
        if self._user_package_management_file_path is None:  # Doesn't exist yet.
            self._user_package_management_file_path = os.path.join(
                Resources.getDataStoragePath(), "packages.json")

        self._installation_dirs_dict = {
            "plugins":
            os.path.abspath(Resources.getStoragePath(Resources.Plugins))
        }  # type: Dict[str, str]

        self._bundled_package_dict = {
        }  # type: Dict[str, Dict[str, Any]] # A dict of all bundled packages
        self._installed_package_dict = {
        }  # type: Dict[str, Dict[str, Any]] # A dict of all installed packages
        self._to_remove_package_set = set(
        )  # type: Set[str] # A set of packages that need to be removed at the next start
        self._to_install_package_dict = {
        }  # type: Dict[str, Dict[str, Any]]  # A dict of packages that need to be installed at the next start
        self._dismissed_packages = set(
        )  # type: Set[str] # A set of packages that are dismissed by the user

        # There can be plugins that provide remote packages (and thus, newer / different versions for a package).
        self._available_package_versions = {
        }  # type: Dict[str, Set[UMVersion]]

        self._packages_with_update_available = set()  # type: Set[str]
Esempio n. 33
0
    def _saveCachedDefinition(self, definition):
        cache_path = Resources.getStoragePath(Resources.Cache, "definitions", self.getApplication().getVersion(), definition.id)

        # Ensure the cache path exists
        os.makedirs(os.path.dirname(cache_path), exist_ok=True)

        with open(cache_path, "wb") as f:
            pickle.dump(definition, f)
Esempio n. 34
0
 def windowClosed(self):
     self.getMachineManager().saveAll()
     Preferences.getInstance().writeToFile(
         Resources.getStoragePath(Resources.Preferences,
                                  self.getApplicationName() + ".cfg"))
     self.applicationShuttingDown.emit()
     self.getBackend().close()
     self.quit()
Esempio n. 35
0
    def _saveCachedDefinition(self, definition):
        cache_path = Resources.getStoragePath(Resources.Cache, "definitions", self.getApplication().getVersion(), definition.id)

        # Ensure the cache path exists
        os.makedirs(os.path.dirname(cache_path), exist_ok=True)

        with open(cache_path, "wb") as f:
            pickle.dump(definition, f)
Esempio n. 36
0
    def _removePlugin(self, plugin_id: str) -> None:
        plugin_folder = os.path.join(
            Resources.getStoragePath(Resources.Resources), "plugins")
        plugin_path = os.path.join(plugin_folder, plugin_id)

        Logger.log("i", "Attempting to remove plugin '%s' from directory '%s'",
                   plugin_id, plugin_path)
        shutil.rmtree(plugin_path)
Esempio n. 37
0
    def getLockFilename(self) -> str:
        """Get the lock filename including full path
        Dependent on when you call this function, Resources.getConfigStoragePath may return different paths
        """

        return Resources.getStoragePath(
            Resources.Resources,
            self._application.getApplicationLockFilename())
Esempio n. 38
0
    def installPlugin(self, plugin_path: str):
        Logger.log("d", "Install plugin got path: %s", plugin_path)
        plugin_path = QUrl(plugin_path).toLocalFile()
        Logger.log("i", "Attempting to install a new plugin %s", plugin_path)
        local_plugin_path = os.path.join(Resources.getStoragePath(Resources.Resources), "plugins")
        plugin_folder = ""
        result = {"status": "error", "message": "", "id": ""}
        success_message = i18n_catalog.i18nc("@info:status", "The plugin has been installed.\nPlease re-start the application to activate the plugin.")

        try:
            with zipfile.ZipFile(plugin_path, "r") as zip_ref:
                plugin_id = None
                for file in zip_ref.infolist():
                    if file.filename.endswith("/"):
                        plugin_id = file.filename.strip("/")
                        break

                if plugin_id is None:
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install plugin from <filename>{0}</filename>:\n<message>{1}</message>", plugin_path, "Invalid plugin file")
                    return result
                result["id"] = plugin_id
                plugin_folder = os.path.join(local_plugin_path, plugin_id)

                if os.path.isdir(plugin_folder):  # Plugin is already installed by user (so not a bundled plugin)
                    metadata = {}
                    with zip_ref.open(plugin_id + "/plugin.json") as metadata_file:
                        metadata = json.loads(metadata_file.read().decode("utf-8"))

                    if "version" in metadata:
                        new_version = Version(metadata["version"])
                        old_version = Version(self.getMetaData(plugin_id)["plugin"]["version"])
                        if new_version > old_version:
                            zip_ref.extractall(plugin_folder)
                            result["status"] = "ok"
                            result["message"] = success_message
                            return result

                    Logger.log("w", "The plugin was already installed. Unable to install it again!")
                    result["status"] = "duplicate"
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install the plugin;\n<message>{0}</message>", "Plugin was already installed")
                    return result
                elif plugin_id in self._plugins:
                    # Plugin is already installed, but not by the user (eg; this is a bundled plugin)
                    # TODO: Right now we don't support upgrading bundled plugins at all, but we might do so in the future.
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install the plugin;\n<message>{0}</message>", "Unable to upgrade or install bundled plugins.")
                    return result

                zip_ref.extractall(plugin_folder)

        except: # Installing a new plugin should never crash the application.
            Logger.logException("d", "An exception occurred while installing plugin {path}".format(path = plugin_path))

            result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install plugin from <filename>{0}</filename>:\n<message>{1}</message>", plugin_folder, "Invalid plugin file")
            return result

        result["status"] = "ok"
        result["message"] = success_message
        return result
Esempio n. 39
0
    def installPlugin(self, plugin_path: str):
        plugin_path = QUrl(plugin_path).toLocalFile()
        Logger.log("d", "Attempting to install a new plugin %s", plugin_path)
        local_plugin_path = os.path.join(Resources.getStoragePath(Resources.Resources), "plugins")
        plugin_folder = ""
        result = {"status": "error", "message": "", "id": ""}
        success_message = i18n_catalog.i18nc("@info:status", "The plugin has been installed.\n Please re-start the application to activate the plugin.")

        try:
            with zipfile.ZipFile(plugin_path, "r") as zip_ref:
                plugin_id = None
                for file in zip_ref.infolist():
                    if file.filename.endswith("/"):
                        plugin_id = file.filename.strip("/")
                        break

                if plugin_id is None:
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install plugin from <filename>{0}</filename>:\n<message>{1}</message>", plugin_path, "Invalid plugin file")
                    return result
                result["id"] = plugin_id
                plugin_folder = os.path.join(local_plugin_path, plugin_id)

                if os.path.isdir(plugin_folder):  # Plugin is already installed by user (so not a bundled plugin)
                    metadata = {}
                    with zip_ref.open(plugin_id + "/plugin.json") as metadata_file:
                        metadata = json.loads(metadata_file.read().decode("utf-8"))

                    if "version" in metadata:
                        new_version = Version(metadata["version"])
                        old_version = Version(self.getMetaData(plugin_id)["plugin"]["version"])
                        if new_version > old_version:
                            zip_ref.extractall(plugin_folder)
                            result["status"] = "ok"
                            result["message"] = success_message
                            return result

                    Logger.log("w", "The plugin was already installed. Unable to install it again!")
                    result["status"] = "duplicate"
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install the plugin; \n<message>{0}</message>", "Plugin was already installed")
                    return result
                elif plugin_id in self._plugins:
                    # Plugin is already installed, but not by the user (eg; this is a bundled plugin)
                    # TODO: Right now we don't support upgrading bundled plugins at all, but we might do so in the future.
                    result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install the plugin; \n<message>{0}</message>", "Unable to upgrade or instal bundled plugins.")
                    return result

                zip_ref.extractall(plugin_folder)

        except: # Installing a new plugin should never crash the application.
            Logger.logException("d", "An exception occurred while installing plugin ")

            result["message"] = i18n_catalog.i18nc("@info:status", "Failed to install plugin from <filename>{0}</filename>:\n<message>{1}</message>", plugin_folder, "Invalid plugin file")
            return result

        result["status"] = "ok"
        result["message"] = success_message
        return result
Esempio n. 40
0
    def _onProfileNameChanged(self, profile, old_name):
        file_name = urllib.parse.quote_plus(old_name) + ".cfg"
        try:
            path = Resources.getStoragePath(Resources.Profiles, file_name)
            os.remove(path)
        except FileNotFoundError:
            pass

        self.profileNameChanged.emit(profile)
Esempio n. 41
0
    def _onInstanceNameChanged(self, instance, old_name):
        file_name = urllib.parse.quote_plus(old_name) + ".cfg"
        try:
            path = Resources.getStoragePath(Resources.MachineInstances, file_name)
            os.remove(path)
        except FileNotFoundError:
            pass

        self.machineInstanceNameChanged.emit(instance)
Esempio n. 42
0
    def _removePlugin(self, plugin_id: str) -> None:
        plugin_folder = os.path.join(Resources.getStoragePath(Resources.Resources), "plugins")
        plugin_path = os.path.join(plugin_folder, plugin_id)

        if plugin_id in self._bundled_plugin_cache:
            del self.bundled_plugin_cache[plugin_id]

        Logger.log("i", "Attempting to remove plugin '%s' from directory '%s'", plugin_id, plugin_path)
        shutil.rmtree(plugin_path)
Esempio n. 43
0
    def __init__(self, file_name):
        super().__init__()
        self._logger =  logging.getLogger(self._name)  # Create python logger
        self._logger.setLevel(logging.DEBUG)

        # Do not try to save to the app dir as it may not be writeable or may not be the right
        # location to save the log file. Instead, try and save in the settings location since
        # that should be writeable.
        self.setFileName(Resources.getStoragePath(Resources.Resources, file_name))
Esempio n. 44
0
    def _onTimeout(self):
        self._saving = True # To prevent the save process from triggering another autosave.
        Logger.log("d", "Autosaving preferences, instances and profiles")

        Application.getInstance().saveSettings()

        Preferences.getInstance().writeToFile(Resources.getStoragePath(Resources.Preferences, Application.getInstance().getApplicationName() + ".cfg"))

        self._saving = False
Esempio n. 45
0
    def saveProfiles(self):
        try:
            for profile in self._profiles:
                if profile.isReadOnly() or not profile.hasChangedSettings():
                    continue

                file_name = urllib.parse.quote_plus(profile.getName()) + ".cfg"
                profile.saveToFile(Resources.getStoragePath(Resources.Profiles, file_name))
        except AttributeError:
            pass
Esempio n. 46
0
    def removeMachine(self, machine):
        self._machines.remove(machine)

        try:
            path = Resources.getStoragePath(Resources.SettingsLocation, urllib.parse.quote_plus(machine.getName()) + ".cfg")
            os.remove(path)
        except FileNotFoundError:
            pass

        self.machinesChanged.emit()
Esempio n. 47
0
    def _installPackage(self, installation_package_data: dict):
        package_info = installation_package_data["package_info"]
        filename = installation_package_data["filename"]

        package_id = package_info["package_id"]

        if not os.path.exists(filename):
            Logger.log("w", "Package [%s] file '%s' is missing, cannot install this package", package_id, filename)
            return

        Logger.log("i", "Installing package [%s] from file [%s]", package_id, filename)

        # If it's installed, remove it first and then install
        if package_id in self._installed_package_dict:
            self._purgePackage(package_id)

        # Install the package
        with zipfile.ZipFile(filename, "r") as archive:

            temp_dir = tempfile.TemporaryDirectory()
            archive.extractall(temp_dir.name)

            from cura.CuraApplication import CuraApplication
            installation_dirs_dict = {
                "materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer),
                "quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer),
                "plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins)),
            }

            for sub_dir_name, installation_root_dir in installation_dirs_dict.items():
                src_dir_path = os.path.join(temp_dir.name, "files", sub_dir_name)
                dst_dir_path = os.path.join(installation_root_dir, package_id)

                if not os.path.exists(src_dir_path):
                    continue

                # Need to rename the container files so they don't get ID conflicts
                to_rename_files = sub_dir_name not in ("plugins",)
                self.__installPackageFiles(package_id, src_dir_path, dst_dir_path, need_to_rename_files= to_rename_files)

        # Remove the file
        os.remove(filename)
Esempio n. 48
0
    def __init__(self, file_name: str) -> None:
        super().__init__()
        self._logger = logging.getLogger(self._name)  # Create python logger
        self._logger.setLevel(logging.DEBUG)
        self._show_once = set()  # type: Set[str]

        # Do not try to save to the app dir as it may not be writeable or may not be the right
        # location to save the log file. Instead, try and save in the settings location since
        # that should be writeable.
        self.setFileName(Resources.getStoragePath(Resources.Resources, file_name))
        VersionUpgradeManager.getInstance().registerIgnoredFile(file_name)
Esempio n. 49
0
 def __init__(self, file_name):
     super().__init__()
     self._logger =  logging.getLogger(self._name) #Create python logger 
     self._logger.setLevel(logging.DEBUG)
     
     if hasattr(sys, "frozen"):
         # Running in py2exe or py2app context, do not try to save to the app dir as it may not be writeable.
         # instead, try and save in the settings location since that should be writeable.
         self.setFileName(Resources.getStoragePath(Resources.Resources, file_name))
     else:
         self.setFileName(file_name)
Esempio n. 50
0
    def saveProfiles(self):
        try:
            Preferences.getInstance().setValue("machines/active_profile", self._active_profile.getName())
            for profile in self._profiles:
                if profile.isReadOnly():
                    continue

                file_name = urllib.parse.quote_plus(profile.getName()) + ".cfg"
                profile.saveToFile(Resources.getStoragePath(Resources.Profiles, file_name))
        except AttributeError:
            pass
Esempio n. 51
0
    def saveSettings(self):
        if not self._started: # Do not do saving during application start
            return

        self.waitConfigLockFile()

        # When starting Cura, we check for the lockFile which is created and deleted here
        with lockFile(self._config_lock_filename):

            for instance in ContainerRegistry.getInstance().findInstanceContainers():
                if not instance.isDirty():
                    continue

                try:
                    data = instance.serialize()
                except NotImplementedError:
                    continue
                except Exception:
                    Logger.logException("e", "An exception occurred when serializing container %s", instance.getId())
                    continue

                mime_type = ContainerRegistry.getMimeTypeForContainer(type(instance))
                file_name = urllib.parse.quote_plus(instance.getId()) + "." + mime_type.preferredSuffix
                instance_type = instance.getMetaDataEntry("type")
                path = None
                if instance_type == "material":
                    path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name)
                elif instance_type == "quality" or instance_type == "quality_changes":
                    path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name)
                elif instance_type == "user":
                    path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name)
                elif instance_type == "variant":
                    path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name)

                if path:
                    instance.setPath(path)
                    with SaveFile(path, "wt") as f:
                        f.write(data)

            for stack in ContainerRegistry.getInstance().findContainerStacks():
                self.saveStack(stack)
Esempio n. 52
0
    def loadProfiles(self):
        storage_path = Resources.getStoragePathForType(Resources.Profiles)

        dirs = Resources.getAllPathsForType(Resources.Profiles)
        for dir in dirs:
            if not os.path.isdir(dir):
                continue

            read_only = dir != storage_path

            for root, dirs, files in os.walk(dir):
                for file_name in files:
                    path = os.path.join(root, file_name)

                    if os.path.isdir(path):
                        continue

                    profile = Profile(self, read_only)
                    try:
                        profile.loadFromFile(path)
                    except Exception as e:
                        Logger.log("e", "An exception occurred loading Profile %s: %s", path, str(e))
                        continue

                    if not self.findProfile(profile.getName(), variant_name = profile.getMachineVariantName(), material_name = profile.getMaterialName(), instance = self._active_machine):
                        self._profiles.append(profile)
                        profile.nameChanged.connect(self._onProfileNameChanged)

        for instance in self._machine_instances:
            try:
                file_name = urllib.parse.quote_plus(instance.getName()) + ".curaprofile"
                instance.getWorkingProfile().loadFromFile(Resources.getStoragePath(Resources.MachineInstanceProfiles, file_name))
            except Exception as e:
                Logger.log("w", "Could not load working profile: %s: %s", file_name, str(e))
                self._setDefaultVariantMaterialProfile(instance)

        self._protect_working_profile = True

        if self._active_machine:
            profile_name = self._active_machine.getActiveProfileName()
            if profile_name == "":
                profile_name = "Normal Quality"

            profile = self.findProfile(self._active_machine.getActiveProfileName(), instance = self._active_machine)
            if profile:
                self.setActiveProfile(profile)
            else:
                profiles = self.getProfiles(instance = self._active_machine)
                if len(profiles) > 0:
                    self.setActiveProfile(profiles[0])

        self.profilesChanged.emit()
        self._protect_working_profile = False
Esempio n. 53
0
    def saveSettings(self):
        if not self._started: # Do not do saving during application start
            return

        for instance in ContainerRegistry.getInstance().findInstanceContainers():
            if not instance.isDirty():
                continue

            try:
                data = instance.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException("e", "An exception occurred when serializing container %s", instance.getId())
                continue

            mime_type = ContainerRegistry.getMimeTypeForContainer(type(instance))
            file_name = urllib.parse.quote_plus(instance.getId()) + "." + mime_type.preferredSuffix
            instance_type = instance.getMetaDataEntry("type")
            path = None
            if instance_type == "material":
                path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name)
            elif instance_type == "quality" or instance_type == "quality_changes":
                path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name)
            elif instance_type == "user":
                path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name)
            elif instance_type == "variant":
                path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name)

            if path:
                instance.setPath(path)
                with SaveFile(path, "wt", -1, "utf-8") as f:
                    f.write(data)

        for stack in ContainerRegistry.getInstance().findContainerStacks():
            if not stack.isDirty():
                continue

            try:
                data = stack.serialize()
            except NotImplementedError:
                continue
            except Exception:
                Logger.logException("e", "An exception occurred when serializing container %s", instance.getId())
                continue

            mime_type = ContainerRegistry.getMimeTypeForContainer(type(stack))
            file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix
            stack_type = stack.getMetaDataEntry("type", None)
            path = None
            if not stack_type or stack_type == "machine":
                path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name)
            elif stack_type == "extruder_train":
                path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name)
            if path:
                stack.setPath(path)
                with SaveFile(path, "wt", -1, "utf-8") as f:
                    f.write(data)
Esempio n. 54
0
    def removeMachineInstance(self, instance):
        if instance not in self._machine_instances:
            return

        self._machine_instances.remove(instance)
        instance.nameChanged.disconnect(self._onInstanceNameChanged)

        file_name = urllib.parse.quote_plus(instance.getName())
        try:
            path = Resources.getStoragePath(Resources.MachineInstances, file_name + ".cfg")
            os.remove(path)
            path = Resources.getStoragePath(Resources.MachineInstanceProfiles, file_name + ".cfg")
            os.remove(path)
        except FileNotFoundError:
            pass

        self.machineInstancesChanged.emit()

        if self._active_machine == instance:
            try:
                self.setActiveMachineInstance(self._machine_instances[0])
            except:
                self.setActiveMachineInstance(None)
Esempio n. 55
0
    def saveStack(self, stack):
        if not stack.isDirty():
            return
        try:
            data = stack.serialize()
        except NotImplementedError:
            return
        except Exception:
            Logger.logException("e", "An exception occurred when serializing container %s", stack.getId())
            return

        mime_type = ContainerRegistry.getMimeTypeForContainer(type(stack))
        file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix
        stack_type = stack.getMetaDataEntry("type", None)
        path = None
        if not stack_type or stack_type == "machine":
            path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name)
        elif stack_type == "extruder_train":
            path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name)
        if path:
            stack.setPath(path)
            with SaveFile(path, "wt") as f:
                f.write(data)
Esempio n. 56
0
    def _onTimeout(self):
        Logger.log("d", "Autosaving preferences, instances and profiles")

        if self._save_preferences:
            Preferences.getInstance().writeToFile(Resources.getStoragePath(Resources.Preferences, Application.getInstance().getApplicationName() + ".cfg"))

        if self._save_instances:
            Application.getInstance().getMachineManager().saveMachineInstances()

        if self._save_profiles:
            Application.getInstance().getMachineManager().saveProfiles()

        self._save_preferences = False
        self._save_instances = False
        self._save_profiles = False
Esempio n. 57
0
    def removeProfile(self, profile):
        if profile not in self._profiles:
            return

        self._profiles.remove(profile)
        profile.nameChanged.disconnect(self._onProfileNameChanged)

        try:
            path = Resources.getStoragePath(Resources.Profiles, urllib.parse.quote_plus(profile.getName()) + ".cfg")
            os.remove(path)
        except FileNotFoundError:
            pass

        self.profilesChanged.emit()

        if profile == self._active_profile:
            self.setActiveProfile(self._profiles[0])
Esempio n. 58
0
    def _saveCachedDefinition(self, definition: DefinitionContainer):
        cache_path = Resources.getStoragePath(Resources.Cache, "definitions", self._application.getVersion(), definition.id)

        # Ensure the cache path exists
        os.makedirs(os.path.dirname(cache_path), exist_ok=True)

        try:
            with open(cache_path, "wb") as f:
                pickle.dump(definition, f, pickle.HIGHEST_PROTOCOL)
        except RecursionError:
            #Sometimes a recursion error in pickling occurs here.
            #The cause is unknown. It must be some circular reference in the definition instances or definition containers.
            #Instead of saving a partial cache and raising an exception, simply fail to save the cache.
            #See CURA-4024.
            Logger.log("w", "The definition cache for definition {definition_id} failed to pickle.".format(definition_id = definition.getId()))
            if os.path.exists(cache_path):
                os.remove(cache_path) #The pickling might be half-complete, which causes EOFError in Pickle when you load it later.
Esempio n. 59
0
    def _deleteFiles(self, container):
        for resource_type in self._resource_types:
            mime_type_name = ""
            for name, container_type in self.__mime_type_map.items():
                if container_type == container.__class__:
                    mime_type_name = name
                    break
            else:
                return

            mime_type = MimeTypeDatabase.getMimeType(mime_type_name)

            for suffix in mime_type.suffixes:
                try:
                    path = Resources.getStoragePath(resource_type, urllib.parse.quote_plus(container.getId()) + "." + suffix)
                    if os.path.isfile(path):
                        os.remove(path)
                except Exception:
                    continue
Esempio n. 60
0
    def __init__(self, application: "QtApplication", parent: Optional[QObject] = None) -> None:
        super().__init__(parent)

        self._application = application
        self._container_registry = self._application.getContainerRegistry()
        self._plugin_registry = self._application.getPluginRegistry()

        # JSON files that keep track of all installed packages.
        self._user_package_management_file_path = None  # type: Optional[str]
        self._bundled_package_management_file_paths = []  # type: List[str]
        for search_path in Resources.getAllPathsForType(Resources.BundledPackages):
            if not os.path.isdir(search_path):
                continue

            # Load all JSON files that are located in the bundled_packages directory.
            for file_name in os.listdir(search_path):
                if not file_name.endswith(".json"):
                    continue
                file_path = os.path.join(search_path, file_name)
                if not os.path.isfile(file_path):
                    continue
                self._bundled_package_management_file_paths.append(file_path)
                Logger.log("i", "Found bundled packages JSON file: {location}".format(location = file_path))

        for search_path in (Resources.getDataStoragePath(), Resources.getConfigStoragePath()):
            candidate_user_path = os.path.join(search_path, "packages.json")
            if os.path.exists(candidate_user_path):
                self._user_package_management_file_path = candidate_user_path
        if self._user_package_management_file_path is None:  # Doesn't exist yet.
            self._user_package_management_file_path = os.path.join(Resources.getDataStoragePath(), "packages.json")

        self._installation_dirs_dict = {"plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins))}  # type: Dict[str, str]

        self._bundled_package_dict = {}  # type: Dict[str, Dict[str, Any]] # A dict of all bundled packages
        self._installed_package_dict = {}  # type: Dict[str, Dict[str, Any]] # A dict of all installed packages
        self._to_remove_package_set = set()  # type: Set[str] # A set of packages that need to be removed at the next start
        self._to_install_package_dict = {}  # type: Dict[str, Dict[str, Any]]  # A dict of packages that need to be installed at the next start

        # There can be plugins that provide remote packages (and thus, newer / different versions for a package).
        self._available_package_versions = {}  # type: Dict[str, Set[UMVersion]]

        self._packages_with_update_available = set()  # type: Set[str]