diff --git a/octoprint_klipper/__init__.py b/octoprint_klipper/__init__.py index 66024c3..f005afc 100644 --- a/octoprint_klipper/__init__.py +++ b/octoprint_klipper/__init__.py @@ -24,6 +24,7 @@ from octoprint.util.comm import parse_firmware_line from octoprint.access.permissions import Permissions, ADMIN_GROUP, USER_GROUP from .modules import KlipperLogAnalyzer import flask +import configparser from flask_babel import gettext class KlipperPlugin( @@ -105,16 +106,22 @@ class KlipperPlugin( def 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"]) ) + + logpath = os.path.expanduser( + self._settings.get(["configuration", "logpath"]) + ) + try: - f = open(filepath, "r", encoding="utf-8") + f = open(configpath, "r") + data["config"] = f.read() f.close() except IOError: self._logger.error( - "Error: Klipper config file not found at: {}".format(filepath) + "Error: Klipper config file not found at: {}".format(configpath) ) return data @@ -133,28 +140,48 @@ class KlipperPlugin( return 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: try: - filepath = os.path.expanduser( - self._settings.get(["configuration", "configpath"]) - ) - if sys.version_info[0] < 3: - data["config"] = data["config"].encode('utf-8') + data["config"] = data["config"].encode('utf-8') + + # Basic validation of config file - makes sure it parses + try: + parser = configparser.RawConfigParser() + parser.read_string(data["config"]) + except configParser.Error as error: + self._logger.error( + "Error: Invalid Klipper config file: {}".format(str(error)) + ) + self.sendMessage("errorPopUp","warning", "OctoKlipper Settings", "Invalid Klipper config file: " + str(error)) + + + f = open(configpath, "w") - f = open(filepath, "w", encoding="utf-8") f.write(data["config"]) f.close() - self._logger.info( - "Writing Klipper config to {}".format(filepath) + self._logger.error( + "Writing Klipper config to {}".format(configpath) ) # Restart klipply to reload config self._printer.commands(self._settings.get(["configuration", "reload_command"])) self.logInfo("Reloading Klipper Configuration.") except IOError: 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: octoprint.plugin.SettingsPlugin.on_settings_save(self, data) @@ -375,13 +402,14 @@ class KlipperPlugin( ) #-- Helpers - def sendMessage(self, type, subtype, payload): + def sendMessage(self, type, subtype, title, payload): self._plugin_manager.send_plugin_message( self._identifier, dict( time=datetime.datetime.now().strftime("%H:%M:%S"), type=type, subtype=subtype, + title=title, payload=payload ) ) @@ -390,13 +418,25 @@ class KlipperPlugin( self._printer.commands("STATUS") def updateStatus(self, type, status): - self.sendMessage("status", type, status) + self.sendMessage("status", type, status, status) def logInfo(self, message): - self.sendMessage("log", "info", message) + self.sendMessage("log", "info", message, message) 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_pythoncompat__ = ">=2.7,<4" diff --git a/octoprint_klipper/static/js/klipper.js b/octoprint_klipper/static/js/klipper.js index e899629..08ca430 100644 --- a/octoprint_klipper/static/js/klipper.js +++ b/octoprint_klipper/static/js/klipper.js @@ -23,9 +23,20 @@ $(function () { self.levelingViewModel = parameters[3]; self.paramMacroViewModel = parameters[4]; self.access = parameters[5]; + self.shortStatus = ko.observable(); self.logMessages = ko.observableArray(); + self.showPopUp = function(popupType, popupTitle, message){ + var title = popupType.toUpperCase() + ": " + popupTitle; + new PNotify({ + title: title, + text: message, + type: popupType, + hide: false + }); + }; + self.showLevelingDialog = function () { var dialog = $("#klipper_leveling_dialog"); dialog.modal({ @@ -106,17 +117,21 @@ $(function () { ); }; - 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.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); + } } };