X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fcbi%2Fluasrc%2Fcbi.lua;h=db76e3b92f338e6b564d0c597ba69b7323605546;hp=4bed9b0e68ebe81dee74786378c347c02e5dd058;hb=2561ed9b7ad5330e8af97047ef420f9bc0b413d0;hpb=8368432a63567d73101a9ea05f7f862065ba0cff diff --git a/libs/cbi/luasrc/cbi.lua b/libs/cbi/luasrc/cbi.lua index 4bed9b0e6..db76e3b92 100644 --- a/libs/cbi/luasrc/cbi.lua +++ b/libs/cbi/luasrc/cbi.lua @@ -30,9 +30,10 @@ require("luci.template") local util = require("luci.util") require("luci.http") require("luci.uvl") -require("luci.fs") + --local event = require "luci.sys.event" +local fs = require("nixio.fs") local uci = require("luci.model.uci") local class = util.class local instanceof = util.instanceof @@ -40,8 +41,10 @@ local instanceof = util.instanceof FORM_NODATA = 0 FORM_PROCEED = 0 FORM_VALID = 1 +FORM_DONE = 1 FORM_INVALID = -1 FORM_CHANGED = 2 +FORM_SKIP = 4 AUTO = true @@ -50,7 +53,7 @@ REMOVE_PREFIX = "cbi.rts." -- Loads a CBI map from given file, creating an environment and returns it function load(cbimap, ...) - require("luci.fs") + local fs = require "nixio.fs" local i18n = require "luci.i18n" require("luci.config") require("luci.util") @@ -58,12 +61,15 @@ function load(cbimap, ...) local upldir = "/lib/uci/upload/" local cbidir = luci.util.libpath() .. "/model/cbi/" - assert(luci.fs.stat(cbimap) or luci.fs.stat(cbidir..cbimap..".lua"), - "Model not found!") + assert(fs.stat(cbimap) or + fs.stat(cbidir..cbimap..".lua") or + fs.stat(cbidir..cbimap..".lua.gz"), + "Model not found!") local func, err = loadfile(cbimap) if not func then - func, err = loadfile(cbidir..cbimap..".lua") + func, err = loadfile(cbidir..cbimap..".lua") or + loadfile(cbidir..cbimap..".lua.gz") end assert(func, err) @@ -166,7 +172,7 @@ local function _uvl_validate_section(node, name) local function tag_section(e) local s = { } - for _, c in ipairs(e.childs) do + for _, c in ipairs(e.childs or { e }) do if c.childs and not c:is(luci.uvl.errors.ERR_DEPENDENCY) then table.insert( s, c.childs[1]:string() ) else @@ -280,6 +286,11 @@ function Template.render(self) luci.template.render(self.template, {self=self}) end +function Template.parse(self, readinput) + self.readinput = (readinput ~= false) + return Map.formvalue(self, "cbi.submit") and FORM_DONE or FORM_NODATA +end + --[[ Map - A map describing a configuration file @@ -296,6 +307,7 @@ function Map.__init__(self, config, ...) self.apply_on_parse = nil self.readinput = true self.proceed = false + self.flow = {} self.uci = uci.cursor() self.save = true @@ -316,7 +328,7 @@ function Map.formvalue(self, key) end function Map.formvaluetable(self, key) - return self.readinput and luci.http.formvaluetable(key) + return self.readinput and luci.http.formvaluetable(key) or {} end function Map.get_scheme(self, sectiontype, option) @@ -344,13 +356,19 @@ end -- Use optimized UCI writing function Map.parse(self, readinput, ...) self.readinput = (readinput ~= false) + + if self:formvalue("cbi.skip") then + self.state = FORM_SKIP + return self:state_handler(self.state) + end + Node.parse(self, ...) if self.save then for i, config in ipairs(self.parsechain) do self.uci:save(config) end - if self:submitstate() and not self.proceed and (self.autoapply or luci.http.formvalue("cbi.apply")) then + if self:submitstate() and not self.proceed and (self.flow.autoapply or luci.http.formvalue("cbi.apply")) then for i, config in ipairs(self.parsechain) do self.uci:commit(config) @@ -454,11 +472,18 @@ Compound = class(Node) function Compound.__init__(self, ...) Node.__init__(self) + self.template = "cbi/compound" self.children = {...} end +function Compound.populate_delegator(self, delegator) + for _, v in ipairs(self.children) do + v.delegator = delegator + end +end + function Compound.parse(self, ...) - local cstate, state = 0, 0 + local cstate, state = 0 for k, child in ipairs(self.children) do cstate = child:parse(...) @@ -476,60 +501,127 @@ Delegator = class(Node) function Delegator.__init__(self, ...) Node.__init__(self, ...) self.nodes = {} + self.defaultpath = {} + self.pageaction = false + self.readinput = true + self.allow_reset = false + self.allow_back = false + self.allow_finish = false self.template = "cbi/delegator" end -function Delegator.state(self, name, node, transitor) - transitor = transitor or self.transistor_linear - local state = {node=node, name=name, transitor=transitor} - - assert(instanceof(node, Node), "Invalid node") +function Delegator.set(self, name, node) + if type(node) == "table" and getmetatable(node) == nil then + node = Compound(unpack(node)) + end + assert(type(node) == "function" or instanceof(node, Compound), "Invalid") assert(not self.nodes[name], "Duplicate entry") - self.nodes[name] = state - self:append(state) + self.nodes[name] = node +end - return state +function Delegator.add(self, name, node) + node = self:set(name, node) + self.defaultpath[#self.defaultpath+1] = name end -function Delegator.get(self, name) - return self.nodes[name] +function Delegator.insert_after(self, name, after) + local n = #self.chain + for k, v in ipairs(self.chain) do + if v == state then + n = k + 1 + break + end + end + table.insert(self.chain, n, name) end -function Delegator.transistor_linear(self, state, cstate) - if cstate > 0 then - for i, child in ipairs(self.children) do - if state == child then - return self.children[i+1] - end +function Delegator.set_route(self, ...) + local n, chain, route = 0, self.chain, {...} + for i = 1, #chain do + if chain[i] == self.current then + n = i + break end - else - return state + end + for i = 1, #route do + n = n + 1 + chain[n] = route[i] + end + for i = n + 1, #chain do + chain[i] = nil end end +function Delegator.get(self, name) + return self.nodes[name] +end + function Delegator.parse(self, ...) - local active = self:getactive() - assert(active, "Invalid state") + local newcurrent + self.chain = self.chain or self:get_chain() + self.current = self.current or self:get_active() + self.active = self.active or self:get(self.current) + assert(self.active, "Invalid state") + + local stat = FORM_DONE + if type(self.active) ~= "function" then + self.active:populate_delegator(self) + stat = self.active:parse() + else + self:active() + end - local cstate = active.node:parse() - self.active = active.transistor(self, active.node, cstate) + if stat > FORM_PROCEED then + if Map.formvalue(self, "cbi.delg.back") then + newcurrent = self:get_prev(self.current) + else + newcurrent = self:get_next(self.current) + end + elseif stat < FORM_PROCEED then + return stat + end + - if not self.active then + if not Map.formvalue(self, "cbi.submit") then + return FORM_NODATA + elseif not newcurrent or not self:get(newcurrent) then return FORM_DONE else - self.active:parse(false) - return FROM_PROCEED + self.current = newcurrent + self.active = self:get(self.current) + if type(self.active) ~= "function" then + self.active:parse(false) + return FROM_PROCEED + else + return self:parse(...) + end end end -function Delegator.render(self, ...) - self.active.node:render(...) +function Delegator.get_next(self, state) + for k, v in ipairs(self.chain) do + if v == state then + return self.chain[k+1] + end + end end -function Delegator.getactive(self) - return self:get(Map.formvalue(self, "cbi.delegated") - or (self.children[1] and self.children[1].name)) +function Delegator.get_prev(self, state) + for k, v in ipairs(self.chain) do + if v == state then + return self.chain[k-1] + end + end +end + +function Delegator.get_chain(self) + local x = Map.formvalue(self, "cbi.delg.path") or self.defaultpath + return type(x) == "table" and x or {x} +end + +function Delegator.get_active(self) + return Map.formvalue(self, "cbi.delg.current") or self.chain[1] end --[[ @@ -561,6 +653,11 @@ SimpleForm.formvaluetable = Map.formvaluetable function SimpleForm.parse(self, readinput, ...) self.readinput = (readinput ~= false) + + if self:formvalue("cbi.skip") then + return FORM_SKIP + end + if self:submitstate() then Node.parse(self, 1, ...) end @@ -727,8 +824,8 @@ function AbstractSection.parse_optionals(self, section) if v.optional and not v:cfgvalue(section) then if field == v.option then field = nil - else self.map.proceed = true + else table.insert(self.optionals[section], v) end end @@ -1202,6 +1299,11 @@ function AbstractValue.parse(self, section, novld) else self.error = { [section] = "invalid" } end + if self.section.error then + table.insert(self.section.error[section], "invalid") + else + self.section.error = {[section] = {"invalid"}} + end self.map.save = false end if fvalue and not (fvalue == cvalue) then @@ -1613,7 +1715,7 @@ end function FileUpload.cfgvalue(self, section) local val = AbstractValue.cfgvalue(self, section) - if val and luci.fs.access(val) then + if val and fs.access(val) then return val end return nil @@ -1627,7 +1729,7 @@ function FileUpload.formvalue(self, section) then return val end - luci.fs.unlink(val) + fs.unlink(val) self.value = nil end return nil @@ -1635,7 +1737,7 @@ 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 + if val and fs.access(val) then fs.unlink(val) end return AbstractValue.remove(self, section) end