Implement Configpath and Logpath Validation
Added JS popup handler. Added configpath and logpath validation when settings are saved. Add logpath validation Change file checking method Check new values instead of old settings on save
This commit is contained in:
parent
a2291b1a3d
commit
e553a69ff5
|
@ -81,41 +81,55 @@ class KlipperPlugin(
|
||||||
def on_settings_load(self):
|
def on_settings_load(self):
|
||||||
data = octoprint.plugin.SettingsPlugin.on_settings_load(self)
|
data = octoprint.plugin.SettingsPlugin.on_settings_load(self)
|
||||||
|
|
||||||
filepath = os.path.expanduser(
|
configpath = os.path.expanduser(
|
||||||
self._settings.get(["configuration", "configpath"])
|
self._settings.get(["configuration", "configpath"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logpath = os.path.expanduser(
|
||||||
|
self._settings.get(["configuration", "logpath"])
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
f = open(filepath, "r")
|
f = open(configpath, "r")
|
||||||
data["config"] = f.read()
|
data["config"] = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
self._logger.error(
|
self._logger.error(
|
||||||
"Error: Klipper config file not found at: {}".format(filepath)
|
"Error: Klipper config file not found at: {}".format(configpath)
|
||||||
)
|
)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def on_settings_save(self, data):
|
def on_settings_save(self, data):
|
||||||
|
if self.keyexists(data, "configuration", "configpath"):
|
||||||
|
configpath = os.path.expanduser(
|
||||||
|
data["configuration"]["configpath"]
|
||||||
|
)
|
||||||
|
self.checkFile("config",configpath)
|
||||||
|
|
||||||
|
if self.keyexists(data, "configuration", "logpath"):
|
||||||
|
logpath = os.path.expanduser(
|
||||||
|
data["configuration"]["logpath"]
|
||||||
|
)
|
||||||
|
self.checkFile("log",logpath)
|
||||||
|
|
||||||
if "config" in data:
|
if "config" in data:
|
||||||
try:
|
try:
|
||||||
filepath = os.path.expanduser(
|
|
||||||
self._settings.get(["configuration", "configpath"])
|
|
||||||
)
|
|
||||||
data["config"] = data["config"].encode('utf-8')
|
data["config"] = data["config"].encode('utf-8')
|
||||||
|
|
||||||
f = open(filepath, "w")
|
f = open(configpath, "w")
|
||||||
f.write(data["config"])
|
f.write(data["config"])
|
||||||
f.close()
|
f.close()
|
||||||
self._logger.info(
|
self._logger.error(
|
||||||
"Writing Klipper config to {}".format(filepath)
|
"Writing Klipper config to {}".format(configpath)
|
||||||
)
|
)
|
||||||
# Restart klipply to reload config
|
# Restart klipply to reload config
|
||||||
self._printer.commands(self._settings.get(["configuration", "reload_command"]))
|
self._printer.commands(self._settings.get(["configuration", "reload_command"]))
|
||||||
self.logInfo("Reloading Klipper Configuration.")
|
self.logInfo("Reloading Klipper Configuration.")
|
||||||
except IOError:
|
except IOError:
|
||||||
self._logger.error(
|
self._logger.error(
|
||||||
"Error: Couldn't write Klipper config file: {}".format(filepath)
|
"Error: Couldn't write Klipper config file: {}".format(configpath)
|
||||||
)
|
)
|
||||||
data.pop("config", None) # we dont want to write the klipper conf to the octoprint settings
|
data.pop("config", None) # we dont want to write the klipper conf to the octoprint settings
|
||||||
else:
|
else:
|
||||||
octoprint.plugin.SettingsPlugin.on_settings_save(self, data)
|
octoprint.plugin.SettingsPlugin.on_settings_save(self, data)
|
||||||
|
|
||||||
|
@ -324,13 +338,14 @@ class KlipperPlugin(
|
||||||
)
|
)
|
||||||
|
|
||||||
#-- Helpers
|
#-- Helpers
|
||||||
def sendMessage(self, type, subtype, payload):
|
def sendMessage(self, type, subtype, title, payload):
|
||||||
self._plugin_manager.send_plugin_message(
|
self._plugin_manager.send_plugin_message(
|
||||||
self._identifier,
|
self._identifier,
|
||||||
dict(
|
dict(
|
||||||
time=datetime.datetime.now().strftime("%H:%M:%S"),
|
time=datetime.datetime.now().strftime("%H:%M:%S"),
|
||||||
type=type,
|
type=type,
|
||||||
subtype=subtype,
|
subtype=subtype,
|
||||||
|
title=title,
|
||||||
payload=payload
|
payload=payload
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -339,13 +354,25 @@ class KlipperPlugin(
|
||||||
self._printer.commands("STATUS")
|
self._printer.commands("STATUS")
|
||||||
|
|
||||||
def updateStatus(self, type, status):
|
def updateStatus(self, type, status):
|
||||||
self.sendMessage("status", type, status)
|
self.sendMessage("status", type, status, status)
|
||||||
|
|
||||||
def logInfo(self, message):
|
def logInfo(self, message):
|
||||||
self.sendMessage("log", "info", message)
|
self.sendMessage("log", "info", message, message)
|
||||||
|
|
||||||
def logError(self, error):
|
def logError(self, error):
|
||||||
self.sendMessage("log", "error", error)
|
self.sendMessage("log", "error", error, error)
|
||||||
|
|
||||||
|
def checkFile(self,filetype,filepath):
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
self.sendMessage("errorPopUp","warning", "OctoKlipper Settings", "Klipper " + filepath + " does not exist!")
|
||||||
|
|
||||||
|
def keyexists(self, dict, key1, key2):
|
||||||
|
try:
|
||||||
|
dict[key1][key2]
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
__plugin_name__ = "OctoKlipper"
|
__plugin_name__ = "OctoKlipper"
|
||||||
__plugin_pythoncompat__ = ">=2.7,<4"
|
__plugin_pythoncompat__ = ">=2.7,<4"
|
||||||
|
|
|
@ -14,126 +14,144 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
function KlipperViewModel(parameters) {
|
function KlipperViewModel(parameters) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.settings = parameters[0];
|
self.settings = parameters[0];
|
||||||
self.loginState = parameters[1];
|
self.loginState = parameters[1];
|
||||||
self.connectionState = parameters[2];
|
self.connectionState = parameters[2];
|
||||||
self.levelingViewModel = parameters[3];
|
self.levelingViewModel = parameters[3];
|
||||||
self.paramMacroViewModel = parameters[4];
|
self.paramMacroViewModel = parameters[4];
|
||||||
|
|
||||||
self.shortStatus = ko.observable();
|
self.shortStatus = ko.observable();
|
||||||
self.logMessages = ko.observableArray();
|
self.logMessages = ko.observableArray();
|
||||||
|
|
||||||
self.showLevelingDialog = function() {
|
|
||||||
var dialog = $("#klipper_leveling_dialog");
|
|
||||||
dialog.modal({
|
|
||||||
show: 'true',
|
|
||||||
backdrop: 'static',
|
|
||||||
keyboard: false
|
|
||||||
});
|
|
||||||
self.levelingViewModel.initView();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.showPidTuningDialog = function() {
|
|
||||||
var dialog = $("#klipper_pid_tuning_dialog");
|
|
||||||
dialog.modal({
|
|
||||||
show: 'true',
|
|
||||||
backdrop: 'static',
|
|
||||||
keyboard: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.showOffsetDialog = function() {
|
|
||||||
var dialog = $("#klipper_offset_dialog");
|
|
||||||
dialog.modal({
|
|
||||||
show: 'true',
|
|
||||||
backdrop: 'static'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.showGraphDialog = function() {
|
|
||||||
var dialog = $("#klipper_graph_dialog");
|
|
||||||
dialog.modal({
|
|
||||||
show: 'true',
|
|
||||||
minHeight: "500px",
|
|
||||||
maxHeight: "600px"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.executeMacro = function(macro) {
|
|
||||||
var paramObjRegex = /{(.*?)}/g;
|
|
||||||
|
|
||||||
if (macro.macro().match(paramObjRegex) == null) {
|
|
||||||
OctoPrint.control.sendGcode(
|
|
||||||
// Use .split to create an array of strings which is sent to
|
|
||||||
// OctoPrint.control.sendGcode instead of a single string.
|
|
||||||
macro.macro().split(/\r\n|\r|\n/)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
self.paramMacroViewModel.process(macro);
|
|
||||||
|
|
||||||
var dialog = $("#klipper_macro_dialog");
|
|
||||||
dialog.modal({
|
|
||||||
show: 'true',
|
|
||||||
backdrop: 'static'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onGetStatus = function() {
|
|
||||||
OctoPrint.control.sendGcode("Status")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onRestartFirmware = function() {
|
|
||||||
OctoPrint.control.sendGcode("FIRMWARE_RESTART")
|
|
||||||
};
|
|
||||||
|
|
||||||
self.onRestartHost = function() {
|
|
||||||
OctoPrint.control.sendGcode("RESTART")
|
|
||||||
};
|
|
||||||
|
|
||||||
self.onAfterBinding = function() {
|
|
||||||
self.connectionState.selectedPort(self.settings.settings.plugins.klipper.connection.port());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onDataUpdaterPluginMessage = function(plugin, message) {
|
|
||||||
if(plugin == "klipper") {
|
|
||||||
if(message["type"] == "status") {
|
|
||||||
self.shortStatus(message["payload"]);
|
|
||||||
} else {
|
|
||||||
self.logMessage(message["time"], message["subtype"], message["payload"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.logMessage = function(timestamp, type, message) {
|
self.showPopUp = function(popupType, popupTitle, message){
|
||||||
self.logMessages.push({
|
var title = popupType.toUpperCase() + ": " + popupTitle;
|
||||||
time: timestamp,
|
new PNotify({
|
||||||
type: type,
|
title: title,
|
||||||
msg: message.replace(/\n/gi, "<br>")}
|
text: message,
|
||||||
);
|
type: popupType,
|
||||||
}
|
hide: false
|
||||||
|
});
|
||||||
self.onClearLog = function() {
|
};
|
||||||
self.logMessages.removeAll();
|
|
||||||
};
|
self.showLevelingDialog = function() {
|
||||||
|
var dialog = $("#klipper_leveling_dialog");
|
||||||
self.isActive = function() {
|
dialog.modal({
|
||||||
return self.connectionState.isOperational() && self.loginState.isUser();
|
show: 'true',
|
||||||
}
|
backdrop: 'static',
|
||||||
}
|
keyboard: false
|
||||||
|
});
|
||||||
|
self.levelingViewModel.initView();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showPidTuningDialog = function() {
|
||||||
|
var dialog = $("#klipper_pid_tuning_dialog");
|
||||||
|
dialog.modal({
|
||||||
|
show: 'true',
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showOffsetDialog = function() {
|
||||||
|
var dialog = $("#klipper_offset_dialog");
|
||||||
|
dialog.modal({
|
||||||
|
show: 'true',
|
||||||
|
backdrop: 'static'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showGraphDialog = function() {
|
||||||
|
var dialog = $("#klipper_graph_dialog");
|
||||||
|
dialog.modal({
|
||||||
|
show: 'true',
|
||||||
|
minHeight: "500px",
|
||||||
|
maxHeight: "600px"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.executeMacro = function(macro) {
|
||||||
|
var paramObjRegex = /{(.*?)}/g;
|
||||||
|
|
||||||
|
if (macro.macro().match(paramObjRegex) == null) {
|
||||||
|
OctoPrint.control.sendGcode(
|
||||||
|
// Use .split to create an array of strings which is sent to
|
||||||
|
// OctoPrint.control.sendGcode instead of a single string.
|
||||||
|
macro.macro().split(/\r\n|\r|\n/)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.paramMacroViewModel.process(macro);
|
||||||
|
|
||||||
|
var dialog = $("#klipper_macro_dialog");
|
||||||
|
dialog.modal({
|
||||||
|
show: 'true',
|
||||||
|
backdrop: 'static'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onGetStatus = function() {
|
||||||
|
OctoPrint.control.sendGcode("Status")
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onRestartFirmware = function() {
|
||||||
|
OctoPrint.control.sendGcode("FIRMWARE_RESTART")
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onRestartHost = function() {
|
||||||
|
OctoPrint.control.sendGcode("RESTART")
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onAfterBinding = function() {
|
||||||
|
self.connectionState.selectedPort(self.settings.settings.plugins.klipper.connection.port());
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onDataUpdaterPluginMessage = function(plugin, data) {
|
||||||
|
if(plugin == "klipper") {
|
||||||
|
if ("warningPopUp" == data.type){
|
||||||
|
self.showPopUp(data.subtype, data.title, data.payload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ("errorPopUp" == data.type){
|
||||||
|
self.showPopUp(data.subtype, data.title, data.payload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(data.type == "status") {
|
||||||
|
self.shortStatus(data.payload);
|
||||||
|
} else {
|
||||||
|
self.logMessage(data.time, data.subtype, data.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
OCTOPRINT_VIEWMODELS.push({
|
self.logMessage = function(timestamp, type, message) {
|
||||||
construct: KlipperViewModel,
|
self.logMessages.push({
|
||||||
dependencies: [
|
time: timestamp,
|
||||||
"settingsViewModel",
|
type: type,
|
||||||
"loginStateViewModel",
|
msg: message.replace(/\n/gi, "<br>")}
|
||||||
"connectionViewModel",
|
);
|
||||||
"klipperLevelingViewModel",
|
};
|
||||||
"klipperMacroDialogViewModel"
|
|
||||||
],
|
self.onClearLog = function() {
|
||||||
elements: ["#tab_plugin_klipper_main", "#sidebar_plugin_klipper", "#navbar_plugin_klipper"]
|
self.logMessages.removeAll();
|
||||||
});
|
};
|
||||||
|
|
||||||
|
self.isActive = function() {
|
||||||
|
return self.connectionState.isOperational() && self.loginState.isUser();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
OCTOPRINT_VIEWMODELS.push({
|
||||||
|
construct: KlipperViewModel,
|
||||||
|
dependencies: [
|
||||||
|
"settingsViewModel",
|
||||||
|
"loginStateViewModel",
|
||||||
|
"connectionViewModel",
|
||||||
|
"klipperLevelingViewModel",
|
||||||
|
"klipperMacroDialogViewModel"
|
||||||
|
],
|
||||||
|
elements: ["#tab_plugin_klipper_main", "#sidebar_plugin_klipper", "#navbar_plugin_klipper"]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue