|
|
|
@ -46,6 +46,8 @@ class WebInterfaceSites:
|
|
|
|
|
self.__resetDataset()
|
|
|
|
|
## store the original http error handler
|
|
|
|
|
self._cp_on_http_error = self.newHTTPErrorHandler
|
|
|
|
|
## set initial language order
|
|
|
|
|
self.langOrder = self.cbox.prefs["WebSettings"]["Languages"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __resetDataset(self):
|
|
|
|
@ -64,7 +66,7 @@ class WebInterfaceSites:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __loadPlugins(self):
|
|
|
|
|
self.pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"])
|
|
|
|
|
self.pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"], self)
|
|
|
|
|
for plugin in self.pluginList.getPlugins():
|
|
|
|
|
if not plugin: continue
|
|
|
|
|
plname = plugin.getName()
|
|
|
|
@ -134,6 +136,14 @@ class WebInterfaceSites:
|
|
|
|
|
return self.return_plugin_action(self.pluginList.getPlugin("disks"))(**param_dict)
|
|
|
|
|
|
|
|
|
|
def newHTTPErrorHandler(self, errorCode, message):
|
|
|
|
|
"""handle http errors gracefully
|
|
|
|
|
|
|
|
|
|
404 - not found errors: ignored if url is below /cryptobox-misc/
|
|
|
|
|
other 404 errors: send the error code and return a nice informative page
|
|
|
|
|
500 - runtime errors: return "ok" exit code and show a polite excuse
|
|
|
|
|
others: are there any other possible http errors?
|
|
|
|
|
"""
|
|
|
|
|
import traceback, sys
|
|
|
|
|
## we ignore uninteresting not-found errors
|
|
|
|
|
if (errorCode == 404) and \
|
|
|
|
|
(cherrypy.request.path.startswith("/cryptobox-misc/") or \
|
|
|
|
@ -151,8 +161,10 @@ class WebInterfaceSites:
|
|
|
|
|
if errorCode == 500:
|
|
|
|
|
## we fix the error code (200 is "OK")
|
|
|
|
|
cherrypy.response.status = 200
|
|
|
|
|
## TODO: 'message' is None - we should check a stack trace or something?
|
|
|
|
|
self.cbox.log.warn("HTTP-ERROR[500] - a runtime error occoured: %s" % str(message))
|
|
|
|
|
self.cbox.log.error("HTTP-ERROR[500] - a runtime error occoured: %s" % str(message))
|
|
|
|
|
## add a traceback and exception information to the lo
|
|
|
|
|
for a in traceback.format_exception(*sys.exc_info()):
|
|
|
|
|
self.cbox.log.error("\t%s" % a)
|
|
|
|
|
self.dataset["Data.Warning"] = "RuntimeError"
|
|
|
|
|
cherrypy.response.body = self.__render("empty")
|
|
|
|
|
return
|
|
|
|
@ -285,7 +297,8 @@ class WebInterfaceSites:
|
|
|
|
|
|
|
|
|
|
examples are: non-https, readonly-config, ...
|
|
|
|
|
"""
|
|
|
|
|
## TODO: maybe add an option "mount" (if it is available, but inactive)?
|
|
|
|
|
## this check is done _after_ "resetDataSet" -> a possible config partition was
|
|
|
|
|
## loaded before
|
|
|
|
|
if self.cbox.prefs.requiresPartition() and not self.cbox.prefs.getActivePartition():
|
|
|
|
|
self.dataset["Data.EnvironmentWarning"] = "ReadOnlyConfig"
|
|
|
|
|
# TODO: turn this on soon (add "not") - for now it is annoying
|
|
|
|
@ -311,31 +324,28 @@ class WebInterfaceSites:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __setWebLang(self, value):
|
|
|
|
|
guess = value
|
|
|
|
|
availLangs = self.cbox.getAvailableLanguages()
|
|
|
|
|
## no language specified: check browser language
|
|
|
|
|
if not guess:
|
|
|
|
|
guess = self.__getPreferredBrowserLanguage(availLangs)
|
|
|
|
|
## no preferred language or invalid language?
|
|
|
|
|
if not guess \
|
|
|
|
|
or not guess in availLangs \
|
|
|
|
|
or re.search(u'\W', guess):
|
|
|
|
|
## warn only for invalid languages
|
|
|
|
|
if not guess is None:
|
|
|
|
|
self.cbox.log.info("invalid language choosen: %s" % guess)
|
|
|
|
|
guess = self.prefs["WebSettings"]["Language"]
|
|
|
|
|
## maybe the language is still not valid
|
|
|
|
|
if not guess in availLangs:
|
|
|
|
|
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]
|
|
|
|
|
self.dataset["Settings.Language"] = guess
|
|
|
|
|
## we only have to save it, if it was specified correctly and explicitly
|
|
|
|
|
if value == guess:
|
|
|
|
|
self.dataset["Settings.LinkAttrs.weblang"] = guess
|
|
|
|
|
"""set the preferred priority of languages according to the following order:
|
|
|
|
|
1. language selected via web interface
|
|
|
|
|
2. preferred browser language setting
|
|
|
|
|
3. languages defined in the config file
|
|
|
|
|
"""
|
|
|
|
|
## start with the configured language order
|
|
|
|
|
langOrder = self.cbox.prefs["WebSettings"]["Languages"][:]
|
|
|
|
|
## put the preferred browser language in front
|
|
|
|
|
guess = self.__getPreferredBrowserLanguage(langOrder)
|
|
|
|
|
if guess:
|
|
|
|
|
langOrder.remove(guess)
|
|
|
|
|
langOrder.insert(0,guess)
|
|
|
|
|
## is the chosen language (via web interface) valid? - put it in front
|
|
|
|
|
if value and (value in langOrder) and (not re.search(u'\W',value)):
|
|
|
|
|
langOrder.remove(value)
|
|
|
|
|
langOrder.insert(0,value)
|
|
|
|
|
elif value:
|
|
|
|
|
self.cbox.log.info("invalid language selected: %s" % value)
|
|
|
|
|
## store current language setting
|
|
|
|
|
self.langOrder = langOrder
|
|
|
|
|
self.dataset["Settings.Language"] = langOrder[0]
|
|
|
|
|
self.dataset["Settings.LinkAttrs.weblang"] = langOrder[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getPreferredBrowserLanguage(self, availLangs):
|
|
|
|
@ -366,6 +376,8 @@ class WebInterfaceSites:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __setDevice(self, device):
|
|
|
|
|
"""check a device name that was chosen via the web interface
|
|
|
|
|
issue a warning if the device is invalid"""
|
|
|
|
|
if device and re.match(u'[\w /\-]+$', device) and self.cbox.getContainer(device):
|
|
|
|
|
self.log.debug("select device: %s" % device)
|
|
|
|
|
return True
|
|
|
|
@ -375,19 +387,10 @@ class WebInterfaceSites:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __checkVolumeName(self, name):
|
|
|
|
|
if name and re.match(u'[\w \-]+$', name):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getLanguageValue(self, value):
|
|
|
|
|
hdf = self.__getLanguageData(self.dataset["Settings.Language"])
|
|
|
|
|
return hdf.getValue(value, "")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __substituteGettext(self, languages, textDomain, hdf):
|
|
|
|
|
"""substitute all texts in the hdf dataset with their translated
|
|
|
|
|
counterparts as returned by gettext
|
|
|
|
|
"""
|
|
|
|
|
import gettext
|
|
|
|
|
try:
|
|
|
|
|
translator = gettext.translation(textDomain, languages=languages)
|
|
|
|
@ -407,41 +410,32 @@ class WebInterfaceSites:
|
|
|
|
|
walk_tree(hdf)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getLanguageData(self, web_lang="en"):
|
|
|
|
|
def __getLanguageData(self):
|
|
|
|
|
"""return the hdf dataset of the main interface and all plugins
|
|
|
|
|
translations are done according to self.langOrder
|
|
|
|
|
"""
|
|
|
|
|
## check if the language setting was changed - use cached data if possible
|
|
|
|
|
try:
|
|
|
|
|
if self.cachedLanguageData["langOrder"] == self.langOrder:
|
|
|
|
|
self.cbox.log.debug("using cached language data")
|
|
|
|
|
return self.cachedLanguageData["hdf"]
|
|
|
|
|
except AttributeError:
|
|
|
|
|
pass
|
|
|
|
|
self.cbox.log.debug("generating language data")
|
|
|
|
|
hdf = neo_util.HDF()
|
|
|
|
|
hdf.readFile(os.path.join(self.prefs["Locations"]["TemplateDir"],"language.hdf"))
|
|
|
|
|
self.__substituteGettext([web_lang], GETTEXT_DOMAIN, hdf)
|
|
|
|
|
self.__substituteGettext(self.langOrder, GETTEXT_DOMAIN, hdf)
|
|
|
|
|
## load the language data of all plugins
|
|
|
|
|
for p in self.pluginList.getPlugins():
|
|
|
|
|
pl_lang = p.getLanguageData()
|
|
|
|
|
self.__substituteGettext([web_lang], "%s-feature-%s" % (GETTEXT_DOMAIN, p.getName()), pl_lang)
|
|
|
|
|
self.__substituteGettext(self.langOrder, "%s-feature-%s" % (GETTEXT_DOMAIN, p.getName()), pl_lang)
|
|
|
|
|
hdf.copy("Plugins.%s" % p.getName(), pl_lang)
|
|
|
|
|
self.cbox.log.debug("language data for plugin loaded: %s" % p.getName())
|
|
|
|
|
## cache result for later retrieval
|
|
|
|
|
self.cachedLanguageData = {"langOrder": self.langOrder, "hdf": hdf}
|
|
|
|
|
return hdf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getLanguageData2(self, web_lang="en"):
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __render(self, renderInfo, plugin=None):
|
|
|
|
|
'''renders from clearsilver templates and returns the resulting html
|
|
|
|
|
'''
|
|
|
|
@ -457,7 +451,7 @@ class WebInterfaceSites:
|
|
|
|
|
|
|
|
|
|
## load the language data
|
|
|
|
|
hdf = neo_util.HDF()
|
|
|
|
|
hdf.copy("Lang", self.__getLanguageData(self.dataset["Settings.Language"]))
|
|
|
|
|
hdf.copy("Lang", self.__getLanguageData())
|
|
|
|
|
|
|
|
|
|
## 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"))
|
|
|
|
|