summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base/luasrc
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-base/luasrc')
-rw-r--r--modules/luci-base/luasrc/cbi.lua86
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua3
-rw-r--r--modules/luci-base/luasrc/http.lua31
-rw-r--r--modules/luci-base/luasrc/http/protocol.lua26
-rw-r--r--modules/luci-base/luasrc/view/cbi/map.htm23
5 files changed, 133 insertions, 36 deletions
diff --git a/modules/luci-base/luasrc/cbi.lua b/modules/luci-base/luasrc/cbi.lua
index 2c1bb4d226..738431b14e 100644
--- a/modules/luci-base/luasrc/cbi.lua
+++ b/modules/luci-base/luasrc/cbi.lua
@@ -336,7 +336,7 @@ function Map.__init__(self, config, ...)
end
function Map.formvalue(self, key)
- return self.readinput and luci.http.formvalue(key)
+ return self.readinput and luci.http.formvalue(key) or nil
end
function Map.formvaluetable(self, key)
@@ -385,41 +385,45 @@ function Map.parse(self, readinput, ...)
Node.parse(self, ...)
- self:_run_hooks("on_save", "on_before_save")
- for i, config in ipairs(self.parsechain) do
- self.uci:save(config)
- end
- self:_run_hooks("on_after_save")
- if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then
- self:_run_hooks("on_before_commit")
+ if self.save then
+ self:_run_hooks("on_save", "on_before_save")
for i, config in ipairs(self.parsechain) do
- self.uci:commit(config)
+ self.uci:save(config)
+ end
+ self:_run_hooks("on_after_save")
+ if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then
+ self:_run_hooks("on_before_commit")
+ for i, config in ipairs(self.parsechain) do
+ self.uci:commit(config)
+
+ -- Refresh data because commit changes section names
+ self.uci:load(config)
+ end
+ self:_run_hooks("on_commit", "on_after_commit", "on_before_apply")
+ if self.apply_on_parse then
+ self.uci:apply(self.parsechain)
+ self:_run_hooks("on_apply", "on_after_apply")
+ else
+ -- This is evaluated by the dispatcher and delegated to the
+ -- template which in turn fires XHR to perform the actual
+ -- apply actions.
+ self.apply_needed = true
+ end
- -- Refresh data because commit changes section names
- self.uci:load(config)
+ -- Reparse sections
+ Node.parse(self, true)
end
- self:_run_hooks("on_commit", "on_after_commit", "on_before_apply")
- if self.apply_on_parse then
- self.uci:apply(self.parsechain)
- self:_run_hooks("on_apply", "on_after_apply")
- else
- -- This is evaluated by the dispatcher and delegated to the
- -- template which in turn fires XHR to perform the actual
- -- apply actions.
- self.apply_needed = true
+ 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
-
- -- Reparse sections
- Node.parse(self, true)
- end
- 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
- if self.proceed then
+ if not self.save then
+ self.state = FORM_INVALID
+ elseif self.proceed then
self.state = FORM_PROCEED
elseif self.changed then
self.state = FORM_CHANGED
@@ -886,14 +890,18 @@ function AbstractSection.render_tab(self, tab, ...)
end
-- Parse optional options
-function AbstractSection.parse_optionals(self, section)
+function AbstractSection.parse_optionals(self, section, noparse)
if not self.optional then
return
end
self.optionals[section] = {}
- local field = self.map:formvalue("cbi.opt."..self.config.."."..section)
+ local field = nil
+ if not noparse then
+ field = self.map:formvalue("cbi.opt."..self.config.."."..section)
+ end
+
for k,v in ipairs(self.children) do
if v.optional and not v:cfgvalue(section) and not self:has_tabs() then
if field == v.option then
@@ -1071,6 +1079,11 @@ function NamedSection.__init__(self, map, section, stype, ...)
self.section = section
end
+function NamedSection.prepare(self)
+ AbstractSection.prepare(self)
+ AbstractSection.parse_optionals(self, self.section, true)
+end
+
function NamedSection.parse(self, novld)
local s = self.section
local active = self:cfgvalue(s)
@@ -1120,6 +1133,15 @@ function TypedSection.__init__(self, map, type, ...)
self.anonymous = false
end
+function TypedSection.prepare(self)
+ AbstractSection.prepare(self)
+
+ local i, s
+ for i, s in ipairs(self:cfgsections()) do
+ AbstractSection.parse_optionals(self, s, true)
+ end
+end
+
-- Return all matching UCI sections for this TypedSection
function TypedSection.cfgsections(self)
local sections = {}
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index cd5d77a12b..2fbc2c96f5 100644
--- a/modules/luci-base/luasrc/dispatcher.lua
+++ b/modules/luci-base/luasrc/dispatcher.lua
@@ -402,9 +402,6 @@ function dispatch(request)
end
if track.setuser then
- -- trigger ubus connection before dropping root privs
- util.ubus()
-
sys.process.setuser(track.setuser)
end
diff --git a/modules/luci-base/luasrc/http.lua b/modules/luci-base/luasrc/http.lua
index 4b35731727..8795dfc4b2 100644
--- a/modules/luci-base/luasrc/http.lua
+++ b/modules/luci-base/luasrc/http.lua
@@ -89,6 +89,37 @@ end
function Request.setfilehandler(self, callback)
self.filehandler = callback
+
+ -- If input has already been parsed then any files are either in temporary files
+ -- or are in self.message.params[key]
+ if self.parsed_input then
+ for param, value in pairs(self.message.params) do
+ repeat
+ -- We're only interested in files
+ if (not value["file"]) then break end
+ -- If we were able to write to temporary file
+ if (value["fd"]) then
+ fd = value["fd"]
+ local eof = false
+ repeat
+ filedata = fd:read(1024)
+ if (filedata:len() < 1024) then
+ eof = true
+ end
+ callback({ name=value["name"], file=value["file"] }, filedata, eof)
+ until (eof)
+ fd:close()
+ value["fd"] = nil
+ -- We had to read into memory
+ else
+ -- There should only be one numbered value in table - the data
+ for k, v in ipairs(value) do
+ callback({ name=value["name"], file=value["file"] }, v, true)
+ end
+ end
+ until true
+ end
+ end
end
function Request._parse_input(self)
diff --git a/modules/luci-base/luasrc/http/protocol.lua b/modules/luci-base/luasrc/http/protocol.lua
index 0cb62aeec9..061c6ad544 100644
--- a/modules/luci-base/luasrc/http/protocol.lua
+++ b/modules/luci-base/luasrc/http/protocol.lua
@@ -114,6 +114,16 @@ local function __initval( tbl, key )
end
-- (Internal function)
+-- Initialize given file parameter.
+local function __initfileval( tbl, key, filename, fd )
+ if tbl[key] == nil then
+ tbl[key] = { file=filename, fd=fd, name=key, "" }
+ else
+ table.insert( tbl[key], "" )
+ end
+end
+
+-- (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.
local function __appendval( tbl, key, chunk )
@@ -313,6 +323,22 @@ function mimedecode_message_body( src, msg, filecb )
__appendval( msg.params, field.name, field.file )
store = filecb
+ elseif field.name and field.file then
+ local nxf = require "nixio"
+ local fd = nxf.mkstemp(field.name)
+ __initfileval ( msg.params, field.name, field.file, fd )
+ if fd then
+ store = function(hdr, buf, eof)
+ fd:write(buf)
+ if (eof) then
+ fd:seek(0, "set")
+ end
+ end
+ else
+ store = function( hdr, buf, eof )
+ __appendval( msg.params, field.name, buf )
+ end
+ end
elseif field.name then
__initval( msg.params, field.name )
diff --git a/modules/luci-base/luasrc/view/cbi/map.htm b/modules/luci-base/luasrc/view/cbi/map.htm
index e90c3f589f..7f256adf13 100644
--- a/modules/luci-base/luasrc/view/cbi/map.htm
+++ b/modules/luci-base/luasrc/view/cbi/map.htm
@@ -8,6 +8,27 @@
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
<%- if firstmap and applymap then cbi_apply_xhr(self.config, parsechain, redirect) end -%>
- <%- self:render_children() %>
+
+ <% if self.tabbed then %>
+ <ul class="cbi-tabmenu">
+ <%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
+ <% for i, section in ipairs(self.children) do %>
+ <script type="text/javascript">cbi_c['container.m-<%=self.config%>.<%=section.sectiontype%>'] = 1;</script>
+ <%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
+ <li id="tab.m-<%=self.config%>.<%=section.sectiontype%>" class="cbi-tab<%=(section.sectiontype == self.selected_tab) and '' or '-disabled'%>">
+ <a onclick="this.blur(); return cbi_t_switch('m-<%=self.config%>', '<%=section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.sectiontype%>"><%=section.title or section.sectiontype %></a>
+ <% if section.sectiontype == self.selected_tab then %><input type="hidden" id="tab.m-<%=self.config%>" name="tab.m-<%=self.config%>" value="<%=section.sectiontype%>" /><% end %>
+ </li>
+ <% end %>
+ </ul>
+ <% for i, section in ipairs(self.children) do %>
+ <div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>>
+ <% section:render() %>
+ </div>
+ <script type="text/javascript">cbi_t_add('m-<%=self.config%>', '<%=section.sectiontype%>')</script>
+ <% end %>
+ <% else %>
+ <%- self:render_children() %>
+ <% end %>
<br />
</div>