Ejemplo n.º 1
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)
Ejemplo n.º 2
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))
        VersionUpgradeManager.getInstance().registerIgnoredFile(file_name)
Ejemplo n.º 3
0
 def __updateSerialized(self, serialized: str) -> str:
     configuration_type = "preferences"
     try:
         from UM.VersionUpgradeManager import VersionUpgradeManager
         version = VersionUpgradeManager.getInstance().getFileVersion(configuration_type, serialized)
         if version is not None:
             result = VersionUpgradeManager.getInstance().updateFilesData(configuration_type, version, [serialized], [""])
             if result is not None:
                 serialized = result.files_data[0]
     except:
         Logger.logException("d", "An exception occurred while trying to update the preferences.")
     return serialized
Ejemplo n.º 4
0
    def __updateSerialized(self, serialized: str) -> str:
        configuration_type = "preferences"

        try:
            from UM.VersionUpgradeManager import VersionUpgradeManager
            version = VersionUpgradeManager.getInstance().getFileVersion(configuration_type, serialized)
            if version is not None:
                result = VersionUpgradeManager.getInstance().updateFilesData(configuration_type, version, [serialized], [""])
                if result is not None:
                    serialized = result.files_data[0]
        except:
            Logger.logException("d", "An exception occurred while trying to update the preferences.")
        return serialized
Ejemplo n.º 5
0
    def initialize(self, check_if_trusted: bool = False) -> None:
        super().initialize()

        preferences = Application.getInstance().getPreferences()
        if check_if_trusted:
            # Need to do this before the preferences are read for the first time, but after obj-creation, which is here.
            preferences.indicateUntrustedPreference("general", "theme",
                                                    lambda value: self._isPathSecure(Resources.getPath(Resources.Themes, value)))
            preferences.indicateUntrustedPreference("backend", "location",
                                                    lambda value: self._isPathSecure(os.path.abspath(value)))
        preferences.addPreference("view/force_empty_shader_cache", False)
        preferences.addPreference("view/opengl_version_detect", OpenGLContext.OpenGlVersionDetect.Autodetect)

        # Read preferences here (upgrade won't work) to get:
        #  - The language in use, so the splash window can be shown in the correct language.
        #  - The OpenGL 'force' parameters.
        try:
            self.readPreferencesFromConfiguration()
        except FileNotFoundError:
            Logger.log("i", "Preferences file not found, ignore and use default language '%s'", self._default_language)

        # Initialize the package manager to remove and install scheduled packages.
        self._package_manager = self._package_manager_class(self, parent = self)

        # If a plugin is removed, check if the matching package is also removed.
        self._plugin_registry.pluginRemoved.connect(lambda plugin_id: self._package_manager.removePackage(plugin_id))

        self._mesh_file_handler = MeshFileHandler(self) #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(self) #type: WorkspaceFileHandler

        if preferences.getValue("view/force_empty_shader_cache"):
            self.setAttribute(Qt.ApplicationAttribute.AA_DisableShaderDiskCache)
        if preferences.getValue("view/opengl_version_detect") != OpenGLContext.OpenGlVersionDetect.ForceModern:
            major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion(
                preferences.getValue("view/opengl_version_detect") == OpenGLContext.OpenGlVersionDetect.ForceLegacy)
        else:
            Logger.info("Force 'modern' OpenGL (4.1 core) -- overrides 'force legacy opengl' preference.")
            major_version, minor_version, profile = (4, 1, QSurfaceFormat.OpenGLContextProfile.CoreProfile)

        if major_version is None or minor_version is None or profile is None:
            Logger.log("e", "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting")
            if not self.getIsHeadLess():
                QMessageBox.critical(None, "Failed to probe OpenGL",
                                     "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers.")
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(major_version, minor_version, profile)
            Logger.log("d", "Detected most suitable OpenGL context version: %s", opengl_version_str)
        if not self.getIsHeadLess():
            OpenGLContext.setDefaultFormat(major_version, minor_version, profile = profile)

        self._qml_import_paths.append(os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 6
0
    def _upgradeProfileVersion(self, serialized: str, profile_id: str,
                               main_version: int,
                               setting_version: int) -> List[Tuple[str, str]]:
        source_version = main_version * 1000000 + setting_version

        from UM.VersionUpgradeManager import VersionUpgradeManager
        results = VersionUpgradeManager.getInstance().updateFilesData(
            "quality_changes", source_version, [serialized], [profile_id])
        if results is None:
            return []

        serialized = results.files_data[0]

        parser = configparser.ConfigParser(interpolation=None)
        parser.read_string(serialized)
        if "general" not in parser:
            Logger.log("w", "Missing required section 'general'.")
            return []

        new_source_version = results.version
        if int(
                new_source_version / 1000000
        ) != InstanceContainer.Version or new_source_version % 1000000 != CuraApplication.SettingVersion:
            Logger.log("e", "Failed to upgrade profile [%s]", profile_id)

        if int(parser["general"]["version"]) != InstanceContainer.Version:
            Logger.log("e", "Failed to upgrade profile [%s]", profile_id)
            return []
        return [(serialized, profile_id)]
Ejemplo n.º 7
0
    def initialize(self) -> None:
        super().initialize()
        # Initialize the package manager to remove and install scheduled packages.
        self._package_manager = self._package_manager_class(self, parent = self)

        self._mesh_file_handler = MeshFileHandler(self) #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(self) #type: WorkspaceFileHandler

        # Remove this and you will get Windows 95 style for all widgets if you are using Qt 5.10+
        self.setStyle("fusion")

        self.setAttribute(Qt.AA_UseDesktopOpenGL)
        major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion()

        if major_version is None or minor_version is None or profile is None:
            Logger.log("e", "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting")
            if not self.getIsHeadLess():
                QMessageBox.critical(None, "Failed to probe OpenGL",
                                     "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers.")
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(major_version, minor_version, profile)
            Logger.log("d", "Detected most suitable OpenGL context version: %s", opengl_version_str)
        if not self.getIsHeadLess():
            OpenGLContext.setDefaultFormat(major_version, minor_version, profile = profile)

        self._qml_import_paths.append(os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 8
0
def collectAllSettingIds():
    VersionUpgradeManager._VersionUpgradeManager__instance = VersionUpgradeManager(MagicMock())

    CuraApplication._initializeSettingDefinitions()

    definition_container = DefinitionContainer("whatever")
    with open(os.path.join(os.path.dirname(__file__), "..", "..", "resources", "definitions", "fdmprinter.def.json"), encoding = "utf-8") as data:
        definition_container.deserialize(data.read())
    return definition_container.getAllKeys()
Ejemplo n.º 9
0
    def initialize(self) -> None:
        super().initialize()

        preferences = Application.getInstance().getPreferences()
        preferences.addPreference("view/force_empty_shader_cache", False)
        preferences.addPreference("view/opengl_version_detect", OpenGLContext.OpenGlVersionDetect.Autodetect)

        # Read preferences here (upgrade won't work) to get:
        #  - The language in use, so the splash window can be shown in the correct language.
        #  - The OpenGL 'force' parameters.
        try:
            preferences_filename = Resources.getPath(Resources.Preferences, self._app_name + ".cfg")
            self._preferences.readFromFile(preferences_filename)
        except FileNotFoundError:
            Logger.log("i", "Preferences file not found, ignore and use default language '%s'", self._default_language)

        # Initialize the package manager to remove and install scheduled packages.
        self._package_manager = self._package_manager_class(self, parent = self)

        self._mesh_file_handler = MeshFileHandler(self) #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(self) #type: WorkspaceFileHandler

        # Remove this and you will get Windows 95 style for all widgets if you are using Qt 5.10+
        self.setStyle("fusion")

        if preferences.getValue("view/force_empty_shader_cache"):
            self.setAttribute(Qt.AA_DisableShaderDiskCache)
        self.setAttribute(Qt.AA_UseDesktopOpenGL)
        if preferences.getValue("view/opengl_version_detect") != OpenGLContext.OpenGlVersionDetect.ForceModern:
            major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion(
                preferences.getValue("view/opengl_version_detect") == OpenGLContext.OpenGlVersionDetect.ForceLegacy)
        else:
            Logger.info("Force 'modern' OpenGL (4.1 core) -- overrides 'force legacy opengl' preference.")
            major_version, minor_version, profile = (4, 1, QSurfaceFormat.CoreProfile)

        if major_version is None or minor_version is None or profile is None:
            Logger.log("e", "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting")
            if not self.getIsHeadLess():
                QMessageBox.critical(None, "Failed to probe OpenGL",
                                     "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers.")
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(major_version, minor_version, profile)
            Logger.log("d", "Detected most suitable OpenGL context version: %s", opengl_version_str)
        if not self.getIsHeadLess():
            OpenGLContext.setDefaultFormat(major_version, minor_version, profile = profile)

        self._qml_import_paths.append(os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 10
0
 def __updateSerialized(self, serialized: str) -> str:
     configuration_type = self.getConfigurationTypeFromSerialized(serialized)
     version = self.getVersionFromSerialized(serialized)
     if configuration_type is not None and version is not None:
         from UM.VersionUpgradeManager import VersionUpgradeManager
         result = VersionUpgradeManager.getInstance().updateFilesData(configuration_type, version,
                                                                      [serialized], [""])
         if result is not None:
             serialized = result.files_data[0]
     return serialized
Ejemplo n.º 11
0
 def __updateSerialized(self, serialized: str) -> str:
     configuration_type = self.getConfigurationTypeFromSerialized(serialized)
     version = self.getVersionFromSerialized(serialized)
     if configuration_type is not None and version is not None:
         from UM.VersionUpgradeManager import VersionUpgradeManager
         result = VersionUpgradeManager.getInstance().updateFilesData(configuration_type, version,
                                                                      [serialized], [""])
         if result is not None:
             serialized = result.files_data[0]
     return serialized
Ejemplo n.º 12
0
def register(app):
    # add Mime type
    mime_type = MimeType(
        name = "application/x-ultimaker-material-profile",
        comment = "Ultimaker Material Profile",
        suffixes = [ "xml.fdm_material" ]
    )
    MimeTypeDatabase.addMimeType(mime_type)

    # add upgrade version
    from cura.CuraApplication import CuraApplication
    from UM.VersionUpgradeManager import VersionUpgradeManager
    VersionUpgradeManager.getInstance().registerCurrentVersion(
        ("materials", XmlMaterialProfile.XmlMaterialProfile.Version * 1000000 + CuraApplication.SettingVersion),
        (CuraApplication.ResourceTypes.MaterialInstanceContainer, "application/x-ultimaker-material-profile")
    )

    return {"version_upgrade": upgrader,
            "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile"),
            }
Ejemplo n.º 13
0
def register(app):
    # add Mime type
    mime_type = MimeType(
        name = "application/x-ultimaker-material-profile",
        comment = "Ultimaker Material Profile",
        suffixes = [ "xml.fdm_material" ]
    )
    MimeTypeDatabase.addMimeType(mime_type)

    # add upgrade version
    from cura.CuraApplication import CuraApplication
    from UM.VersionUpgradeManager import VersionUpgradeManager
    VersionUpgradeManager.getInstance().registerCurrentVersion(
        ("materials", XmlMaterialProfile.XmlMaterialProfile.Version * 1000000 + CuraApplication.SettingVersion),
        (CuraApplication.ResourceTypes.MaterialInstanceContainer, "application/x-ultimaker-material-profile")
    )

    return {"version_upgrade": upgrader,
            "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile"),
            }
Ejemplo n.º 14
0
 def _updateSerialized(cls, serialized: str, file_name: Optional[str] = None) -> str:
     configuration_type = cls.getConfigurationTypeFromSerialized(serialized)
     version = cls.getVersionFromSerialized(serialized)
     if configuration_type is not None and version is not None:
         from UM.VersionUpgradeManager import VersionUpgradeManager
         result = VersionUpgradeManager.getInstance().updateFilesData(configuration_type, version,
                                                                      [serialized],
                                                                      [file_name if file_name else ""])
         if result is not None:
             serialized = result.files_data[0]
     return serialized
Ejemplo n.º 15
0
 def _updateSerialized(cls,
                       serialized: str,
                       file_name: Optional[str] = None) -> str:
     configuration_type = cls.getConfigurationTypeFromSerialized(serialized)
     version = cls.getVersionFromSerialized(serialized)
     if configuration_type is not None and version is not None:
         from UM.VersionUpgradeManager import VersionUpgradeManager
         result = VersionUpgradeManager.getInstance().updateFilesData(
             configuration_type, version, [serialized],
             [file_name if file_name else ""])
         if result is not None:
             serialized = result.files_data[0]
     return serialized
Ejemplo n.º 16
0
    def getVersionFromSerialized(cls, serialized: str) -> Optional[int]:
        configuration_type = cls.getConfigurationTypeFromSerialized(serialized)
        if not configuration_type:
            Logger.log("d", "Could not get type from serialized.")
            return None

        # Get version
        version = None
        try:
            from UM.VersionUpgradeManager import VersionUpgradeManager
            version = VersionUpgradeManager.getInstance().getFileVersion(configuration_type, serialized)
        except Exception as e:
            Logger.log("d", "Could not get version from serialized: %s", e)
        return version
Ejemplo n.º 17
0
    def getVersionFromSerialized(cls, serialized: str) -> Optional[int]:
        configuration_type = cls.getConfigurationTypeFromSerialized(serialized)
        if not configuration_type:
            Logger.log("d", "Could not get type from serialized.")
            return None

        # Get version
        version = None
        try:
            from UM.VersionUpgradeManager import VersionUpgradeManager
            version = VersionUpgradeManager.getInstance().getFileVersion(configuration_type, serialized)
        except Exception as e:
            Logger.log("d", "Could not get version from serialized: %s", e)
        return version
Ejemplo n.º 18
0
    def initialize(self) -> None:
        super().initialize()

        self._mesh_file_handler = MeshFileHandler(self) #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(self) #type: WorkspaceFileHandler

        # For some reason, with Qt 5.9 and up, the default "windows" style seems like Windows 95. We have to set the
        # style to "fusion" so it looks less ugly.
        pyqt_version_parts = [int(n) for n in PYQT_VERSION_STR.split(".")]
        if len(pyqt_version_parts) < 2:  # Make sure there are at less 2 parts in the version
            pyqt_version_parts += [0 for _ in range(2 - len(pyqt_version_parts))]
        if pyqt_version_parts[0] == 5 and pyqt_version_parts[1] > 8:
            self.setStyle("fusion")

        # For some reason, with Qt 5.9 and up, the default "windows" style seems like Windows 95. We have to set the
        # style to "fusion" so it looks less ugly.
        pyqt_version_parts = [int(n) for n in PYQT_VERSION_STR.split(".")]
        if len(pyqt_version_parts) < 2:  # Make sure there are at less 2 parts in the version
            pyqt_version_parts += [0 for _ in range(2 - len(pyqt_version_parts))]
        if pyqt_version_parts[0] == 5 and pyqt_version_parts[1] > 8:
            self.setStyle("fusion")

        self.setAttribute(Qt.AA_UseDesktopOpenGL)
        major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion()

        if major_version is None and minor_version is None and profile is None:
            Logger.log("e", "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting")
            QMessageBox.critical(None, "Failed to probe OpenGL",
                                 "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers.")
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(major_version, minor_version, profile)
            Logger.log("d", "Detected most suitable OpenGL context version: %s", opengl_version_str)
        OpenGLContext.setDefaultFormat(major_version, minor_version, profile = profile)

        self._qml_import_paths.append(os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 19
0
    def initialize(self) -> None:
        super().initialize()

        self._mesh_file_handler = MeshFileHandler(self)  #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(
            self)  #type: WorkspaceFileHandler

        self.setAttribute(Qt.AA_UseDesktopOpenGL)
        major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion(
        )

        if major_version is None and minor_version is None and profile is None:
            Logger.log(
                "e",
                "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting"
            )
            QMessageBox.critical(
                None, "Failed to probe OpenGL",
                "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers."
            )
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(
                major_version, minor_version, profile)
            Logger.log("d",
                       "Detected most suitable OpenGL context version: %s",
                       opengl_version_str)
        OpenGLContext.setDefaultFormat(major_version,
                                       minor_version,
                                       profile=profile)

        self._qml_import_paths.append(
            os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(
            os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 20
0
 def setup_method(self, method):
     self._upgrade_manager = VersionUpgradeManager()
Ejemplo n.º 21
0
class TestVersionUpgradeManager():
    ##  Executed before the first test function is executed.
    def setup_method(self, method):
        self._upgrade_manager = VersionUpgradeManager()

    ##  Executed after the last test function was executed.
    def teardown_method(self, method):
        pass

    ##  The individual test cases for shortest upgrade paths.
    #
    #   Each entry contains a list of possible upgrades. Each upgrade has a
    #   from_version, a to_version and a preference_type field. Each entry also
    #   has a destination version to upgrade to and a preference type to filter
    #   on. Each entry has a list of possible answers, each of which is a
    #   mapping of version numbers to indices referring to upgrades in the input
    #   list. Lastly, each entry has a name for debugging.
    test_shortest_paths_data = [
        ({
            "name": "two-step",
            "upgrades": [
                { "from_version": 0, "to_version": 1, "preference_type": "a" },
                { "from_version": 1, "to_version": 2, "preference_type": "a" }
            ],
            "destination": 2,
            "preference_type": "a",
            "answers": [
                { 0: 0, 1: 1 }
            ]
        }),
        ({
            "name": "two-options",
            "upgrades": [
                { "from_version": 0, "to_version": 1, "preference_type": "a" },
                { "from_version": 0, "to_version": 1, "preference_type": "a" }
            ],
            "destination": 1,
            "preference_type": "a",
            "answers": [
                { 0: 0 },
                { 0: 1 }
            ]
        }),
        ({
            "name": "shortcut",
            "upgrades": [
                { "from_version": 0, "to_version": 1, "preference_type": "a" },
                { "from_version": 1, "to_version": 2, "preference_type": "a" },
                { "from_version": 0, "to_version": 2, "preference_type": "a" }
            ],
            "destination": 2,
            "preference_type": "a",
            "answers": [
                { 0: 2, 1: 1 }
            ]
        }),
        ({
            "name": "preference-type-filter",
            "upgrades": [
                { "from_version": 0, "to_version": 2, "preference_type": "b" },
                { "from_version": 1, "to_version": 2, "preference_type": "a" },
                { "from_version": 0, "to_version": 1, "preference_type": "a" }
            ],
            "destination": 2,
            "preference_type": "a",
            "answers": [
                { 0: 2, 1: 1 }
            ]
        })
    ]

    ##  Tests the algorithm to find shortest paths to update plug-ins.
    #
    #   This function is normally not "exposed" (though Python puts no
    #   limitations on that). However, since the accuracy of this function
    #   should only affect the execution speed, it is wise to test this function
    #   nonetheless.
    #
    #   \param data The data containing individual tests.
    @pytest.mark.parametrize("data", test_shortest_paths_data)
    def test_shortest_paths(self, data):
        registry = Application.getInstance().getPluginRegistry()
        self._loadUpgrades(data["upgrades"])
        shortest_paths = self._upgrade_manager._findShortestUpgradePaths(data["preference_type"], data["destination"]) # Find the shortest path.

        # Convert the upgrades in the path to indices in our original data.
        to_indices = {}
        for version, upgrade in shortest_paths.items():
            metadata = registry.getMetaData(upgrade.getPluginId())["version_upgrade"]
            for key, value in metadata.items(): # Get just the first element of the dict. There is always only one.
                preference_type = key
                from_version = metadata[preference_type]["from"]
                to_version = metadata[preference_type]["to"]
                break
            for i in range(0, len(data["upgrades"])): # Which index does it have?
                if data["upgrades"][i]["from_version"] == from_version and data["upgrades"][i]["to_version"] == to_version and data["upgrades"][i]["preference_type"] == preference_type:
                    to_indices[from_version] = i
                    break

        # Compare with the answers.
        for answer in data["answers"]:
            if len(answer) != len(to_indices): # Not the same amount of source versions.
                continue # Incorrect answer.
            for version, upgrade in answer.items():
                if version not in to_indices: # Key is missing!
                    break # Incorrect answer.
                if answer[version] != to_indices[version]: # Different plug-in for this version!
                    break # Incorrect answer.
            else: # No indices were different. Answer is correct.
                break
        else: # No answers were correct.
            assert False # Incorrect path.

    ##  Create a plug-in registry with the specified upgrade plug-ins in it.
    #
    #   \param upgrades Metadata of upgrades to fill the registry with, as
    #   obtained from test_shortest_paths_data.
    def _loadUpgrades(self, upgrades):
        registry = Application.getInstance().getPluginRegistry()
        for upgrade in upgrades: # Artificially fill the plug-in registry with my own metadata!
            plugin_object = PluginObject()
            metadata = { # Correctly fill the metadata for this plug-in.
                "plugin": {
                    "name": "Upgrade Test", # Note: Don't use internationalisation here, lest it be grabbed by gettext.
                    "author": "Ultimaker",
                    "version": "1.0",
                    "description": "Upgrade plug-in to test with.",
                    "api": 2
                },
                "version_upgrade": {}
            }
            metadata["version_upgrade"][upgrade["preference_type"]] = {}
            metadata["version_upgrade"][upgrade["preference_type"]]["from"] = upgrade["from_version"]
            metadata["version_upgrade"][upgrade["preference_type"]]["to"] = upgrade["to_version"]
            id = upgrade["preference_type"] + "-from-" + str(upgrade["from_version"]) + "-to-" + str(upgrade["to_version"]) # ID becomes "type-from-#-to-#".
            plugin_object.setPluginId(id)
            registry._plugins[id] = plugin_object
            registry._meta_data[id] = metadata
            self._upgrade_manager._addVersionUpgrade(plugin_object)
Ejemplo n.º 22
0
def upgrade_manager(application):
    VersionUpgradeManager._VersionUpgradeManager__instance = None
    upgrade_manager = VersionUpgradeManager(application)
    return upgrade_manager
Ejemplo n.º 23
0
    def startSplashWindowPhase(self) -> None:
        super().startSplashWindowPhase()
        i18n_catalog = i18nCatalog("uranium")
        self.showSplashMessage(
            i18n_catalog.i18nc("@info:progress",
                               "Initializing package manager..."))
        self._package_manager.initialize()

        # Read preferences here (upgrade won't work) to get the language in use, so the splash window can be shown in
        # the correct language.
        try:
            preferences_filename = Resources.getPath(Resources.Preferences,
                                                     self._app_name + ".cfg")
            self._preferences.readFromFile(preferences_filename)
        except FileNotFoundError:
            Logger.log(
                "i",
                "Preferences file not found, ignore and use default language '%s'",
                self._default_language)

        signal.signal(signal.SIGINT, signal.SIG_DFL)
        # This is done here as a lot of plugins require a correct gl context. If you want to change the framework,
        # these checks need to be done in your <framework>Application.py class __init__().

        self._configuration_error_message = ConfigurationErrorMessage(
            self,
            i18n_catalog.i18nc("@info:status",
                               "Your configuration seems to be corrupt."),
            lifetime=0,
            title=i18n_catalog.i18nc("@info:title", "Configuration errors"))
        # Remove, install, and then loading plugins
        self.showSplashMessage(
            i18n_catalog.i18nc("@info:progress", "Loading plugins..."))
        # Remove and install the plugins that have been scheduled
        self._plugin_registry.initializeBeforePluginsAreLoaded()
        self._loadPlugins()
        self._plugin_registry.checkRequiredPlugins(self.getRequiredPlugins())
        self.pluginsLoaded.emit()

        self.showSplashMessage(
            i18n_catalog.i18nc("@info:progress", "Updating configuration..."))
        with self._container_registry.lockFile():
            VersionUpgradeManager.getInstance().upgrade()

        # Load preferences again because before we have loaded the plugins, we don't have the upgrade routine for
        # the preferences file. Now that we have, load the preferences file again so it can be upgraded and loaded.
        self.showSplashMessage(
            i18n_catalog.i18nc("@info:progress", "Loading preferences..."))
        try:
            preferences_filename = Resources.getPath(Resources.Preferences,
                                                     self._app_name + ".cfg")
            with open(preferences_filename, "r", encoding="utf-8") as f:
                serialized = f.read()
            # This performs the upgrade for Preferences
            self._preferences.deserialize(serialized)
            self._preferences.setValue("general/plugins_to_remove", "")
            self._preferences.writeToFile(preferences_filename)
        except (FileNotFoundError, UnicodeDecodeError):
            Logger.log(
                "i",
                "The preferences file cannot be found or it is corrupted, so we will use default values"
            )

        self.processEvents()
        # Force the configuration file to be written again since the list of plugins to remove maybe changed
        try:
            self._preferences_filename = Resources.getPath(
                Resources.Preferences, self._app_name + ".cfg")
            self._preferences.readFromFile(self._preferences_filename)
        except FileNotFoundError:
            Logger.log(
                "i",
                "The preferences file '%s' cannot be found, will use default values",
                self._preferences_filename)
            self._preferences_filename = Resources.getStoragePath(
                Resources.Preferences, self._app_name + ".cfg")

        # FIXME: This is done here because we now use "plugins.json" to manage plugins instead of the Preferences file,
        # but the PluginRegistry will still import data from the Preferences files if present, such as disabled plugins,
        # so we need to reset those values AFTER the Preferences file is loaded.
        self._plugin_registry.initializeAfterPluginsAreLoaded()

        # Check if we have just updated from an older version
        self._preferences.addPreference("general/last_run_version", "")
        last_run_version_str = self._preferences.getValue(
            "general/last_run_version")
        if not last_run_version_str:
            last_run_version_str = self._version
        last_run_version = Version(last_run_version_str)
        current_version = Version(self._version)
        if last_run_version < current_version:
            self._just_updated_from_old_version = True
        self._preferences.setValue("general/last_run_version",
                                   str(current_version))
        self._preferences.writeToFile(self._preferences_filename)

        # Preferences: recent files
        self._preferences.addPreference("%s/recent_files" % self._app_name, "")
        file_names = self._preferences.getValue("%s/recent_files" %
                                                self._app_name).split(";")
        for file_name in file_names:
            if not os.path.isfile(file_name):
                continue
            self._recent_files.append(QUrl.fromLocalFile(file_name))

        if not self.getIsHeadLess():
            # Initialize System tray icon and make it invisible because it is used only to show pop up messages
            self._tray_icon = None
            if self._tray_icon_name:
                self._tray_icon = QIcon(
                    Resources.getPath(Resources.Images, self._tray_icon_name))
                self._tray_icon_widget = QSystemTrayIcon(self._tray_icon)
                self._tray_icon_widget.setVisible(False)
class TestVersionUpgradeManager():
    ##  Executed before the first test function is executed.
    def setup_method(self, method):
        self._upgrade_manager = VersionUpgradeManager()

    ##  Executed after the last test function was executed.
    def teardown_method(self, method):
        pass

    ##  The individual test cases for shortest upgrade paths.
    #
    #   Each entry contains a list of possible upgrades. Each upgrade has a
    #   from_version, a to_version and a preference_type field. Each entry also
    #   has a destination version to upgrade to and a preference type to filter
    #   on. Each entry has a list of possible answers, each of which is a
    #   mapping of version numbers to indices referring to upgrades in the input
    #   list. Lastly, each entry has a name for debugging.
    test_shortest_paths_data = [({
        "name":
        "two-step",
        "upgrades": [{
            "from_version": 0,
            "to_version": 1,
            "preference_type": "a"
        }, {
            "from_version": 1,
            "to_version": 2,
            "preference_type": "a"
        }],
        "destination":
        2,
        "preference_type":
        "a",
        "answers": [{
            0: 0,
            1: 1
        }]
    }),
                                ({
                                    "name":
                                    "two-options",
                                    "upgrades": [{
                                        "from_version": 0,
                                        "to_version": 1,
                                        "preference_type": "a"
                                    }, {
                                        "from_version": 0,
                                        "to_version": 1,
                                        "preference_type": "a"
                                    }],
                                    "destination":
                                    1,
                                    "preference_type":
                                    "a",
                                    "answers": [{
                                        0: 0
                                    }, {
                                        0: 1
                                    }]
                                }),
                                ({
                                    "name":
                                    "shortcut",
                                    "upgrades": [{
                                        "from_version": 0,
                                        "to_version": 1,
                                        "preference_type": "a"
                                    }, {
                                        "from_version": 1,
                                        "to_version": 2,
                                        "preference_type": "a"
                                    }, {
                                        "from_version": 0,
                                        "to_version": 2,
                                        "preference_type": "a"
                                    }],
                                    "destination":
                                    2,
                                    "preference_type":
                                    "a",
                                    "answers": [{
                                        0: 2,
                                        1: 1
                                    }]
                                }),
                                ({
                                    "name":
                                    "preference-type-filter",
                                    "upgrades": [{
                                        "from_version": 0,
                                        "to_version": 2,
                                        "preference_type": "b"
                                    }, {
                                        "from_version": 1,
                                        "to_version": 2,
                                        "preference_type": "a"
                                    }, {
                                        "from_version": 0,
                                        "to_version": 1,
                                        "preference_type": "a"
                                    }],
                                    "destination":
                                    2,
                                    "preference_type":
                                    "a",
                                    "answers": [{
                                        0: 2,
                                        1: 1
                                    }]
                                })]

    ##  Tests the algorithm to find shortest paths to update plug-ins.
    #
    #   This function is normally not "exposed" (though Python puts no
    #   limitations on that). However, since the accuracy of this function
    #   should only affect the execution speed, it is wise to test this function
    #   nonetheless.
    #
    #   \param data The data containing individual tests.
    @pytest.mark.parametrize("data", test_shortest_paths_data)
    def test_shortest_paths(self, data):
        registry = Application.getInstance().getPluginRegistry()
        self._loadUpgrades(data["upgrades"])
        shortest_paths = self._upgrade_manager._findShortestUpgradePaths(
            data["preference_type"],
            data["destination"])  # Find the shortest path.

        # Convert the upgrades in the path to indices in our original data.
        to_indices = {}
        for version, upgrade in shortest_paths.items():
            metadata = registry.getMetaData(
                upgrade.getPluginId())["version_upgrade"]
            for key, value in metadata.items(
            ):  # Get just the first element of the dict. There is always only one.
                preference_type = key
                from_version = metadata[preference_type]["from"]
                to_version = metadata[preference_type]["to"]
                break
            for i in range(0,
                           len(data["upgrades"])):  # Which index does it have?
                if data["upgrades"][i]["from_version"] == from_version and data[
                        "upgrades"][i]["to_version"] == to_version and data[
                            "upgrades"][i][
                                "preference_type"] == preference_type:
                    to_indices[from_version] = i
                    break

        # Compare with the answers.
        for answer in data["answers"]:
            if len(answer) != len(
                    to_indices):  # Not the same amount of source versions.
                continue  # Incorrect answer.
            for version, upgrade in answer.items():
                if version not in to_indices:  # Key is missing!
                    break  # Incorrect answer.
                if answer[version] != to_indices[
                        version]:  # Different plug-in for this version!
                    break  # Incorrect answer.
            else:  # No indices were different. Answer is correct.
                break
        else:  # No answers were correct.
            assert False  # Incorrect path.

    ##  Create a plug-in registry with the specified upgrade plug-ins in it.
    #
    #   \param upgrades Metadata of upgrades to fill the registry with, as
    #   obtained from test_shortest_paths_data.
    def _loadUpgrades(self, upgrades):
        registry = Application.getInstance().getPluginRegistry()
        for upgrade in upgrades:  # Artificially fill the plug-in registry with my own metadata!
            plugin_object = PluginObject()
            metadata = {  # Correctly fill the metadata for this plug-in.
                "plugin": {
                    "name":
                    "Upgrade Test",  # Note: Don't use internationalisation here, lest it be grabbed by gettext.
                    "author": "Ultimaker",
                    "version": "1.0",
                    "description": "Upgrade plug-in to test with.",
                    "api": 2
                },
                "version_upgrade": {}
            }
            metadata["version_upgrade"][upgrade["preference_type"]] = {}
            metadata["version_upgrade"][
                upgrade["preference_type"]]["from"] = upgrade["from_version"]
            metadata["version_upgrade"][
                upgrade["preference_type"]]["to"] = upgrade["to_version"]
            id = upgrade["preference_type"] + "-from-" + str(
                upgrade["from_version"]) + "-to-" + str(
                    upgrade["to_version"])  # ID becomes "type-from-#-to-#".
            plugin_object.setPluginId(id)
            registry._plugins[id] = plugin_object
            registry._meta_data[id] = metadata
            self._upgrade_manager._addVersionUpgrade(plugin_object)
Ejemplo n.º 25
0
    def startSplashWindowPhase(self) -> None:
        super().startSplashWindowPhase()

        self._package_manager.initialize()

        # Read preferences here (upgrade won't work) to get the language in use, so the splash window can be shown in
        # the correct language.
        try:
            preferences_filename = Resources.getPath(Resources.Preferences, self._app_name + ".cfg")
            self._preferences.readFromFile(preferences_filename)
        except FileNotFoundError:
            Logger.log("i", "Preferences file not found, ignore and use default language '%s'", self._default_language)

        signal.signal(signal.SIGINT, signal.SIG_DFL)
        # This is done here as a lot of plugins require a correct gl context. If you want to change the framework,
        # these checks need to be done in your <framework>Application.py class __init__().

        i18n_catalog = i18nCatalog("uranium")

        self._configuration_error_message = ConfigurationErrorMessage(self,
              i18n_catalog.i18nc("@info:status", "Your configuration seems to be corrupt."),
              lifetime = 0,
              title = i18n_catalog.i18nc("@info:title", "Configuration errors")
              )
        # Remove, install, and then loading plugins
        self.showSplashMessage(i18n_catalog.i18nc("@info:progress", "Loading plugins..."))
        # Remove and install the plugins that have been scheduled
        self._plugin_registry.initializeBeforePluginsAreLoaded()
        self._loadPlugins()
        self._plugin_registry.checkRequiredPlugins(self.getRequiredPlugins())
        self.pluginsLoaded.emit()

        self.showSplashMessage(i18n_catalog.i18nc("@info:progress", "Updating configuration..."))
        with self._container_registry.lockFile():
            VersionUpgradeManager.getInstance().upgrade()

        # Load preferences again because before we have loaded the plugins, we don't have the upgrade routine for
        # the preferences file. Now that we have, load the preferences file again so it can be upgraded and loaded.
        try:
            preferences_filename = Resources.getPath(Resources.Preferences, self._app_name + ".cfg")
            with open(preferences_filename, "r", encoding = "utf-8") as f:
                serialized = f.read()
            # This performs the upgrade for Preferences
            self._preferences.deserialize(serialized)
            self._preferences.setValue("general/plugins_to_remove", "")
            self._preferences.writeToFile(preferences_filename)
        except FileNotFoundError:
            Logger.log("i", "The preferences file cannot be found, will use default values")

        # Force the configuration file to be written again since the list of plugins to remove maybe changed
        self.showSplashMessage(i18n_catalog.i18nc("@info:progress", "Loading preferences..."))
        try:
            self._preferences_filename = Resources.getPath(Resources.Preferences, self._app_name + ".cfg")
            self._preferences.readFromFile(self._preferences_filename)
        except FileNotFoundError:
            Logger.log("i", "The preferences file '%s' cannot be found, will use default values",
                       self._preferences_filename)
            self._preferences_filename = Resources.getStoragePath(Resources.Preferences, self._app_name + ".cfg")

        # FIXME: This is done here because we now use "plugins.json" to manage plugins instead of the Preferences file,
        # but the PluginRegistry will still import data from the Preferences files if present, such as disabled plugins,
        # so we need to reset those values AFTER the Preferences file is loaded.
        self._plugin_registry.initializeAfterPluginsAreLoaded()

        # Check if we have just updated from an older version
        self._preferences.addPreference("general/last_run_version", "")
        last_run_version_str = self._preferences.getValue("general/last_run_version")
        if not last_run_version_str:
            last_run_version_str = self._version
        last_run_version = Version(last_run_version_str)
        current_version = Version(self._version)
        if last_run_version < current_version:
            self._just_updated_from_old_version = True
        self._preferences.setValue("general/last_run_version", str(current_version))
        self._preferences.writeToFile(self._preferences_filename)

        # Preferences: recent files
        self._preferences.addPreference("%s/recent_files" % self._app_name, "")
        file_names = self._preferences.getValue("%s/recent_files" % self._app_name).split(";")
        for file_name in file_names:
            if not os.path.isfile(file_name):
                continue
            self._recent_files.append(QUrl.fromLocalFile(file_name))

        if not self.getIsHeadLess():
            # Initialize System tray icon and make it invisible because it is used only to show pop up messages
            self._tray_icon = None
            if self._tray_icon_name:
                self._tray_icon = QIcon(Resources.getPath(Resources.Images, self._tray_icon_name))
                self._tray_icon_widget = QSystemTrayIcon(self._tray_icon)
                self._tray_icon_widget.setVisible(False)
 def setup_method(self, method):
     self._upgrade_manager = VersionUpgradeManager()