From dba8ca79fdf4513814b5c0f19243bf51e27c23ae Mon Sep 17 00:00:00 2001 From: lars Date: Tue, 12 Sep 2006 08:55:20 +0000 Subject: [PATCH] plugin interface implemented example plugins added: date and network moved "logs" to plugins --- pythonrewrite/bin2/CryptoBox.py | 8 +- pythonrewrite/bin2/CryptoBoxExceptions.py | 9 +++ pythonrewrite/bin2/CryptoBoxSettings.py | 1 + pythonrewrite/bin2/Plugins.py | 76 +++++++++++++++++++ pythonrewrite/bin2/WebInterfaceDataset.py | 48 +++++++----- pythonrewrite/bin2/WebInterfaceSites.py | 70 +++++++++++------ pythonrewrite/bin2/cryptobox.conf | 5 ++ pythonrewrite/bin2/unittests.CryptoBox.py | 1 + pythonrewrite/lang/de.hdf | 25 ------ pythonrewrite/lang/en.hdf | 26 ------- pythonrewrite/lang/si.hdf | 25 ------ pythonrewrite/plugins/date/date.py | 36 +++++++++ pythonrewrite/plugins/date/form_date.cs | 42 ++++++++++ pythonrewrite/plugins/date/lang/en.hdf | 35 +++++++++ pythonrewrite/plugins/logs/lang/en.hdf | 13 ++++ pythonrewrite/plugins/logs/logs.py | 21 +++++ pythonrewrite/plugins/logs/show_log.cs | 13 ++++ pythonrewrite/plugins/network/form_network.cs | 22 ++++++ pythonrewrite/plugins/network/lang/en.hdf | 20 +++++ pythonrewrite/plugins/network/network.py | 33 ++++++++ pythonrewrite/plugins/plugin-interface.txt | 36 +++++++++ pythonrewrite/templates/footer.cs | 38 +++++----- pythonrewrite/templates/form_system.cs | 33 ++++---- pythonrewrite/templates/main.cs | 4 +- pythonrewrite/templates/show_log.cs | 13 ---- pythonrewrite/templates/show_status.cs | 2 +- pythonrewrite/templates/show_volume.cs | 2 +- 27 files changed, 483 insertions(+), 174 deletions(-) create mode 100644 pythonrewrite/bin2/Plugins.py create mode 100644 pythonrewrite/plugins/date/date.py create mode 100644 pythonrewrite/plugins/date/form_date.cs create mode 100644 pythonrewrite/plugins/date/lang/en.hdf create mode 100644 pythonrewrite/plugins/logs/lang/en.hdf create mode 100644 pythonrewrite/plugins/logs/logs.py create mode 100644 pythonrewrite/plugins/logs/show_log.cs create mode 100644 pythonrewrite/plugins/network/form_network.cs create mode 100644 pythonrewrite/plugins/network/lang/en.hdf create mode 100644 pythonrewrite/plugins/network/network.py create mode 100644 pythonrewrite/plugins/plugin-interface.txt delete mode 100644 pythonrewrite/templates/show_log.cs diff --git a/pythonrewrite/bin2/CryptoBox.py b/pythonrewrite/bin2/CryptoBox.py index d5cefc5..daf75da 100755 --- a/pythonrewrite/bin2/CryptoBox.py +++ b/pythonrewrite/bin2/CryptoBox.py @@ -26,6 +26,9 @@ class CryptoBox: put things like logging, conf and oter stuff in here, that might be used by more classes, it will be passed on to them''' + + VERSION = "0.3~1" + def __init__(self, config_file=None): import CryptoBoxSettings self.log = self.__getStartupLogger() @@ -141,13 +144,14 @@ class CryptoBoxProps(CryptoBox): return [] try: fd = open(log_file, "r") - if maxSize: content = fd.readlines(maxSize) - else: content = fd.readlines() + if maxSize: fd.seek(-maxSize, 2) # seek relative to the end of the file + content = fd.readlines() fd.close() except IOError: self.log.warn("failed to read the log file (%s)" % log_file) return [] if lines: content = content[-lines:] + content.reverse() return content diff --git a/pythonrewrite/bin2/CryptoBoxExceptions.py b/pythonrewrite/bin2/CryptoBoxExceptions.py index 652f25a..f99e84a 100644 --- a/pythonrewrite/bin2/CryptoBoxExceptions.py +++ b/pythonrewrite/bin2/CryptoBoxExceptions.py @@ -8,6 +8,15 @@ class CryptoBoxError(Exception): pass +class CBPluginError(CryptoBoxError): + """should be raised for plugin specific problems""" + + +class CBPluginActionError(CBPluginError): + """should be raised when a plugin action failed""" + pass + + class CBConfigError(CryptoBoxError): """any kind of error related to the configuration of a cryptobox""" pass diff --git a/pythonrewrite/bin2/CryptoBoxSettings.py b/pythonrewrite/bin2/CryptoBoxSettings.py index 155a27e..dfa266a 100644 --- a/pythonrewrite/bin2/CryptoBoxSettings.py +++ b/pythonrewrite/bin2/CryptoBoxSettings.py @@ -171,6 +171,7 @@ NameDatabase = fileWriteable(default="/var/cache/cryptobox/volumen_names.db") TemplateDir = directoryExists(default="/usr/share/cryptobox/template") LangDir = directoryExists(default="/usr/share/cryptobox/lang") DocDir = directoryExists(default="/usr/share/doc/cryptobox/html") +PluginDir = directoryExists(default="/usr/share/cryptobox/plugins") [Log] Level = option("debug", "info", "warn", "error", default="warn") diff --git a/pythonrewrite/bin2/Plugins.py b/pythonrewrite/bin2/Plugins.py new file mode 100644 index 0000000..1d87df6 --- /dev/null +++ b/pythonrewrite/bin2/Plugins.py @@ -0,0 +1,76 @@ +# $Id$ + +import imp +import os +import logging + + +class PluginManager: + """manage available plugins""" + + def __init__(self, plugin_dirs=None): + self.log = logging.getLogger("CryptoBox") + if hasattr(plugin_dirs, "__iter__"): + self.plugin_dirs = [os.path.abspath(dir) for dir in plugin_dirs] + else: + self.plugin_dirs = [os.path.abspath(plugin_dirs)] + + + def allPlugins(self): + for plfile in self.__getPluginFiles(): + yield os.path.basename(plfile)[:-3] + + + def getPlugin(self, name): + for plfile in self.__getPluginFiles(): + if name == os.path.basename(plfile)[:-3]: + return imp.load_source(name, plfile) + else: + return None + + + def getTemplateFileName(self, plname, template_name): + """return the name of the template file, if it is part of the mentioned plugin + """ + result = [os.path.join(os.path.dirname(cur_file), template_name + ".cs") + for cur_file in self.__getPluginFiles() + if plname == os.path.basename(cur_file)[:-3]] + for templ_file in result: + if os.access(templ_file, os.R_OK) and os.path.isfile(templ_file): + return templ_file + else: + return None + + + + def loadLanguageData(self, hdf, lang="en"): + for plfile in self.__getPluginFiles(): + langdir = os.path.join(os.path.dirname(plfile), "lang") + selected_langfile = os.path.join(langdir, lang + ".hdf") + default_langfile = os.path.join(langdir, "en.hdf") + for langfile in (selected_langfile, default_langfile): + if os.access(langfile, os.R_OK): + self.log.debug("Loading plugin language file: %s" % langfile) + hdf.readFile(langfile) + break + else: + self.log.debug("Couldn't find a plugin language file (%s)" % default_langfile) + + + def __getPluginFiles(self): + result = [] + for dir in [os.path.abspath(e) for e in self.plugin_dirs if os.access(e, os.R_OK) and os.path.isdir(e)]: + for plname in [f for f in os.listdir(dir)]: + pldir = os.path.join(dir, plname) + plfile = os.path.join(pldir, plname + ".py") + if os.path.isfile(plfile) and os.access(plfile, os.R_OK): + result.append(plfile) + return result + + +if __name__ == "__main__": + x = PluginManager("../plugins") + for a in x.allPlugins(): + print "Plugin: %s" % a + print x.getPlugin(a).getStatus() + diff --git a/pythonrewrite/bin2/WebInterfaceDataset.py b/pythonrewrite/bin2/WebInterfaceDataset.py index 2b61cdd..a91e7be 100644 --- a/pythonrewrite/bin2/WebInterfaceDataset.py +++ b/pythonrewrite/bin2/WebInterfaceDataset.py @@ -1,7 +1,7 @@ import os import CryptoBoxContainer -## useful constant for many functions +## useful constant for some functions CONT_TYPES = CryptoBoxContainer.CryptoBoxContainer.Types class WebInterfaceDataset(dict): @@ -16,6 +16,31 @@ class WebInterfaceDataset(dict): self.__setCryptoBoxState() + def setPluginState(self, plugins): + for pl in plugins.allPlugins(): + self["Data.Status.Modules." + pl] = plugins.getPlugin(pl).getStatus(self.cbox) + + + def setCurrentDiskState(self, device): + for container in self.cbox.getContainerList(): + if container.getDevice() == device: + isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 + isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 + isMounted = container.isMounted() and 1 or 0 + self["Data.CurrentDisk.device"] = container.getDevice() + self["Data.CurrentDisk.name"] = container.getName() + self["Data.CurrentDisk.encryption"] = isEncrypted + self["Data.CurrentDisk.plaintext"] = isPlain + self["Data.CurrentDisk.active"] = isMounted + if isMounted: + (size, avail, used) = container.getCapacity() + percent = used / size + self["Data.CurrentDisk.capacity.used"] = used + self["Data.CurrentDisk.capacity.free"] = avail + self["Data.CurrentDisk.capacity.size"] = size + self["Data.CurrentDisk.capacity.percent"] = percent + + def __setConfigValues(self): self["Settings.TemplateDir"] = os.path.abspath(self.prefs["Locations"]["TemplateDir"]) self["Settings.LanguageDir"] = os.path.abspath(self.prefs["Locations"]["LangDir"]) @@ -26,6 +51,7 @@ class WebInterfaceDataset(dict): def __setCryptoBoxState(self): + self["Data.Version"] = self.cbox.VERSION avail_counter = 0 active_counter = 0 for container in self.cbox.getContainerList(): @@ -45,26 +71,6 @@ class WebInterfaceDataset(dict): ## TODO: open issues: Data.Config.AdminPasswordIsSet - def setCurrentDiskState(self, device): - for container in self.cbox.getContainerList(): - if container.getDevice() == device: - isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 - isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 - isMounted = container.isMounted() and 1 or 0 - self["Data.CurrentDisk.device"] = container.getDevice() - self["Data.CurrentDisk.name"] = container.getName() - self["Data.CurrentDisk.encryption"] = isEncrypted - self["Data.CurrentDisk.plaintext"] = isPlain - self["Data.CurrentDisk.active"] = isMounted - - if isMounted: - (size, avail, used) = container.getCapacity() - percent = used / size - self["Data.CurrentDisk.capacity.used"] = used - self["Data.CurrentDisk.capacity.free"] = avail - self["Data.CurrentDisk.capacity.size"] = size - self["Data.CurrentDisk.capacity.percent"] = percent - def __getLanguageName(self, lang): import neo_cgi, neo_util, neo_cs hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf") diff --git a/pythonrewrite/bin2/WebInterfaceSites.py b/pythonrewrite/bin2/WebInterfaceSites.py index 880d5cc..7534ac6 100755 --- a/pythonrewrite/bin2/WebInterfaceSites.py +++ b/pythonrewrite/bin2/WebInterfaceSites.py @@ -1,6 +1,8 @@ import CryptoBox import WebInterfaceDataset import re +from Plugins import PluginManager +from CryptoBoxExceptions import * class WebInterfaceSites: ''' @@ -14,6 +16,16 @@ class WebInterfaceSites: self.log = logging.getLogger("CryptoBox") self.prefs = self.cbox.prefs self.__resetDataset() + self.plugins = PluginManager(self.prefs["Locations"]["PluginDir"]) + self.__exposePlugins() + + + def __exposePlugins(self): + for plname in self.plugins.allPlugins(): + self.log.info("Plugin '%s' loaded" % plname) + ## this should be the "easiest" way to expose all modules as URLs + setattr(self, "module_" + plname, self.return_module_action(plname)) + setattr(getattr(self, "module_" + plname), "exposed", True) def __resetDataset(self): @@ -65,12 +77,6 @@ class WebInterfaceSites: return self.__render("show_status") - def config(self,weblang=""): - self.__resetDataset() - self.__setWebLang(weblang) - pass - - def doc(self,page="",weblang=""): '''prints the offline wikipage ''' @@ -86,22 +92,11 @@ class WebInterfaceSites: self.dataset["Data.Doc.Page"] ="CryptoBoxUser" return self.__render("show_doc") + - - def system(self, shutdowntype="", weblang=""): - # TODO: check weblang + def system(self, weblang=""): self.__resetDataset() self.__setWebLang(weblang) - if shutdowntype == "reboot": - self.dataset["Data.Success"] = "ReBoot" - self.dataset["Data.Redirect.Action"] = "show_status" - self.dataset["Data.Redirect.Delay"] = "180" - self.log.info("TODO: call function for system reboot") - elif shutdowntype == "poweroff": - self.dataset["Data.Success"] = "PowerOff" - self.log.info("TODO: call function for system shutdown") - else: - self.log.warn("This shutdown-mode (%s) is not supported." % shutdowntype) return self.__render("form_system") @@ -315,7 +310,27 @@ class WebInterfaceSites: return self.__render("show_status") return self.__render("show_volume") - + + def return_module_action(self, module): + def handler(**args): + self.__resetDataset() + try: + self.__setWebLang(args["weblang"]) + del args["weblang"] + except KeyError: + pass + plugin = self.plugins.getPlugin(module) + try: + nextTemplate = plugin.doAction(self.cbox, **args) + except CBPluginActionError, errMsg: + self.log.debug(errMsg) + self.dataset["Data.Warning"] = errMsg + nextTemplate = "empty" + plugin.prepareForm(self.dataset, self.cbox) + return self.__render(nextTemplate, module) + return handler + + ''' ## DONE: these functions are pythonized #################### show_log ####################### @@ -403,7 +418,7 @@ class WebInterfaceSites: return False - def __render(self, template): + def __render(self, template, module=None): '''renders from clearsilver templates and returns the resulting html Gets a dictionary with all settings, nessessary for rendering. @@ -411,7 +426,6 @@ class WebInterfaceSites: object, that calls this render method. This might be bloat but this way the render method has always a complete, actual set of values. ''' - import os try: import neo_cgi, neo_util, neo_cs @@ -421,7 +435,11 @@ class WebInterfaceSites: sys.stderr.write(errorMsg) raise ImportError, errorMsg - self.dataset["Data.Action"] = template + module_cs_file = False + if module: + module_cs_file = self.plugins.getTemplateFileName(module, template) + default_cs_file = os.path.join(self.prefs["Locations"]["TemplateDir"], template + ".cs") + self.dataset["Data.TemplateFile"] = module_cs_file or default_cs_file self.log.info("rendering site: " + template) cs_path = os.path.join(self.prefs["Locations"]["TemplateDir"], "main.cs") @@ -435,11 +453,16 @@ class WebInterfaceSites: log.error("Couldn't read language file: %s" % hdf_path) return "Couldn't read language file: %s" % hdf_path + ## add the current state of the plugins to the hdf dataset + self.dataset.setPluginState(self.plugins) + hdf = neo_util.HDF() hdf.readFile(hdf_path) self.log.debug(self.dataset) for key in self.dataset.keys(): hdf.setValue(key,str(self.dataset[key])) + ## load languaga data of plugins + self.plugins.loadLanguageData(hdf, lang=self.dataset["Settings.Language"]) cs = neo_cs.CS(hdf) cs.parseFile(cs_path) return cs.render() @@ -462,6 +485,7 @@ class WebInterfaceSites: test.exposed = True + """ ## TODO: check this before anything else if self.cbox.getAvailableDocLanguages(): diff --git a/pythonrewrite/bin2/cryptobox.conf b/pythonrewrite/bin2/cryptobox.conf index 397ffaf..c609f0d 100644 --- a/pythonrewrite/bin2/cryptobox.conf +++ b/pythonrewrite/bin2/cryptobox.conf @@ -32,6 +32,11 @@ LangDir = ../lang #DocDir = /usr/share/doc/cryptobox/html DocDir = ../doc/html +# path to the plugin directory +#PluginDir = /usr/share/cryptobox/plugins +PluginDir = ../plugins + + [Log] # possible values are "debug", "info", "warn" and "error" or numbers from diff --git a/pythonrewrite/bin2/unittests.CryptoBox.py b/pythonrewrite/bin2/unittests.CryptoBox.py index 79a7d42..29ddd00 100755 --- a/pythonrewrite/bin2/unittests.CryptoBox.py +++ b/pythonrewrite/bin2/unittests.CryptoBox.py @@ -48,6 +48,7 @@ MountParentDir = %s TemplateDir = ../templates LangDir = ../lang DocDir = ../doc/html +PluginDir = ../plugins [Log] Level = debug Destination = file diff --git a/pythonrewrite/lang/de.hdf b/pythonrewrite/lang/de.hdf index 47e3686..336f873 100644 --- a/pythonrewrite/lang/de.hdf +++ b/pythonrewrite/lang/de.hdf @@ -134,36 +134,11 @@ Lang { Text = Die ausgewählte Sprache ist nicht verfügbar! } - InvalidIP { - Title = Ungültige IP - Text = Die ausgewählte Netzwerkadresse ist nicht gültig! - } - - InvalidTimeOut { - Title = Ungültige Zeitabschaltung - Text = Der ausgewählte Wert der Zeitabschaltung ist nicht gültig! - } - - ConfigTimeOutFailed { - Title = Fehler beim Ändern der Zeitabschaltung - Text = Der Wert der Zeitabschaltung konnte nicht geändert werden! - } - ConfigLanguageFailed { Title = Fehler beim Ändern der Spracheinstellung Text = Die Spracheinstellung konnte nicht geändert werden! } - ConfigIPFailed { - Title = Fehler beim Ändern der Netzwerkadresse - Text = Die Netzwerkadresse konnte nicht geändert werden! - } - - IPAddressChanged { - Title = Änderung der Netzwerk-Adresse - Text = Die Netzwerk-Adresse der CryptoBox wurde verändert. In wenigen Sekunden werden sie zu der neuen Adresse umgeleitet. - } - NoDiskAvailableForMount { Title = Kein Daten-Container verfügbar Text = Es ist kein inaktiver Daten-Container verfügbar. Vielleicht sind bereits alle Container aktiv? diff --git a/pythonrewrite/lang/en.hdf b/pythonrewrite/lang/en.hdf index 7c3bb34..6535dd8 100644 --- a/pythonrewrite/lang/en.hdf +++ b/pythonrewrite/lang/en.hdf @@ -11,7 +11,6 @@ Lang { Mount = Activation of encrypted data Umount = Deactivation of encrypted data Config = CryptoBox configuration - Log = CryptoBox logfiles System = System Status = Status Volume = Properties of @@ -31,7 +30,6 @@ Lang { PartitionInfo = Current partioning of the disk: IPAddress = Network address (IP) of the CryptoBox: TimeOut = Timeout for deactivation of the encrypted filesystem (in minutes): - EmptyLog = The logfiles of the CryptoBox are empty. SelectLanguage = Language preferences: RedirectNote = Click here if your browser does not support automatic redirection. ProjectHomePage = Website of project @@ -59,7 +57,6 @@ Lang { Config = Configuration PowerOff = Shutdown ReBoot = Reboot - Protocol = Show logfiles Documentation = Help Status = Status System = System @@ -134,35 +131,12 @@ Lang { Text = The selected language is not available! } - InvalidIP { - Title = Invalid IP address - Text = The selected network address is not valid! - } - - InvalidTimeOut { - Title = Invalid timeout - Text = The selected timeout is not valid! - } - - ConfigTimeOutFailed { - Title = Error during change of timeout - Text = The timeout value could not be changed! - } ConfigLanguageFailed { Title = Error during change of language preferences Text = The language preferences could not be changed! } - ConfigIPFailed { - Title = Error during change of network address - Text = The network address could not be changed! - } - - IPAddressChanged { - Title = Change of network address - Text = The network address has been changed. In a few seconds you will get redirected to the new address. - } NoDiskAvailableForMount { Title = No partition available diff --git a/pythonrewrite/lang/si.hdf b/pythonrewrite/lang/si.hdf index 46f8e3d..5346c6f 100644 --- a/pythonrewrite/lang/si.hdf +++ b/pythonrewrite/lang/si.hdf @@ -125,35 +125,10 @@ Lang { Text = Izbrani jezik ni na voljo! } - InvalidIP { - Title = Napačen IP naslov - Text = Izbran omrežni naslov ni veljaven! - } - - InvalidTimeOut { - Title = Nepravilen čas preklica - Text = Izbran čas preklica ni veljaven! - } - - ConfigTimeOutFailed { - Title = Napaka med spremembo časa preklica - Text = Časa preklica ne morete spremeniti! - } - ConfigLanguageFailed { Title = Napaka med spremembo jezikovnih nastavitev Text = Spreminjanje jezikovnih nastavitev ni mogoče. } - - ConfigIPFailed { - Title = Napaka med spreminjanjem omrežnega naslova. - Text = Spreminjanje omrežnega naslova ni mogoče. - } - - IPAddressChanged { - Title = Sprememba omrežnega naslova - Text = Omrežni naslov je spremenjen. V nekaj sekundah boste preusmerjeni na nov naslov. - } } diff --git a/pythonrewrite/plugins/date/date.py b/pythonrewrite/plugins/date/date.py new file mode 100644 index 0000000..59b1a91 --- /dev/null +++ b/pythonrewrite/plugins/date/date.py @@ -0,0 +1,36 @@ +from CryptoBoxExceptions import CBPluginActionError + + +def prepareForm(hdf, cbox): + date = __getCurrentDate() + hdf["Data.Modules.date.year"] = date.year + hdf["Data.Modules.date.month"] = date.month + hdf["Data.Modules.date.day"] = date.day + hdf["Data.Modules.date.hour"] = date.hour + hdf["Data.Modules.date.minute"] = date.minute + + +def doAction(cbox, store=None, year=0, month=0, day=0, hour=0, minute=0): + import datetime + if store: + try: + year, month, day = int(year), int(month), int(day) + hour, minute = int(hour), int(minute) + new_date = datetime.datetime(year, month, day, hour, minute) + except ValueError: + raise CBPluginActionError, "InvalidDate" + # TODO: how to set the current time? (and how to become root?) + ## we will continue with the system menue + return "form_system" + else: + return "form_date" + + +def getStatus(cbox): + return str(__getCurrentDate()) + + +def __getCurrentDate(): + import datetime + return datetime.datetime(2000,1,1).now() + diff --git a/pythonrewrite/plugins/date/form_date.cs b/pythonrewrite/plugins/date/form_date.cs new file mode 100644 index 0000000..838db44 --- /dev/null +++ b/pythonrewrite/plugins/date/form_date.cs @@ -0,0 +1,42 @@ + + +

+ + + +


+ + +

+ +


+  :  +

+ + + + + + + diff --git a/pythonrewrite/plugins/date/lang/en.hdf b/pythonrewrite/plugins/date/lang/en.hdf new file mode 100644 index 0000000..44824b5 --- /dev/null +++ b/pythonrewrite/plugins/date/lang/en.hdf @@ -0,0 +1,35 @@ +Lang { + + Title.ConfigDate = Date and time setting + + Button.ConfigDate = Set date and time + + Text.Date = Date + Text.Time = Time + Text.Months { + 1 = January + 2 = February + 3 = March + 4 = April + 5 = May + 6 = June + 7 = July + 8 = August + 9 = September + 10 = October + 11 = November + 12 = December + } + + Modules.date { + Name = Change date and time + Link = Set date/time + Rank = 10 + } + + WarningMessage.InvalidDate { + Title = Invalid value + Text = An invalid value for date or time was supplied. Please try again. + } + +} diff --git a/pythonrewrite/plugins/logs/lang/en.hdf b/pythonrewrite/plugins/logs/lang/en.hdf new file mode 100644 index 0000000..af85d64 --- /dev/null +++ b/pythonrewrite/plugins/logs/lang/en.hdf @@ -0,0 +1,13 @@ +Lang { + + Title.Log = CryptoBox logfiles + + Text.EmptyLog = The logfile of the CryptoBox is empty. + + Modules.logs { + Name = Show the content of the log file + Link = Show the log file + Rank = 90 + } + +} diff --git a/pythonrewrite/plugins/logs/logs.py b/pythonrewrite/plugins/logs/logs.py new file mode 100644 index 0000000..81a09d7 --- /dev/null +++ b/pythonrewrite/plugins/logs/logs.py @@ -0,0 +1,21 @@ +from CryptoBoxExceptions import CBPluginActionError + + +def prepareForm(hdf, cbox): + hdf["Data.Modules.logs.Content"] = __getLogContent(cbox) + + +def doAction(cbox): + return "show_log" + + +def getStatus(cbox): + return "%s:%s:%s" % ( + cbox.prefs["Log"]["Level"], + cbox.prefs["Log"]["Destination"], + cbox.prefs["Log"]["Details"]) + + +def __getLogContent(cbox, lines=30, maxSize=2000): + return "
".join(cbox.getLogData(lines, maxSize)) + diff --git a/pythonrewrite/plugins/logs/show_log.cs b/pythonrewrite/plugins/logs/show_log.cs new file mode 100644 index 0000000..91d910f --- /dev/null +++ b/pythonrewrite/plugins/logs/show_log.cs @@ -0,0 +1,13 @@ + + +
+ +

+ + +

+ +

+ + +
diff --git a/pythonrewrite/plugins/network/form_network.cs b/pythonrewrite/plugins/network/form_network.cs new file mode 100644 index 0000000..072ceae --- /dev/null +++ b/pythonrewrite/plugins/network/form_network.cs @@ -0,0 +1,22 @@ + + +

+ + + +


+ . + . + . +

+ + + + + + + diff --git a/pythonrewrite/plugins/network/lang/en.hdf b/pythonrewrite/plugins/network/lang/en.hdf new file mode 100644 index 0000000..7e1861d --- /dev/null +++ b/pythonrewrite/plugins/network/lang/en.hdf @@ -0,0 +1,20 @@ +Lang { + + Title.Network = Network settings + + Button.Network = Update settings + + Text.IP = Network address + + Modules.network { + Name = Configure network + Link = Configure network + Rank = 30 + } + + Warning.InvalidIP { + Title = Invalid value + Text = An invalid network address (IP) was supplied. Please try again. + } + +} diff --git a/pythonrewrite/plugins/network/network.py b/pythonrewrite/plugins/network/network.py new file mode 100644 index 0000000..04529dd --- /dev/null +++ b/pythonrewrite/plugins/network/network.py @@ -0,0 +1,33 @@ +from CryptoBoxExceptions import CBPluginActionError + + +def prepareForm(hdf, cbox): + (oc1, oc2, oc3, oc4) = __getCurrentIP() + hdf["Data.Modules.network.ip.oc1"] = oc1 + hdf["Data.Modules.network.ip.oc2"] = oc2 + hdf["Data.Modules.network.ip.oc3"] = oc3 + hdf["Data.Modules.network.ip.oc4"] = oc4 + + +def doAction(cbox, store=None, ip1="", ip2="", ip3="", ip4=""): + if store: + try: + # TODO: check the IP here + pass + except ValueError: + raise CBPluginActionError, "InvalidIP" + # TODO: how to set the new IP? (and how to become root?) + ## we will continue with the system menue + return "form_system" + else: + return "form_network" + + +def getStatus(cbox): + return "%d.%d.%d.%d" % __getCurrentIP() + + +def __getCurrentIP(): + # TODO: for now we only provide a dummy + return (192,168,0,23) + diff --git a/pythonrewrite/plugins/plugin-interface.txt b/pythonrewrite/plugins/plugin-interface.txt new file mode 100644 index 0000000..97ff779 --- /dev/null +++ b/pythonrewrite/plugins/plugin-interface.txt @@ -0,0 +1,36 @@ +The following directory structure is required: + - python code: plugins/MODULENAME/MODULENAME.py (all lower case is recommended) + - language files: plugins/MODULENAME/lang/(en|de|??).hdf + - clearsilver templates: plugins/MODULENAME/*.cs + + +Python code interface: + def prepareForm(hdf, cbox): + - here you may add some items to the hdf dataset used by the templates + - the recommended namespace is Data.Modules.MODULENAME.??? + + def doAction(cbox, store=None, ???): + - this function will get called whenever this module is involved in a request + - all arguments should be optional (e.g. for displaying a form without previous input values) + - the argument "store" should be used to process a form submission (just a recommendation) + - if the processing failed for some reason (invalid input, ...), it should raise a CBPluginException (e.g. CBPluginActionError) - the error message should be the name of a warning message (maybe defined in the plugin specific language file) - e.g. "InvalidDate" for Lang.WarningMessage.InvalidDate + - the return value should be the name of the template that should be displayed after processing (a template file in the module directory takes precedence over global template files) + + def def getStatus(cbox): + - returns a string, that described a state connected to this module (e.g. the current date and time (for the "date" plugin) + + +Language file structure: + - the following values _must_ be defined: + Lang.Modules.MODULENAME.Name (a short description) + Lang.Modules.MODULENAME.Link (the visible text for links to this module) + Lang.Modules.MODULENAME.Rank (defines the order of the plugins displayed) + - all other elements should follow the usual structure of language files + + +Clearsilver template: + - should start with a "

" tag + - links to the module (e.g. in form headers) could look like the following: + + - a hidden input field called "store" should be used to indicate a form submission + diff --git a/pythonrewrite/templates/footer.cs b/pythonrewrite/templates/footer.cs index 3107ddf..508216c 100644 --- a/pythonrewrite/templates/footer.cs +++ b/pythonrewrite/templates/footer.cs @@ -7,29 +7,31 @@ - - + + + +Data.Config.IP= +Data.Config.Language= +Data.Config.TimeOut= +Data.Status.Config= +Data.Status.InitRunning= +Data.Status.IP= +Data.Status.Mounted= +Data.Status.Modules.= +CBOX-STATUS-end --> - + diff --git a/pythonrewrite/templates/form_system.cs b/pythonrewrite/templates/form_system.cs index 9582285..2563dd7 100644 --- a/pythonrewrite/templates/form_system.cs +++ b/pythonrewrite/templates/form_system.cs @@ -4,25 +4,24 @@

- diff --git a/pythonrewrite/templates/main.cs b/pythonrewrite/templates/main.cs index 33a2335..d5192ef 100644 --- a/pythonrewrite/templates/main.cs +++ b/pythonrewrite/templates/main.cs @@ -3,14 +3,14 @@ - + - + diff --git a/pythonrewrite/templates/show_log.cs b/pythonrewrite/templates/show_log.cs deleted file mode 100644 index e8b134c..0000000 --- a/pythonrewrite/templates/show_log.cs +++ /dev/null @@ -1,13 +0,0 @@ - - -
- -

- - -

- -

- - -
diff --git a/pythonrewrite/templates/show_status.cs b/pythonrewrite/templates/show_status.cs index 8971a73..6824a64 100644 --- a/pythonrewrite/templates/show_status.cs +++ b/pythonrewrite/templates/show_status.cs @@ -21,7 +21,7 @@ ?>">

: -