* Performance optimizations

* libs/core: Added bytecode stripping function to luci.util
* libs/core: Added smart indexcache that automatically updates cached index-files on change
* libs/web: Enabled template caching support
* Core Translation part 4
This commit is contained in:
Steven Barth 2008-06-01 12:12:18 +00:00
parent 1da5feb9f7
commit b454395a8d
14 changed files with 204 additions and 83 deletions

View file

@ -102,3 +102,31 @@ a_srv_dropbear1 = "Dropbear offers SSH network shell access and an integrated SC
a_srv_d_pwauth = "Password authentication"
a_srv_d_pwauth1 = "Allow SSH password authentication"
a_w_wifi1 = [[On this pages you find confiugration options for WLAN based wireless networks.]]
a_w_wifi2 = [[You can easily integrate your 802.11a/b/g/n-devices into your physical network and use
the virtual adapter support to build wireless repeaters or offer several networks with one device.]]
a_w_wifi3 = [[There is support for Managed, Client, Ad-Hoc and WDS operating modes as well as
WPA and WPA2 encryption for secure communnication.]]
a_w_devices1 = "Here you can configure installed wifi devices."
a_w_channel = "Channel"
a_w_txantenna = "Transmit Antenna"
a_w_rxantenna = "Receive Antenna"
a_w_distance1 = "Distance to furthest station (m)"
a_w_diversity = "Diversity"
a_w_countrycode = "Country Code"
a_w_connlimit = "Connection Limit"
a_w_networks1 = [[You can run several wifi networks with one device. Be aware that there are certain
hardware and driverspecific restrictions. Normally you can operate 1 Ad-Hoc or up to 3 Master-Mode and 1 Client-Mode
network simultaneously.]]
a_w_netid = "Network Name (ESSID)"
a_w_network1 = "Add the Wifi network to physical network"
a_w_txpwr = "Transmit Power"
a_w_brcmburst = "Broadcom Frameburst"
a_w_athburst = "Atheros Frameburst"
a_w_radiussrv = "Radius-Server"
a_w_radiusport = "Radius-Port"
a_w_apisolation = "AP-Isolation"
a_w_apisolation1 = "Prevents Client to Client communication"
a_w_hideessid = "Hide ESSID"

View file

@ -13,9 +13,12 @@ delete = "Delete"
descr = "Description"
design = "Design"
device = "Device"
devices = "Devices"
disable = "disable"
distance = "Distance"
enable = "enable"
encryption = "Encryption"
error = "Error"
filesystem = "Filesystem"
@ -27,11 +30,17 @@ hostname = "Hostname"
install = "Install"
installed = "installed"
key = "Key"
language = "Language"
load = "Load"
manpage = "see '%s' manpage"
mode = "Mode"
network = "Network"
networks = "Networks"
notinstalled = "not installed"
ok = "OK"
@ -53,8 +62,11 @@ statistics = "Statistics"
syslog = "System Log"
system = "System"
type = "Type"
unknownerror = "Unknown Error"
version = "Version"
webui = "Web UI"
webui = "Web UI"
wifi = "Wifi"

View file

@ -27,6 +27,7 @@ limitations under the License.
module("luci.fs", package.seeall)
require("posix")
posix.umask("rwx------")
-- Glob
glob = posix.glob

View file

@ -96,6 +96,13 @@ function contains(table, value)
end
-- Dumps and strips a Lua-Function
function dump(f)
local d = string.dump(f)
return d and strip_bytecode(d)
end
-- Dumps a table to stdout (useful for testing and debugging)
function dumptable(t, i)
i = i or 0
@ -181,12 +188,77 @@ function split(str, pat, max, regex)
return t
end
-- Bytecode stripping function by Peter Cawley from http://lua-users.org/lists/lua-l/2008-02/msg01158.html
function strip_bytecode(dump)
local version, format, endian, int, size, ins, num = dump:byte(5, 11)
local subint
if endian == 1 then
subint = function(dump, i, l)
local val = 0
for n = l, 1, -1 do
val = val * 256 + dump:byte(i + n - 1)
end
return val, i + l
end
else
subint = function(dump, i, l)
local val = 0
for n = 1, l, 1 do
val = val * 256 + dump:byte(i + n - 1)
end
return val, i + l
end
end
local strip_function
strip_function = function(dump)
local count, offset = subint(dump, 1, size)
local stripped, dirty = string.rep("\0", size), offset + count
offset = offset + count + int * 2 + 4
offset = offset + int + subint(dump, offset, int) * ins
count, offset = subint(dump, offset, int)
for n = 1, count do
local t
t, offset = subint(dump, offset, 1)
if t == 1 then
offset = offset + 1
elseif t == 4 then
offset = offset + size + subint(dump, offset, size)
elseif t == 3 then
offset = offset + num
end
end
count, offset = subint(dump, offset, int)
stripped = stripped .. dump:sub(dirty, offset - 1)
for n = 1, count do
local proto, off = strip_function(dump:sub(offset, -1))
stripped, offset = stripped .. proto, offset + off - 1
end
offset = offset + subint(dump, offset, int) * int + int
count, offset = subint(dump, offset, int)
for n = 1, count do
offset = offset + subint(dump, offset, size) + size + int * 2
end
count, offset = subint(dump, offset, int)
for n = 1, count do
offset = offset + subint(dump, offset, size) + size
end
stripped = stripped .. string.rep("\0", int * 3)
return stripped, offset
end
return dump:sub(1,12) .. strip_function(dump:sub(13,-1))
end
-- Removes whitespace from beginning and end of a string
function trim(str)
local s = str:gsub("^%s*(.-)%s*$", "%1")
return s
end
-- Updates given table with new values
function update(t, updates)
for k, v in pairs(updates) do

View file

@ -25,10 +25,9 @@ limitations under the License.
]]--
module("luci.config", package.seeall)
require("luci.model.uci")
require("luci.util")
require("luci.sys")
local uci = require("luci.model.uci")
local util = require("luci.util")
module("luci.config")
-- Warning! This is only for fallback and compatibility purporses! --
main = {}
@ -42,7 +41,7 @@ main.lang = "de"
-- Now overwrite with UCI values
local ucidata = luci.model.uci.sections("luci")
local ucidata = uci.sections("luci")
if ucidata then
luci.util.update(luci.config, ucidata)
util.update(_M, ucidata)
end

View file

@ -177,7 +177,7 @@ end
-- Calls the index function of all available controllers
function createindex_plain(path, suffix)
local cachetime = nil
local cache = nil
local controllers = luci.util.combine(
luci.fs.glob(path .. "*" .. suffix) or {},
@ -185,32 +185,38 @@ function createindex_plain(path, suffix)
)
if indexcache then
cachetime = luci.fs.mtime(indexcache)
cache = luci.fs.mtime(indexcache)
if not cachetime then
if not cache then
luci.fs.mkdir(indexcache)
luci.fs.chmod(indexcache, "a=,u=rwx")
cache = luci.fs.mtime(indexcache)
end
end
if not cachetime then
for i,c in ipairs(controllers) do
c = "luci.controller." .. c:sub(#path+1, #c-#suffix):gsub("/", ".")
stat, mod = pcall(require, c)
for i,c in ipairs(controllers) do
local module = "luci.controller." .. c:sub(#path+1, #c-#suffix):gsub("/", ".")
local cachefile = indexcache .. "/" .. module
local stime
local ctime
if cache then
stime = luci.fs.mtime(c) or 0
ctime = luci.fs.mtime(cachefile) or 0
end
if not cache or stime > ctime then
stat, mod = pcall(require, module)
if stat and mod and type(mod.index) == "function" then
index[c] = mod.index
index[module] = mod.index
if indexcache then
luci.fs.writefile(indexcache .. "/" .. c, string.dump(mod.index))
if cache then
luci.fs.writefile(cachefile, luci.util.dump(mod.index))
end
end
end
else
for i,c in ipairs(luci.fs.dir(indexcache)) do
if c:sub(1) ~= "." then
index[c] = loadfile(indexcache .. "/" .. c)
end
else
index[module] = loadfile(cachefile)
end
end
end
@ -226,7 +232,7 @@ function createtree()
-- Load default translation
luci.i18n.loadc("default")
local scope = _G
local scope = luci.util.clone(_G)
for k,v in pairs(_M) do
if type(v) == "function" then
scope[k] = v

View file

@ -39,7 +39,7 @@ end
-- Loads a translation and copies its data into the global translation table
function load(file, force)
if force or not loaded[file] then
local f = loadfile(i18ndir .. file)
local f = loadfile(i18ndir..file..".lua") or loadfile(i18ndir..file)
if f then
setfenv(f, table)
f()
@ -54,8 +54,8 @@ function load(file, force)
end
-- Same as load but autocompletes the filename with .LANG from config.lang
function loadc(file)
return load(file .. "." .. require("luci.config").main.lang)
function loadc(file, force)
return load(file .. "." .. require("luci.config").main.lang, force)
end
-- Returns the i18n-value defined by "key" or if there is no such: "default"

View file

@ -30,22 +30,17 @@ require("luci.util")
require("luci.fs")
require("luci.http")
viewdir = luci.sys.libpath() .. "/view/"
luci.config.template = luci.config.template or {}
viewdir = luci.config.template.viewdir or luci.sys.libpath() .. "/view"
compiledir = luci.config.template.compiledir or luci.sys.libpath() .. "/view"
-- Compile modes:
-- none: Never compile, only use precompiled data from files
-- memory: Always compile, do not save compiled files, ignore precompiled
-- file: Compile on demand, save compiled files, update precompiled
compiler_mode = "memory"
-- This applies to compiler modes "always" and "smart"
--
-- Produce compiled lua code rather than lua sourcecode
-- WARNING: Increases template size heavily!!!
-- This produces the same bytecode as luac but does not have a strip option
compiler_enable_bytecode = false
compiler_mode = luci.config.template.compiler_mode or "memory"
-- Define the namespace for template modules
@ -107,12 +102,7 @@ function compile(template)
template = template:gsub("<%%"..tostring(k).."%%>", re)
end
if compiler_enable_bytecode then
tf = loadstring(template)
template = string.dump(tf)
end
return template
return loadstring(template)
end
-- Oldstyle render shortcut
@ -156,8 +146,8 @@ function Template.__init__(self, name)
end
-- Compile and build
local sourcefile = viewdir .. name .. ".htm"
local compiledfile = viewdir .. name .. ".lua"
local sourcefile = viewdir .. "/" .. name .. ".htm"
local compiledfile = compiledir .. "/" .. name .. ".lua"
local err
if compiler_mode == "file" then
@ -171,9 +161,15 @@ function Template.__init__(self, name)
source, err = luci.fs.readfile(sourcefile)
if source then
local compiled = compile(source)
luci.fs.writefile(compiledfile, compiled)
self.template, err = loadstring(compiled)
local compiled, err = compile(source)
local compiledfile_dir = luci.fs.dirname(compiledfile)
if not luci.fs.mtime(compiledfile_dir) then
luci.fs.mkdir(compiledfile_dir)
end
luci.fs.writefile(compiledfile, luci.util.dump(compiled))
self.template = compiled
end
else
self.template, err = loadfile(compiledfile)
@ -186,7 +182,7 @@ function Template.__init__(self, name)
local source
source, err = luci.fs.readfile(sourcefile)
if source then
self.template, err = loadstring(compile(source))
self.template, err = compile(source)
end
end

View file

@ -34,6 +34,10 @@ config event uci_oncommit
config internal languages
option de "Deutsch"
option en "English"
config internal template
option compiler_mode file
option compiledir "/tmp/.lucitplcache"
config internal themes
option OpenWRT "/luci-static/openwrt.org"

View file

@ -1,18 +1,21 @@
module("luci.controller.admin.wifi", package.seeall)
function index()
luci.i18n.loadc("admin-core")
local i18n = luci.i18n.translate
local page = node("admin", "wifi")
page.target = template("admin_wifi/index")
page.title = "Drahtlos"
page.title = i18n("wifi", "Drahtlos")
page.order = 60
local page = node("admin", "wifi", "devices")
page.target = cbi("admin_wifi/devices")
page.title = "Geräte"
page.title = i18n("devices", "Geräte")
page.order = 10
local page = node("admin", "wifi", "networks")
page.target = cbi("admin_wifi/networks")
page.title = "Netze"
page.title = i18n("networks", "Netze")
page.order = 20
end

View file

@ -1,15 +1,15 @@
-- ToDo: Translate, Add descriptions and help texts
m = Map("wireless", "Geräte", [[An dieser Stelle können eingebaute WLAN-Geräte konfiguriert werden.]])
m = Map("wireless", translate("devices", "Geräte"), translate("a_w_devices1",
"An dieser Stelle können eingebaute WLAN-Geräte konfiguriert werden."))
s = m:section(TypedSection, "wifi-device")
--s.addremove = true
en = s:option(Flag, "disabled", "Aktivieren")
en = s:option(Flag, "disabled", translate("enable", "Aktivieren"))
en.enabled = "0"
en.disabled = "1"
t = s:option(ListValue, "type", "Typ")
t = s:option(ListValue, "type", translate("type", "Typ"))
t:value("broadcom")
t:value("atheros")
t:value("mac80211")
@ -22,7 +22,7 @@ for driver in luci.sys.execl(c)[1]:gmatch("[^ ]+") do
end
]]--
mode = s:option(ListValue, "mode", "Modus")
mode = s:option(ListValue, "mode", translate("mode", "Modus"))
mode:value("", "standard")
mode:value("11b", "802.11b")
mode:value("11g", "802.11g")
@ -30,22 +30,22 @@ mode:value("11a", "802.11a")
mode:value("11bg", "802.11b+g")
mode.rmempty = true
s:option(Value, "channel", "Funkkanal")
s:option(Value, "channel", translate("a_w_channel", "Funkkanal"))
s:option(Value, "txantenna", "Sendeantenne").rmempty = true
s:option(Value, "txantenna", translate("a_w_txantenna", "Sendeantenne")).rmempty = true
s:option(Value, "rxantenna", "Empfangsantenne").rmempty = true
s:option(Value, "rxantenna", translate("a_w_rxantenna", "Empfangsantenne")).rmempty = true
s:option(Value, "distance", "Distanz",
"Distanz zum am weitesten entfernten Funkpartner (m)").rmempty = true
s:option(Value, "distance", translate("distance", "Distanz"),
translate("a_w_distance1", "Distanz zum am weitesten entfernten Funkpartner (m)")).rmempty = true
s:option(Value, "diversity", "Diversität"):depends("type", "atheros")
s:option(Value, "diversity", translate("a_w_diversity", "Diversität")):depends("type", "atheros")
country = s:option(Value, "country", "Ländercode")
country = s:option(Value, "country", translate("a_w_countrycode", "Ländercode"))
country.optional = true
country:depends("type", "broadcom")
maxassoc = s:option(Value, "maxassoc", "Verbindungslimit")
maxassoc = s:option(Value, "maxassoc", translate("a_w_connlimit", "Verbindungslimit"))
maxassoc:depends("type", "broadcom")
maxassoc.optional = true

View file

@ -1,16 +1,16 @@
-- ToDo: Translate, Add descriptions and help texts
m = Map("wireless", "Netze", [[Pro WLAN-Gerät können mehrere Netze bereitgestellt werden.
m = Map("wireless", translate("networks", "Netze"), translate("a_w_networks1", [[Pro WLAN-Gerät können mehrere Netze bereitgestellt werden.
Es sollte beachtet werden, dass es hardware- / treiberspezifische Einschränkungen gibt.
So kann pro WLAN-Gerät in der Regel entweder 1 Ad-Hoc-Zugang ODER bis zu 3 Access-Point und 1 Client-Zugang
gleichzeitig erstellt werden.]])
gleichzeitig erstellt werden.]]))
s = m:section(TypedSection, "wifi-iface")
s.addremove = true
s.anonymous = true
s:option(Value, "ssid", "Netzkennung (ESSID)").maxlength = 32
s:option(Value, "ssid", translate("a_w_netid", "Netzkennung (ESSID)")).maxlength = 32
device = s:option(ListValue, "device", "Gerät")
device = s:option(ListValue, "device", translate("device", "Gerät"))
local d = luci.model.uci.sections("wireless")
if d then
for k, v in pairs(d) do
@ -20,7 +20,7 @@ if d then
end
end
network = s:option(ListValue, "network", "Netzwerk", "WLAN-Netz zu Netzwerk hinzufügen")
network = s:option(ListValue, "network", translate("network", "Netzwerk"), translate("a_w_network1", "WLAN-Netz zu Netzwerk hinzufügen"))
network:value("")
for k, v in pairs(luci.model.uci.sections("network")) do
if v[".type"] == "interface" and k ~= "loopback" then
@ -28,7 +28,7 @@ for k, v in pairs(luci.model.uci.sections("network")) do
end
end
mode = s:option(ListValue, "mode", "Modus")
mode = s:option(ListValue, "mode", translate("mode", "Modus"))
mode:value("ap", "Access Point")
mode:value("adhoc", "Ad-Hoc")
mode:value("sta", "Client")
@ -36,13 +36,13 @@ mode:value("wds", "WDS")
s:option(Value, "bssid", "BSSID").optional = true
s:option(Value, "txpower", "Sendeleistung", "dbm").rmempty = true
s:option(Value, "txpower", translate("a_w_txpwr", "Sendeleistung"), "dbm").rmempty = true
s:option(Flag, "frameburst", "Broadcom-Frameburst").optional = true
s:option(Flag, "bursting", "Atheros-Frameburst").optional = true
s:option(Flag, "frameburst", translate("a_w_brcmburst", "Broadcom-Frameburst")).optional = true
s:option(Flag, "bursting", translate("a_w_athburst", "Atheros-Frameburst")).optional = true
encr = s:option(ListValue, "encryption", "Verschlüsselung")
encr = s:option(ListValue, "encryption", translate("encryption", "Verschlüsselung"))
encr:value("none", "keine")
encr:value("wep", "WEP")
encr:value("psk", "WPA-PSK")
@ -50,7 +50,7 @@ encr:value("wpa", "WPA-Radius")
encr:value("psk2", "WPA2-PSK")
encr:value("wpa2", "WPA2-Radius")
key = s:option(Value, "key", "Schlüssel")
key = s:option(Value, "key", translate("key", "Schlüssel"))
key:depends("encryption", "wep")
key:depends("encryption", "psk")
key:depends("encryption", "wpa")
@ -58,19 +58,19 @@ key:depends("encryption", "psk2")
key:depends("encryption", "wpa2")
key.rmempty = true
server = s:option(Value, "server", "Radius-Server")
server = s:option(Value, "server", translate("a_w_radiussrv", "Radius-Server"))
server:depends("encryption", "wpa")
server:depends("encryption", "wpa2")
server.rmempty = true
port = s:option(Value, "port", "Radius-Port")
port = s:option(Value, "port", translate("a_w_radiusport", "Radius-Port"))
port:depends("encryption", "wpa")
port:depends("encryption", "wpa2")
port.rmempty = true
s:option(Flag, "isolate", "AP-Isolation", "Unterbindet Client-Client-Verkehr").optional = true
s:option(Flag, "isolate", translate("a_w_apisolation", "AP-Isolation"), translate("a_w_apisolation1", "Unterbindet Client-Client-Verkehr")).optional = true
s:option(Flag, "hidden", "ESSID verstecken").optional = true
s:option(Flag, "hidden", translate("a_w_hideessid", "ESSID verstecken")).optional = true

View file

@ -1,9 +1,9 @@
<%+header%>
<h1><%:wifi Drahtlos%></h1>
<p><%:wifi1 Hier finden sich Konfiugrationsmöglichkeiten für Drahtlos-Netzwerke nach dem WLAN-Standard.%></p>
<p><%:wifi2 802.11b/g/a/n-Geräte können so einfach in das bestehende physische Netzwerk integriert werden.
<p><%:a_w_wifi1 Hier finden sich Konfiugrationsmöglichkeiten für Drahtlos-Netzwerke nach dem WLAN-Standard.%></p>
<p><%:a_w_wifi2 802.11b/g/a/n-Geräte können so einfach in das bestehende physische Netzwerk integriert werden.
Die Unterstützung von virtuellen Adaptern ermöglicht auch den Einsatz als Wireless-Repeater oder von
mehreren Netzwerken gleichzeitig auf einem Gerät.%></p>
<p><%:wifi3 Es werden Managed, Client, Ad-Hoc und WDS-Modus unterstützt sowie WPA und WPA2-Verschlüsselung zur gesicherten
<p><%:a_w_wifi3 Es werden Managed, Client, Ad-Hoc und WDS-Modus unterstützt sowie WPA und WPA2-Verschlüsselung zur gesicherten
Kommunikation.%></p>
<%+footer%>