* luci-0.8: backport library fixes
This commit is contained in:
parent
8a690a0614
commit
bb63ae4647
16 changed files with 272 additions and 79 deletions
|
@ -167,3 +167,13 @@ function cbi_combobox_init(id, values, def, man) {
|
|||
});
|
||||
cbi_combobox(id, values, def, man);
|
||||
}
|
||||
|
||||
function cbi_filebrowser(id, url, defpath) {
|
||||
var field = document.getElementById(id);
|
||||
var browser = window.open(
|
||||
url + ( field.value || defpath || '' ) + '?field=' + id,
|
||||
"luci_filebrowser", "width=300,height=400,left=100,top=200,scrollbars=yes"
|
||||
);
|
||||
|
||||
browser.focus();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ require("luci.template")
|
|||
require("luci.util")
|
||||
require("luci.http")
|
||||
require("luci.uvl")
|
||||
require("luci.fs")
|
||||
|
||||
local uci = require("luci.model.uci")
|
||||
local class = luci.util.class
|
||||
|
@ -38,6 +39,7 @@ local instanceof = luci.util.instanceof
|
|||
FORM_NODATA = 0
|
||||
FORM_VALID = 1
|
||||
FORM_INVALID = -1
|
||||
FORM_CHANGED = 2
|
||||
|
||||
AUTO = true
|
||||
|
||||
|
@ -51,6 +53,7 @@ function load(cbimap, ...)
|
|||
require("luci.config")
|
||||
require("luci.util")
|
||||
|
||||
local upldir = "/lib/uci/upload/"
|
||||
local cbidir = luci.util.libpath() .. "/model/cbi/"
|
||||
local func, err = loadfile(cbimap) or loadfile(cbidir..cbimap..".lua")
|
||||
assert(func, err)
|
||||
|
@ -69,7 +72,9 @@ function load(cbimap, ...)
|
|||
return rawget(tbl, key) or _M[key] or _G[key]
|
||||
end}))
|
||||
|
||||
local maps = {func()}
|
||||
local maps = { func() }
|
||||
local uploads = { }
|
||||
local has_upload = false
|
||||
|
||||
for i, map in ipairs(maps) do
|
||||
if not instanceof(map, Node) then
|
||||
|
@ -77,8 +82,57 @@ function load(cbimap, ...)
|
|||
return nil
|
||||
else
|
||||
map:prepare()
|
||||
if map.upload_fields then
|
||||
has_upload = true
|
||||
for _, field in ipairs(map.upload_fields) do
|
||||
uploads[
|
||||
field.config .. '.' ..
|
||||
field.section.sectiontype .. '.' ..
|
||||
field.option
|
||||
] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if has_upload then
|
||||
local uci = luci.model.uci.cursor()
|
||||
local prm = luci.http.context.request.message.params
|
||||
local fd, cbid
|
||||
|
||||
luci.http.setfilehandler(
|
||||
function( field, chunk, eof )
|
||||
if not field then return end
|
||||
if field.name and not cbid then
|
||||
local c, s, o = field.name:gmatch(
|
||||
"cbid%.([^%.]+)%.([^%.]+)%.([^%.]+)"
|
||||
)()
|
||||
|
||||
if c and s and o then
|
||||
local t = uci:get( c, s )
|
||||
if t and uploads[c.."."..t.."."..o] then
|
||||
local path = upldir .. field.name
|
||||
fd = io.open(path, "w")
|
||||
if fd then
|
||||
cbid = field.name
|
||||
prm[cbid] = path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if field.name == cbid and fd then
|
||||
fd:write(chunk)
|
||||
end
|
||||
|
||||
if eof and fd then
|
||||
fd:close()
|
||||
fd = nil
|
||||
cbid = nil
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
return maps
|
||||
end
|
||||
|
@ -251,6 +305,9 @@ function Map.get_scheme(self, sectiontype, option)
|
|||
end
|
||||
end
|
||||
|
||||
function Map.submitstate(self)
|
||||
return luci.http.formvalue("cbi.submit")
|
||||
end
|
||||
|
||||
-- Chain foreign config
|
||||
function Map.chain(self, config)
|
||||
|
@ -288,6 +345,19 @@ function Map.parse(self)
|
|||
for i, config in ipairs(self.parsechain) do
|
||||
self.uci:unload(config)
|
||||
end
|
||||
if type(self.commit_handler) == "function" then
|
||||
self:commit_handler(self:submitstate())
|
||||
end
|
||||
end
|
||||
|
||||
if self:submitstate() then
|
||||
if self.save then
|
||||
return self.changed and FORM_CHANGED or FORM_VALID
|
||||
else
|
||||
return FORM_INVALID
|
||||
end
|
||||
else
|
||||
return FORM_NODATA
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -383,11 +453,12 @@ function SimpleForm.parse(self, ...)
|
|||
end
|
||||
|
||||
local state =
|
||||
not luci.http.formvalue("cbi.submit") and 0
|
||||
or valid and 1
|
||||
or -1
|
||||
not self:submitstate() and FORM_NODATA
|
||||
or valid and FORM_VALID
|
||||
or FORM_INVALID
|
||||
|
||||
self.dorender = not self.handle or self:handle(state, self.data) ~= false
|
||||
return state
|
||||
end
|
||||
|
||||
function SimpleForm.render(self, ...)
|
||||
|
@ -396,6 +467,10 @@ function SimpleForm.render(self, ...)
|
|||
end
|
||||
end
|
||||
|
||||
function SimpleForm.submitstate(self)
|
||||
return luci.http.formvalue("cbi.submit")
|
||||
end
|
||||
|
||||
function SimpleForm.section(self, class, ...)
|
||||
if instanceof(class, AbstractSection) then
|
||||
local obj = class(self, ...)
|
||||
|
@ -616,6 +691,10 @@ function Table.__init__(self, form, data, ...)
|
|||
return data[section] and data[section][option]
|
||||
end
|
||||
|
||||
function datasource.submitstate(self)
|
||||
return luci.http.formvalue("cbi.submit")
|
||||
end
|
||||
|
||||
function datasource.del(...)
|
||||
return true
|
||||
end
|
||||
|
@ -632,7 +711,7 @@ end
|
|||
|
||||
function Table.parse(self)
|
||||
for i, k in ipairs(self:cfgsections()) do
|
||||
if luci.http.formvalue("cbi.submit") then
|
||||
if self.map:submitstate() then
|
||||
Node.parse(self, k)
|
||||
end
|
||||
end
|
||||
|
@ -695,7 +774,7 @@ function NamedSection.parse(self, novld)
|
|||
|
||||
if active then
|
||||
AbstractSection.parse_dynamic(self, s)
|
||||
if luci.http.formvalue("cbi.submit") then
|
||||
if self.map:submitstate() then
|
||||
Node.parse(self, s)
|
||||
|
||||
if not novld and not self.override_scheme and self.map.scheme then
|
||||
|
@ -770,7 +849,7 @@ function TypedSection.parse(self, novld)
|
|||
local co
|
||||
for i, k in ipairs(self:cfgsections()) do
|
||||
AbstractSection.parse_dynamic(self, k)
|
||||
if luci.http.formvalue("cbi.submit") then
|
||||
if self.map:submitstate() then
|
||||
Node.parse(self, k)
|
||||
|
||||
if not novld and not self.override_scheme and self.map.scheme then
|
||||
|
@ -1325,3 +1404,58 @@ function Button.__init__(self, ...)
|
|||
self.inputstyle = nil
|
||||
self.rmempty = true
|
||||
end
|
||||
|
||||
|
||||
FileUpload = class(AbstractValue)
|
||||
|
||||
function FileUpload.__init__(self, ...)
|
||||
AbstractValue.__init__(self, ...)
|
||||
self.template = "cbi/upload"
|
||||
if not self.map.upload_fields then
|
||||
self.map.upload_fields = { self }
|
||||
else
|
||||
self.map.upload_fields[#self.map.upload_fields+1] = self
|
||||
end
|
||||
end
|
||||
|
||||
function FileUpload.formcreated(self, section)
|
||||
return AbstractValue.formcreated(self, section) or
|
||||
luci.http.formvalue("cbi.rlf."..section.."."..self.option) or
|
||||
luci.http.formvalue("cbi.rlf."..section.."."..self.option..".x")
|
||||
end
|
||||
|
||||
function FileUpload.cfgvalue(self, section)
|
||||
local val = AbstractValue.cfgvalue(self, section)
|
||||
if val and luci.fs.access(val) then
|
||||
return val
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function FileUpload.formvalue(self, section)
|
||||
local val = AbstractValue.formvalue(self, section)
|
||||
if val then
|
||||
if not luci.http.formvalue("cbi.rlf."..section.."."..self.option) and
|
||||
not luci.http.formvalue("cbi.rlf."..section.."."..self.option..".x")
|
||||
then
|
||||
return val
|
||||
end
|
||||
luci.fs.unlink(val)
|
||||
self.value = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function FileUpload.remove(self, section)
|
||||
local val = AbstractValue.formvalue(self, section)
|
||||
if val and luci.fs.access(val) then luci.fs.unlink(val) end
|
||||
return AbstractValue.remove(self, section)
|
||||
end
|
||||
|
||||
|
||||
FileBrowser = class(AbstractValue)
|
||||
|
||||
function FileBrowser.__init__(self, ...)
|
||||
AbstractValue.__init__(self, ...)
|
||||
self.template = "cbi/browser"
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ $Id$
|
|||
-%>
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-input-<% self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.title)%> />
|
||||
<input class="cbi-input-<%=self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.title)%> />
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
|
|
|
@ -13,7 +13,7 @@ $Id$
|
|||
|
||||
-%>
|
||||
|
||||
<div>
|
||||
<div class="cbi-page-actions">
|
||||
<input class="cbi-button cbi-button-apply" type="submit" name="cbi.apply" value="<%:saveapply%>" />
|
||||
<input class="cbi-button cbi-button-save" type="submit" value="<%:save%>" />
|
||||
<input class="cbi-button cbi-button-reset" type="reset" value="<%:reset%>" />
|
||||
|
|
|
@ -14,7 +14,7 @@ $Id$
|
|||
-%>
|
||||
|
||||
<%+header%>
|
||||
<form method="post" action="<%=luci.http.getenv("REQUEST_URI")%>">
|
||||
<form method="post" action="<%=luci.http.getenv("REQUEST_URI")%>" enctype="multipart/form-data">
|
||||
<div>
|
||||
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
|
||||
<input type="hidden" name="cbi.submit" value="1" />
|
||||
|
|
|
@ -32,6 +32,7 @@ $Id$
|
|||
<br />
|
||||
</fieldset>
|
||||
<% elseif self.addremove then %>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
|
@ -39,5 +40,6 @@ $Id$
|
|||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<input type="submit" class="cbi-button-add" name="cbi.cns.<%=self.config%>.<%=self.section%>" value="<%:cbi_add%>" />
|
||||
</fieldset>
|
||||
<%- end %>
|
||||
<% end %>
|
||||
<!-- /nsection -->
|
||||
|
|
|
@ -41,6 +41,7 @@ $Id$
|
|||
<%- end %>
|
||||
|
||||
<% if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create">
|
||||
<% if self.anonymous then -%>
|
||||
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>" value="<%:cbi_add%>" />
|
||||
|
@ -54,4 +55,5 @@ $Id$
|
|||
<%- end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end %>
|
||||
</fieldset>
|
||||
|
|
|
@ -33,7 +33,6 @@ local string = require "string"
|
|||
local coroutine = require "coroutine"
|
||||
|
||||
local getmetatable, setmetatable = getmetatable, setmetatable
|
||||
local getfenv, setfenv = getfenv, setfenv
|
||||
local rawget, rawset, unpack = rawget, rawset, unpack
|
||||
local tostring, type, assert = tostring, type, assert
|
||||
local ipairs, pairs, loadstring = ipairs, pairs, loadstring
|
||||
|
|
|
@ -131,7 +131,7 @@ function urlencode_params( tbl )
|
|||
return enc
|
||||
end
|
||||
|
||||
--- (Internal function)
|
||||
-- (Internal function)
|
||||
-- Initialize given parameter and coerce string into table when the parameter
|
||||
-- already exists.
|
||||
-- @param tbl Table where parameter should be created
|
||||
|
@ -147,7 +147,7 @@ local function __initval( tbl, key )
|
|||
end
|
||||
end
|
||||
|
||||
--- (Internal function)
|
||||
-- (Internal function)
|
||||
-- Append given data to given parameter, either by extending the string value
|
||||
-- or by appending it to the last string in the parameter's value table.
|
||||
-- @param tbl Table containing the previously initialized parameter value
|
||||
|
@ -163,7 +163,7 @@ local function __appendval( tbl, key, chunk )
|
|||
end
|
||||
end
|
||||
|
||||
--- (Internal function)
|
||||
-- (Internal function)
|
||||
-- Finish the value of given parameter, either by transforming the string value
|
||||
-- or - in the case of multi value parameters - the last element in the
|
||||
-- associated values table.
|
||||
|
@ -563,12 +563,14 @@ function parse_message_header( src )
|
|||
-- Populate common environment variables
|
||||
msg.env = {
|
||||
CONTENT_LENGTH = msg.headers['Content-Length'];
|
||||
CONTENT_TYPE = msg.headers['Content-Type'];
|
||||
CONTENT_TYPE = msg.headers['Content-Type'] or msg.headers['Content-type'];
|
||||
REQUEST_METHOD = msg.request_method:upper();
|
||||
REQUEST_URI = msg.request_uri;
|
||||
SCRIPT_NAME = msg.request_uri:gsub("?.+$","");
|
||||
SCRIPT_FILENAME = ""; -- XXX implement me
|
||||
SERVER_PROTOCOL = "HTTP/" .. string.format("%.1f", msg.http_version)
|
||||
SERVER_PROTOCOL = "HTTP/" .. string.format("%.1f", msg.http_version);
|
||||
QUERY_STRING = msg.request_uri:match("?")
|
||||
and msg.request_uri:gsub("^.+?","") or ""
|
||||
}
|
||||
|
||||
-- Populate HTTP_* environment variables
|
||||
|
@ -617,7 +619,7 @@ function parse_message_body( src, msg, filecb )
|
|||
|
||||
-- Is it application/x-www-form-urlencoded ?
|
||||
elseif msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
|
||||
msg.env.CONTENT_TYPE == "application/x-www-form-urlencoded"
|
||||
msg.env.CONTENT_TYPE:match("^application/x%-www%-form%-urlencoded")
|
||||
then
|
||||
return urldecode_message_body( src, msg, filecb )
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ function if_none_match( req, stat )
|
|||
return true
|
||||
end
|
||||
|
||||
-- 14.27 / If-Range
|
||||
--- 14.27 / If-Range
|
||||
-- The If-Range header is currently not implemented due to the lack of general
|
||||
-- byte range stuff in luci.http.protocol . This function will always return
|
||||
-- false, 412 to indicate a failed precondition.
|
||||
|
@ -131,7 +131,7 @@ function if_range( req, stat )
|
|||
return false, 412
|
||||
end
|
||||
|
||||
-- 14.28 / If-Unmodified-Since
|
||||
--- 14.28 / If-Unmodified-Since
|
||||
-- Test whether the given message object contains an "If-Unmodified-Since"
|
||||
-- header and compare it against the given stat object.
|
||||
-- @param req HTTP request message object
|
||||
|
|
|
@ -36,7 +36,7 @@ $(BOA_DIR)/.configured: $(BOA_DIR)/.patched
|
|||
touch $@
|
||||
|
||||
boa-compile: $(BOA_DIR)/.configured
|
||||
$(MAKE) -C $(BOA_DIR)/src CC=$(CC) CFLAGS="$(CFLAGS)"
|
||||
$(MAKE) -C $(BOA_DIR)/src CC=$(CC) CFLAGS="$(CFLAGS) -DINET6 -DACCEPT_ON -DWHEN_DOES_THIS_APPLY"
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE) $(LUA_CFLAGS) -I$(BOA_DIR)/src $(FPIC) -c -o $@ $<
|
||||
|
|
|
@ -59,6 +59,7 @@ function handle_req(context)
|
|||
env.REMOTE_PORT = context.remote_port
|
||||
env.SERVER_ADDR = context.server_addr
|
||||
env.HTTP_COOKIE = context.cookie
|
||||
env.HTTP_ACCEPT = context.http_accept
|
||||
env.SCRIPT_NAME = env.REQUEST_URI:sub(1, #env.REQUEST_URI - #env.PATH_INFO)
|
||||
|
||||
luci.sgi.webuci.run(env, vars)
|
||||
|
|
|
@ -267,6 +267,15 @@ config variable
|
|||
option datatype 'string'
|
||||
option required false
|
||||
|
||||
# Variable default value (schema.@variable.default)
|
||||
config variable
|
||||
option name 'default'
|
||||
option title 'Default value of this variable'
|
||||
option section 'schema.variable'
|
||||
option type 'variable'
|
||||
option datatype 'string'
|
||||
option required false
|
||||
|
||||
# Variable validators (schema.@variable.validator)
|
||||
config variable
|
||||
option name 'validator'
|
||||
|
|
|
@ -161,9 +161,9 @@ function dispatch(request)
|
|||
end
|
||||
|
||||
-- Init template engine
|
||||
if not track.notemplate then
|
||||
if (c and c.index) or not track.notemplate then
|
||||
local tpl = require("luci.template")
|
||||
local media = luci.config.main.mediaurlbase
|
||||
local media = track.mediaurlbase or luci.config.main.mediaurlbase
|
||||
if not pcall(tpl.Template, "themes/%s/header" % fs.basename(media)) then
|
||||
media = nil
|
||||
for name, theme in pairs(luci.config.themes) do
|
||||
|
@ -183,6 +183,7 @@ function dispatch(request)
|
|||
viewns.striptags = util.striptags
|
||||
viewns.controller = luci.http.getenv("SCRIPT_NAME")
|
||||
viewns.media = media
|
||||
viewns.theme = fs.basename(media)
|
||||
viewns.resource = luci.config.main.resourcebase
|
||||
viewns.REQUEST_URI = (luci.http.getenv("SCRIPT_NAME") or "") .. (luci.http.getenv("PATH_INFO") or "")
|
||||
end
|
||||
|
@ -231,9 +232,20 @@ function dispatch(request)
|
|||
luci.sys.process.setuser(track.setuser)
|
||||
end
|
||||
|
||||
if c and type(c.target) == "function" then
|
||||
context.dispatched = c
|
||||
if c and (c.index or type(c.target) == "function") then
|
||||
ctx.dispatched = c
|
||||
ctx.requested = ctx.requested or ctx.dispatched
|
||||
end
|
||||
|
||||
if c and c.index then
|
||||
local tpl = require "luci.template"
|
||||
|
||||
if util.copcall(tpl.render, "indexer", {}) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if c and type(c.target) == "function" then
|
||||
util.copcall(function()
|
||||
local oldenv = getfenv(c.target)
|
||||
local module = require(c.module)
|
||||
|
@ -457,7 +469,13 @@ end
|
|||
-- @param ... Additional parameters passed to the function
|
||||
function call(name, ...)
|
||||
local argv = {...}
|
||||
return function() return getfenv()[name](unpack(argv)) end
|
||||
return function(...)
|
||||
if #argv > 0 then
|
||||
return getfenv()[name](unpack(argv), ...)
|
||||
else
|
||||
return getfenv()[name](...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a template render dispatching target.
|
||||
|
@ -475,13 +493,20 @@ function cbi(model)
|
|||
return function(...)
|
||||
require("luci.cbi")
|
||||
require("luci.template")
|
||||
local http = require "luci.http"
|
||||
|
||||
maps = luci.cbi.load(model, ...)
|
||||
|
||||
local state = nil
|
||||
|
||||
for i, res in ipairs(maps) do
|
||||
res:parse()
|
||||
local cstate = res:parse()
|
||||
if not state or cstate < state then
|
||||
state = cstate
|
||||
end
|
||||
end
|
||||
|
||||
http.header("X-CBI-State", state or 0)
|
||||
luci.template.render("cbi/header")
|
||||
for i, res in ipairs(maps) do
|
||||
res:render()
|
||||
|
@ -496,13 +521,20 @@ function form(model)
|
|||
return function(...)
|
||||
require("luci.cbi")
|
||||
require("luci.template")
|
||||
local http = require "luci.http"
|
||||
|
||||
maps = luci.cbi.load(model, ...)
|
||||
|
||||
local state = nil
|
||||
|
||||
for i, res in ipairs(maps) do
|
||||
res:parse()
|
||||
local cstate = res:parse()
|
||||
if not state or cstate < state then
|
||||
state = cstate
|
||||
end
|
||||
end
|
||||
|
||||
http.header("X-CBI-State", state or 0)
|
||||
luci.template.render("header")
|
||||
for i, res in ipairs(maps) do
|
||||
res:render()
|
||||
|
|
|
@ -192,6 +192,7 @@ end
|
|||
--- Set the mime type of following content data.
|
||||
-- @param mime Mimetype of following content
|
||||
function prepare_content(mime)
|
||||
if not context.headers or not context.headers["content-type"] then
|
||||
if mime == "application/xhtml+xml" then
|
||||
if not getenv("HTTP_ACCEPT") or
|
||||
not getenv("HTTP_ACCEPT"):find("application/xhtml+xml", nil, true) then
|
||||
|
@ -200,6 +201,7 @@ function prepare_content(mime)
|
|||
header("Vary", "Accept")
|
||||
end
|
||||
header("Content-Type", mime)
|
||||
end
|
||||
end
|
||||
|
||||
--- Get the RAW HTTP input source
|
||||
|
|
|
@ -45,7 +45,7 @@ end
|
|||
-- @param force Force reload even if already loaded (optional)
|
||||
-- @return Success status
|
||||
function load(file, lang, force)
|
||||
lang = lang or ""
|
||||
lang = lang and lang:gsub("_", "-") or ""
|
||||
if force or not loaded[lang] or not loaded[lang][file] then
|
||||
local f = loadfile(i18ndir .. file .. "." .. lang .. ".lua")
|
||||
if f then
|
||||
|
@ -75,7 +75,7 @@ end
|
|||
--- Set the context default translation language.
|
||||
-- @param lang Two-letter language code
|
||||
function setlanguage(lang)
|
||||
context.lang = lang
|
||||
context.lang = lang:gsub("_", "-")
|
||||
end
|
||||
|
||||
--- Return the translated value for a specific translation key.
|
||||
|
|
Loading…
Reference in a new issue