language namespace for plugins separated
plugin interface changed ("prepareForm" removed) plugins do not raise exceptions anymore first part of the partitioning plugin device-specific stuff moved to CryptoBoxTools
This commit is contained in:
parent
f2a7ceb61c
commit
de3280806f
26 changed files with 622 additions and 309 deletions
|
@ -18,6 +18,7 @@ import CryptoBoxContainer
|
||||||
from CryptoBoxExceptions import *
|
from CryptoBoxExceptions import *
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import CryptoBoxTools
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,10 +113,16 @@ class CryptoBoxProps(CryptoBox):
|
||||||
def __init__(self, config_file=None):
|
def __init__(self, config_file=None):
|
||||||
'''read config and fill class variables'''
|
'''read config and fill class variables'''
|
||||||
CryptoBox.__init__(self, config_file)
|
CryptoBox.__init__(self, config_file)
|
||||||
|
self.__reReadContainerList()
|
||||||
|
|
||||||
|
|
||||||
|
def __reReadContainerList(self):
|
||||||
self.containers = []
|
self.containers = []
|
||||||
for device in self.__getAvailablePartitions():
|
for device in CryptoBoxTools.getAvailablePartitions():
|
||||||
if self.isDeviceAllowed(device):
|
if self.isDeviceAllowed(device):
|
||||||
self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self))
|
self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self))
|
||||||
|
## sort by container name
|
||||||
|
self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1)
|
||||||
|
|
||||||
|
|
||||||
def isDeviceAllowed(self, devicename):
|
def isDeviceAllowed(self, devicename):
|
||||||
|
@ -185,9 +192,22 @@ class CryptoBoxProps(CryptoBox):
|
||||||
"assign a name to a uuid in the ContainerNameDatabase"
|
"assign a name to a uuid in the ContainerNameDatabase"
|
||||||
used_uuid = self.getUUIDForName(name)
|
used_uuid = self.getUUIDForName(name)
|
||||||
"first remove potential conflicting uuid/name combination"
|
"first remove potential conflicting uuid/name combination"
|
||||||
if used_uuid: del self.prefs.nameDB[used_uuid]
|
if used_uuid:
|
||||||
|
## remember the container which name was overriden
|
||||||
|
for e in self.containers:
|
||||||
|
if e.getName() == name:
|
||||||
|
forcedRename = e
|
||||||
|
break
|
||||||
|
del self.prefs.nameDB[used_uuid]
|
||||||
self.prefs.nameDB[uuid] = name
|
self.prefs.nameDB[uuid] = name
|
||||||
self.prefs.nameDB.write()
|
self.prefs.nameDB.write()
|
||||||
|
## rename the container that lost its name (necessary while we use cherrypy)
|
||||||
|
if used_uuid:
|
||||||
|
## this is surely not the best way to regenerate the name
|
||||||
|
dev = e.getDevice()
|
||||||
|
old_index = self.containers.index(e)
|
||||||
|
self.containers.remove(e)
|
||||||
|
self.containers.insert(old_index, CryptoBoxContainer.CryptoBoxContainer(dev,self))
|
||||||
|
|
||||||
|
|
||||||
def getNameForUUID(self, uuid):
|
def getNameForUUID(self, uuid):
|
||||||
|
@ -244,102 +264,6 @@ class CryptoBoxProps(CryptoBox):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
""" ************ internal stuff starts here *********** """
|
|
||||||
|
|
||||||
def __getAvailablePartitions(self):
|
|
||||||
"retrieve a list of all available containers"
|
|
||||||
ret_list = []
|
|
||||||
try:
|
|
||||||
"the following reads all lines of /proc/partitions and adds the mentioned devices"
|
|
||||||
fpart = open("/proc/partitions", "r")
|
|
||||||
try:
|
|
||||||
line = fpart.readline()
|
|
||||||
while line:
|
|
||||||
p_details = line.split()
|
|
||||||
if (len(p_details) == 4):
|
|
||||||
"the following code prevents double entries like /dev/hda and /dev/hda1"
|
|
||||||
(p_major, p_minor, p_size, p_device) = p_details
|
|
||||||
if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor):
|
|
||||||
p_parent = re.sub('[1-9]?[0-9]$', '', p_device)
|
|
||||||
if p_parent == p_device:
|
|
||||||
if [e for e in ret_list if re.search('^' + p_parent + '[1-9]?[0-9]$', e)]:
|
|
||||||
"major partition - its children are already in the list"
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
"major partition - but there are no children for now"
|
|
||||||
ret_list.append(p_device)
|
|
||||||
else:
|
|
||||||
"minor partition - remove parent if necessary"
|
|
||||||
if p_parent in ret_list: ret_list.remove(p_parent)
|
|
||||||
ret_list.append(p_device)
|
|
||||||
line = fpart.readline()
|
|
||||||
finally:
|
|
||||||
fpart.close()
|
|
||||||
return [self.__getAbsoluteDeviceName(e) for e in ret_list]
|
|
||||||
except IOError:
|
|
||||||
self.log.warning("Could not read /proc/partitions")
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def __getAbsoluteDeviceName(self, shortname):
|
|
||||||
""" returns the absolute file name of a device (e.g.: "hda1" -> "/dev/hda1")
|
|
||||||
this does also work for device mapper devices
|
|
||||||
if the result is non-unique, one arbitrary value is returned"""
|
|
||||||
if re.search('^/', shortname): return shortname
|
|
||||||
default = os.path.join("/dev", shortname)
|
|
||||||
if os.path.exists(default): return default
|
|
||||||
result = self.__findMajorMinorOfDevice(shortname)
|
|
||||||
"if no valid major/minor was found -> exit"
|
|
||||||
if not result: return default
|
|
||||||
(major, minor) = result
|
|
||||||
"for device-mapper devices (major == 254) ..."
|
|
||||||
if major == 254:
|
|
||||||
result = self.__findMajorMinorDeviceName("/dev/mapper", major, minor)
|
|
||||||
if result: return result[0]
|
|
||||||
"now check all files in /dev"
|
|
||||||
result = self.__findMajorMinorDeviceName("/dev", major, minor)
|
|
||||||
if result: return result[0]
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def __findMajorMinorOfDevice(self, device):
|
|
||||||
"return the major/minor numbers of a block device by querying /sys/block/?/dev"
|
|
||||||
if not os.path.exists(os.path.join("/sys/block", device)): return None
|
|
||||||
blockdev_info_file = os.path.join(os.path.join("/sys/block", device), "dev")
|
|
||||||
try:
|
|
||||||
f_blockdev_info = open(blockdev_info_file, "r")
|
|
||||||
blockdev_info = f_blockdev_info.read()
|
|
||||||
f_blockdev_info.close()
|
|
||||||
(str_major, str_minor) = blockdev_info.split(":")
|
|
||||||
"numeric conversion"
|
|
||||||
try:
|
|
||||||
major = int(str_major)
|
|
||||||
minor = int(str_minor)
|
|
||||||
return (major, minor)
|
|
||||||
except ValueError:
|
|
||||||
"unknown device numbers -> stop guessing"
|
|
||||||
return None
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def __findMajorMinorDeviceName(self, dir, major, minor):
|
|
||||||
"returns the names of devices with the specified major and minor number"
|
|
||||||
collected = []
|
|
||||||
try:
|
|
||||||
subdirs = [os.path.join(dir, e) for e in os.listdir(dir) if (not os.path.islink(os.path.join(dir, e))) and os.path.isdir(os.path.join(dir, e))]
|
|
||||||
"do a recursive call to parse the directory tree"
|
|
||||||
for dirs in subdirs:
|
|
||||||
collected.extend(self.__findMajorMinorDeviceName(dirs, major, minor))
|
|
||||||
"filter all device inodes in this directory"
|
|
||||||
collected.extend([os.path.realpath(os.path.join(dir, e)) for e in os.listdir(dir) if (os.major(os.stat(os.path.join(dir, e)).st_rdev) == major) and (os.minor(os.stat(os.path.join(dir, e)).st_rdev) == minor)])
|
|
||||||
result = []
|
|
||||||
for e in collected:
|
|
||||||
if e not in result: result.append(e)
|
|
||||||
return collected
|
|
||||||
except OSError:
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cb = CryptoBox()
|
cb = CryptoBox()
|
||||||
|
|
|
@ -205,6 +205,7 @@ class CryptoBoxContainer:
|
||||||
|
|
||||||
def __getUUID(self):
|
def __getUUID(self):
|
||||||
"""return UUID for luks partitions, ext2/3 and vfat filesystems"""
|
"""return UUID for luks partitions, ext2/3 and vfat filesystems"""
|
||||||
|
emergency_default = self.device.replace(os.path.sep, "_")
|
||||||
devnull = None
|
devnull = None
|
||||||
try:
|
try:
|
||||||
devnull = open(os.devnull, "w")
|
devnull = open(os.devnull, "w")
|
||||||
|
@ -214,7 +215,7 @@ class CryptoBoxContainer:
|
||||||
shell=False,
|
shell=False,
|
||||||
stdin=None,
|
stdin=None,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=devnull,
|
stderr=subprocess.PIPE,
|
||||||
args=[self.Progs["blkid"],
|
args=[self.Progs["blkid"],
|
||||||
"-s", "UUID",
|
"-s", "UUID",
|
||||||
"-o", "value",
|
"-o", "value",
|
||||||
|
@ -225,10 +226,10 @@ class CryptoBoxContainer:
|
||||||
result = proc.stdout.read().strip()
|
result = proc.stdout.read().strip()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
self.log.warn("retrieving of partition type via 'blkid' failed: %s" % (proc.stderr.read().strip(), ))
|
self.log.warn("retrieving of partition type via 'blkid' failed: %s" % (proc.stderr.read().strip(), ))
|
||||||
return None
|
return emergency_default
|
||||||
devnull.close()
|
devnull.close()
|
||||||
if result: return result
|
if result: return result
|
||||||
return self.device.replace(os.path.sep, "_")
|
return emergency_default
|
||||||
|
|
||||||
|
|
||||||
def __getTypeOfPartition(self):
|
def __getTypeOfPartition(self):
|
||||||
|
|
117
pythonrewrite/bin/CryptoBoxTools.py
Normal file
117
pythonrewrite/bin/CryptoBoxTools.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
logger = logging.getLogger("CryptoBox")
|
||||||
|
|
||||||
|
|
||||||
|
def getAvailablePartitions():
|
||||||
|
"retrieve a list of all available containers"
|
||||||
|
ret_list = []
|
||||||
|
try:
|
||||||
|
"the following reads all lines of /proc/partitions and adds the mentioned devices"
|
||||||
|
fpart = open("/proc/partitions", "r")
|
||||||
|
try:
|
||||||
|
line = fpart.readline()
|
||||||
|
while line:
|
||||||
|
p_details = line.split()
|
||||||
|
if (len(p_details) == 4):
|
||||||
|
"the following code prevents double entries like /dev/hda and /dev/hda1"
|
||||||
|
(p_major, p_minor, p_size, p_device) = p_details
|
||||||
|
if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor):
|
||||||
|
p_parent = re.sub('[1-9]?[0-9]$', '', p_device)
|
||||||
|
if p_parent == p_device:
|
||||||
|
if [e for e in ret_list if re.search('^' + p_parent + '[1-9]?[0-9]$', e)]:
|
||||||
|
"major partition - its children are already in the list"
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
"major partition - but there are no children for now"
|
||||||
|
ret_list.append(p_device)
|
||||||
|
else:
|
||||||
|
"minor partition - remove parent if necessary"
|
||||||
|
if p_parent in ret_list: ret_list.remove(p_parent)
|
||||||
|
ret_list.append(p_device)
|
||||||
|
line = fpart.readline()
|
||||||
|
finally:
|
||||||
|
fpart.close()
|
||||||
|
return map(getAbsoluteDeviceName, ret_list)
|
||||||
|
except IOError:
|
||||||
|
logger.warning("Could not read /proc/partitions")
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def getAbsoluteDeviceName(shortname):
|
||||||
|
""" returns the absolute file name of a device (e.g.: "hda1" -> "/dev/hda1")
|
||||||
|
this does also work for device mapper devices
|
||||||
|
if the result is non-unique, one arbitrary value is returned"""
|
||||||
|
if re.search('^/', shortname): return shortname
|
||||||
|
default = os.path.join("/dev", shortname)
|
||||||
|
if os.path.exists(default): return default
|
||||||
|
result = findMajorMinorOfDevice(shortname)
|
||||||
|
"if no valid major/minor was found -> exit"
|
||||||
|
if not result: return default
|
||||||
|
(major, minor) = result
|
||||||
|
"for device-mapper devices (major == 254) ..."
|
||||||
|
if major == 254:
|
||||||
|
result = findMajorMinorDeviceName("/dev/mapper", major, minor)
|
||||||
|
if result: return result[0]
|
||||||
|
"now check all files in /dev"
|
||||||
|
result = findMajorMinorDeviceName("/dev", major, minor)
|
||||||
|
if result: return result[0]
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def findMajorMinorOfDevice(device):
|
||||||
|
"return the major/minor numbers of a block device by querying /sys/block/?/dev"
|
||||||
|
if not os.path.exists(os.path.join(os.path.sep,"sys","block",device)): return None
|
||||||
|
blockdev_info_file = os.path.join(os.path.join(os.path.sep,"sys","block", device), "dev")
|
||||||
|
try:
|
||||||
|
f_blockdev_info = open(blockdev_info_file, "r")
|
||||||
|
blockdev_info = f_blockdev_info.read()
|
||||||
|
f_blockdev_info.close()
|
||||||
|
(str_major, str_minor) = blockdev_info.split(":")
|
||||||
|
"numeric conversion"
|
||||||
|
try:
|
||||||
|
major = int(str_major)
|
||||||
|
minor = int(str_minor)
|
||||||
|
return (major, minor)
|
||||||
|
except ValueError:
|
||||||
|
"unknown device numbers -> stop guessing"
|
||||||
|
return None
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def findMajorMinorDeviceName(dir, major, minor):
|
||||||
|
"returns the names of devices with the specified major and minor number"
|
||||||
|
collected = []
|
||||||
|
try:
|
||||||
|
subdirs = [os.path.join(dir, e) for e in os.listdir(dir) if (not os.path.islink(os.path.join(dir, e))) and os.path.isdir(os.path.join(dir, e))]
|
||||||
|
"do a recursive call to parse the directory tree"
|
||||||
|
for dirs in subdirs:
|
||||||
|
collected.extend(findMajorMinorDeviceName(dirs, major, minor))
|
||||||
|
"filter all device inodes in this directory"
|
||||||
|
collected.extend([os.path.realpath(os.path.join(dir, e)) for e in os.listdir(dir) if (os.major(os.stat(os.path.join(dir, e)).st_rdev) == major) and (os.minor(os.stat(os.path.join(dir, e)).st_rdev) == minor)])
|
||||||
|
## remove double entries
|
||||||
|
result = []
|
||||||
|
for e in collected:
|
||||||
|
if e not in result: result.append(e)
|
||||||
|
return result
|
||||||
|
except OSError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def getParentBlockDevices():
|
||||||
|
devs = []
|
||||||
|
for line in file("/proc/partitions"):
|
||||||
|
p_details = line.split()
|
||||||
|
## we expect four values - otherwise continue with next iteration
|
||||||
|
if len(p_details) != 4: continue
|
||||||
|
(p_major, p_minor, p_size, p_device) = p_details
|
||||||
|
## we expect numeric values in the first two columns
|
||||||
|
if re.search(u'\D',p_major) or re.search(u'\D',p_minor): continue
|
||||||
|
## now let us check, if it is a (parent) block device or a partition
|
||||||
|
if not os.path.isdir(os.path.join(os.path.sep, "sys", "block", p_device)): continue
|
||||||
|
devs.append(p_device)
|
||||||
|
return map(getAbsoluteDeviceName, devs)
|
||||||
|
|
|
@ -44,14 +44,19 @@ class PluginManager:
|
||||||
|
|
||||||
|
|
||||||
def loadLanguageData(self, hdf, lang="en"):
|
def loadLanguageData(self, hdf, lang="en"):
|
||||||
|
import neo_cgi, neo_util
|
||||||
for plfile in self.__getPluginFiles():
|
for plfile in self.__getPluginFiles():
|
||||||
|
plname = os.path.basename(plfile)[:-3]
|
||||||
langdir = os.path.join(os.path.dirname(plfile), "lang")
|
langdir = os.path.join(os.path.dirname(plfile), "lang")
|
||||||
selected_langfile = os.path.join(langdir, lang + ".hdf")
|
selected_langfile = os.path.join(langdir, lang + ".hdf")
|
||||||
default_langfile = os.path.join(langdir, "en.hdf")
|
default_langfile = os.path.join(langdir, "en.hdf")
|
||||||
for langfile in (selected_langfile, default_langfile):
|
for langfile in (selected_langfile, default_langfile):
|
||||||
if os.access(langfile, os.R_OK):
|
if os.access(langfile, os.R_OK):
|
||||||
self.log.debug("Loading plugin language file: %s" % langfile)
|
self.log.debug("Loading plugin language file: %s" % langfile)
|
||||||
hdf.readFile(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
|
break
|
||||||
else:
|
else:
|
||||||
self.log.debug("Couldn't find a plugin language file (%s)" % default_langfile)
|
self.log.debug("Couldn't find a plugin language file (%s)" % default_langfile)
|
||||||
|
|
|
@ -18,7 +18,7 @@ class WebInterfaceDataset(dict):
|
||||||
|
|
||||||
def setPluginState(self, plugins):
|
def setPluginState(self, plugins):
|
||||||
for pl in plugins.allPlugins():
|
for pl in plugins.allPlugins():
|
||||||
self["Data.Status.Modules." + pl] = plugins.getPlugin(pl).getStatus(self.cbox)
|
self["Data.Status.Plugins." + pl] = plugins.getPlugin(pl).getStatus(self.cbox)
|
||||||
|
|
||||||
|
|
||||||
def setCurrentDiskState(self, device):
|
def setCurrentDiskState(self, device):
|
||||||
|
@ -48,6 +48,7 @@ class WebInterfaceDataset(dict):
|
||||||
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.DocLang"] = self.prefs["WebSettings"]["DocLanguage"]
|
||||||
|
self["Settings.PluginDir"] = self.prefs["Locations"]["PluginDir"]
|
||||||
|
|
||||||
|
|
||||||
def __setCryptoBoxState(self):
|
def __setCryptoBoxState(self):
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
import CryptoBox
|
import CryptoBox
|
||||||
import WebInterfaceDataset
|
import WebInterfaceDataset
|
||||||
import re
|
import re
|
||||||
from Plugins import PluginManager
|
import Plugins
|
||||||
from CryptoBoxExceptions import *
|
from CryptoBoxExceptions import *
|
||||||
|
|
||||||
|
|
||||||
|
class WebInterfacePlugins:
|
||||||
|
|
||||||
|
def __init__(self, log, plugins, handler_func):
|
||||||
|
for plname in plugins.allPlugins():
|
||||||
|
log.info("Plugin '%s' loaded" % plname)
|
||||||
|
## this should be the "easiest" way to expose all plugins as URLs
|
||||||
|
setattr(self, plname, handler_func(plname))
|
||||||
|
setattr(getattr(self, plname), "exposed", True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WebInterfaceSites:
|
class WebInterfaceSites:
|
||||||
'''
|
'''
|
||||||
url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'}
|
url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'}
|
||||||
|
@ -16,16 +28,9 @@ 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.plugins = PluginManager(self.prefs["Locations"]["PluginDir"])
|
self.pluginList = Plugins.PluginManager(self.prefs["Locations"]["PluginDir"])
|
||||||
self.__exposePlugins()
|
self.plugins = WebInterfacePlugins(self.log, self.pluginList, self.return_plugin_action)
|
||||||
|
self.plugins.index = self.system
|
||||||
|
|
||||||
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):
|
def __resetDataset(self):
|
||||||
|
@ -134,8 +139,8 @@ class WebInterfaceSites:
|
||||||
try:
|
try:
|
||||||
container.setName(volume_name)
|
container.setName(volume_name)
|
||||||
# TODO: specify the possible exceptions
|
# TODO: specify the possible exceptions
|
||||||
except Exception:
|
except Exception, errMsg:
|
||||||
self.log.warn("failed to rename the volume '%s' to '%s'" % (device, volume_name))
|
self.log.warn("failed to rename the volume '%s' to '%s: %s'" % (device, volume_name, errMsg))
|
||||||
self.dataset["Data.Warning"] = "SetVolumeNameFailed"
|
self.dataset["Data.Warning"] = "SetVolumeNameFailed"
|
||||||
else:
|
else:
|
||||||
self.log.info("successfully renamed volume '%s' to '%s'" % (device, volume_name))
|
self.log.info("successfully renamed volume '%s' to '%s'" % (device, volume_name))
|
||||||
|
@ -311,7 +316,7 @@ class WebInterfaceSites:
|
||||||
return self.__render("show_volume")
|
return self.__render("show_volume")
|
||||||
|
|
||||||
|
|
||||||
def return_module_action(self, module):
|
def return_plugin_action(self, plugin_name):
|
||||||
def handler(**args):
|
def handler(**args):
|
||||||
self.__resetDataset()
|
self.__resetDataset()
|
||||||
try:
|
try:
|
||||||
|
@ -319,15 +324,9 @@ class WebInterfaceSites:
|
||||||
del args["weblang"]
|
del args["weblang"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
plugin = self.plugins.getPlugin(module)
|
plugin = self.pluginList.getPlugin(plugin_name)
|
||||||
try:
|
nextTemplate = plugin.doAction(self.dataset, self.cbox, **args)
|
||||||
nextTemplate = plugin.doAction(self.cbox, **args)
|
return self.__render(nextTemplate, plugin_name)
|
||||||
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
|
return handler
|
||||||
|
|
||||||
|
|
||||||
|
@ -418,7 +417,7 @@ class WebInterfaceSites:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __render(self, template, module=None):
|
def __render(self, template, plugin=None):
|
||||||
'''renders from clearsilver templates and returns the resulting html
|
'''renders from clearsilver templates and returns the resulting html
|
||||||
|
|
||||||
Gets a dictionary with all settings, nessessary for rendering.
|
Gets a dictionary with all settings, nessessary for rendering.
|
||||||
|
@ -430,16 +429,16 @@ class WebInterfaceSites:
|
||||||
try:
|
try:
|
||||||
import neo_cgi, neo_util, neo_cs
|
import neo_cgi, neo_util, neo_cs
|
||||||
except ImportError:
|
except ImportError:
|
||||||
errorMsg = "Could not import clearsilver modules. Try 'apt-get install python-clearsilver'."
|
errorMsg = "Could not import clearsilver module. Try 'apt-get install python-clearsilver'."
|
||||||
self.log.error(errorMsg)
|
self.log.error(errorMsg)
|
||||||
sys.stderr.write(errorMsg)
|
sys.stderr.write(errorMsg)
|
||||||
raise ImportError, errorMsg
|
raise ImportError, errorMsg
|
||||||
|
|
||||||
module_cs_file = False
|
plugin_cs_file = False
|
||||||
if module:
|
if plugin:
|
||||||
module_cs_file = self.plugins.getTemplateFileName(module, template)
|
plugin_cs_file = self.pluginList.getTemplateFileName(plugin, template)
|
||||||
default_cs_file = os.path.join(self.prefs["Locations"]["TemplateDir"], template + ".cs")
|
default_cs_file = os.path.join(self.prefs["Locations"]["TemplateDir"], template + ".cs")
|
||||||
self.dataset["Data.TemplateFile"] = module_cs_file or default_cs_file
|
self.dataset["Data.TemplateFile"] = plugin_cs_file or default_cs_file
|
||||||
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.join(self.prefs["Locations"]["TemplateDir"], "main.cs")
|
||||||
|
@ -454,7 +453,7 @@ class WebInterfaceSites:
|
||||||
return "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
|
## add the current state of the plugins to the hdf dataset
|
||||||
self.dataset.setPluginState(self.plugins)
|
self.dataset.setPluginState(self.pluginList)
|
||||||
|
|
||||||
hdf = neo_util.HDF()
|
hdf = neo_util.HDF()
|
||||||
hdf.readFile(hdf_path)
|
hdf.readFile(hdf_path)
|
||||||
|
@ -462,7 +461,7 @@ class WebInterfaceSites:
|
||||||
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
|
## load languaga data of plugins
|
||||||
self.plugins.loadLanguageData(hdf, lang=self.dataset["Settings.Language"])
|
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()
|
return cs.render()
|
||||||
|
|
|
@ -1,26 +1,17 @@
|
||||||
from CryptoBoxExceptions import CBPluginActionError
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def prepareForm(hdf, cbox):
|
def doAction(hdf, cbox, store=None, year=0, month=0, day=0, hour=0, minute=0):
|
||||||
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
|
import datetime
|
||||||
|
__prepareFormData(hdf, cbox)
|
||||||
if store:
|
if store:
|
||||||
try:
|
try:
|
||||||
year, month, day = int(year), int(month), int(day)
|
year, month, day = int(year), int(month), int(day)
|
||||||
hour, minute = int(hour), int(minute)
|
hour, minute = int(hour), int(minute)
|
||||||
new_date = datetime.datetime(year, month, day, hour, minute)
|
new_date = datetime.datetime(year, month, day, hour, minute)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CBPluginActionError, "InvalidDate"
|
hdf["Data.Warning"] = "Plugins.date.InvalidDate"
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
shell = False,
|
shell = False,
|
||||||
args = [
|
args = [
|
||||||
|
@ -33,7 +24,8 @@ def doAction(cbox, store=None, year=0, month=0, day=0, hour=0, minute=0):
|
||||||
if proc.returncode == 0:
|
if proc.returncode == 0:
|
||||||
return "form_system"
|
return "form_system"
|
||||||
else:
|
else:
|
||||||
raise CBPluginActionError, "InvalidDate"
|
hdf["Data.Warning"] = "Plugins.date.InvalidDate"
|
||||||
|
return "form_date"
|
||||||
else:
|
else:
|
||||||
return "form_date"
|
return "form_date"
|
||||||
|
|
||||||
|
@ -42,6 +34,15 @@ def getStatus(cbox):
|
||||||
return str(__getCurrentDate())
|
return str(__getCurrentDate())
|
||||||
|
|
||||||
|
|
||||||
|
def __prepareFormData(hdf, cbox):
|
||||||
|
date = __getCurrentDate()
|
||||||
|
hdf["Data.Plugins.date.year"] = date.year
|
||||||
|
hdf["Data.Plugins.date.month"] = date.month
|
||||||
|
hdf["Data.Plugins.date.day"] = date.day
|
||||||
|
hdf["Data.Plugins.date.hour"] = date.hour
|
||||||
|
hdf["Data.Plugins.date.minute"] = date.minute
|
||||||
|
|
||||||
|
|
||||||
def __getCurrentDate():
|
def __getCurrentDate():
|
||||||
import datetime
|
import datetime
|
||||||
return datetime.datetime(2000,1,1).now()
|
return datetime.datetime(2000,1,1).now()
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
<?cs # $Id$ ?>
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
<h1><?cs var:html_escape(Lang.Title.ConfigDate) ?></h1>
|
<h1><?cs var:html_escape(Lang.Plugins.date.Title.ConfigDate) ?></h1>
|
||||||
|
|
||||||
<?cs call:print_form_header("module_date") ?>
|
<?cs call:print_form_header("plugins/date") ?>
|
||||||
|
|
||||||
<p><label for="date"><?cs var:html_escape(Lang.Text.Date) ?>: </label><br/>
|
<p><label for="date"><?cs var:html_escape(Lang.Plugins.date.Text.Date) ?>: </label><br/>
|
||||||
<select name="day" size="0"><?cs
|
<select name="day" size="0"><?cs
|
||||||
loop: x = #1, #31, #1 ?>
|
loop: x = #1, #31, #1 ?>
|
||||||
<?cs if:x == Data.Modules.date.day ?><option selected="selected"><?cs
|
<?cs if:x == Data.Plugins.date.day ?><option selected="selected"><?cs
|
||||||
else ?><option><?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
else ?><option><?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
||||||
</select>
|
</select>
|
||||||
<select name="month" size="0"><?cs
|
<select name="month" size="0"><?cs
|
||||||
loop: x = #1, #12, #1 ?>
|
loop: x = #1, #12, #1 ?>
|
||||||
<?cs if:x == Data.Modules.date.month ?><option selected="selected" <?cs
|
<?cs if:x == Data.Plugins.date.month ?><option selected="selected" <?cs
|
||||||
else ?><option <?cs /if ?>value="<?cs var:x ?>"><?cs
|
else ?><option <?cs /if ?>value="<?cs var:x ?>"><?cs
|
||||||
var:html_escape(Lang.Text.Months[x]) ?></option><?cs /loop ?>
|
var:html_escape(Lang.Plugins.date.Text.Months[x]) ?></option><?cs /loop ?>
|
||||||
</select>
|
</select>
|
||||||
<select name="year" size="0"><?cs
|
<select name="year" size="0"><?cs
|
||||||
loop: x = #2006, #2025, #1 ?>
|
loop: x = #2006, #2025, #1 ?>
|
||||||
<?cs if:x == Data.Modules.date.year ?><option selected="selected"><?cs
|
<?cs if:x == Data.Plugins.date.year ?><option selected="selected"><?cs
|
||||||
else ?><option><?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
else ?><option><?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
||||||
</select></p>
|
</select></p>
|
||||||
|
|
||||||
<p><label for="time"><?cs var:html_escape(Lang.Text.Time) ?>: </label><br/>
|
<p><label for="time"><?cs var:html_escape(Lang.Plugins.date.Text.Time) ?>: </label><br/>
|
||||||
<select name="hour" size="0"><?cs
|
<select name="hour" size="0"><?cs
|
||||||
loop: x = #0, #23, #1 ?>
|
loop: x = #0, #23, #1 ?>
|
||||||
<?cs if:x == Data.Modules.date.hour ?><option selected="selected"><?cs
|
<?cs if:x == Data.Plugins.date.hour ?><option selected="selected"><?cs
|
||||||
else ?><option><?cs /if ?><?cs if:x<10 ?>0<?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
else ?><option><?cs /if ?><?cs if:x<10 ?>0<?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
||||||
</select> :
|
</select> :
|
||||||
<select name="minute" size="0"><?cs
|
<select name="minute" size="0"><?cs
|
||||||
loop: x = #0, #59, #1 ?>
|
loop: x = #0, #59, #1 ?>
|
||||||
<?cs if:x == Data.Modules.date.minute ?><option selected="selected"><?cs
|
<?cs if:x == Data.Plugins.date.minute ?><option selected="selected"><?cs
|
||||||
else ?><option><?cs /if ?><?cs if:x<10 ?>0<?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
else ?><option><?cs /if ?><?cs if:x<10 ?>0<?cs /if ?><?cs var:x ?></option><?cs /loop ?>
|
||||||
</select></p>
|
</select></p>
|
||||||
|
|
||||||
<input type="hidden" name="store" value="yes" />
|
<input type="hidden" name="store" value="yes" />
|
||||||
|
|
||||||
<button type="submit"><?cs var:html_escape(Lang.Button.ConfigDate) ?></button>
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.date.Button.ConfigDate) ?></button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,29 @@
|
||||||
Lang {
|
Name = Change date and time
|
||||||
|
Link = Set date/time
|
||||||
|
Rank = 10
|
||||||
|
|
||||||
Title.ConfigDate = Date and time setting
|
Title.ConfigDate = Date and time setting
|
||||||
|
|
||||||
Button.ConfigDate = Set date and time
|
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.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
WarningMessage.InvalidDate {
|
||||||
|
Title = Invalid value
|
||||||
|
Text = An invalid value for date or time was supplied. Please try again.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
Lang {
|
Name = Show the content of the log file
|
||||||
|
Link = Show log file
|
||||||
|
Rank = 90
|
||||||
|
|
||||||
Title.Log = CryptoBox logfiles
|
Title.Log = CryptoBox logfiles
|
||||||
|
|
||||||
Text.EmptyLog = The logfile of the CryptoBox is empty.
|
Text.EmptyLog = The logfile of the CryptoBox is empty.
|
||||||
|
|
||||||
Modules.logs {
|
|
||||||
Name = Show the content of the log file
|
|
||||||
Link = Show log file
|
|
||||||
Rank = 90
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
from CryptoBoxExceptions import CBPluginActionError
|
|
||||||
|
|
||||||
|
def doAction(hdf, cbox):
|
||||||
def prepareForm(hdf, cbox):
|
__prepareFormData(hdf,cbox)
|
||||||
hdf["Data.Modules.logs.Content"] = __getLogContent(cbox)
|
|
||||||
|
|
||||||
|
|
||||||
def doAction(cbox):
|
|
||||||
return "show_log"
|
return "show_log"
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +11,10 @@ def getStatus(cbox):
|
||||||
cbox.prefs["Log"]["Details"])
|
cbox.prefs["Log"]["Details"])
|
||||||
|
|
||||||
|
|
||||||
|
def __prepareFormData(hdf, cbox):
|
||||||
|
hdf["Data.Plugins.logs.Content"] = __getLogContent(cbox)
|
||||||
|
|
||||||
|
|
||||||
def __getLogContent(cbox, lines=30, maxSize=2000):
|
def __getLogContent(cbox, lines=30, maxSize=2000):
|
||||||
return "<br/>".join(cbox.getLogData(lines, maxSize))
|
return "<br/>".join(cbox.getLogData(lines, maxSize))
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?cs # $Id: show_log.cs 374 2006-05-30 18:47:34Z lars $ ?>
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
<div id="log">
|
<div id="log">
|
||||||
|
|
||||||
<h1><?cs var:html_escape(Lang.Title.Log) ?></h1>
|
<h1><?cs var:html_escape(Lang.Plugins.logs.Title.Log) ?></h1>
|
||||||
|
|
||||||
<?cs if:Data.Modules.logs.Content ?>
|
<?cs if:Data.Plugins.logs.Content ?>
|
||||||
<p class="console"><?cs var:Data.Modules.logs.Content ?></p>
|
<p class="console"><?cs var:Data.Plugins.logs.Content ?></p>
|
||||||
<?cs else ?>
|
<?cs else ?>
|
||||||
<p><?cs var:html_escape(Lang.Text.EmptyLog) ?></p>
|
<p><?cs var:html_escape(Lang.Plugins.logs.Text.EmptyLog) ?></p>
|
||||||
<?cs /if ?>
|
<?cs /if ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
<?cs # $Id$ ?>
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
<h1><?cs var:html_escape(Lang.Title.Network) ?></h1>
|
<h1><?cs var:html_escape(Lang.Plugins.network.Title.Network) ?></h1>
|
||||||
|
|
||||||
<?cs call:print_form_header("module_network") ?>
|
<?cs call:print_form_header("plugins/network") ?>
|
||||||
|
|
||||||
<p><label for="ip"><?cs var:html_escape(Lang.Text.IP) ?>: </label><br/>
|
<p><label for="ip"><?cs var:html_escape(Lang.Plugins.network.Text.IP) ?>: </label><br/>
|
||||||
<input type="text" name="ip1" size="3" id="ip" value="<?cs
|
<input type="text" name="ip1" size="3" id="ip" value="<?cs
|
||||||
var:Data.Modules.network.ip.oc1 ?>" />.
|
var:Data.Plugins.network.ip.oc1 ?>" />.
|
||||||
<input type="text" name="ip2" size="3" value="<?cs
|
<input type="text" name="ip2" size="3" value="<?cs
|
||||||
var:Data.Modules.network.ip.oc2 ?>" />.
|
var:Data.Plugins.network.ip.oc2 ?>" />.
|
||||||
<input type="text" name="ip3" size="3" value="<?cs
|
<input type="text" name="ip3" size="3" value="<?cs
|
||||||
var:Data.Modules.network.ip.oc3 ?>" />.
|
var:Data.Plugins.network.ip.oc3 ?>" />.
|
||||||
<input type="text" name="ip4" size="3" value="<?cs
|
<input type="text" name="ip4" size="3" value="<?cs
|
||||||
var:Data.Modules.network.ip.oc4 ?>" /></p>
|
var:Data.Plugins.network.ip.oc4 ?>" /></p>
|
||||||
|
|
||||||
<input type="hidden" name="store" value="yes" />
|
<input type="hidden" name="store" value="yes" />
|
||||||
|
|
||||||
<button type="submit"><?cs var:html_escape(Lang.Button.Network) ?></button>
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.network.Button.Network) ?></button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
Lang {
|
Name = Configure network
|
||||||
|
Link = Configure network
|
||||||
|
Rank = 30
|
||||||
|
|
||||||
Title.Network = Network settings
|
Title.Network = Network settings
|
||||||
|
|
||||||
Button.Network = Update settings
|
Button.Network = Update settings
|
||||||
|
|
||||||
Text.IP = Network address
|
Text.IP = Network address
|
||||||
|
|
||||||
Modules.network {
|
|
||||||
Name = Configure network
|
|
||||||
Link = Configure network
|
|
||||||
Rank = 30
|
|
||||||
}
|
|
||||||
|
|
||||||
WarningMessage.InvalidIP {
|
WarningMessage {
|
||||||
|
InvalidIP {
|
||||||
Title = Invalid value
|
Title = Invalid value
|
||||||
Text = An invalid network address (IP) was supplied. Please try again.
|
Text = An invalid network address (IP) was supplied. Please try again.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SuccessMessage {
|
||||||
|
IPChanged {
|
||||||
|
Title = Network address changed
|
||||||
|
Text = The network address has been changed. In a few seconds you will get redirected to the new address.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
from CryptoBoxExceptions import CBPluginActionError
|
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import imp
|
import imp
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def prepareForm(hdf, cbox):
|
def doAction(hdf, cbox, store=None, ip1="", ip2="", ip3="", ip4=""):
|
||||||
(oc1, oc2, oc3, oc4) = __getCurrentIP(cbox)
|
__prepareFormData(hdf, cbox)
|
||||||
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:
|
if store:
|
||||||
try:
|
try:
|
||||||
for ip_in in (ip1, ip2, ip3, ip4):
|
for ip_in in (ip1, ip2, ip3, ip4):
|
||||||
|
@ -22,11 +14,16 @@ def doAction(cbox, store=None, ip1="", ip2="", ip3="", ip4=""):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
ip = "%d.%d.%d.%d" % (int(ip1), int(ip2), int(ip3), int(ip4))
|
ip = "%d.%d.%d.%d" % (int(ip1), int(ip2), int(ip3), int(ip4))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CBPluginActionError, "InvalidIP"
|
hdf["Data.Warning"] = "Plugins.network.InvalidIP"
|
||||||
|
return "form_system"
|
||||||
if __setIP(cbox, ip):
|
if __setIP(cbox, ip):
|
||||||
|
hdf["Data.Success"] = "Plugins.network.IPChanged"
|
||||||
|
hdf["Data.Redirect.URL"] = ""
|
||||||
|
hdf["Data.Redirect.Delay"] = 30
|
||||||
return "form_system"
|
return "form_system"
|
||||||
else:
|
else:
|
||||||
raise CBPluginActionError, "InvalidIP"
|
hdf["Data.Warning"] = "Plugins.network.InvalidIP"
|
||||||
|
return "form_network"
|
||||||
else:
|
else:
|
||||||
return "form_network"
|
return "form_network"
|
||||||
|
|
||||||
|
@ -35,14 +32,22 @@ def getStatus(cbox):
|
||||||
return "%d.%d.%d.%d" % __getCurrentIP(cbox)
|
return "%d.%d.%d.%d" % __getCurrentIP(cbox)
|
||||||
|
|
||||||
|
|
||||||
|
def __prepareFormData(hdf, cbox):
|
||||||
|
(oc1, oc2, oc3, oc4) = __getCurrentIP(cbox)
|
||||||
|
hdf["Data.Plugins.network.ip.oc1"] = oc1
|
||||||
|
hdf["Data.Plugins.network.ip.oc2"] = oc2
|
||||||
|
hdf["Data.Plugins.network.ip.oc3"] = oc3
|
||||||
|
hdf["Data.Plugins.network.ip.oc4"] = oc4
|
||||||
|
|
||||||
|
|
||||||
def __getCurrentIP(cbox):
|
def __getCurrentIP(cbox):
|
||||||
root_action_mod = imp.load_source("root_action", os.path.join(os.path.dirname(__file__), "root_action.py"))
|
root_action_plug = imp.load_source("root_action", os.path.join(os.path.dirname(__file__), "root_action.py"))
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
shell = False,
|
shell = False,
|
||||||
stdout = subprocess.PIPE,
|
stdout = subprocess.PIPE,
|
||||||
args = [
|
args = [
|
||||||
root_action_mod.IFCONFIG_BIN,
|
root_action_plug.IFCONFIG_BIN,
|
||||||
root_action_mod.IFACE])
|
root_action_plug.IFACE])
|
||||||
(output, error) = proc.communicate()
|
(output, error) = proc.communicate()
|
||||||
if proc.returncode != 0: return (0,0,0,0)
|
if proc.returncode != 0: return (0,0,0,0)
|
||||||
match = re.search(u'inet [\w]+:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\s',output)
|
match = re.search(u'inet [\w]+:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\s',output)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?cs loop: x = #0, subcount(Data.Plugins.partition.Parts)-1, #1 ?>
|
||||||
|
<input type="hidden" name="part<?cs var:x ?>_size" value="<?cs var:Data.Plugins.partition.Parts[x].Size ?>" />
|
||||||
|
<input type="hidden" name="part<?cs var:x ?>_type" value="<?cs var:Data.Plugins.partition.Parts[x].Type ?>" /><?cs
|
||||||
|
/loop ?>
|
||||||
|
|
||||||
|
<input type="hidden" name="block_device" value="<?cs var:html_escape(Data.Plugins.partition.Device) ?>" />
|
||||||
|
|
||||||
|
|
33
pythonrewrite/plugins/partition/lang/en.hdf
Normal file
33
pythonrewrite/plugins/partition/lang/en.hdf
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
Name = Disk partitioning
|
||||||
|
Link = Disk partitioning
|
||||||
|
Rank = 80
|
||||||
|
|
||||||
|
Title.Partition = Disk partitions
|
||||||
|
|
||||||
|
Button {
|
||||||
|
SelectDevice = Repartition disk
|
||||||
|
AddPartition = Add another partition
|
||||||
|
Back = Back
|
||||||
|
SavePartitions = Save changes
|
||||||
|
AbortPartitions = Cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
FS {
|
||||||
|
Type = Filesystem type
|
||||||
|
Fat = FAT (Windows)
|
||||||
|
Ext2 = Ext2
|
||||||
|
Ext3 = Ext3
|
||||||
|
Reiser = Reiser
|
||||||
|
}
|
||||||
|
Size = Size (MB)
|
||||||
|
SelectDevice = Choose a disk for partitioning
|
||||||
|
NoDevicesAvailable = No suitable disks found - please check your configuration and hardware setup.
|
||||||
|
|
||||||
|
|
||||||
|
WarningMessage {
|
||||||
|
InvalidInput {
|
||||||
|
Title = Invalid input
|
||||||
|
Text = You entered an invalid value.
|
||||||
|
}
|
||||||
|
}
|
132
pythonrewrite/plugins/partition/partition.py
Normal file
132
pythonrewrite/plugins/partition/partition.py
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import imp
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import CryptoBoxTools
|
||||||
|
|
||||||
|
PartTypes = {
|
||||||
|
"linux" : "L",
|
||||||
|
"windows" : "0xC"}
|
||||||
|
|
||||||
|
logger = logging.getLogger("CryptoBox")
|
||||||
|
|
||||||
|
def doAction(hdf, cbox, **args):
|
||||||
|
try:
|
||||||
|
step = args["step"]
|
||||||
|
del args["step"]
|
||||||
|
except KeyError:
|
||||||
|
step = "select_device"
|
||||||
|
if step == "add_partition":
|
||||||
|
return __actionAddPartition(hdf, cbox, args)
|
||||||
|
if step == "del_partition":
|
||||||
|
return __actionDelPartition(hdf, cbox, args)
|
||||||
|
elif step == "finish":
|
||||||
|
return __actionFinish(hdf, cbox, args)
|
||||||
|
else: # for "select_device" and for invalid targets
|
||||||
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
|
||||||
|
|
||||||
|
def getStatus(cbox):
|
||||||
|
return "%d.%d.%d.%d" % __getCurrentIP(cbox)
|
||||||
|
|
||||||
|
|
||||||
|
def __isDeviceValid(device, cbox):
|
||||||
|
if not cbox.isDeviceAllowed(device):
|
||||||
|
return False
|
||||||
|
if not device in CryptoBoxTools.getParentBlockDevices():
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def __actionSelectDevice(hdf, cbox, args):
|
||||||
|
block_devices = [e
|
||||||
|
for e in CryptoBoxTools.getParentBlockDevices()
|
||||||
|
if cbox.isDeviceAllowed(e)]
|
||||||
|
counter = 0
|
||||||
|
for a in block_devices:
|
||||||
|
hdf["Data.Plugins.partition.BlockDevices.%d" % counter] = a
|
||||||
|
cbox.log.debug("found a suitable block device: %s" % a)
|
||||||
|
counter += 1
|
||||||
|
return "select_device"
|
||||||
|
|
||||||
|
|
||||||
|
def __actionAddPartition(hdf, cbox, args):
|
||||||
|
try:
|
||||||
|
device = args["block_device"]
|
||||||
|
except KeyError:
|
||||||
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
#FIXME: the following check should obviuosly get reversed
|
||||||
|
if __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
size = __getDeviceSize(device)
|
||||||
|
hdf["Data.Plugins.partition.Device"] = device
|
||||||
|
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||||
|
parts = __getPartitionsFromArgs(args, size)
|
||||||
|
__setPartitionData(hdf, parts, size)
|
||||||
|
return "set_partitions"
|
||||||
|
|
||||||
|
|
||||||
|
def __actionDelPartition(hdf, cbox, args):
|
||||||
|
try:
|
||||||
|
device = args["block_device"]
|
||||||
|
except KeyError:
|
||||||
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
#FIXME: the following check should obviuosly get reversed
|
||||||
|
if __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
size = __getDeviceSize(device)
|
||||||
|
hdf["Data.Plugins.partition.Device"] = device
|
||||||
|
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||||
|
parts = __getPartitionsFromArgs(args, size)
|
||||||
|
__setPartitionData(hdf, parts[:-1], size)
|
||||||
|
return "set_partitions"
|
||||||
|
|
||||||
|
|
||||||
|
def __setPartitionData(hdf, parts, size):
|
||||||
|
availSize = size
|
||||||
|
i = 0
|
||||||
|
for part in parts:
|
||||||
|
logger.debug(part)
|
||||||
|
hdf["Data.Plugins.partition.Parts.%d.Size" % i] = part["size"]
|
||||||
|
hdf["Data.Plugins.partition.Parts.%d.Type" % i] = part["type"]
|
||||||
|
availSize -= part["size"]
|
||||||
|
i += 1
|
||||||
|
hdf["Data.Plugins.partition.availSize"] = availSize
|
||||||
|
for t in PartTypes.keys():
|
||||||
|
hdf["Data.Plugins.partition.Types.%s" % t] = t
|
||||||
|
|
||||||
|
|
||||||
|
def __getPartitionsFromArgs(args, maxSize):
|
||||||
|
parts = []
|
||||||
|
done = False
|
||||||
|
availSize = maxSize
|
||||||
|
i = -1
|
||||||
|
while not done:
|
||||||
|
i += 1
|
||||||
|
try:
|
||||||
|
size = int(args["part%d_size" % i])
|
||||||
|
partType = args["part%d_type" % i]
|
||||||
|
if int(size) > availSize: continue
|
||||||
|
if int(size) <= 0: continue
|
||||||
|
if not partType in PartTypes.keys(): continue
|
||||||
|
parts.append({"size":size, "type":partType})
|
||||||
|
availSize -= size
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
except KeyError:
|
||||||
|
done = True
|
||||||
|
return parts
|
||||||
|
|
||||||
|
|
||||||
|
def __getDeviceSize(device):
|
||||||
|
rdev = os.stat(device).st_rdev
|
||||||
|
minor = os.minor(rdev)
|
||||||
|
major = os.major(rdev)
|
||||||
|
for f in file("/proc/partitions"):
|
||||||
|
try:
|
||||||
|
elements = f.split()
|
||||||
|
if len(elements) != 4: continue
|
||||||
|
if (int(elements[0]) == major) and (int(elements[1]) == minor):
|
||||||
|
return int(elements[2])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return 0
|
||||||
|
|
33
pythonrewrite/plugins/partition/root_action.py
Executable file
33
pythonrewrite/plugins/partition/root_action.py
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env python2.4
|
||||||
|
|
||||||
|
#TODO: add netmask and gateway
|
||||||
|
|
||||||
|
## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script
|
||||||
|
PLUGIN_TYPE = "cryptobox"
|
||||||
|
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = sys.argv[1:]
|
||||||
|
|
||||||
|
self_bin =sys.argv[0]
|
||||||
|
|
||||||
|
if len(args) > 1:
|
||||||
|
sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [IFCONFIG_BIN, IFACE, args[0]])
|
||||||
|
proc.communicate()
|
||||||
|
sys.exit(proc.returncode)
|
||||||
|
|
27
pythonrewrite/plugins/partition/select_device.cs
Normal file
27
pythonrewrite/plugins/partition/select_device.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
|
<h1><?cs var:html_escape(Lang.Plugins.partition.Title.Partition) ?></h1>
|
||||||
|
|
||||||
|
<?cs if:subcount(Data.Plugins.partition.BlockDevices) > 0 ?>
|
||||||
|
|
||||||
|
<?cs call:print_form_header("plugins/partition") ?>
|
||||||
|
|
||||||
|
<p><label for="block_device"><?cs var:html_escape(Lang.Plugins.partition.Text.SelectDevice) ?>: </label><br/>
|
||||||
|
<select name="block_device" id="block_device" size="0">
|
||||||
|
<?cs each:x = Data.Plugins.partition.BlockDevices
|
||||||
|
?><option><?cs var:html_escape(x) ?></option>
|
||||||
|
<?cs /each ?>
|
||||||
|
</select></p>
|
||||||
|
|
||||||
|
<input type="hidden" name="step" value="add_partition" />
|
||||||
|
|
||||||
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.SelectDevice) ?></button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?cs else ?>
|
||||||
|
|
||||||
|
<p><?cs var:html_escape(Lang.Plugins.partition.Text.NoDevicesAvailable) ?></p>
|
||||||
|
|
||||||
|
<?cs /if ?>
|
||||||
|
|
37
pythonrewrite/plugins/partition/set_partitions.cs
Normal file
37
pythonrewrite/plugins/partition/set_partitions.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
|
<h1><?cs var:html_escape(Lang.Plugins.partition.Title.Partition) ?></h1>
|
||||||
|
|
||||||
|
<p> <?cs loop: x = #0, subcount(Data.Plugins.partition.Parts)-1, #1 ?>
|
||||||
|
<p><?cs var:x ?> - <?cs var:Data.Plugins.partition.Parts[x].Size ?> - <?cs var:Data.Plugins.partition.Parts[x].Type ?></p><?cs
|
||||||
|
/loop ?></p>
|
||||||
|
|
||||||
|
<?cs if:Data.Plugins.partition.availSize ?>
|
||||||
|
<?cs call:print_form_header("plugins/partition") ?>
|
||||||
|
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?><?cs
|
||||||
|
|
||||||
|
# new partition input if space is available ?><?cs
|
||||||
|
set: x = subcount(Data.Plugins.partition.Parts) ?>
|
||||||
|
<p><?cs var:x ?> - <input type="text" name="part<?cs var:x ?>_size" value="<?cs var:Data.Plugins.partition.availSize ?>" /> - <select name="part<?cs var:x ?>_type" size="0"><?cs each: t = Data.Plugins.partition.Types ?><option><?cs var:t ?></option><?cs /each ?></select></p>
|
||||||
|
|
||||||
|
<input type="hidden" name="step" value="add_partition" />
|
||||||
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.AddPartition) ?></button>
|
||||||
|
</form>
|
||||||
|
<?cs /if ?>
|
||||||
|
|
||||||
|
<?cs if:subcount(Data.Plugins.partition.Parts) > 0 ?>
|
||||||
|
<?cs call:print_form_header("plugins/partition") ?>
|
||||||
|
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?>
|
||||||
|
<input type="hidden" name="step" value="del_partition" />
|
||||||
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.Back) ?></button>
|
||||||
|
</form>
|
||||||
|
<?cs /if ?>
|
||||||
|
|
||||||
|
<?cs if:subcount(Data.Plugins.partition.Parts) > 0 ?>
|
||||||
|
<?cs call:print_form_header("plugins/partition") ?>
|
||||||
|
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?>
|
||||||
|
<input type="hidden" name="step" value="finish" />
|
||||||
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.SavePartitions) ?></button>
|
||||||
|
</form>
|
||||||
|
<?cs /if ?>
|
||||||
|
|
|
@ -1,36 +1,33 @@
|
||||||
The following directory structure is required:
|
The following directory structure is required:
|
||||||
- python code: plugins/MODULENAME/MODULENAME.py (all lower case is recommended)
|
- python code: plugins/PLUGINNAME/PLUGINNAME.py (all lower case is recommended)
|
||||||
- language files: plugins/MODULENAME/lang/(en|de|??).hdf
|
- language files: plugins/PLUGINNAME/lang/(en|de|??).hdf
|
||||||
- clearsilver templates: plugins/MODULENAME/*.cs
|
- clearsilver templates: plugins/PLUGINNAME/*.cs
|
||||||
|
|
||||||
|
|
||||||
Python code interface:
|
Python code interface:
|
||||||
def prepareForm(hdf, cbox):
|
def doAction(hdf, cbox, store=None, ???):
|
||||||
- here you may add some items to the hdf dataset used by the templates
|
- this function will get called whenever this plugins is involved in a request
|
||||||
- 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)
|
- 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)
|
- 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
|
- if the processing failed for some reason (invalid input, ...), it should manually set the "Data.Warning" (resp. "Data.Error" or "Data.Success") to a value of your choice (preferably you may want to use messages of your namespace (e.g. "Plugins.PLUGINNAME.InvalidInput"))
|
||||||
- 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)
|
- the return value should be the name of the template that should be displayed after processing (a template file in the plugin directory takes precedence over global template files)
|
||||||
|
|
||||||
def def getStatus(cbox):
|
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)
|
- returns a string, that described a state connected to this plugin (e.g. the current date and time (for the "date" plugin)
|
||||||
|
|
||||||
|
|
||||||
Language file structure:
|
Language file structure:
|
||||||
|
- the content of the language file will be added to the hdf dataset below "Lang.Plugins.PLUGINNAME" (this avoids namespace conflicts)
|
||||||
- the following values _must_ be defined:
|
- the following values _must_ be defined:
|
||||||
Lang.Modules.MODULENAME.Name (a short description)
|
Name (a short description)
|
||||||
Lang.Modules.MODULENAME.Link (the visible text for links to this module)
|
Link (the visible text for links to this plugin)
|
||||||
Lang.Modules.MODULENAME.Rank (defines the order of the plugins displayed)
|
Rank (defines the order of the plugins displayed (0..100))
|
||||||
- all other elements should follow the usual structure of language files
|
- all warnings, error and success messages should be stored below WarningMessage.??? (resp. ErrorMessage or SuccessMessage)
|
||||||
|
|
||||||
|
|
||||||
Clearsilver template:
|
Clearsilver template:
|
||||||
- should start with a "<h1>" tag
|
- should start with a "<h1>" tag
|
||||||
- links to the module (e.g. in form headers) could look like the following:
|
- links to the plugin (e.g. in form headers) could look like the following:
|
||||||
<?cs call:link("module_MODULENAME",'','','','') ?>
|
<?cs call:link("plugins/PLUGINNAME",'','','','') ?>
|
||||||
- a hidden input field called "store" should be used to indicate a form submission
|
- a hidden input field called "store" should be used to indicate a form submission
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ Data.Status.Config=<?cs var:html_escape(Data.Status.Config) ?>
|
||||||
Data.Status.InitRunning=<?cs var:html_escape(Data.Status.InitRunning) ?>
|
Data.Status.InitRunning=<?cs var:html_escape(Data.Status.InitRunning) ?>
|
||||||
Data.Status.IP=<?cs var:html_escape(Data.Status.IP) ?>
|
Data.Status.IP=<?cs var:html_escape(Data.Status.IP) ?>
|
||||||
Data.Status.Mounted=<?cs var:html_escape(Data.Status.Mounted) ?>
|
Data.Status.Mounted=<?cs var:html_escape(Data.Status.Mounted) ?>
|
||||||
<?cs each:x = Data.Status.Modules ?>Data.Status.Modules.<?cs
|
<?cs each:x = Data.Status.Plugins ?>Data.Status.Plugins.<?cs
|
||||||
var:name(x) ?>=<?cs var: html_escape(x) ?>
|
var:name(x) ?>=<?cs var: html_escape(x) ?>
|
||||||
<?cs /each
|
<?cs /each
|
||||||
?>CBOX-STATUS-end -->
|
?>CBOX-STATUS-end -->
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
|
|
||||||
<?cs # sort the Plugins - using the most stupid way :) ?>
|
<?cs # sort the Plugins - using the most stupid way :) ?>
|
||||||
<?cs loop: order = #0, #100, #1
|
<?cs loop: order = #0, #100, #1
|
||||||
?><?cs # plugins ?><?cs each:x = Lang.Modules
|
?><?cs # plugins ?><?cs each:x = Lang.Plugins
|
||||||
?><?cs if:x.Rank == order ?>
|
?><?cs if:x.Rank == order ?>
|
||||||
<li><a href="<?cs call:link('module_' + name(x),'','','','') ?>" title="<?cs
|
<li><a href="<?cs call:link('plugins/' + name(x),'','','','') ?>" title="<?cs
|
||||||
var:html_escape(x.Link) ?>"><?cs var:html_escape(x.Link) ?></a></li><?cs
|
var:html_escape(x.Link) ?>"><?cs var:html_escape(x.Link) ?></a></li><?cs
|
||||||
/if ?><?cs
|
/if ?><?cs
|
||||||
/each ?><?cs
|
/each ?><?cs
|
||||||
/loop ?>
|
/loop ?>
|
||||||
<?cs # maybe someone forgot to set the rank of a module: we try to catch them ?>
|
<?cs # maybe someone forgot to set the rank of a plugin: we try to catch them ?>
|
||||||
|
|
||||||
<?cs # plugins ?><?cs each:x = Lang.Modules ?><?cs
|
<?cs # plugins ?><?cs each:x = Lang.Plugins ?><?cs
|
||||||
if:!x.Rank || !(x.Rank >= 0 && x.Rank <= 100) ?>
|
if:!x.Rank || !(x.Rank >= 0 && x.Rank <= 100) ?>
|
||||||
<li><a href="<?cs call:link('module_' + name(x),'','','','') ?>" title="<?cs
|
<li><a href="<?cs call:link('plugins/' + name(x),'','','','') ?>" title="<?cs
|
||||||
var:html_escape(x.Link) ?>"><?cs var:html_escape(x.Link) ?></a></li><?cs
|
var:html_escape(x.Link) ?>"><?cs var:html_escape(x.Link) ?></a></li><?cs
|
||||||
/if ?><?cs
|
/if ?><?cs
|
||||||
/each ?>
|
/each ?>
|
||||||
|
|
|
@ -1,41 +1,45 @@
|
||||||
<?cs # $Id$ ?><?cs
|
<?cs # $Id$ ?><?cs
|
||||||
|
|
||||||
def:warning(warnname)
|
# the following macro is as ugly as possible - but somehow we have to manage
|
||||||
?><div class="warning"><?cs
|
to use 'normal' and 'plugin' messages in a clean way:
|
||||||
if:?Lang.WarningMessage[warnname].Title
|
Lang.WarningMessage.??? - used by core functions
|
||||||
?>
|
Lang.Plugins.PLUGINNAME.WarningMessage.??? - used by plugins ?><?cs
|
||||||
<h1><?cs var:html_escape(Lang.WarningMessage[warnname].Title) ?></h1>
|
def:message_dispatch(mname, type, category)
|
||||||
<p><?cs var:html_escape(Lang.WarningMessage[warnname].Text) ?></p>
|
?><?cs # split the message name into a (potentially existing) plugin-name prefix and the suffix (the python equivalent of the following three lines would be:
|
||||||
<?cs else ?>
|
plugPrefix, PlugSuffix = mname[0:mname.find(".",8), mname[mname.find(".",8)+1:]
|
||||||
<h1>unknown warning message</h1>
|
?><?cs loop:x = #8, #40, #1 ?><?cs if:(string.slice(mname,x,x+1) == ".") && !(?savedX) ?><?cs set:savedX = x ?><?cs /if ?><?cs /loop
|
||||||
<p>could not find warning message: '<?cs var:warnname ?>'</p>
|
?><?cs set:plugPrefix = string.slice(mname,0,savedX)
|
||||||
|
?><?cs set:plugSuffix = string.slice(mname,savedX+1,string.length(mname))
|
||||||
|
?><?cs # preparations are done - now start writing
|
||||||
|
?><div class="<?cs var:type ?>"><?cs
|
||||||
|
# check if it is a 'normal' message ?><?cs
|
||||||
|
if:?Lang[category][mname].Title ?>
|
||||||
|
<h1><?cs var:html_escape(Lang[category][mname].Title) ?></h1>
|
||||||
|
<p><?cs var:html_escape(Lang[category][mname].Text) ?></p>
|
||||||
|
<?cs # check if the mname starts with "Plugins." ... ?><?cs
|
||||||
|
elif:(string.slice(mname,0,8) == "Plugins.") && ?Lang[plugPrefix][category][plugSuffix].Title ?>
|
||||||
|
<h1><?cs var:html_escape(Lang[plugPrefix][category][plugSuffix].Title) ?></h1>
|
||||||
|
<p><?cs var:html_escape(Lang[plugPrefix][category][plugSuffix].Text) ?></p>
|
||||||
|
<?cs # the message does not seem to exist ... ?><?cs
|
||||||
|
else ?>
|
||||||
|
<h1>unknown <?cs var:type ?> message</h1>
|
||||||
|
<p>could not find <?cs var:type ?> message: '<?cs var:mname ?>'</p>
|
||||||
<?cs /if ?></div><?cs
|
<?cs /if ?></div><?cs
|
||||||
/def ?><?cs
|
/def ?><?cs
|
||||||
|
|
||||||
|
|
||||||
def:error(errname)
|
def:warning(mname)
|
||||||
?><div class="error"><?cs
|
?><?cs call:message_dispatch(mname, "warning", "WarningMessage") ?><?cs
|
||||||
if:?Lang.ErrorMessage[errname].Title
|
|
||||||
?>
|
|
||||||
<h1><?cs var:html_escape(Lang.ErrorMessage[errname].Title) ?></h1>
|
|
||||||
<p><?cs var:html_escape(Lang.ErrorMessage[errname].Text) ?></p>
|
|
||||||
<?cs else ?>
|
|
||||||
<h1>unknown error message</h1>
|
|
||||||
<p>could not find error message: '<?cs var:errname ?>'</p>
|
|
||||||
<?cs /if ?></div><?cs
|
|
||||||
/def ?><?cs
|
/def ?><?cs
|
||||||
|
|
||||||
|
|
||||||
def:success(succname)
|
def:error(mname)
|
||||||
?><div class="success"><?cs
|
?><?cs call:message_dispatch(mname, "error", "ErrorMessage") ?><?cs
|
||||||
if:?Lang.SuccessMessage[succname].Title
|
/def ?><?cs
|
||||||
?>
|
|
||||||
<h1><?cs var:html_escape(Lang.SuccessMessage[succname].Title) ?></h1>
|
|
||||||
<p><?cs var:html_escape(Lang.SuccessMessage[succname].Text) ?></p>
|
def:success(mname)
|
||||||
<?cs else ?>
|
?><?cs call:message_dispatch(mname, "success", "SuccessMessage") ?><?cs
|
||||||
<h1>unknown success message</h1>
|
|
||||||
<p>could not find success message: '<?cs var:succname ?>'</p>
|
|
||||||
<?cs /if ?></div><?cs
|
|
||||||
/def ?><?cs
|
/def ?><?cs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
<?cs # $Id$ ?>
|
<?cs # $Id$ ?>
|
||||||
|
|
||||||
<!-- TODO: completely useless for now - do something about it :) -->
|
<?cs # we use "loop" instead of "each" to keep the order of the disks ?>
|
||||||
|
<?cs loop: index = #0, subcount(Data.Disks)-1, #1 ?>
|
||||||
|
|
||||||
<?cs each:volume = Data.Disks ?>
|
<a href="<?cs call:link('show_volume','device',Data.Disks[index].device,'','') ?>" title="<?cs
|
||||||
|
var:Data.Disks[index].name ?>">
|
||||||
<a href="<?cs call:link('show_volume','device',volume.device,'','') ?>" title="<?cs
|
|
||||||
var:volume.name ?>">
|
|
||||||
<?cs # the "div" is the container for the background image ?>
|
<?cs # the "div" is the container for the background image ?>
|
||||||
<div class="<?cs if:volume.isActive ?>active<?cs else ?>passive<?cs /if ?><?cs
|
<div class="<?cs if:Data.Disks[index].active ?>active<?cs else ?>passive<?cs /if ?><?cs
|
||||||
if:volume.device == Data.CurrentDisk.device ?> current<?cs /if ?>">
|
if:Data.Disks[index].device == Data.CurrentDisk.device ?> current<?cs /if ?>">
|
||||||
<p><?cs var:volume.name ?></p>
|
<p><?cs var:Data.Disks[index].name ?></p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<?cs /loop ?>
|
||||||
<?cs /each ?>
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue