Skip to content

Commit 95ef253

Browse files
committed
✨ New info warning type & warn about fw dev builds
1 parent 3e551fe commit 95ef253

File tree

10 files changed

+162
-11
lines changed

10 files changed

+162
-11
lines changed

octoprint_firmware_check/__init__.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
from .checks import Severity
1818
from .checks.firmware_broken import FirmwareBrokenChecks
19+
from .checks.firmware_development import FirmwareDevelopmentChecks
1920
from .checks.firmware_unsafe import FirmwareUnsafeChecks
2021

2122
TERMINAL_WARNING = """
@@ -27,9 +28,19 @@
2728
2829
"""
2930

31+
TERMINAL_INFO = """
32+
---------------------------------------------------------------------------
33+
{message}
34+
35+
Learn more at {url}
36+
---------------------------------------------------------------------------
37+
38+
"""
39+
3040
FIRMWARE_CHECKS = {
3141
"firmware-unsafe": FirmwareUnsafeChecks.as_dict(),
3242
"firmware-broken": FirmwareBrokenChecks.as_dict(),
43+
"firmware-development": FirmwareDevelopmentChecks.as_dict(),
3344
}
3445

3546

@@ -38,6 +49,7 @@ class FirmwareCheckPlugin(
3849
octoprint.plugin.EventHandlerPlugin,
3950
octoprint.plugin.SimpleApiPlugin,
4051
octoprint.plugin.TemplatePlugin,
52+
octoprint.plugin.SettingsPlugin,
4153
):
4254

4355
# noinspection PyMissingConstructor
@@ -55,7 +67,19 @@ def get_template_configs(self):
5567
data_bind="visible: printerState.isOperational() && loginState.isAdmin() && warnings().length > 0",
5668
icon="exclamation-triangle",
5769
styles_wrapper=["display: none"],
58-
)
70+
template="firmware_check_sidebar_warning.jinja2",
71+
suffix="_warning",
72+
),
73+
dict(
74+
type="sidebar",
75+
name=gettext("Info"),
76+
data_bind="visible: printerState.isOperational() && loginState.isAdmin() && infos().length > 0",
77+
icon="info-circle",
78+
styles_wrapper=["display: none"],
79+
template="firmware_check_sidebar_info.jinja2",
80+
suffix="_info",
81+
),
82+
dict(type="settings", name=gettext("Firmware Check"), custom_bindings=False),
5983
]
6084

6185
##~~ AssetPlugin API
@@ -83,6 +107,11 @@ def on_api_get(self, request):
83107
return flask.make_response("Insufficient rights", 403)
84108
return flask.jsonify(self._warnings)
85109

110+
##~~ SettingsPlugin API
111+
112+
def get_settings_defaults(self):
113+
return {"ignore_infos": False}
114+
86115
##~~ GCODE received hook handler
87116

88117
def on_gcode_received(self, comm_instance, line, *args, **kwargs):
@@ -220,15 +249,25 @@ def _run_checks(self, check_type, *args, **kwargs):
220249
self._ping_clients()
221250

222251
def _register_warning(self, warning_type, message, severity, url):
252+
output = TERMINAL_WARNING
253+
if severity == Severity.INFO:
254+
output = TERMINAL_INFO
255+
223256
self._log_to_terminal(
224-
TERMINAL_WARNING.format(
257+
output.format(
225258
message="\n".join(textwrap.wrap(message, 75)),
226259
warning_type=warning_type,
227260
url=url,
228261
)
229262
)
230263
self._warnings[warning_type] = dict(message=message, severity=severity, url=url)
231264

265+
logline = "{}. More information at {}".format(message, url)
266+
if severity == Severity.INFO:
267+
self._logger.info(logline)
268+
else:
269+
self._logger.warning(logline)
270+
232271
def _reset_warnings(self):
233272
self._warnings.clear()
234273
self._ping_clients()

octoprint_firmware_check/checks/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,5 @@ def received(self, line):
150150

151151
class Severity(object):
152152
INFO = "info"
153+
WARNING = "warning"
153154
CRITICAL = "critical"

octoprint_firmware_check/checks/firmware_broken.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def as_dict(cls):
1919
"communication protocol. This may cause print failures or other annoyances. "
2020
"You'll need to take additional steps for OctoPrint to fully work with it."
2121
),
22-
severity=Severity.INFO,
22+
severity=Severity.WARNING,
2323
)
2424

2525

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import absolute_import, division, print_function, unicode_literals
3+
4+
__license__ = "GNU Affero General Public License http://www.gnu.org/licenses/agpl.html"
5+
__copyright__ = "Copyright (C) 2019 The OctoPrint Project - Released under terms of the AGPLv3 License"
6+
7+
from flask_babel import gettext
8+
9+
from . import Check, Severity
10+
11+
12+
class FirmwareDevelopmentChecks(object):
13+
@classmethod
14+
def as_dict(cls):
15+
return dict(
16+
checks=(MarlinBugfixCheck(),),
17+
message=gettext(
18+
"Your printer's firmware is a development build. It might be more unstable "
19+
"than a release version and should be updated regularly."
20+
),
21+
severity=Severity.INFO,
22+
)
23+
24+
25+
class MarlinBugfixCheck(Check):
26+
"""
27+
Marlin bugfix builds.
28+
29+
Identified by firmware name that contains "Marlin bugfix-"
30+
"""
31+
32+
name = "marlin_bugfix"
33+
34+
def m115(self, name, data):
35+
self._triggered = name and "marlin bugfix-" in name.lower()
36+
self._active = False

octoprint_firmware_check/static/css/firmware_check.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

octoprint_firmware_check/static/js/firmware_check.js

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ $(function () {
55
self.loginState = parameters[0];
66
self.printerState = parameters[1];
77
self.access = parameters[2];
8+
self.settings = parameters[3];
89

910
self.warnings = ko.observableArray([]);
11+
self.infos = ko.observableArray([]);
12+
13+
self.disablingInfos = ko.observable(false);
1014

1115
self.requestData = function () {
1216
if (
@@ -28,22 +32,47 @@ $(function () {
2832

2933
self.fromResponse = function (data) {
3034
var warnings = [];
35+
var infos = [];
3136
_.each(data, function (data, warning_type) {
32-
warnings.push({
37+
var item = {
3338
type: warning_type,
3439
message: gettext(data.message),
3540
severity: data.severity,
3641
url: data.url
37-
});
42+
};
43+
if (data.severity === "info") {
44+
if (!self.settings.settings.plugins.firmware_check.ignore_infos()) {
45+
infos.push(item);
46+
}
47+
} else {
48+
warnings.push(item);
49+
}
3850
});
3951
self.warnings(warnings);
52+
self.infos(infos);
4053
};
4154

4255
self.onStartup = function () {
4356
self.requestData();
4457
};
4558

46-
self.onUserPermissionsChanged = self.onUserLoggedIn = self.onUserLoggedOut = function () {
59+
var subbed = false;
60+
self.onStartup = self.onUserPermissionsChanged = self.onUserLoggedIn = self.onUserLoggedOut = function () {
61+
if (
62+
self.settings &&
63+
self.settings.settings &&
64+
self.settings.settings.plugins &&
65+
self.settings.settings.plugins.firmware_check &&
66+
!subbed
67+
) {
68+
subbed = true;
69+
self.settings.settings.plugins.firmware_check.ignore_infos.subscribe(
70+
function () {
71+
self.requestData();
72+
}
73+
);
74+
}
75+
4776
self.requestData();
4877
};
4978

@@ -70,17 +99,40 @@ $(function () {
7099
return gettext("Critical Warning: Firmware Unsafe");
71100
case "firmware-broken":
72101
return gettext("Warning: Firmware Broken");
102+
case "firmware-development":
103+
return gettext("Info: Firmware Development Build");
73104
default:
74105
return data.severity === "critical"
75106
? gettext("Critical Warning")
76-
: gettext("Warning");
107+
: data.severity === "warning"
108+
? gettext("Warning")
109+
: gettext("Info");
110+
}
111+
};
112+
113+
self.disableInfos = function () {
114+
if (self.loginState.hasPermission(self.access.permissions.SETTINGS)) {
115+
self.disablingInfos(true);
116+
OctoPrint.settings
117+
.savePluginSettings("firmware_check", {ignore_infos: true})
118+
.always(function () {
119+
self.disablingInfos(false);
120+
});
77121
}
78122
};
79123
}
80124

81125
OCTOPRINT_VIEWMODELS.push({
82126
construct: FirmwareCheckViewModel,
83-
dependencies: ["loginStateViewModel", "printerStateViewModel", "accessViewModel"],
84-
elements: ["#sidebar_plugin_firmware_check_wrapper"]
127+
dependencies: [
128+
"loginStateViewModel",
129+
"printerStateViewModel",
130+
"accessViewModel",
131+
"settingsViewModel"
132+
],
133+
elements: [
134+
"#sidebar_plugin_firmware_check_warning_wrapper",
135+
"#sidebar_plugin_firmware_check_info_wrapper"
136+
]
85137
});
86138
});

octoprint_firmware_check/static/less/firmware_check.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#sidebar_plugin_firmware_check_wrapper {
1+
#sidebar_plugin_firmware_check_warning_wrapper {
22
border: 1px solid #b94a48;
33

44
.accordion-heading {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>{{ _('Firmware Check') }}</h3>
2+
3+
<form class="form-horizontal" onsubmit="return false;">
4+
<div class="control-group">
5+
<div class="controls">
6+
<label class="checkbox">
7+
<input type="checkbox" data-bind="checked: settings.plugins.firmware_check.ignore_infos"> {{ _('Disable warnings of severity "info"') }}
8+
</label>
9+
<span class="help-block">{{ _('Check this to disable warnings from firmware checks that are only of informational "heads-up" nature, like running a firmware development build.') }}</span>
10+
</div>
11+
</div>
12+
</form>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!-- ko foreach: infos -->
2+
<p><strong data-bind="text: $root.warningText($data)"></strong></p>
3+
<p class="firmware_check_info" data-bind="class: $root.cssClass($data)">
4+
<span data-bind="text: message"></span><br>
5+
<a target="_blank" rel="noreferrer noopener" data-bind="attr: {href: url}">{{ _('Learn more...') }}</a>
6+
</p>
7+
<!-- /ko -->
8+
9+
<small>
10+
<a href="javascript:void(0)" data-bind="click: disableInfos">{{ _('Disable firmware checks of severity "Info"') }}</a> <i class="fa fa-spinner fa-spin" data-bind="visible: disablingInfos"></i>
11+
</small>

0 commit comments

Comments
 (0)