Browse Source

Put the firmware-update meta-data in the 'normal' printer definitions and make the code handle that.

Remco Burema 6 years ago
parent
commit
2e3abbc904

+ 7 - 24
plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py

@@ -10,15 +10,12 @@ from typing import Set
 from UM.Extension import Extension
 from UM.Application import Application
 from UM.Logger import Logger
-from UM.PluginRegistry import PluginRegistry
-from UM.Qt.QtApplication import QtApplication
 from UM.i18n import i18nCatalog
 from UM.Settings.ContainerRegistry import ContainerRegistry
 
 from cura.Settings.GlobalStack import GlobalStack
 
 from .FirmwareUpdateCheckerJob import FirmwareUpdateCheckerJob
-from .FirmwareUpdateCheckerLookup import FirmwareUpdateCheckerLookup, getSettingsKeyForMachine
 from .FirmwareUpdateCheckerMessage import FirmwareUpdateCheckerMessage
 
 i18n_catalog = i18nCatalog("cura")
@@ -38,18 +35,14 @@ class FirmwareUpdateChecker(Extension):
         if Application.getInstance().getPreferences().getValue("info/automatic_update_check"):
             ContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
 
-        # Partly initialize after creation, since we need our own path from the plugin-manager.
-        self._download_url = None
         self._check_job = None
         self._checked_printer_names = set()  # type: Set[str]
-        self._lookups = None
-        QtApplication.pluginsLoaded.connect(self._onPluginsLoaded)
 
     ##  Callback for the message that is spawned when there is a new version.
     def _onActionTriggered(self, message, action):
         if action == FirmwareUpdateCheckerMessage.STR_ACTION_DOWNLOAD:
             machine_id = message.getMachineId()
-            download_url = self._lookups.getRedirectUserFor(machine_id)
+            download_url = message.getDownloadUrl()
             if download_url is not None:
                 if QDesktopServices.openUrl(QUrl(download_url)):
                     Logger.log("i", "Redirected browser to {0} to show newly available firmware.".format(download_url))
@@ -66,18 +59,6 @@ class FirmwareUpdateChecker(Extension):
     def _onJobFinished(self, *args, **kwargs):
         self._check_job = None
 
-    def _onPluginsLoaded(self):
-        if self._lookups is not None:
-            return
-
-        self._lookups = FirmwareUpdateCheckerLookup(os.path.join(PluginRegistry.getInstance().getPluginPath(
-            "FirmwareUpdateChecker"), "resources/machines.json"))
-
-        # Initialize the Preference called `latest_checked_firmware` that stores the last version
-        # checked for each printer.
-        for machine_id in self._lookups.getMachineIds():
-            Application.getInstance().getPreferences().addPreference(getSettingsKeyForMachine(machine_id), "")
-
     ##  Connect with software.ultimaker.com, load latest.version and check version info.
     #   If the version info is different from the current version, spawn a message to
     #   allow the user to download it.
@@ -85,16 +66,18 @@ class FirmwareUpdateChecker(Extension):
     #   \param silent type(boolean) Suppresses messages other than "new version found" messages.
     #                               This is used when checking for a new firmware version at startup.
     def checkFirmwareVersion(self, container = None, silent = False):
-        if self._lookups is None:
-            self._onPluginsLoaded()
-
         container_name = container.definition.getName()
         if container_name in self._checked_printer_names:
             return
         self._checked_printer_names.add(container_name)
 
+        metadata = container.definition.getMetaData().get("firmware_update_info")
+        if metadata is None:
+            Logger.log("i", "No machine with name {0} in list of firmware to check.".format(container_name))
+            return
+
         self._check_job = FirmwareUpdateCheckerJob(container = container, silent = silent,
-                                                   lookups = self._lookups,
+                                                   machine_name = container_name, metadata = metadata,
                                                    callback = self._onActionTriggered)
         self._check_job.start()
         self._check_job.finished.connect(self._onJobFinished)

+ 19 - 11
plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py

@@ -9,7 +9,7 @@ from UM.Version import Version
 
 import urllib.request
 from urllib.error import URLError
-from typing import Dict
+from typing import Dict, Optional
 
 from .FirmwareUpdateCheckerLookup import FirmwareUpdateCheckerLookup, getSettingsKeyForMachine
 from .FirmwareUpdateCheckerMessage import FirmwareUpdateCheckerMessage
@@ -25,13 +25,15 @@ class FirmwareUpdateCheckerJob(Job):
     ZERO_VERSION = Version(STRING_ZERO_VERSION)
     EPSILON_VERSION = Version(STRING_EPSILON_VERSION)
 
-    def __init__(self, container, silent, lookups: FirmwareUpdateCheckerLookup, callback) -> None:
+    def __init__(self, container, silent, machine_name, metadata, callback) -> None:
         super().__init__()
         self._container = container
         self.silent = silent
         self._callback = callback
 
-        self._lookups = lookups
+        self._machine_name = machine_name
+        self._metadata = metadata
+        self._lookups = None  # type:Optional[FirmwareUpdateCheckerLookup]
         self._headers = {}  # type:Dict[str, str]  # Don't set headers yet.
 
     def getUrlResponse(self, url: str) -> str:
@@ -50,10 +52,12 @@ class FirmwareUpdateCheckerJob(Job):
         raw_str = response.split("\n", 1)[0].rstrip()
         return Version(raw_str)
 
-    def getCurrentVersionForMachine(self, machine_id: int) -> Version:
+    def getCurrentVersion(self) -> Version:
         max_version = self.ZERO_VERSION
+        if self._lookups is None:
+            return max_version
 
-        machine_urls = self._lookups.getCheckUrlsFor(machine_id)
+        machine_urls = self._lookups.getCheckUrls()
         if machine_urls is not None:
             for url in machine_urls:
                 version = self.parseVersionResponse(self.getUrlResponse(url))
@@ -61,16 +65,20 @@ class FirmwareUpdateCheckerJob(Job):
                     max_version = version
 
         if max_version < self.EPSILON_VERSION:
-            Logger.log("w", "MachineID {0} not handled!".format(repr(machine_id)))
+            Logger.log("w", "MachineID {0} not handled!".format(self._lookups.getMachineName()))
 
         return max_version
 
     def run(self):
         if self._lookups is None:
-            Logger.log("e", "Can not check for a new release. URL not set!")
-            return
+            self._lookups = FirmwareUpdateCheckerLookup(self._machine_name, self._metadata)
 
         try:
+            # Initialize a Preference that stores the last version checked for this printer.
+            Application.getInstance().getPreferences().addPreference(
+                getSettingsKeyForMachine(self._lookups.getMachineId()), "")
+
+            # Get headers
             application_name = Application.getInstance().getApplicationName()
             application_version = Application.getInstance().getVersion()
             self._headers = {"User-Agent": "%s - %s" % (application_name, application_version)}
@@ -79,11 +87,11 @@ class FirmwareUpdateCheckerJob(Job):
             machine_name = self._container.definition.getName()
 
             # If it is not None, then we compare between the checked_version and the current_version
-            machine_id = self._lookups.getMachineByName(machine_name.lower())
+            machine_id = self._lookups.getMachineId()
             if machine_id is not None:
                 Logger.log("i", "You have a(n) {0} in the printer list. Let's check the firmware!".format(machine_name))
 
-                current_version = self.getCurrentVersionForMachine(machine_id)
+                current_version = self.getCurrentVersion()
 
                 # If it is the first time the version is checked, the checked_version is ""
                 setting_key_str = getSettingsKeyForMachine(machine_id)
@@ -99,7 +107,7 @@ class FirmwareUpdateCheckerJob(Job):
                 # notify the user when no new firmware version is available.
                 if (checked_version != "") and (checked_version != current_version):
                     Logger.log("i", "SHOWING FIRMWARE UPDATE MESSAGE")
-                    message = FirmwareUpdateCheckerMessage(machine_id, machine_name)
+                    message = FirmwareUpdateCheckerMessage(machine_id, machine_name, self._lookups.getRedirectUserUrl())
                     message.actionTriggered.connect(self._callback)
                     message.show()
             else:

+ 20 - 45
plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerLookup.py

@@ -1,11 +1,7 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-import json
-
-from typing import Callable, Dict, List, Optional
-
-from UM.Logger import Logger
+from typing import List, Optional
 
 from UM.i18n import i18nCatalog
 i18n_catalog = i18nCatalog("cura")
@@ -17,44 +13,23 @@ def getSettingsKeyForMachine(machine_id: int) -> str:
 
 class FirmwareUpdateCheckerLookup:
 
-    def __init__(self, json_path) -> None:
-        # Open the .json file with the needed lookup-lists for each machine(/model) and retrieve "raw" json.
-        with open(json_path, "r", encoding = "utf-8") as json_file:
-            machines_json = json.load(json_file).get("machines")
-        if machines_json is None:
-            Logger.log("e", "Missing or inaccessible: {0}".format(json_path))
-            return
-
+    def __init__(self, machine_name, machine_json) -> None:
         # Parse all the needed lookup-tables from the ".json" file(s) in the resources folder.
-        self._machine_ids = []  # type:List[int]
-        self._machine_per_name = {}  # type:Dict[str, int]
-        self._parse_version_url_per_machine = {}  # type:Dict[int, Callable]
-        self._check_urls_per_machine = {}  # type:Dict[int, List[str]]
-        self._redirect_user_per_machine = {}  # type:Dict[int, str]
-        try:
-            for machine_json in machines_json:
-                machine_id = machine_json.get("id")
-                machine_name = machine_json.get("name").lower()  # Lower in case upper-case char are added to the json.
-                self._machine_ids.append(machine_id)
-                self._machine_per_name[machine_name] = machine_id
-                self._check_urls_per_machine[machine_id] = []  # Multiple check-urls: see "_comment" in the .json file.
-                for check_url in machine_json.get("check_urls"):
-                    self._check_urls_per_machine[machine_id].append(check_url)
-                self._redirect_user_per_machine[machine_id] = machine_json.get("update_url")
-        except Exception as ex:
-            Logger.log("e", "Couldn't parse firmware-update-check lookup-lists from file because {0}.".format(ex))
-
-    def getMachineIds(self) -> List[int]:
-        return self._machine_ids
-
-    def getMachineByName(self, machine_name: str) -> Optional[int]:
-        return self._machine_per_name.get(machine_name)
-
-    def getParseVersionUrlFor(self, machine_id: int) -> Optional[Callable]:
-        return self._parse_version_url_per_machine.get(machine_id)
-
-    def getCheckUrlsFor(self, machine_id: int) -> Optional[List[str]]:
-        return self._check_urls_per_machine.get(machine_id)
-
-    def getRedirectUserFor(self, machine_id: int) -> Optional[str]:
-        return self._redirect_user_per_machine.get(machine_id)
+        self._machine_id = machine_json.get("id")
+        self._machine_name = machine_name.lower()  # Lower in-case upper-case chars are added to the original json.
+        self._check_urls = []  # type:List[str]
+        for check_url in machine_json.get("check_urls"):
+            self._check_urls.append(check_url)
+        self._redirect_user = machine_json.get("update_url")
+
+    def getMachineId(self) -> Optional[int]:
+        return self._machine_id
+
+    def getMachineName(self) -> Optional[int]:
+        return self._machine_name
+
+    def getCheckUrls(self) -> Optional[List[str]]:
+        return self._check_urls
+
+    def getRedirectUserUrl(self) -> Optional[str]:
+        return self._redirect_user

+ 5 - 1
plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerMessage.py

@@ -9,7 +9,7 @@ i18n_catalog = i18nCatalog("cura")
 class FirmwareUpdateCheckerMessage(Message):
     STR_ACTION_DOWNLOAD = "download"
 
-    def __init__(self, machine_id: int, machine_name: str) -> None:
+    def __init__(self, machine_id: int, machine_name: str, download_url: str) -> None:
         super().__init__(i18n_catalog.i18nc(
             "@info Don't translate {machine_name}, since it gets replaced by a printer name!",
             "New features are available for your {machine_name}! It is recommended to update the firmware on your printer.").format(
@@ -19,6 +19,7 @@ class FirmwareUpdateCheckerMessage(Message):
                 "New %s firmware available") % machine_name)
 
         self._machine_id = machine_id
+        self._download_url = download_url
 
         self.addAction(self.STR_ACTION_DOWNLOAD,
                           i18n_catalog.i18nc("@action:button", "How to update"),
@@ -29,3 +30,6 @@ class FirmwareUpdateCheckerMessage(Message):
 
     def getMachineId(self) -> int:
         return self._machine_id
+
+    def getDownloadUrl(self) -> str:
+        return self._download_url

+ 0 - 33
plugins/FirmwareUpdateChecker/resources/machines.json

@@ -1,33 +0,0 @@
-{
-    "_comment": "There are multiple 'check_urls', because sometimes an URL is about to be phased out, and it's useful to have a new 'future-proof' one at the ready.",
-
-    "machines":
-    [
-        {
-            "id": 9066,
-            "name": "ultimaker 3",
-            "check_urls":
-            [
-                "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
-                "http://software.ultimaker.com/releases/firmware/9066/stable/version.txt"
-            ],
-            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
-        },
-        {
-            "id": 9511,
-            "name": "ultimaker 3 extended",
-            "check_urls":
-            [
-                "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
-                "http://software.ultimaker.com/releases/firmware/9511/stable/version.txt"
-            ],
-            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
-        },
-        {
-            "id": 9051,
-            "name": "ultimaker s5",
-            "check_urls": ["http://software.ultimaker.com/releases/firmware/9051/stable/version.txt"],
-            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
-        }
-    ]
-}

+ 10 - 1
resources/definitions/ultimaker3.def.json

@@ -24,7 +24,16 @@
         },
         "first_start_actions": [ "DiscoverUM3Action" ],
         "supported_actions": [ "DiscoverUM3Action" ],
-        "supports_usb_connection": false
+        "supports_usb_connection": false,
+        "firmware_update_info": {
+            "id": 9066,
+            "check_urls":
+            [
+                "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
+                "http://software.ultimaker.com/releases/firmware/9066/stable/version.txt"
+            ],
+            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
+        }
     },
 
 

+ 10 - 1
resources/definitions/ultimaker3_extended.def.json

@@ -23,7 +23,16 @@
             "1": "ultimaker3_extended_extruder_right"
         },
         "first_start_actions": [ "DiscoverUM3Action" ],
-        "supported_actions": [ "DiscoverUM3Action" ]
+        "supported_actions": [ "DiscoverUM3Action" ],
+        "firmware_update_info": {
+            "id": 9511,
+            "check_urls":
+            [
+                "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
+                "http://software.ultimaker.com/releases/firmware/9511/stable/version.txt"
+            ],
+            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
+        }
     },
 
     "overrides": {

+ 6 - 1
resources/definitions/ultimaker_s5.def.json

@@ -30,7 +30,12 @@
         "first_start_actions": [ "DiscoverUM3Action" ],
         "supported_actions": [ "DiscoverUM3Action" ],
         "supports_usb_connection": false,
-        "weight": -1
+        "weight": -1,
+        "firmware_update_info": {
+            "id": 9051,
+            "check_urls": ["http://software.ultimaker.com/releases/firmware/9051/stable/version.txt"],
+            "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware"
+        }
     },
 
     "overrides": {