* luci/libs/cbi:

- implement file upload fields
	- change default enctype in forms to multipart/form-data
	- add upload template
* luci/libs/web:
	- dispatch file uploads to cbi form fields
* luci/i18n:
	- add german and english translations for file upload fields
This commit is contained in:
Jo-Philipp Wich 2008-09-23 00:10:51 +00:00
parent 225de06244
commit 6b3985b6be
8 changed files with 178 additions and 43 deletions

View file

@ -1,5 +1,6 @@
cbi_add = 'Add entry'
cbi_del = 'Remove entry'
cbi_replace = 'Replace entry'
cbi_invalid = 'Invalid input value'
cbi_invalid_section = '<strong>Validation failed:</strong> Please check any input fields for mistakes.'
cbi_missing = 'This field is mandatory'
@ -12,3 +13,4 @@ cbi_manual = '-- custom --'
cbi_select = '-- Please choose --'
cbi_gorel = 'Go to relevant configuration page'
cbi_applying = 'Applying changes'
cbi_upload = 'Uploaded File'

View file

@ -4,6 +4,7 @@
<i18n:msg xml:id="cbi_add">Add entry</i18n:msg>
<i18n:msg xml:id="cbi_del">Remove entry</i18n:msg>
<i18n:msg xml:id="cbi_replace">Replace entry</i18n:msg>
<i18n:msg xml:id="cbi_invalid">Invalid input value</i18n:msg>
<i18n:msg xml:id="cbi_invalid_section"><strong>Validation failed:</strong> Please check any input fields for mistakes.</i18n:msg>
<i18n:msg xml:id="cbi_missing">This field is mandatory</i18n:msg>
@ -16,5 +17,6 @@
<i18n:msg xml:id="cbi_select">-- Please choose --</i18n:msg>
<i18n:msg xml:id="cbi_gorel">Go to relevant configuration page</i18n:msg>
<i18n:msg xml:id="cbi_applying">Applying changes</i18n:msg>
<i18n:msg xml:id="cbi_upload">Uploaded File</i18n:msg>
</i18n:msgs>

View file

@ -1,5 +1,6 @@
cbi_add = 'Eintrag hinzufügen'
cbi_del = 'Eintrag entfernen'
cbi_replace = 'Eintrag ersetzen'
cbi_invalid = 'Ungültige Eingabe'
cbi_invalid_section = '<strong>Validierung fehlgeschlagen:</strong> Bitte die Eingabefelder auf Fehler überprüfen.'
cbi_missing = 'Dieses Feld muss ausgefüllt werden'
@ -11,3 +12,4 @@ cbi_manual = '-- benutzerdefiniert --'
cbi_select = '-- Bitte auswählen --'
cbi_gorel = 'Gehe zu relevanter Konfigurationsseite'
cbi_applying = 'Änderungen werden angewandt'
cbi_upload = 'hochgeladene Datei'

View file

@ -4,6 +4,7 @@
<i18n:msg xml:id="cbi_add">Eintrag hinzufügen</i18n:msg>
<i18n:msg xml:id="cbi_del">Eintrag entfernen</i18n:msg>
<i18n:msg xml:id="cbi_replace">Eintrag ersetzen</i18n:msg>
<i18n:msg xml:id="cbi_invalid">Ungültige Eingabe</i18n:msg>
<i18n:msg xml:id="cbi_invalid_section"><strong>Validierung fehlgeschlagen:</strong> Bitte die Eingabefelder auf Fehler überprüfen.</i18n:msg>
<i18n:msg xml:id="cbi_missing">Dieses Feld muss ausgefüllt werden</i18n:msg>
@ -15,5 +16,6 @@
<i18n:msg xml:id="cbi_select">-- Bitte auswählen --</i18n:msg>
<i18n:msg xml:id="cbi_gorel">Gehe zu relevanter Konfigurationsseite</i18n:msg>
<i18n:msg xml:id="cbi_applying">Änderungen werden angewandt</i18n:msg>
<i18n:msg xml:id="cbi_upload">hochgeladene Datei</i18n:msg>
</i18n:msgs>

View file

@ -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
@ -1328,3 +1329,44 @@ 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.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

View file

@ -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" />

View file

@ -0,0 +1,28 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<%
local t = require("luci.tools.webadmin")
local v = self:cfgvalue(section)
-%>
<%+cbi/valueheader%>
<% if v then %>
<%:cbi_upload Uploaded File%> (<%=t.byte_format(luci.fs.stat(v).size or 0)%>)
<input type="hidden"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> />
<input type="image" value="<%:cbi_replace%>" name="cbi.rlf.<%=section .. "." .. self.option%>" alt="<%:cbi_replace%>" title="<%:cbi_replace%>" src="<%=resource%>/cbi/reload.gif" />
<% else %>
<input type="file"<%= attr("name", cbid) .. attr("id", cbid) %> />
<% end %>
<%+cbi/valuefooter%>

View file

@ -466,6 +466,63 @@ function cbi(model)
maps = luci.cbi.load(model, ...)
local uploads = { }
local has_upload = false
for _, map in ipairs(maps) do
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
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 = "/lib/uci/upload/"..field.name
fd = io.open(path, "w")
if fd then
cbid = field.name
prm[cbid] = path
-- else
-- io.stderr:write("E: " .. err .. "\n")
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
for i, res in ipairs(maps) do
res:parse()
end