From 41cf85d9db8e2c8c9af9f2e75f86dd059f95f865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 12 May 2017 14:58:30 +0200 Subject: [PATCH 01/13] Some rephrasing --- .github/ISSUE_TEMPLATE.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 4970021e..97a7e30c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -10,13 +10,14 @@ This is a bug and feature tracker, please only use it to report bugs or request features within OctoPrint (not OctoPi, not any OctoPrint plugins and not unofficial OctoPrint versions). -Do not seek support here ("I need help with ..."), that belongs on -the mailing list or the G+ community (both linked in the "guidelines -for contributing" linked above, read it!), NOT here. +Do not seek support here ("I need help with ...", "I have a +question ..."), that belongs on the mailing list or the G+ community +(both linked in the "guidelines for contributing" linked above, read +them!), NOT here. -Mark requests with a "[Request]" prefix in the title please. Fully fill -out the bug reporting template for bug reports (if you don't know where -to find some information - it's all described in the Contribution +Mark requests with a "[Request]" prefix in the title please. For bug +reports fully fill out the bug reporting template (if you don't know +where to find some information - it's all described in the Contribution Guidelines linked up there in the big yellow box). When reporting a bug do NOT delete ANY lines from the template but @@ -91,7 +92,7 @@ reporting communication issues. Never truncate. serial.log is usually not written due to performance reasons and must be enabled explicitly. Provide at the very least the FULL contents of your terminal tab at the time of the bug occurrence, even if you do not have -a serial.log.] +a serial.log (which the Contribution Guidelines tell you where to find).] #### Link to contents of Javascript console in the browser From 4c65313c7f6d3996643b7b5a481eb481a0702ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 15 May 2017 12:40:05 +0200 Subject: [PATCH 02/13] Fix a regression causing job data to be reset on completion of a print Fixes #1917 --- src/octoprint/printer/standard.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index 7c3ba32e..a0c1b817 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -1070,13 +1070,17 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): must_be_set=False) def on_comm_print_job_done(self): - self._updateProgressData() - self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()}) self._fileManager.delete_recovery_data() payload = self._payload_for_print_job_event() if payload: payload["time"] = self._comm.getPrintTime() + self._updateProgressData(completion=1.0, + filepos=payload["size"], + printTime=payload["time"], + printTimeLeft=0) + self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()}) + eventManager().fire(Events.PRINT_DONE, payload) self.script("afterPrintDone", context=dict(event=payload), @@ -1088,6 +1092,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): payload["time"], True, self._printerProfileManager.get_current_or_default()["id"]) + else: + self._updateProgressData() + self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()}) + def on_comm_print_job_failed(self): payload = self._payload_for_print_job_event() @@ -1134,7 +1142,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._sdStreaming = True self._setJobData(filename, filesize, True) - self._updateProgressData() + self._updateProgressData(completion=0.0, filepos=0, printTime=0) self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()}) def on_comm_file_transfer_done(self, filename): @@ -1162,6 +1170,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._logger.exception("Error while trying to persist print recovery data") def _payload_for_print_job_event(self, location=None, print_job_file=None, position=None): + print_job_size = None if print_job_file is None: with self._selectedFileMutex: selected_file = self._selectedFile @@ -1169,9 +1178,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): return dict() print_job_file = selected_file.get("filename", None) + print_job_size = selected_file.get("filesize", None) location = FileDestinations.SDCARD if selected_file.get("sd", False) else FileDestinations.LOCAL - if not print_job_file or not location: + if not print_job_file or not print_job_size or not location: return dict() if location == FileDestinations.SDCARD: @@ -1190,6 +1200,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): result= dict(name=name, path=path, origin=origin, + size=print_job_size, # TODO deprecated, remove in 1.4.0 file=full_path, From 6d73e6557b627ac3aa005cb72dac4a7573c04343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 15 May 2017 13:03:40 +0200 Subject: [PATCH 03/13] Timelapse: Disable "save as default" along other controls Fixes #1918 --- src/octoprint/templates/tabs/timelapse.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/octoprint/templates/tabs/timelapse.jinja2 b/src/octoprint/templates/tabs/timelapse.jinja2 index 5ed1ee92..d749dcf7 100644 --- a/src/octoprint/templates/tabs/timelapse.jinja2 +++ b/src/octoprint/templates/tabs/timelapse.jinja2 @@ -50,7 +50,7 @@
From 51959319eb46f36ebbd2310e39f8998a0054c1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 16 May 2017 16:00:40 +0200 Subject: [PATCH 04/13] PGMR: Fix call to non existing onAlways Closes #1919 --- .../plugins/pluginmanager/static/js/pluginmanager.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js index 57b1b92d..0ee352e0 100644 --- a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js +++ b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js @@ -526,13 +526,11 @@ $(function() { if (reinstall) { OctoPrint.plugins.pluginmanager.reinstall(reinstall, url, followDependencyLinks) .done(onSuccess) - .fail(onError) - .always(onAlways); + .fail(onError); } else { OctoPrint.plugins.pluginmanager.install(url, followDependencyLinks) .done(onSuccess) - .fail(onError) - .always(onAlways); + .fail(onError); } }; From 2bae87b85a53315ecc79b750f2a63f33e8a5dd94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 17 May 2017 10:59:48 +0200 Subject: [PATCH 05/13] Preparing release of 1.3.3rc2 --- CHANGELOG.md | 14 ++++++++++++-- SUPPORTERS.md | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5b37bf0..613f1702 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,21 @@ # OctoPrint Changelog +## 1.3.3rc2 (2017-05-17) + +### Bug fixes + + * [#1917](https://github.com/foosel/OctoPrint/issues/1917) (regression) - Fix job data resetting on print job completion. + * [#1918](https://github.com/foosel/OctoPrint/issues/1918) (regression) - Fix "save as default" checkbox not being disabled when other controls are disabled. + * [#1919](https://github.com/foosel/OctoPrint/issues/1919) (regression) - Fix call to no longer existing function in Plugin Manager UI. + +([Commits](https://github.com/foosel/OctoPrint/compare/1.3.3rc1...1.3.3rc2)) + ## 1.3.3rc1 (2017-05-11) ### Improvements - * [#478](https://github.com/foosel/OctoPrint/issues/478) - Made webcam stream contained fixed height (with selectable aspect ratio) to prevent jumps of the controls beneath it on load. - * [#748](https://github.com/foosel/OctoPrint/issues/748) - Added delete confirmation and bulk delete for timelapses. See also the discussion in brainstorming ticket [#1807].(https://github.com/foosel/OctoPrint/issues/1807). + * [#478](https://github.com/foosel/OctoPrint/issues/478) - Made webcam stream container fixed height (with selectable aspect ratio) to prevent jumps of the controls beneath it on load. + * [#748](https://github.com/foosel/OctoPrint/issues/748) - Added delete confirmation and bulk delete for timelapses. See also the discussion in brainstorming ticket [#1807](https://github.com/foosel/OctoPrint/issues/1807). * [#1092](https://github.com/foosel/OctoPrint/issues/1092) - Added new event to the file manager: `FileAdded`, `FileRemoved`, `FolderAdded`, `FolderRemoved`. Contrary to the `Upload` event, `FileAdded` will always fire when a file was added to storage through the file manager, not only when added through the web interface. Extended documentation accordingly. * [#1521](https://github.com/foosel/OctoPrint/issues/1521) - Software update plugin: Display timestamp of last version cache refresh in "Advanced options" area. * [#1734](https://github.com/foosel/OctoPrint/issues/1734) - Treat default/initial printer profile like all other printer profiles, persisting it to disk instead of `config.yaml` and allowing deletion. OctoPrint will migrate the existing default profile to the new location on first start. diff --git a/SUPPORTERS.md b/SUPPORTERS.md index 50a82c76..393d83e9 100644 --- a/SUPPORTERS.md +++ b/SUPPORTERS.md @@ -64,4 +64,4 @@ thanks to everyone who contributed! * Timeshell.ca * Trent Shumay -and 1076 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file +and 1084 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file From 337957198b39f2140615891d33905c0834e5d845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 17 May 2017 13:33:28 +0200 Subject: [PATCH 06/13] Introducing staging/* branches for rc preparation That way we can switch maintenance over to follow-up stable release preparation earlier and don't have to hold back commits. --- .versioneer-lookup | 3 +++ CONTRIBUTING.md | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/.versioneer-lookup b/.versioneer-lookup index 342b9dec..d17ee7e6 100644 --- a/.versioneer-lookup +++ b/.versioneer-lookup @@ -22,5 +22,8 @@ maintenance 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev fix/.* 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev improve/.* 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev +# staging/maintenance is currently the branch for preparation of 1.3.3rc3 (if we'll need that) +staging/maintenance 1.3.3rc2 3fbd477d15b5776ca929ea578c5437720aaf7f31 pep440-dev + # every other branch is a development branch and thus gets resolved to 1.4.0-dev for now .* 1.4.0 7f5d03d0549bcbd26f40e7e4a3297ea5204fb1cc pep440-dev diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3fb3411..b8ba81c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -365,10 +365,16 @@ There are three main branches in OctoPrint: the `maintenance` branch and are now being pushed on the "Maintenance" pre release channel for further testing. Version number follows the scheme `..rc` (e.g. `1.2.9rc1`). + * `staging/maintenance`: Any preparation for potential follow-up RCs takes place here. + Version number follows the scheme `..rc.dev` (e.g. + `1.2.9rc1.dev3`) for a current Maintenance RC of `..rc`. * `rc/devel`: This branch is reserved for future releases that have graduated from the `devel` branch and are now being pushed on the "Devel" pre release channel for further testing. Version number follows the scheme `..0rc` (e.g. `1.3.0rc1`) for a current stable OctoPrint version of `..`. + * `staging/devel`: Any preparation for potential follow-up Devel RCs takes place + here. Version number follows the scheme `..0rc.dev` (e.g. + `1.3.0rc1.dev12`) for a current Devel RC of `..0rc`. Additionally, from time to time you might see other branches pop up in the repository. Those usually have one of the following prefixes: From a54c8fbeb7e8974449fcacb71b5eae0f000017b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 17 May 2017 13:35:15 +0200 Subject: [PATCH 07/13] maintenance branch is now 1.3.4.dev --- .versioneer-lookup | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.versioneer-lookup b/.versioneer-lookup index d17ee7e6..9585f8ad 100644 --- a/.versioneer-lookup +++ b/.versioneer-lookup @@ -16,11 +16,11 @@ prerelease HEAD \(detached.* -# maintenance is currently the branch for preparation of maintenance release 1.3.3 +# maintenance is currently the branch for preparation of maintenance release 1.3.4 # so are any fix/... and improve/... branches -maintenance 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev -fix/.* 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev -improve/.* 1.3.3 0a69dbeddb301d5a32827a3f0d561f875df24234 pep440-dev +maintenance 1.3.4 3fbd477d15b5776ca929ea578c5437720aaf7f31 pep440-dev +fix/.* 1.3.4 3fbd477d15b5776ca929ea578c5437720aaf7f31 pep440-dev +improve/.* 1.3.4 3fbd477d15b5776ca929ea578c5437720aaf7f31 pep440-dev # staging/maintenance is currently the branch for preparation of 1.3.3rc3 (if we'll need that) staging/maintenance 1.3.3rc2 3fbd477d15b5776ca929ea578c5437720aaf7f31 pep440-dev From 7795320fc81f69c9d8629e919409167fce0e8e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 15 May 2017 13:05:39 +0200 Subject: [PATCH 08/13] Allow timelapse config through UI when not connected to printer That restriction didn't really make sense. As mentioned in #1918 --- src/octoprint/static/js/app/viewmodels/timelapse.js | 2 +- src/octoprint/templates/tabs/timelapse.jinja2 | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/octoprint/static/js/app/viewmodels/timelapse.js b/src/octoprint/static/js/app/viewmodels/timelapse.js index f6a96c68..ed26a414 100644 --- a/src/octoprint/static/js/app/viewmodels/timelapse.js +++ b/src/octoprint/static/js/app/viewmodels/timelapse.js @@ -48,7 +48,7 @@ $(function() { return ("timed" == self.timelapseType()); }); self.saveButtonEnabled = ko.pureComputed(function() { - return self.isDirty() && self.isOperational() && !self.isPrinting() && self.loginState.isUser(); + return self.isDirty() && !self.isPrinting() && self.loginState.isUser(); }); self.isOperational.subscribe(function() { diff --git a/src/octoprint/templates/tabs/timelapse.jinja2 b/src/octoprint/templates/tabs/timelapse.jinja2 index d749dcf7..0decec27 100644 --- a/src/octoprint/templates/tabs/timelapse.jinja2 +++ b/src/octoprint/templates/tabs/timelapse.jinja2 @@ -5,7 +5,7 @@

{{ _('Timelapse Configuration') }}

- @@ -16,25 +16,25 @@
- + {{ _('sec') }}
- + {{ _('fps') }}
- + {{ _('sec') }}
@@ -42,7 +42,7 @@
- + {{ _('mm') }}
{{ _('Enter the retraction z-hop used in the firmware or the gcode file to trigger snapshots for the timelapse only if a real layer change happens. For this to work properly your retraction z-hop has to be different from your layerheight!') }} From 9ad180c02a6adef24b2c1d87e6db2e91bc9451c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 15 May 2017 15:21:36 +0200 Subject: [PATCH 09/13] Disable "Upload to SD" ui elements while printing As suggested by @ntoff in #1914 --- src/octoprint/static/js/app/viewmodels/files.js | 5 +++-- src/octoprint/templates/overlays/dragndrop.jinja2 | 2 +- src/octoprint/templates/sidebar/files.jinja2 | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/octoprint/static/js/app/viewmodels/files.js b/src/octoprint/static/js/app/viewmodels/files.js index 5da2cd3a..6b94f997 100644 --- a/src/octoprint/static/js/app/viewmodels/files.js +++ b/src/octoprint/static/js/app/viewmodels/files.js @@ -841,13 +841,14 @@ $(function() { function evaluateDropzones() { var enableLocal = self.loginState.isUser(); - var enableSd = enableLocal && CONFIG_SD_SUPPORT && self.printerState.isSdReady(); + var enableSd = enableLocal && CONFIG_SD_SUPPORT && self.printerState.isSdReady() && !self.isPrinting(); self._setDropzone("local", enableLocal); self._setDropzone("sdcard", enableSd); } self.loginState.isUser.subscribe(evaluateDropzones); self.printerState.isSdReady.subscribe(evaluateDropzones); + self.isPrinting.subscribe(evaluateDropzones); evaluateDropzones(); self.requestData(); @@ -1106,7 +1107,7 @@ $(function() { if (foundLocal) { self.dropZoneLocalBackground.addClass("hover"); self.dropZoneSdBackground.removeClass("hover"); - } else if (foundSd && self.printerState.isSdReady()) { + } else if (foundSd && self.printerState.isSdReady() && !self.isPrinting()) { self.dropZoneSdBackground.addClass("hover"); self.dropZoneLocalBackground.removeClass("hover"); } else if (found) { diff --git a/src/octoprint/templates/overlays/dragndrop.jinja2 b/src/octoprint/templates/overlays/dragndrop.jinja2 index 91a74a38..bb67ae1b 100644 --- a/src/octoprint/templates/overlays/dragndrop.jinja2 +++ b/src/octoprint/templates/overlays/dragndrop.jinja2 @@ -4,7 +4,7 @@ {% if enableSdSupport %}

{{ _('Upload locally') }}
-

{{ _('Upload to SD') }}
({{ _('SD not initialized') }})
+

{{ _('Upload to SD') }}
({{ _('Cannot upload to printer\'s SD while printing') }})({{ _('SD not initialized') }})
{% else %}

{{ _('Upload') }}
diff --git a/src/octoprint/templates/sidebar/files.jinja2 b/src/octoprint/templates/sidebar/files.jinja2 index 99b199df..4a06d7d7 100644 --- a/src/octoprint/templates/sidebar/files.jinja2 +++ b/src/octoprint/templates/sidebar/files.jinja2 @@ -55,18 +55,18 @@
{% if enableSdSupport %} - + {{ _('Upload') }} - + {{ _('Upload to SD') }} - + {% else %} - + {{ _('Upload') }} From c1c75f032dfc1c720ebfc39985c872062e3a2639 Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2017 06:01:20 +0200 Subject: [PATCH 10/13] Fixed webcam not loading bug if first/initial tab is "Control" (cherry picked from commit d66a4f3) --- src/octoprint/static/js/app/viewmodels/control.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/octoprint/static/js/app/viewmodels/control.js b/src/octoprint/static/js/app/viewmodels/control.js index 544eeeed..ecf86eb7 100644 --- a/src/octoprint/static/js/app/viewmodels/control.js +++ b/src/octoprint/static/js/app/viewmodels/control.js @@ -442,6 +442,7 @@ $(function() { self.additionalControls = additionalControls; self.rerenderControls(); } + self._enableWebcam(); }; self.onFocus = function (data, event) { From dc8473bc4d5ddab59a0692a98fde47ad385ad6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 16 May 2017 13:54:28 +0200 Subject: [PATCH 11/13] Add check for valid job file type to job validation --- src/octoprint/printer/__init__.py | 4 ++++ src/octoprint/printer/standard.py | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/octoprint/printer/__init__.py b/src/octoprint/printer/__init__.py index e26a80e4..8e4b1e3c 100644 --- a/src/octoprint/printer/__init__.py +++ b/src/octoprint/printer/__init__.py @@ -299,6 +299,7 @@ class PrinterInterface(object): after the file is selected. Raises: + InvalidFileType: if the file is not a machinecode file and hence cannot be printed InvalidFileLocation: if an absolute path was provided and not contained within local storage or doesn't exist """ @@ -593,3 +594,6 @@ class UnknownScript(Exception): class InvalidFileLocation(Exception): pass + +class InvalidFileType(Exception): + pass diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index a0c1b817..45c309c7 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -17,9 +17,9 @@ import time from octoprint import util as util from octoprint.events import eventManager, Events -from octoprint.filemanager import FileDestinations, NoSuchStorage +from octoprint.filemanager import FileDestinations, NoSuchStorage, valid_file_type from octoprint.plugin import plugin_manager, ProgressPlugin -from octoprint.printer import PrinterInterface, PrinterCallback, UnknownScript, InvalidFileLocation +from octoprint.printer import PrinterInterface, PrinterCallback, UnknownScript, InvalidFileLocation, InvalidFileType from octoprint.printer.estimation import TimeEstimationHelper from octoprint.settings import settings from octoprint.util import comm as comm @@ -846,6 +846,9 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._stateMonitor.add_temperature(data) def _validateJob(self, filename, sd): + if not valid_file_type(filename, type="machinecode"): + raise InvalidFileType("{} is not a machinecode file, cannot print".format(filename)) + if sd: return From 9dfee34f01349830c7192a600022da3e55c854e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 16 May 2017 15:54:52 +0200 Subject: [PATCH 12/13] Fix various popup buttons allowing multiple clicks As suggested by @ntoff in #1914 --- .../announcements/static/js/announcements.js | 6 ++-- .../pluginmanager/static/js/pluginmanager.js | 12 ++++++- .../static/js/softwareupdate.js | 32 +++++++++++++++---- src/octoprint/static/js/app/helpers.js | 8 ++++- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/octoprint/plugins/announcements/static/js/announcements.js b/src/octoprint/plugins/announcements/static/js/announcements.js index 2fe4dbb7..be569b5f 100644 --- a/src/octoprint/plugins/announcements/static/js/announcements.js +++ b/src/octoprint/plugins/announcements/static/js/announcements.js @@ -258,22 +258,22 @@ $(function() { buttons: [{ text: gettext("Later"), click: function(notice) { - self.hiddenChannels.push(key); notice.remove(); + self.hiddenChannels.push(key); } }, { text: gettext("Mark read"), click: function(notice) { - self.markRead(key, value.last); notice.remove(); + self.markRead(key, value.last); } }, { text: gettext("Read..."), addClass: "btn-primary", click: function(notice) { + notice.remove(); self.showAnnouncementDialog(key); self.markRead(key, value.last); - notice.remove(); } }] }, diff --git a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js index 0ee352e0..6ea6e897 100644 --- a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js +++ b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js @@ -685,17 +685,21 @@ $(function() { hide: false }; + var restartClicked = false; if (self.restartCommandSpec) { options.confirm = { confirm: true, buttons: [{ text: gettext("Restart now"), - click: function () { + click: function (notice) { + if (restartClicked) return; + restartClicked = true; showConfirmationDialog({ message: gettext("This will restart your OctoPrint server."), onproceed: function() { OctoPrint.system.executeCommand("core", "restart") .done(function() { + notice.remove(); new PNotify({ title: gettext("Restart in progress"), text: gettext("The server is now being restarted in the background") @@ -707,6 +711,9 @@ $(function() { text: gettext("Trying to restart the server produced an error, please check octoprint.log for details. You'll have to restart manually.") }) }); + }, + onclose: function() { + restartClicked = false; } }); } @@ -716,6 +723,7 @@ $(function() { notification = PNotify.singleButtonNotify(options); } else if (response.needs_refresh) { + var refreshClicked = false; notification = PNotify.singleButtonNotify({ title: titleSuccess, text: textReload, @@ -724,6 +732,8 @@ $(function() { buttons: [{ text: gettext("Reload now"), click: function () { + if (refreshClicked) return; + refreshClicked = true; location.reload(true); } }] diff --git a/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js b/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js index cfc20cb5..5431186d 100644 --- a/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js +++ b/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js @@ -123,8 +123,9 @@ $(function() { self.config_updateMethod = ko.observable(); self.config_releaseChannel = ko.observable(); - self.configurationDialog = $("#settings_plugin_softwareupdate_configurationdialog"); - self.confirmationDialog = $("#softwareupdate_confirmation_dialog"); + self.configurationDialog = undefined; + self.confirmationDialog = undefined; + self._updateClicked = false; self.config_availableCheckTypes = ko.observableArray([]); self.config_availableReleaseChannels = ko.observableArray([]); @@ -357,7 +358,11 @@ $(function() { }, { text: gettext("Update now"), addClass: "btn-primary", - click: self.update + click: function() { + if (self._updateClicked) return; + self._updateClicked = true; + self.update(); + } }] }; options["buttons"] = { @@ -501,8 +506,14 @@ $(function() { }; self.update = function(force) { - if (self.updateInProgress) return; - if (!self.loginState.isAdmin()) return; + if (self.updateInProgress) { + self._updateClicked = false; + return; + } + if (!self.loginState.isAdmin()) { + self._updateClicked = false; + return; + } if (self.printerState.isPrinting()) { self._showPopup({ @@ -510,6 +521,7 @@ $(function() { text: gettext("A print job is currently in progress. Updating will be prevented until it is done."), type: "error" }); + self._updateClicked = false; } else { self.forceUpdate = (force == true); self.confirmationDialog.modal("show"); @@ -518,9 +530,13 @@ $(function() { }; self.confirmUpdate = function() { - self.confirmationDialog.modal("hide"); self.performUpdate(self.forceUpdate, _.map(self.availableAndPossible(), function(info) { return info.key })); + self.confirmationDialog.modal("hide"); + }; + + self.confirmationHidden = function() { + self._updateClicked = false; }; self._showWorkingDialog = function(title) { @@ -578,6 +594,10 @@ $(function() { self.onStartup = function() { self.workingDialog = $("#settings_plugin_softwareupdate_workingdialog"); self.workingOutput = $("#settings_plugin_softwareupdate_workingdialog_output"); + self.configurationDialog = $("#settings_plugin_softwareupdate_configurationdialog"); + self.confirmationDialog = $("#softwareupdate_confirmation_dialog"); + + self.confirmationDialog.on("hidden", self.confirmationHidden); }; self.onServerDisconnect = function() { diff --git a/src/octoprint/static/js/app/helpers.js b/src/octoprint/static/js/app/helpers.js index 98a24d5b..744ce15b 100644 --- a/src/octoprint/static/js/app/helpers.js +++ b/src/octoprint/static/js/app/helpers.js @@ -646,6 +646,7 @@ function showConfirmationDialog(msg, onacknowledge, options) { var proceed = options.proceed || gettext("Proceed"); var proceedClass = options.proceedClass || "danger"; var onproceed = options.onproceed || undefined; + var onclose = options.onclose || undefined; var dialogClass = options.dialogClass || ""; var modalHeader = $('

' + title + '

'); @@ -663,14 +664,19 @@ function showConfirmationDialog(msg, onacknowledge, options) { .append($('
').addClass('modal-header').append(modalHeader)) .append($('
').addClass('modal-body').append(modalBody)) .append($('
').addClass('modal-footer').append(cancelButton).append(proceedButton)); + modal.on('hidden', function(event) { + if (onclose && _.isFunction(onclose)) { + onclose(event); + } + }); modal.modal("show"); proceedButton.click(function(e) { e.preventDefault(); - modal.modal("hide"); if (onproceed && _.isFunction(onproceed)) { onproceed(e); } + modal.modal("hide"); }); return modal; From 9fac314d7138f79091a9bd95eccd222bcd12e8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 17 May 2017 12:56:14 +0200 Subject: [PATCH 13/13] SWU: restart asynchronously instead of synchronously Otherwise we will block ourselves, waiting for the restart command to complete which it only can when we are no longer there. Should reduce restart times on update significantly. Downside is that we no longer can wait for the return code of the call. However, that should be caught by our UI handler timing out for the restart and showing an error prompting the user to restart manually. --- src/octoprint/plugins/softwareupdate/__init__.py | 2 +- src/octoprint/plugins/softwareupdate/util.py | 4 ++-- src/octoprint/server/__init__.py | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/octoprint/plugins/softwareupdate/__init__.py b/src/octoprint/plugins/softwareupdate/__init__.py index 507c5593..ee0df3da 100644 --- a/src/octoprint/plugins/softwareupdate/__init__.py +++ b/src/octoprint/plugins/softwareupdate/__init__.py @@ -868,7 +868,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin, self._logger.info("Restarting...") try: - util.execute(restart_command) + util.execute(restart_command, evaluate_returncode=False, async=True) except exceptions.ScriptError as e: self._logger.exception("Error while restarting via command {}".format(restart_command)) self._logger.warn("Restart stdout:\n{}".format(e.stdout)) diff --git a/src/octoprint/plugins/softwareupdate/util.py b/src/octoprint/plugins/softwareupdate/util.py index 27335182..020fce3d 100644 --- a/src/octoprint/plugins/softwareupdate/util.py +++ b/src/octoprint/plugins/softwareupdate/util.py @@ -9,12 +9,12 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms from .exceptions import ScriptError -def execute(command, cwd=None, evaluate_returncode=True): +def execute(command, cwd=None, evaluate_returncode=True, async=False): import sarge p = None try: - p = sarge.run(command, cwd=cwd, stdout=sarge.Capture(), stderr=sarge.Capture()) + p = sarge.run(command, cwd=cwd, stdout=sarge.Capture(), stderr=sarge.Capture(), async=async) except: returncode = p.returncode if p is not None else None stdout = p.stdout.text if p is not None and p.stdout is not None else "" diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 20397ef7..4f17e23c 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -550,7 +550,7 @@ class Server(object): "on_shutdown", sorting_context="ShutdownPlugin.on_shutdown") - # wait for shutdown even to be processed, but maximally for 15s + # wait for shutdown event to be processed, but maximally for 15s event_timeout = 15.0 if eventManager.join(timeout=event_timeout): self._logger.warn("Event loop was still busy processing after {}s, shutting down anyhow".format(event_timeout)) @@ -565,13 +565,16 @@ class Server(object): def sigterm_handler(*args, **kwargs): # will stop tornado on SIGTERM, making the program exit cleanly def shutdown_tornado(): + self._logger.debug("Shutting down tornado's IOLoop...") ioloop.stop() + self._logger.debug("SIGTERM received...") ioloop.add_callback_from_signal(shutdown_tornado) signal.signal(signal.SIGTERM, sigterm_handler) try: # this is the main loop - as long as tornado is running, OctoPrint is running ioloop.start() + self._logger.debug("Tornado's IOLoop stopped") except (KeyboardInterrupt, SystemExit): pass except: