diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py new file mode 100644 index 0000000000..3b58a56481 --- /dev/null +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py @@ -0,0 +1,33 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from UM.Extension import Extension +from UM.Preferences import Preferences +from UM.i18n import i18nCatalog + +from .FirmwareUpdateCheckerJob import FirmwareUpdateCheckerJob + +i18n_catalog = i18nCatalog("cura") + + +## This Extension checks for new versions of the firmware based on the latest checked version number. +# The plugin is currently only usable for applications maintained by Ultimaker. But it should be relatively easy +# to change it to work for other applications. +class FirmwareUpdateChecker(Extension): + url = "http://software.ultimaker.com/jedi/releases/latest.version" + + def __init__(self): + super().__init__() + + Preferences.getInstance().addPreference("info/latest_checked_firmware", "") + self.checkFirmwareVersion(True) + + ## 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. + # + # \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, silent = False): + job = FirmwareUpdateCheckerJob(silent = silent, url = self.url) + job.start() \ No newline at end of file diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py new file mode 100644 index 0000000000..913ac96025 --- /dev/null +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -0,0 +1,79 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from UM.Preferences import Preferences +from UM.Application import Application +from UM.Message import Message +from UM.Logger import Logger +from UM.Job import Job + +import urllib.request +import codecs + +from PyQt5.QtCore import QUrl +from PyQt5.QtGui import QDesktopServices + + +from UM.i18n import i18nCatalog +i18n_catalog = i18nCatalog("cura") + + +## This job checks if there is an update available on the provided URL. +class FirmwareUpdateCheckerJob(Job): + def __init__(self, silent = False, url = None): + super().__init__() + self.silent = silent + self._url = url + self._download_url = None # If an update was found, the download_url will be set to the location of the new version. + + ## Callback for the message that is spawned when there is a new version. + def actionTriggered(self, message, action): + if action == "download": + if self._download_url is not None: + QDesktopServices.openUrl(QUrl(self._download_url)) + + def run(self): + self._download_url = None # Reset download ur. + if not self._url: + Logger.log("e", "Can not check for a new release. URL not set!") + return + + Logger.log("i", "Checking for new version of firmware") + try: + request = urllib.request.Request(self._url) + current_version_file = urllib.request.urlopen(request) + reader = codecs.getreader("utf-8") + + # Nothing to parse, just get the string + # TODO: In the future may be done by parsing a JSON file + current_version = reader(current_version_file).readline().rstrip() + Logger.log("i", "Reading firmware version: %s" % current_version) + + # If it is the first time the version is checked, the checked_version is None + checked_version = Preferences.getInstance().getValue("info/latest_checked_firmware") + active_machine = Preferences.getInstance().getValue("cura/active_machine") + # If it is not None, then we compare between the checked_version and the current_version + # Now we just do that if the active printer is Ultimaker 3 or Ultimaker 3 Extended + if ((active_machine == "Ultimaker 3 Extended") or (active_machine == "Ultimaker 3"))\ + and ((checked_version is None) or (checked_version != current_version)): + message = Message(i18n_catalog.i18nc("@info", "New %s firmware available

To ensure that your " + "%s is equiped with the latest features it is recommended " + "to update the firmware regularly. This can be done on the " + "%s (when connected to the network) or via USB." + % (active_machine, active_machine, active_machine))) + message.addAction("download", i18n_catalog.i18nc("@action:button", "Download"), "[no_icon]", "[no_description]") + + # If we do this in a cool way, the download url should be available in the JSON file + self._download_url = "https://ultimaker.com/en/resources/20500-upgrade-firmware" + message.actionTriggered.connect(self.actionTriggered) + # Sometimes it's shown, sometimes not + #message.show() + Application.getInstance().showMessage(message) + + Preferences.getInstance().setValue("info/latest_checked_firmware", current_version) + + except Exception as e: + Logger.log("w", "Failed to check for new version: %s" % e) + if not self.silent: + Message(i18n_catalog.i18nc("@info", "Could not access update information.")).show() + return \ No newline at end of file diff --git a/plugins/FirmwareUpdateChecker/__init__.py b/plugins/FirmwareUpdateChecker/__init__.py new file mode 100644 index 0000000000..5da6130772 --- /dev/null +++ b/plugins/FirmwareUpdateChecker/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from UM.i18n import i18nCatalog +from . import FirmwareUpdateChecker + +i18n_catalog = i18nCatalog("cura") + +def getMetaData(): + return { + } + +def register(app): + return { "extension": FirmwareUpdateChecker.FirmwareUpdateChecker()} diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json new file mode 100644 index 0000000000..d6a9f9fbd7 --- /dev/null +++ b/plugins/FirmwareUpdateChecker/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "Firmware Update Checker", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Checks for firmware updates.", + "api": 4, + "i18n-catalog": "cura" +}