removed setting "DocLanguage" (replaced by general "Language")
plugins are now classes inherited from CryptoBoxPlugin language detection added (via request header "Accept-Language")
This commit is contained in:
parent
56e954d1c4
commit
90efd72b8b
11 changed files with 287 additions and 164 deletions
|
@ -52,7 +52,7 @@ class CryptoBox:
|
||||||
try:
|
try:
|
||||||
log_handler = logging.getLogger("CryptoBox")
|
log_handler = logging.getLogger("CryptoBox")
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format='%(asctime)s %(module)s %(levelname)s %(message)s',
|
format='%(asctime)s CryptoBox %(levelname)s: %(message)s',
|
||||||
stderr=sys.stderr)
|
stderr=sys.stderr)
|
||||||
log_handler.setLevel(logging.ERROR)
|
log_handler.setLevel(logging.ERROR)
|
||||||
log_handler.info("loggingsystem is up'n running")
|
log_handler.info("loggingsystem is up'n running")
|
||||||
|
@ -249,35 +249,10 @@ class CryptoBoxProps(CryptoBox):
|
||||||
for file in os.listdir(self.prefs["Locations"]["LangDir"]):
|
for file in os.listdir(self.prefs["Locations"]["LangDir"]):
|
||||||
if file.endswith(".hdf"): languages.append(file.rstrip(".hdf"))
|
if file.endswith(".hdf"): languages.append(file.rstrip(".hdf"))
|
||||||
if len(languages) < 1:
|
if len(languages) < 1:
|
||||||
self.log.warn("No .hdf files found! The website won't render properly.")
|
self.log.error("No .hdf files found! The website won't render properly.")
|
||||||
return languages
|
return languages
|
||||||
|
|
||||||
|
|
||||||
def getAvailableDocLanguages(self):
|
|
||||||
'''reads all dirs in path DocDir and returns a list of
|
|
||||||
available documentation languages, this list might be empty.'''
|
|
||||||
doclangs = []
|
|
||||||
regpat = re.compile(r"^\w+$")
|
|
||||||
try:
|
|
||||||
doc_dir = self.prefs["Locations"]["DocDir"]
|
|
||||||
except KeyError:
|
|
||||||
self.log.error("Could not find a configuration setting: [Locations]->DocDir - please check the config file")
|
|
||||||
return []
|
|
||||||
if not os.path.exists(doc_dir):
|
|
||||||
self.log.error("The configured documentation directory (%s) does not exist" % (doc_dir, ))
|
|
||||||
return []
|
|
||||||
try:
|
|
||||||
for e in os.listdir(doc_dir):
|
|
||||||
if regpat.search(e) and os.path.isdir(os.path.join(doc_dir, e)):
|
|
||||||
doclangs.append(e)
|
|
||||||
if len(doclangs) < 1:
|
|
||||||
self.log.warn("Didn't find any documentation files.")
|
|
||||||
return doclangs
|
|
||||||
except OSError:
|
|
||||||
self.log.error("Could not access the documentations directory (%s)" % (doc_dir,))
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cb = CryptoBox()
|
cb = CryptoBox()
|
||||||
|
|
|
@ -45,7 +45,7 @@ class CryptoBoxContainer:
|
||||||
self.cbox = cbox
|
self.cbox = cbox
|
||||||
self.log = logging.getLogger("CryptoBox")
|
self.log = logging.getLogger("CryptoBox")
|
||||||
self.Progs = self.cbox.prefs["Programs"]
|
self.Progs = self.cbox.prefs["Programs"]
|
||||||
self.__resetObject()
|
self.resetObject()
|
||||||
|
|
||||||
|
|
||||||
def getName(self):
|
def getName(self):
|
||||||
|
@ -93,14 +93,28 @@ class CryptoBoxContainer:
|
||||||
int(info.f_bsize*(info.f_blocks-info.f_bavail)/1024/1024))
|
int(info.f_bsize*(info.f_blocks-info.f_bavail)/1024/1024))
|
||||||
|
|
||||||
|
|
||||||
|
def resetObject(self):
|
||||||
|
""" recheck the information about this container
|
||||||
|
this is especially useful after changing the type via 'create' """
|
||||||
|
self.uuid = self.__getUUID()
|
||||||
|
self.type = self.__getTypeOfPartition()
|
||||||
|
self.name = self.__getNameOfContainer()
|
||||||
|
if self.type == self.Types["luks"]:
|
||||||
|
self.mount = self.__mountLuks
|
||||||
|
self.umount = self.__umountLuks
|
||||||
|
if self.type == self.Types["plain"]:
|
||||||
|
self.mount = self.__mountPlain
|
||||||
|
self.umount = self.__umountPlain
|
||||||
|
|
||||||
|
|
||||||
def create(self, type, password=None):
|
def create(self, type, password=None):
|
||||||
if type == self.Types["luks"]:
|
if type == self.Types["luks"]:
|
||||||
self.__createLuks(password)
|
self.__createLuks(password)
|
||||||
self.__resetObject()
|
self.resetObject()
|
||||||
return
|
return
|
||||||
if type == self.Types["plain"]:
|
if type == self.Types["plain"]:
|
||||||
self.__createPlain()
|
self.__createPlain()
|
||||||
self.__resetObject()
|
self.resetObject()
|
||||||
return
|
return
|
||||||
raise "InvalidType", "invalid container type (%d) supplied" % (type, )
|
raise "InvalidType", "invalid container type (%d) supplied" % (type, )
|
||||||
|
|
||||||
|
@ -171,20 +185,6 @@ class CryptoBoxContainer:
|
||||||
|
|
||||||
" ****************** internal stuff ********************* "
|
" ****************** internal stuff ********************* "
|
||||||
|
|
||||||
def __resetObject(self):
|
|
||||||
""" recheck the information about this container
|
|
||||||
this is especially useful after changing the type via 'create' """
|
|
||||||
self.uuid = self.__getUUID()
|
|
||||||
self.type = self.__getTypeOfPartition()
|
|
||||||
self.name = self.__getNameOfContainer()
|
|
||||||
if self.type == self.Types["luks"]:
|
|
||||||
self.mount = self.__mountLuks
|
|
||||||
self.umount = self.__umountLuks
|
|
||||||
if self.type == self.Types["plain"]:
|
|
||||||
self.mount = self.__mountPlain
|
|
||||||
self.umount = self.__umountPlain
|
|
||||||
|
|
||||||
|
|
||||||
def __getNameOfContainer(self):
|
def __getNameOfContainer(self):
|
||||||
"retrieve the name of the container by querying the database"
|
"retrieve the name of the container by querying the database"
|
||||||
def_name = self.cbox.getNameForUUID(self.uuid)
|
def_name = self.cbox.getNameForUUID(self.uuid)
|
||||||
|
|
65
pythonrewrite/bin/CryptoBoxPlugin.py
Normal file
65
pythonrewrite/bin/CryptoBoxPlugin.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# parent class for all plugins of the CryptoBox
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class CryptoBoxPlugin:
|
||||||
|
|
||||||
|
def __init__(self, cbox, pluginDir):
|
||||||
|
self.cbox = cbox
|
||||||
|
self.hdf = {}
|
||||||
|
self.pluginDir = pluginDir
|
||||||
|
self.hdf_prefix = "Data.Plugins.%s." % self.getName()
|
||||||
|
|
||||||
|
|
||||||
|
def doAction(self, **args):
|
||||||
|
"""override doAction with your plugin code"""
|
||||||
|
raise Exception, "undefined action handler ('doAction') in plugin '%'" % self.getName()
|
||||||
|
|
||||||
|
|
||||||
|
def getStatus(self):
|
||||||
|
"""you should override this, to supply useful state information"""
|
||||||
|
raise Exception, "undefined state handler ('getStatus') in plugin '%'" % self.getName()
|
||||||
|
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
"""the name of the python file (module) should be the name of the plugin"""
|
||||||
|
return self.__module__
|
||||||
|
|
||||||
|
|
||||||
|
def getTemplateFileName(self, template_name):
|
||||||
|
"""return the filename of the template, if it is part of this plugin
|
||||||
|
|
||||||
|
use this function to check, if the plugin provides the specified template
|
||||||
|
"""
|
||||||
|
result_file = os.path.join(self.pluginDir, template_name + ".cs")
|
||||||
|
if os.access(result_file, os.R_OK) and os.path.isfile(result_file):
|
||||||
|
return result_file
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def getLanguageData(self, lang="en"):
|
||||||
|
import neo_cgi, neo_util
|
||||||
|
langdir = os.path.abspath(os.path.join(self.pluginDir, "lang"))
|
||||||
|
## first: the default language file (english)
|
||||||
|
langFiles = [os.path.join(langdir, "en.hdf")]
|
||||||
|
## maybe we have to load a translation afterwards
|
||||||
|
if lang != "en":
|
||||||
|
langFiles.append(os.path.join(langdir, lang + ".hdf"))
|
||||||
|
for langFile in langFiles:
|
||||||
|
if os.access(langFile, os.R_OK):
|
||||||
|
lang_hdf = neo_util.HDF()
|
||||||
|
lang_hdf.readFile(langFile)
|
||||||
|
return lang_hdf
|
||||||
|
self.cbox.log.debug("Couldn't find a valid plugin language file (%s)" % str(langFiles))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def loadDataSet(self, hdf):
|
||||||
|
for (key, value) in self.hdf.items():
|
||||||
|
hdf.setValue(key, str(value))
|
||||||
|
|
|
@ -226,8 +226,8 @@ def run_umount(args):
|
||||||
destination = args[0]
|
destination = args[0]
|
||||||
del args[0]
|
del args[0]
|
||||||
# check permissions for the destination
|
# check permissions for the destination
|
||||||
if not isWriteable(destination, DEV_TYPES["dir"]):
|
if not isWriteable(os.path.dirname(destination), DEV_TYPES["dir"]):
|
||||||
raise "WrongArguments", "the mountpoint (%s) is not writeable" % (destination, )
|
raise "WrongArguments", "the parent of the mountpoint (%s) is not writeable" % (destination, )
|
||||||
if len(args) != 0: raise "WrongArguments", "umount does not allow arguments"
|
if len(args) != 0: raise "WrongArguments", "umount does not allow arguments"
|
||||||
except TypeError:
|
except TypeError:
|
||||||
raise "WrongArguments", "invalid arguments supplied"
|
raise "WrongArguments", "invalid arguments supplied"
|
||||||
|
|
|
@ -146,7 +146,7 @@ class CryptoBoxSettings:
|
||||||
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Details")
|
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Details")
|
||||||
except IOError:
|
except IOError:
|
||||||
raise CryptoBoxExceptions.CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"])
|
raise CryptoBoxExceptions.CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"])
|
||||||
log_handler.setFormatter(logging.Formatter('%(asctime)s %(module)s %(levelname)s: %(message)s'))
|
log_handler.setFormatter(logging.Formatter('%(asctime)s CryptoBox %(levelname)s: %(message)s'))
|
||||||
cbox_log = logging.getLogger("CryptoBox")
|
cbox_log = logging.getLogger("CryptoBox")
|
||||||
## remove previous handlers
|
## remove previous handlers
|
||||||
cbox_log.handlers = []
|
cbox_log.handlers = []
|
||||||
|
@ -182,7 +182,6 @@ Details = string(min=1)
|
||||||
[WebSettings]
|
[WebSettings]
|
||||||
Stylesheet = string(min=1)
|
Stylesheet = string(min=1)
|
||||||
Language = string(min=1, default="en")
|
Language = string(min=1, default="en")
|
||||||
DocLanguage = string(min=1, default="en")
|
|
||||||
|
|
||||||
[Programs]
|
[Programs]
|
||||||
cryptsetup = fileExecutable(default="/sbin/cryptsetup")
|
cryptsetup = fileExecutable(default="/sbin/cryptsetup")
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CryptoBoxWebserver:
|
||||||
})
|
})
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
# just use this config, when we're startet directly
|
# just use this config, when we're started directly
|
||||||
cherrypy.config.update(file = "cryptoboxwebserver.conf")
|
cherrypy.config.update(file = "cryptoboxwebserver.conf")
|
||||||
cherrypy.server.start()
|
cherrypy.server.start()
|
||||||
|
|
||||||
|
|
|
@ -8,60 +8,46 @@ import logging
|
||||||
class PluginManager:
|
class PluginManager:
|
||||||
"""manage available plugins"""
|
"""manage available plugins"""
|
||||||
|
|
||||||
def __init__(self, plugin_dirs=None):
|
def __init__(self, cbox, plugin_dirs="."):
|
||||||
|
self.cbox = cbox
|
||||||
self.log = logging.getLogger("CryptoBox")
|
self.log = logging.getLogger("CryptoBox")
|
||||||
if hasattr(plugin_dirs, "__iter__"):
|
if hasattr(plugin_dirs, "__iter__"):
|
||||||
self.plugin_dirs = [os.path.abspath(dir) for dir in plugin_dirs]
|
self.plugin_dirs = [os.path.abspath(dir) for dir in plugin_dirs]
|
||||||
else:
|
else:
|
||||||
self.plugin_dirs = [os.path.abspath(plugin_dirs)]
|
self.plugin_dirs = [os.path.abspath(plugin_dirs)]
|
||||||
|
self.pluginList = self.__getAllPlugins()
|
||||||
|
|
||||||
|
|
||||||
def allPlugins(self):
|
def getPlugins(self):
|
||||||
for plfile in self.__getPluginFiles():
|
return self.pluginList[:]
|
||||||
yield os.path.basename(plfile)[:-3]
|
|
||||||
|
|
||||||
|
|
||||||
def getPlugin(self, name):
|
def getPlugin(self, name):
|
||||||
|
for p in self.pluginList[:]:
|
||||||
|
if p.getName() == name:
|
||||||
|
return p
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def __getAllPlugins(self):
|
||||||
|
list = []
|
||||||
|
for plfile in self.__getPluginFiles():
|
||||||
|
list.append(self.__getPluginClass(os.path.basename(plfile)[:-3]))
|
||||||
|
return list
|
||||||
|
|
||||||
|
|
||||||
|
def __getPluginClass(self, name):
|
||||||
for plfile in self.__getPluginFiles():
|
for plfile in self.__getPluginFiles():
|
||||||
if name == os.path.basename(plfile)[:-3]:
|
if name == os.path.basename(plfile)[:-3]:
|
||||||
return imp.load_source(name, plfile)
|
try:
|
||||||
|
pl_class = getattr(imp.load_source(name, plfile), name)
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
return pl_class(self.cbox, os.path.dirname(plfile))
|
||||||
else:
|
else:
|
||||||
return None
|
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"):
|
|
||||||
import neo_cgi, neo_util
|
|
||||||
for plfile in self.__getPluginFiles():
|
|
||||||
plname = os.path.basename(plfile)[:-3]
|
|
||||||
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)
|
|
||||||
lang_hdf = neo_util.HDF()
|
|
||||||
lang_hdf.readFile(langfile)
|
|
||||||
## add the language data below "Lang.Plugins.PLUGINNAME"
|
|
||||||
hdf.copy("Lang.Plugins." + plname, lang_hdf)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.log.debug("Couldn't find a plugin language file (%s)" % default_langfile)
|
|
||||||
|
|
||||||
|
|
||||||
def __getPluginFiles(self):
|
def __getPluginFiles(self):
|
||||||
result = []
|
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 dir in [os.path.abspath(e) for e in self.plugin_dirs if os.access(e, os.R_OK) and os.path.isdir(e)]:
|
||||||
|
@ -74,8 +60,8 @@ class PluginManager:
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
x = PluginManager("../plugins")
|
x = PluginManager(None, None, "../plugins")
|
||||||
for a in x.allPlugins():
|
for a in x.getPlugins():
|
||||||
print "Plugin: %s" % a
|
if not a is None:
|
||||||
print x.getPlugin(a).getStatus()
|
print "Plugin: %s" % a.getName()
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,12 @@ class WebInterfaceDataset(dict):
|
||||||
templates
|
templates
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, cbox, prefs):
|
def __init__(self, cbox, prefs, plugins):
|
||||||
self.prefs = prefs
|
self.prefs = prefs
|
||||||
self.cbox = cbox
|
self.cbox = cbox
|
||||||
self.__setConfigValues()
|
self.__setConfigValues()
|
||||||
self.__setCryptoBoxState()
|
self.__setCryptoBoxState()
|
||||||
|
self.__setPluginList(plugins)
|
||||||
|
|
||||||
|
|
||||||
def setPluginState(self, plugins):
|
|
||||||
for pl in plugins.allPlugins():
|
|
||||||
self["Data.Status.Plugins." + pl] = plugins.getPlugin(pl).getStatus(self.cbox)
|
|
||||||
|
|
||||||
|
|
||||||
def setCurrentDiskState(self, device):
|
def setCurrentDiskState(self, device):
|
||||||
|
@ -46,6 +41,8 @@ class WebInterfaceDataset(dict):
|
||||||
avail_counter = 0
|
avail_counter = 0
|
||||||
active_counter = 0
|
active_counter = 0
|
||||||
for container in self.cbox.getContainerList():
|
for container in self.cbox.getContainerList():
|
||||||
|
## useful if the container was changed during an action
|
||||||
|
container.resetObject()
|
||||||
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
|
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
|
||||||
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
|
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
|
||||||
isMounted = container.isMounted() and 1 or 0
|
isMounted = container.isMounted() and 1 or 0
|
||||||
|
@ -65,7 +62,6 @@ class WebInterfaceDataset(dict):
|
||||||
self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"])
|
self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"])
|
||||||
self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"]
|
self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"]
|
||||||
self["Settings.Language"] = self.prefs["WebSettings"]["Language"]
|
self["Settings.Language"] = self.prefs["WebSettings"]["Language"]
|
||||||
self["Settings.DocLang"] = self.prefs["WebSettings"]["DocLanguage"]
|
|
||||||
self["Settings.PluginDir"] = self.prefs["Locations"]["PluginDir"]
|
self["Settings.PluginDir"] = self.prefs["Locations"]["PluginDir"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,5 +77,15 @@ class WebInterfaceDataset(dict):
|
||||||
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf")
|
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf")
|
||||||
hdf = neo_util.HDF()
|
hdf = neo_util.HDF()
|
||||||
hdf.readFile(hdf_path)
|
hdf.readFile(hdf_path)
|
||||||
return hdf.getValue("Lang.Name",lang)
|
return hdf.getValue("Name",lang)
|
||||||
|
|
||||||
|
|
||||||
|
def __setPluginList(self, plugins):
|
||||||
|
for p in plugins:
|
||||||
|
lang_data = p.getLanguageData()
|
||||||
|
entryName = "Settings.PluginList." + p.getName()
|
||||||
|
self[entryName] = p.getName()
|
||||||
|
self[entryName + ".Rank"] = lang_data.getValue("Rank", "100")
|
||||||
|
self[entryName + ".Link"] = lang_data.getValue("Link", p.getName())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,15 @@ from CryptoBoxExceptions import *
|
||||||
class WebInterfacePlugins:
|
class WebInterfacePlugins:
|
||||||
|
|
||||||
def __init__(self, log, plugins, handler_func):
|
def __init__(self, log, plugins, handler_func):
|
||||||
for plname in plugins.allPlugins():
|
for plugin in plugins.getPlugins():
|
||||||
|
if not plugin: continue
|
||||||
|
plname = plugin.getName()
|
||||||
log.info("Plugin '%s' loaded" % plname)
|
log.info("Plugin '%s' loaded" % plname)
|
||||||
## this should be the "easiest" way to expose all plugins as URLs
|
## this should be the "easiest" way to expose all plugins as URLs
|
||||||
setattr(self, plname, handler_func(plname))
|
setattr(self, plname, handler_func(plugin))
|
||||||
setattr(getattr(self, plname), "exposed", True)
|
setattr(getattr(self, plname), "exposed", True)
|
||||||
|
# TODO: check, if this really works - for now the "stream_response" feature seems to be broken
|
||||||
|
#setattr(getattr(self, plname), "stream_respones", True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,22 +32,19 @@ class WebInterfaceSites:
|
||||||
self.log = logging.getLogger("CryptoBox")
|
self.log = logging.getLogger("CryptoBox")
|
||||||
self.prefs = self.cbox.prefs
|
self.prefs = self.cbox.prefs
|
||||||
self.__resetDataset()
|
self.__resetDataset()
|
||||||
self.pluginList = Plugins.PluginManager(self.prefs["Locations"]["PluginDir"])
|
|
||||||
self.plugins = WebInterfacePlugins(self.log, self.pluginList, self.return_plugin_action)
|
|
||||||
self.plugins.index = self.system
|
|
||||||
|
|
||||||
|
|
||||||
def __resetDataset(self):
|
def __resetDataset(self):
|
||||||
"""this method has to be called at the beginning of every "site" action
|
"""this method has to be called at the beginning of every "site" action
|
||||||
important: only at the beginning of an action (to not loose information)
|
important: only at the beginning of an action (to not loose information)
|
||||||
important: for _every_ "site" action (cherrypy is stateful)
|
important: for _every_ "site" action (cherrypy is stateful)
|
||||||
|
also take care for the plugins, as they also contain datasets
|
||||||
"""
|
"""
|
||||||
self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs)
|
self.pluginList = Plugins.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"])
|
||||||
|
self.plugins = WebInterfacePlugins(self.log, self.pluginList, self.return_plugin_action)
|
||||||
|
## publish the url "/system" as an alias for "/plugins"
|
||||||
def __isHDAvailable(self):
|
self.plugins.index = self.system
|
||||||
#TODO: implement this
|
self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs, self.pluginList.getPlugins())
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def __check_config(self):
|
def __check_config(self):
|
||||||
|
@ -274,9 +275,14 @@ class WebInterfaceSites:
|
||||||
|
|
||||||
|
|
||||||
def test(self, weblang=""):
|
def test(self, weblang=""):
|
||||||
|
import cherrypy
|
||||||
self.__resetDataset()
|
self.__resetDataset()
|
||||||
self.__setWebLang(weblang)
|
self.__setWebLang(weblang)
|
||||||
return "test passed"
|
for x in pref_langs:
|
||||||
|
yield "Lang: %s<br/>" % x
|
||||||
|
for (key,value) in headers.items():
|
||||||
|
yield "%s: %s<br/>" % (key,value)
|
||||||
|
#return "test passed"
|
||||||
|
|
||||||
|
|
||||||
def umount_do(self, device, weblang=""):
|
def umount_do(self, device, weblang=""):
|
||||||
|
@ -315,7 +321,7 @@ class WebInterfaceSites:
|
||||||
return self.__render("show_volume")
|
return self.__render("show_volume")
|
||||||
|
|
||||||
|
|
||||||
def return_plugin_action(self, plugin_name):
|
def return_plugin_action(self, plugin):
|
||||||
def handler(**args):
|
def handler(**args):
|
||||||
self.__resetDataset()
|
self.__resetDataset()
|
||||||
try:
|
try:
|
||||||
|
@ -323,9 +329,10 @@ class WebInterfaceSites:
|
||||||
del args["weblang"]
|
del args["weblang"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
plugin = self.pluginList.getPlugin(plugin_name)
|
nextTemplate = plugin.doAction(**args)
|
||||||
nextTemplate = plugin.doAction(self.dataset, self.cbox, **args)
|
## set the default template
|
||||||
return self.__render(nextTemplate, plugin_name)
|
if not nextTemplate: nextTemplate = "form_system"
|
||||||
|
return self.__render(nextTemplate, plugin)
|
||||||
return handler
|
return handler
|
||||||
|
|
||||||
|
|
||||||
|
@ -384,20 +391,56 @@ class WebInterfaceSites:
|
||||||
## TODO: add some code to evaluate the language setting of the browser
|
## TODO: add some code to evaluate the language setting of the browser
|
||||||
guess = value
|
guess = value
|
||||||
availLangs = self.cbox.getAvailableLanguages()
|
availLangs = self.cbox.getAvailableLanguages()
|
||||||
## TODO: add some warnings for an invalid choosen language
|
if not guess:
|
||||||
|
guess = self.__getPreferredBrowserLanguage(availLangs)
|
||||||
if not guess or \
|
if not guess or \
|
||||||
not guess in availLangs or \
|
not guess in availLangs or \
|
||||||
re.search(u'\W', guess):
|
re.search(u'\W', guess):
|
||||||
|
self.cbox.log.info("invalid language choosen: %s" % guess)
|
||||||
guess = self.prefs["WebSettings"]["Language"]
|
guess = self.prefs["WebSettings"]["Language"]
|
||||||
|
## TODO: extract the current "browser-language" - this should be the first guess
|
||||||
## maybe the language is still not valid
|
## maybe the language is still not valid
|
||||||
if not guess in availLangs:
|
if not guess in availLangs:
|
||||||
self.log.warn("the configured language is invalid: %s" % guess)
|
self.log.warn("the configured language is invalid: %s" % guess)
|
||||||
|
guess = "en"
|
||||||
|
## maybe there is no english dataset???
|
||||||
|
if not guess in availLangs:
|
||||||
|
self.log.warn("couldn't find the english dataset")
|
||||||
guess = availLangs[0]
|
guess = availLangs[0]
|
||||||
self.dataset["Settings.Language"] = guess
|
self.dataset["Settings.Language"] = guess
|
||||||
self.dataset["Settings.DocLang"] = guess
|
## we only have to save it, if it was specified correctly and explicitly
|
||||||
|
if value == guess:
|
||||||
self.dataset["Settings.LinkAttrs.weblang"] = guess
|
self.dataset["Settings.LinkAttrs.weblang"] = guess
|
||||||
|
|
||||||
|
|
||||||
|
def __getPreferredBrowserLanguage(self, availLangs):
|
||||||
|
"""guess the preferred language of the user (as sent by the browser)
|
||||||
|
take the first language, that is part of 'availLangs'
|
||||||
|
"""
|
||||||
|
import cherrypy
|
||||||
|
try:
|
||||||
|
pref_lang_header = cherrypy.request.headers["Accept-Language"]
|
||||||
|
except KeyError:
|
||||||
|
## no language header was specified
|
||||||
|
return None
|
||||||
|
## this could be a typical 'Accept-Language' header:
|
||||||
|
## de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
|
||||||
|
regex = re.compile(u"\w+(-\w+)?(;q=[\d\.]+)?$")
|
||||||
|
pref_langs = [e.split(";",1)[0]
|
||||||
|
for e in pref_lang_header.split(",")
|
||||||
|
if regex.match(e)]
|
||||||
|
## is one of these preferred languages available?
|
||||||
|
for lang in pref_langs:
|
||||||
|
if lang in availLangs: return lang
|
||||||
|
## we try to be nice: also look for "de" if "de-de" was specified ...
|
||||||
|
for lang in pref_langs:
|
||||||
|
## use only the first part of the language
|
||||||
|
short_lang = lang.split("-",1)[0]
|
||||||
|
if short_lang in availLangs: return short_lang
|
||||||
|
## we give up
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def __setDevice(self, device):
|
def __setDevice(self, device):
|
||||||
if device and re.match(u'[\w /\-]+$', device) and self.cbox.getContainer(device):
|
if device and re.match(u'[\w /\-]+$', device) and self.cbox.getContainer(device):
|
||||||
self.log.debug("select device: %s" % device)
|
self.log.debug("select device: %s" % device)
|
||||||
|
@ -416,15 +459,33 @@ class WebInterfaceSites:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __render(self, template, plugin=None):
|
def __getLanguageData(self, web_lang="en"):
|
||||||
'''renders from clearsilver templates and returns the resulting html
|
import neo_cgi, neo_util, os
|
||||||
|
default_lang = "en"
|
||||||
|
conf_lang = self.prefs["WebSettings"]["Language"]
|
||||||
|
hdf = neo_util.HDF()
|
||||||
|
langDir = os.path.abspath(self.prefs["Locations"]["LangDir"])
|
||||||
|
langFiles = []
|
||||||
|
## first: read default language (en)
|
||||||
|
if (default_lang != conf_lang) and (default_lang != web_lang):
|
||||||
|
langFiles.append(os.path.join(langDir, default_lang + ".hdf"))
|
||||||
|
## second: read language as defined in the config file
|
||||||
|
if (conf_lang != web_lang):
|
||||||
|
langFiles.append(os.path.join(langDir, conf_lang + ".hdf"))
|
||||||
|
## third: read language as configured via web interface
|
||||||
|
langFiles.append(os.path.join(langDir, web_lang + ".hdf"))
|
||||||
|
for langFile in langFiles:
|
||||||
|
if os.access(langFile, os.R_OK):
|
||||||
|
hdf.readFile(langFile)
|
||||||
|
else:
|
||||||
|
log.warn("Couldn't read language file: %s" % langFile)
|
||||||
|
return hdf
|
||||||
|
|
||||||
Gets a dictionary with all settings, nessessary for rendering.
|
|
||||||
In fact the dictionary is a copy of the CryptoBoxWerbserverSite
|
def __render(self, renderInfo, plugin=None):
|
||||||
object, that calls this render method. This might be bloat but
|
'''renders from clearsilver templates and returns the resulting html
|
||||||
this way the render method has always a complete, actual set of values.
|
|
||||||
'''
|
'''
|
||||||
import os
|
import os, types
|
||||||
try:
|
try:
|
||||||
import neo_cgi, neo_util, neo_cs
|
import neo_cgi, neo_util, neo_cs
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -433,40 +494,78 @@ class WebInterfaceSites:
|
||||||
sys.stderr.write(errorMsg)
|
sys.stderr.write(errorMsg)
|
||||||
raise ImportError, errorMsg
|
raise ImportError, errorMsg
|
||||||
|
|
||||||
plugin_cs_file = False
|
## is renderInfo a string (filename of the template) or a dictionary?
|
||||||
|
if type(renderInfo) == types.DictType:
|
||||||
|
template = renderInfo["template"]
|
||||||
|
if renderInfo.has_key("generator"):
|
||||||
|
generator = renderInfo["generator"]
|
||||||
|
else:
|
||||||
|
generator = False
|
||||||
|
else:
|
||||||
|
(template, generator) = (renderInfo, None)
|
||||||
|
|
||||||
|
## load the language data
|
||||||
|
hdf = neo_util.HDF()
|
||||||
|
hdf.copy("Lang", self.__getLanguageData(self.dataset["Settings.Language"]))
|
||||||
|
|
||||||
|
## first: assume, that the template file is in the global template directory
|
||||||
|
self.dataset["Settings.TemplateFile"] = os.path.abspath(os.path.join(self.prefs["Locations"]["TemplateDir"], template + ".cs"))
|
||||||
|
|
||||||
if plugin:
|
if plugin:
|
||||||
plugin_cs_file = self.pluginList.getTemplateFileName(plugin, template)
|
## check, if the plugin provides the template file -> overriding
|
||||||
default_cs_file = os.path.join(self.prefs["Locations"]["TemplateDir"], template + ".cs")
|
plugin_cs_file = plugin.getTemplateFileName(template)
|
||||||
self.dataset["Data.TemplateFile"] = plugin_cs_file or default_cs_file
|
if plugin_cs_file:
|
||||||
|
self.dataset["Settings.TemplateFile"] = plugin_cs_file
|
||||||
|
## add the current state of the plugins to the hdf dataset
|
||||||
|
self.dataset["Data.Status.Plugins.%s" % plugin.getName()] = plugin.getStatus()
|
||||||
|
## load the language data
|
||||||
|
pl_lang = plugin.getLanguageData(self.dataset["Settings.Language"])
|
||||||
|
if pl_lang:
|
||||||
|
hdf.copy("Lang.Plugins.%s" % plugin.getName(), pl_lang)
|
||||||
|
## load the dataset of the plugin
|
||||||
|
plugin.loadDataSet(hdf)
|
||||||
|
|
||||||
self.log.info("rendering site: " + template)
|
self.log.info("rendering site: " + template)
|
||||||
|
|
||||||
cs_path = os.path.join(self.prefs["Locations"]["TemplateDir"], "main.cs")
|
cs_path = os.path.abspath(os.path.join(self.prefs["Locations"]["TemplateDir"], "main.cs"))
|
||||||
if not os.access(cs_path, os.R_OK):
|
if not os.access(cs_path, os.R_OK):
|
||||||
log.error("Couldn't read clearsilver file: %s" % cs_path)
|
log.error("Couldn't read clearsilver file: %s" % cs_path)
|
||||||
return "Couldn't read clearsilver file: %s" % cs_path
|
yield "Couldn't read clearsilver file: %s" % cs_path
|
||||||
|
return
|
||||||
|
|
||||||
# use the user selected language instead of the configured
|
## update the container hdf-dataset (necessary if a plugin changed the state of a container)
|
||||||
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], self.dataset["Settings.Language"] + ".hdf")
|
|
||||||
if not os.access(hdf_path, os.R_OK):
|
|
||||||
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.pluginList)
|
|
||||||
|
|
||||||
## update the container information
|
|
||||||
self.dataset.setContainersState()
|
self.dataset.setContainersState()
|
||||||
|
|
||||||
hdf = neo_util.HDF()
|
|
||||||
hdf.readFile(hdf_path)
|
|
||||||
self.log.debug(self.dataset)
|
self.log.debug(self.dataset)
|
||||||
for key in self.dataset.keys():
|
for key in self.dataset.keys():
|
||||||
hdf.setValue(key,str(self.dataset[key]))
|
hdf.setValue(key,str(self.dataset[key]))
|
||||||
## load languaga data of plugins
|
|
||||||
self.pluginList.loadLanguageData(hdf, lang=self.dataset["Settings.Language"])
|
|
||||||
cs = neo_cs.CS(hdf)
|
cs = neo_cs.CS(hdf)
|
||||||
cs.parseFile(cs_path)
|
cs.parseFile(cs_path)
|
||||||
return cs.render()
|
|
||||||
|
## is there a generator containing additional information?
|
||||||
|
if generator is None:
|
||||||
|
## all content in one flush
|
||||||
|
yield cs.render()
|
||||||
|
else:
|
||||||
|
content_generate = generator()
|
||||||
|
dummy_line = """<!-- CONTENT_DUMMY -->"""
|
||||||
|
## now we do it linewise - checking for the content marker
|
||||||
|
for line in cs.render().splitlines():
|
||||||
|
if line.find(dummy_line) != -1:
|
||||||
|
yield line.replace(dummy_line, content_generate.next())
|
||||||
|
else:
|
||||||
|
yield line + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def test_stream(self):
|
||||||
|
"""just for testing purposes - to check if the "stream_response" feature
|
||||||
|
actually works - for now (September 02006) it does not seem to be ok"""
|
||||||
|
import time
|
||||||
|
yield "<html><head><title>neu</title></head><body><p><ul>"
|
||||||
|
for a in range(10):
|
||||||
|
yield "<li>yes: %d - %s</li>" % (a, str(time.time()))
|
||||||
|
time.sleep(1)
|
||||||
|
yield "</ul></p></html>"
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
@ -484,12 +583,6 @@ class WebInterfaceSites:
|
||||||
umount_do.exposed = True
|
umount_do.exposed = True
|
||||||
show_volumes.exposed = True
|
show_volumes.exposed = True
|
||||||
test.exposed = True
|
test.exposed = True
|
||||||
|
test_stream.exposed = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
## TODO: check this before anything else
|
|
||||||
if self.cbox.getAvailableDocLanguages():
|
|
||||||
self.dataset["Data.Error"] = "NoDocumentation"
|
|
||||||
return self.__render("show_status")
|
|
||||||
"""
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# comma separated list of possible prefixes for accesible devices
|
# comma separated list of possible prefixes for accesible devices
|
||||||
# beware: .e.g "/dev/hd" grants access to _all_ harddisks
|
# beware: .e.g "/dev/hd" grants access to _all_ harddisks
|
||||||
AllowedDevices = /dev/loop
|
AllowedDevices = /dev/loop, /dev/sda
|
||||||
|
|
||||||
|
|
||||||
# the default name prefix of not unnamed containers
|
# the default name prefix of not unnamed containers
|
||||||
|
@ -67,9 +67,6 @@ Stylesheet = /cryptobox-misc/cryptobox.css
|
||||||
# default language
|
# default language
|
||||||
Language = de
|
Language = de
|
||||||
|
|
||||||
# default language for documentation
|
|
||||||
DocLanguage = de
|
|
||||||
|
|
||||||
|
|
||||||
[Programs]
|
[Programs]
|
||||||
cryptsetup = /sbin/cryptsetup
|
cryptsetup = /sbin/cryptsetup
|
||||||
|
|
|
@ -12,3 +12,5 @@ static_filter.on = True
|
||||||
# TODO: use live-cd/live-cd-tree.d/var/www/favicon.ico
|
# TODO: use live-cd/live-cd-tree.d/var/www/favicon.ico
|
||||||
static_filter.file = "/usr/share/doc/python-cherrypy/cherrypy/favicon.ico"
|
static_filter.file = "/usr/share/doc/python-cherrypy/cherrypy/favicon.ico"
|
||||||
|
|
||||||
|
[/test_stream]
|
||||||
|
stream_response = True
|
||||||
|
|
Loading…
Reference in a new issue