" + _.sprintf(gettext("Failed to remove config %(name)s.
Please consult octoprint.log for details.
"), { name: _.escape(backup) }); + html += pnotifyAdditionalInfo('' + _.escape(response.responseText) + ""); + new PNotify({ + title: gettext("Could not remove config"), + text: html, + type: "error", + hide: false, + }); + }); + }; + + showConfirmationDialog( + _.sprintf(gettext('You are about to delete backed config file "%(name)s".'), { + name: _.escape(backup), + }), + perform + ); + }; + + self.restoreBak = function (backup) { + if (!self.loginState.hasPermission(self.access.permissions.PLUGIN_KLIPPER_CONFIG)) return; + + var restore = function () { + OctoPrint.plugins.klipper.restoreBackup(backup).done(function (response) { + self.klipperViewModel.consoleMessage("debug", "restoreCfg: " + backup + " / " + response.restored); + }); + }; + + var html = "
" + gettext("This will overwrite any file with the same name on the configpath.") + "
" + "" + backup + "
"; + + showConfirmationDialog({ + title: gettext("Are you sure you want to restore now?"), + html: html, + proceed: gettext("Proceed"), + onproceed: restore, + }); + }; + + self.markFilesOnPage = function () { + self.markedForFileRestore(_.uniq(self.markedForFileRestore().concat(_.map(self.backups.paginatedItems(), "file")))); + }; + + self.markAllFiles = function () { + self.markedForFileRestore(_.map(self.backups.allItems, "file")); + }; + + self.clearMarkedFiles = function () { + self.markedForFileRestore.removeAll(); + }; + + self.restoreMarkedFiles = function () { + var perform = function () { + self._bulkRestore(self.markedForFileRestore()).done(function () { + self.markedForFileRestore.removeAll(); + }); + }; + + showConfirmationDialog( + _.sprintf(gettext("You are about to restore %(count)d backed config files."), { + count: self.markedForFileRestore().length, + }), + perform + ); + }; + + self.removeMarkedFiles = function () { + var perform = function () { + self._bulkRemove(self.markedForFileRestore()).done(function () { + self.markedForFileRestore.removeAll(); + }); + }; + + showConfirmationDialog( + _.sprintf(gettext("You are about to delete %(count)d backed config files."), { + count: self.markedForFileRestore().length, + }), + perform + ); + }; + + self._bulkRestore = function (files) { + var title, message, handler; + + title = gettext("Restoring klipper config files"); + self.klipperViewModel.consoleMessage("debug", title); + message = _.sprintf(gettext("Restoring %(count)d backed config files..."), { + count: files.length, + }); + + handler = function (filename) { + return OctoPrint.plugins.klipper + .restoreBackup(filename) + .done(function (response) { + deferred.notify( + _.sprintf(gettext("Restored %(filename)s..."), { + filename: _.escape(filename), + }), + true + ); + self.klipperViewModel.consoleMessage("debug", "restoreCfg: " + filename + " / " + response); + self.markedForFileRestore.remove(function (item) { + return item.name == filename; + }); + }) + .fail(function () { + deferred.notify(_.sprintf(gettext("Restoring of %(filename)s failed, continuing..."), { filename: _.escape(filename) }), false); + }); + }; + + var deferred = $.Deferred(); + + var promise = deferred.promise(); + + var options = { + title: title, + message: message, + max: files.length, + output: true, + }; + showProgressModal(options, promise); + + var requests = []; + + _.each(files, function (filename) { + var request = handler(filename); + requests.push(request); + }); + + $.when.apply($, _.map(requests, wrapPromiseWithAlways)).done(function () { + deferred.resolve(); + }); + + return promise; + }; + + self._bulkRemove = function (files) { + var title, message, handler; + + title = gettext("Deleting backup files"); + message = _.sprintf(gettext("Deleting %(count)d backed files..."), { + count: files.length, + }); + + handler = function (filename) { + return OctoPrint.plugins.klipper + .deleteBackup(filename) + .done(function () { + deferred.notify(_.sprintf(gettext("Deleted %(filename)s..."), { filename: _.escape(filename) }), true); + self.markedForFileRestore.remove(function (item) { + return item.name == filename; + }); + }) + .fail(function () { + deferred.notify(_.sprintf(gettext("Deleting of %(filename)s failed, continuing..."), { filename: _.escape(filename) }), false); + }); + }; + + var deferred = $.Deferred(); + var promise = deferred.promise(); + var options = { + title: title, + message: message, + max: files.length, + output: true, + }; + showProgressModal(options, promise); + + var requests = []; + _.each(files, function (filename) { + var request = handler(filename); + requests.push(request); + }); + + $.when.apply($, _.map(requests, wrapPromiseWithAlways)).done(function () { + deferred.resolve(); + self.listBakFiles(); + }); + + return promise; + }; + } + + OCTOPRINT_VIEWMODELS.push({ + construct: KlipperBackupViewModel, + dependencies: ["loginStateViewModel", "klipperViewModel", "accessViewModel"], + elements: ["#klipper_backups_dialog"], + }); +}); diff --git a/octoprint_klipper/static/js/klipper_editor.js b/octoprint_klipper/static/js/klipper_editor.js new file mode 100644 index 0000000..8e34c34 --- /dev/null +++ b/octoprint_klipper/static/js/klipper_editor.js @@ -0,0 +1,398 @@ +//" + gettext("Reload Configfile after SAVE_CONFIG?") + "
"; + + showConfirmationDialog({ + title: gettext("Externally changed config") + " " + baseconfig, + html: html, + proceed: gettext("Proceed"), + onproceed: perform, + }); + } + } + }; + + self.askSaveFaulty = function () { + return new Promise(function (resolve) { + var html = "" + _.sprintf(gettext("Failed to remove config %(name)s.
Please consult octoprint.log for details.
"), { name: _.escape(config) }); + html += pnotifyAdditionalInfo('' + _.escape(response.responseText) + ""); + new PNotify({ + title: gettext("Could not remove config"), + text: html, + type: "error", + hide: false, + }); + }); + }; + + showConfirmationDialog( + _.sprintf(gettext('You are about to delete config file "%(name)s".'), { + name: _.escape(config), + }), + perform + ); + }; + + self.markFilesOnPage = function () { + self.markedForFileRemove(_.uniq(self.markedForFileRemove().concat(_.map(self.configs.paginatedItems(), "file")))); + }; + + self.markAllFiles = function () { + self.markedForFileRemove(_.map(self.configs.allItems, "file")); + }; + + self.clearMarkedFiles = function () { + self.markedForFileRemove.removeAll(); + }; + + self.removeMarkedFiles = function () { + var perform = function () { + self._bulkRemove(self.markedForFileRemove()).done(function () { + self.markedForFileRemove.removeAll(); + }); + }; + + showConfirmationDialog( + _.sprintf(gettext("You are about to delete %(count)d config files."), { + count: self.markedForFileRemove().length, + }), + perform + ); + }; + + self._bulkRemove = function (files) { + var title, message, handler; + + title = gettext("Deleting config files"); + message = _.sprintf(gettext("Deleting %(count)d config files..."), { + count: files.length, + }); + + handler = function (filename) { + return OctoPrint.plugins.klipper + .deleteCfg(filename) + .done(function () { + deferred.notify( + _.sprintf(gettext("Deleted %(filename)s..."), { + filename: _.escape(filename), + }), + true + ); + self.markedForFileRemove.remove(function (item) { + return item.name == filename; + }); + }) + .fail(function () { + deferred.notify(_.sprintf(gettext("Deleting of %(filename)s failed, continuing..."), { filename: _.escape(filename) }), false); + }); + }; + + var deferred = $.Deferred(); + var promise = deferred.promise(); + var options = { + title: title, + message: message, + max: files.length, + output: true, + }; + showProgressModal(options, promise); + + var requests = []; + _.each(files, function (filename) { + var request = handler(filename); + requests.push(request); + }); + + $.when.apply($, _.map(requests, wrapPromiseWithAlways)).done(function () { + deferred.resolve(); + self.listCfgFiles(); + }); + + return promise; + }; + + self.showBackupsDialog = function () { + self.klipperViewModel.consoleMessage("debug", "showBackupsDialog"); + self.klipperBackupViewModel.listBakFiles(); + var dialog = $("#klipper_backups_dialog"); + dialog.modal({ + show: "true", + }); + }; + + self.showEditor = function () { + if (!self.klipperViewModel.hasRight("CONFIG")) return; + + var editorDialog = $("#klipper_editor"); + editorDialog.modal({ + show: "true", + width: "90%", + backdrop: "static", + }); + } + + self.newFile = function () { + if (!self.klipperViewModel.hasRight("CONFIG")) return; + var config = { + content: "", + file: "Change Filename", + }; + self.klipperEditorViewModel.process(config).then( + function() { self.showEditor(); } + ); + }; + + self.openConfig = function (file) { + if (!self.klipperViewModel.hasRight("CONFIG")) return; + + OctoPrint.plugins.klipper.getCfg(file).done(function (response) { + var config = { + content: response.response.config, + file: file, + }; + self.klipperEditorViewModel.process(config).then( + function() { self.showEditor(); } + ); + }); + }; + + self.addMacro = function () { + self.settings.settings.plugins.klipper.macros.push({ + name: "Macro", + macro: "", + sidebar: true, + tab: true, + }); + }; + + self.removeMacro = function (macro) { + self.settings.settings.plugins.klipper.macros.remove(macro); + }; + + self.moveMacroUp = function (macro) { + self.moveItemUp(self.settings.settings.plugins.klipper.macros, macro); + }; + + self.moveMacroDown = function (macro) { + self.moveItemDown(self.settings.settings.plugins.klipper.macros, macro); + }; + + self.addProbePoint = function () { + self.settings.settings.plugins.klipper.probe.points.push({ + name: "point-#", + x: 0, + y: 0, + z: 0, + }); + }; + + self.removeProbePoint = function (point) { + self.settings.settings.plugins.klipper.probe.points.remove(point); + }; + + self.moveProbePointUp = function (macro) { + self.moveItemUp(self.settings.settings.plugins.klipper.probe.points, macro); + }; + + self.moveProbePointDown = function (macro) { + self.moveItemDown(self.settings.settings.plugins.klipper.probe.points, macro); + }; + + self.moveItemDown = function (list, item) { + var i = list().indexOf(item); + if (i < list().length - 1) { + var rawList = list(); + list.splice(i, 2, rawList[i + 1], rawList[i]); + } + }; + + self.moveItemUp = function (list, item) { + var i = list().indexOf(item); + if (i > 0) { + var rawList = list(); + list.splice(i - 1, 2, rawList[i], rawList[i - 1]); + } + }; + + self.onDataUpdaterPluginMessage = function (plugin, data) { + if (plugin == "klipper" && data.type == "reload" && data.subtype == "configlist") { + self.klipperViewModel.consoleMessage("debug", "onDataUpdaterPluginMessage klipper reload configlist"); + self.listCfgFiles(); + } + }; + } + + OCTOPRINT_VIEWMODELS.push({ + construct: KlipperSettingsViewModel, + dependencies: ["settingsViewModel", "klipperViewModel", "klipperEditorViewModel", "klipperBackupViewModel", "accessViewModel"], + elements: ["#settings_plugin_klipper"], + }); }); diff --git a/octoprint_klipper/static/js/lib/ace/mode-klipper_config.js b/octoprint_klipper/static/js/lib/ace/mode-klipper_config.js index 92a538a..0aad9e4 100644 --- a/octoprint_klipper/static/js/lib/ace/mode-klipper_config.js +++ b/octoprint_klipper/static/js/lib/ace/mode-klipper_config.js @@ -160,7 +160,7 @@ ace.define("ace/mode/klipper_config_highlight_rules",[], function(require, expor caseInsensitive: true }, { token: "support.type", - regex: /[\^~!]*(?:z:)?[a-zA-Z]{1,2}\d{1,2}(?:\.\d{1,2})?/, + regex: /[\^~!]*(?:z:)?[a-zA-Z]{1,4}(?:gpio)?\d{1,2}(?:\.\d{1,2})?/, caseInsensitive: true }], "#config_line_start_gcode": [{ @@ -192,8 +192,8 @@ ace.define("ace/mode/klipper_config_highlight_rules",[], function(require, expor }] }], "#config_line": [{ - token: ["variable.name", "variable.name"], - regex: /(?!gcode|sensor_type|rpi:)(\w+)(\s*[:]\s*)/, + token: ["variable.name", "variable.name", "variable.name", "variable.name"], + regex: /(?!gcode|sensor_type|rpi:)(\w+)(\s*[:]\s*\w+[:])|(?!gcode|sensor_type|rpi:)(\w+)(\s*[:]\s*)/, push: [{ token: "text", regex: /$/, diff --git a/octoprint_klipper/templates/klipper_backups_dialog.jinja2 b/octoprint_klipper/templates/klipper_backups_dialog.jinja2 new file mode 100644 index 0000000..1754550 --- /dev/null +++ b/octoprint_klipper/templates/klipper_backups_dialog.jinja2 @@ -0,0 +1,110 @@ + diff --git a/octoprint_klipper/templates/klipper_editor.jinja2 b/octoprint_klipper/templates/klipper_editor.jinja2 new file mode 100644 index 0000000..23f131b --- /dev/null +++ b/octoprint_klipper/templates/klipper_editor.jinja2 @@ -0,0 +1,46 @@ + diff --git a/octoprint_klipper/templates/klipper_graph_dialog.jinja2 b/octoprint_klipper/templates/klipper_graph_dialog.jinja2 index a0508e8..5c8b675 100644 --- a/octoprint_klipper/templates/klipper_graph_dialog.jinja2 +++ b/octoprint_klipper/templates/klipper_graph_dialog.jinja2 @@ -1,12 +1,12 @@