FirmwareUpdateCheckerJob.py 4.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # Copyright (c) 2017 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from UM.Application import Application
  4. from UM.Message import Message
  5. from UM.Logger import Logger
  6. from UM.Job import Job
  7. import urllib.request
  8. import codecs
  9. from UM.i18n import i18nCatalog
  10. i18n_catalog = i18nCatalog("cura")
  11. ## This job checks if there is an update available on the provided URL.
  12. class FirmwareUpdateCheckerJob(Job):
  13. def __init__(self, container = None, silent = False, url = None, callback = None, set_download_url_callback = None):
  14. super().__init__()
  15. self._container = container
  16. self.silent = silent
  17. self._url = url
  18. self._callback = callback
  19. self._set_download_url_callback = set_download_url_callback
  20. def run(self):
  21. if not self._url:
  22. Logger.log("e", "Can not check for a new release. URL not set!")
  23. return
  24. try:
  25. application_name = Application.getInstance().getApplicationName()
  26. headers = {"User-Agent": "%s - %s" % (application_name, Application.getInstance().getVersion())}
  27. request = urllib.request.Request(self._url, headers = headers)
  28. current_version_file = urllib.request.urlopen(request)
  29. reader = codecs.getreader("utf-8")
  30. # get machine name from the definition container
  31. machine_name = self._container.definition.getName()
  32. machine_name_parts = machine_name.lower().split(" ")
  33. # If it is not None, then we compare between the checked_version and the current_version
  34. # Now we just do that if the active printer is Ultimaker 3 or Ultimaker 3 Extended or any
  35. # other Ultimaker 3 that will come in the future
  36. if len(machine_name_parts) >= 2 and machine_name_parts[:2] == ["ultimaker", "3"]:
  37. Logger.log("i", "You have a UM3 in printer list. Let's check the firmware!")
  38. # Nothing to parse, just get the string
  39. # TODO: In the future may be done by parsing a JSON file with diferent version for each printer model
  40. current_version = reader(current_version_file).readline().rstrip()
  41. # If it is the first time the version is checked, the checked_version is ''
  42. checked_version = Application.getInstance().getPreferences().getValue("info/latest_checked_firmware")
  43. # If the checked_version is '', it's because is the first time we check firmware and in this case
  44. # we will not show the notification, but we will store it for the next time
  45. Application.getInstance().getPreferences().setValue("info/latest_checked_firmware", current_version)
  46. Logger.log("i", "Reading firmware version of %s: checked = %s - latest = %s", machine_name, checked_version, current_version)
  47. # The first time we want to store the current version, the notification will not be shown,
  48. # because the new version of Cura will be release before the firmware and we don't want to
  49. # notify the user when no new firmware version is available.
  50. if (checked_version != "") and (checked_version != current_version):
  51. Logger.log("i", "SHOWING FIRMWARE UPDATE MESSAGE")
  52. message = Message(i18n_catalog.i18nc(
  53. "@info Don't translate {machine_name}, since it gets replaced by a printer name!",
  54. "New features are available for your {machine_name}! It is recommended to update the firmware on your printer.").format(
  55. machine_name=machine_name),
  56. title=i18n_catalog.i18nc(
  57. "@info:title The %s gets replaced with the printer name.",
  58. "New %s firmware available") % machine_name)
  59. message.addAction("download",
  60. i18n_catalog.i18nc("@action:button", "How to update"),
  61. "[no_icon]",
  62. "[no_description]",
  63. button_style=Message.ActionButtonStyle.LINK,
  64. button_align=Message.ActionButtonStyle.BUTTON_ALIGN_LEFT)
  65. # If we do this in a cool way, the download url should be available in the JSON file
  66. if self._set_download_url_callback:
  67. self._set_download_url_callback("https://ultimaker.com/en/resources/20500-upgrade-firmware")
  68. message.actionTriggered.connect(self._callback)
  69. message.show()
  70. except Exception as e:
  71. Logger.log("w", "Failed to check for new version: %s", e)
  72. if not self.silent:
  73. Message(i18n_catalog.i18nc("@info", "Could not access update information.")).show()
  74. return