summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-radicale
diff options
context:
space:
mode:
authorChristian Schoenebeck <christian.schoenebeck@gmail.com>2016-02-07 22:10:21 +0100
committerChristian Schoenebeck <christian.schoenebeck@gmail.com>2016-02-07 22:10:21 +0100
commitcde9a6234e637f9885406dad5592f56ccb5aee3a (patch)
tree8802d75f28ccf26e8d61d24bae49c31672ba7fa5 /applications/luci-app-radicale
parent9b5724d39ea7b5da3cec358f26ec2ef698c73690 (diff)
parent026ac8d033f4c0a65b0c8d121d1a2a86b2bd1ee1 (diff)
Merge pull request #643 from chris5560/master
luci-app-radicale: bump to version 1.1.0
Diffstat (limited to 'applications/luci-app-radicale')
-rw-r--r--applications/luci-app-radicale/Makefile4
-rw-r--r--applications/luci-app-radicale/luasrc/controller/radicale.lua298
-rw-r--r--applications/luci-app-radicale/luasrc/model/cbi/radicale.lua306
-rw-r--r--applications/luci-app-radicale/luasrc/view/radicale/btn_startstop.htm6
-rw-r--r--applications/luci-app-radicale/luasrc/view/radicale/ro_value.htm35
-rw-r--r--applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm49
-rw-r--r--applications/luci-app-radicale/po/de/radicale.po50
-rw-r--r--applications/luci-app-radicale/po/sv/radicale.po43
-rw-r--r--applications/luci-app-radicale/po/templates/radicale.pot29
9 files changed, 482 insertions, 338 deletions
diff --git a/applications/luci-app-radicale/Makefile b/applications/luci-app-radicale/Makefile
index c403ba54d6..2b969ace50 100644
--- a/applications/luci-app-radicale/Makefile
+++ b/applications/luci-app-radicale/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008-2015 The LuCI Team <luci@lists.subsignal.org>
+# Copyright (C) 2008-2016 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
@@ -10,7 +10,7 @@ PKG_NAME:=luci-app-radicale
# Version == major.minor.patch
# increase "minor" on new functionality and "patch" on patches/optimization
-PKG_VERSION:=1.0.2
+PKG_VERSION:=1.1.0
# Release == build
# increase on changes of translation files
diff --git a/applications/luci-app-radicale/luasrc/controller/radicale.lua b/applications/luci-app-radicale/luasrc/controller/radicale.lua
index 10ec1fe545..0be433a48d 100644
--- a/applications/luci-app-radicale/luasrc/controller/radicale.lua
+++ b/applications/luci-app-radicale/luasrc/controller/radicale.lua
@@ -1,15 +1,23 @@
--- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+-- Copyright 2014-2016 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-- Licensed under the Apache License, Version 2.0
module("luci.controller.radicale", package.seeall)
-local NX = require("nixio")
-local NXFS = require("nixio.fs")
-local DISP = require "luci.dispatcher"
-local HTTP = require("luci.http")
+local NX = require("nixio")
+local NXFS = require("nixio.fs")
+local DISP = require("luci.dispatcher")
+local HTTP = require("luci.http")
local I18N = require("luci.i18n") -- not globally avalible here
-local UTIL = require("luci.util")
-local SYS = require("luci.sys")
+local IPKG = require("luci.model.ipkg")
+local UTIL = require("luci.util")
+local SYS = require("luci.sys")
+
+local srv_name = "radicale"
+local srv_ver_min = "1.1" -- minimum version of service required
+local srv_ver_cmd = [[/usr/bin/radicale --version]]
+local app_name = "luci-app-radicale"
+local app_title = I18N.translate("Radicale CalDAV/CardDAV Server")
+local app_version = "1.1.0-1"
function index()
entry( {"admin", "services", "radicale"}, alias("admin", "services", "radicale", "edit"), _("CalDAV/CardDAV"), 58)
@@ -19,6 +27,75 @@ function index()
entry( {"admin", "services", "radicale", "status"}, call("_status") ).leaf = true
end
+-- Application / Service specific information functions
+function app_description()
+ return I18N.translate("The Radicale Project is a complete CalDAV (calendar) and CardDAV (contact) server solution.") .. [[<br />]]
+ .. I18N.translate("Calendars and address books are available for both local and remote access, possibly limited through authentication policies.") .. [[<br />]]
+ .. I18N.translate("They can be viewed and edited by calendar and contact clients on mobile phones or computers.")
+end
+function app_title_main()
+ return [[<a href="javascript:alert(']]
+ .. I18N.translate("Version Information")
+ .. [[\n\n]] .. app_name
+ .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]] .. app_version
+ .. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("required") .. [[:]]
+ .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
+ .. srv_ver_min .. [[ ]] .. I18N.translate("or higher")
+ .. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("installed") .. [[:]]
+ .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
+ .. (service_version() or I18N.translate("NOT installed"))
+ .. [[\n\n]]
+ .. [[')">]]
+ .. I18N.translate(app_title)
+ .. [[</a>]]
+end
+function app_title_back()
+ return [[<a href="]]
+ .. DISP.build_url("admin", "services", "radicale")
+ .. [[">]]
+ .. I18N.translate(app_title)
+ .. [[</a>]]
+end
+function app_err_value()
+ if not service_version() then
+ return [[<h3><strong><br /><font color="red">&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. I18N.translate("Software package '%s' is not installed." % srv_name)
+ .. [[</font><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. I18N.translate("required") .. [[: ]] .. srv_name .. [[ ]] .. srv_ver_min
+ .. [[<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
+ .. I18N.translate("Please install current version !")
+ .. [[</a><br />&nbsp;</strong></h3>]]
+ else
+ return [[<h3><strong><br /><font color="red">&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. I18N.translate("Software package '%s' is outdated." % srv_name)
+ .. [[</font><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. I18N.translate("installed") .. [[: ]] .. srv_name .. [[ ]] .. service_version()
+ .. [[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. I18N.translate("required") .. [[: ]] .. srv_name .. [[ ]] .. srv_ver_min
+ .. [[<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;]]
+ .. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
+ .. I18N.translate("Please update to current version !")
+ .. [[</a><br />&nbsp;</strong></h3>]]
+ end
+end
+
+function service_version()
+ local ver = nil
+ IPKG.list_installed(srv_name, function(n, v, d)
+ if v and (#v > 0) then ver = v end
+ end
+ )
+ if not ver or (#ver == 0) then
+ ver = UTIL.exec(srv_ver_cmd)
+ if #ver == 0 then ver = nil end
+ end
+ return ver
+end
+function service_ok()
+ return IPKG.compare_versions((service_version() or "0"), ">=", srv_ver_min)
+end
+
-- called by XHR.get from detail_logview.htm
function _logread()
-- read application settings
@@ -60,138 +137,103 @@ function _status()
HTTP.write(tostring(pid)) -- HTTP needs string not number
end
--- Application / Service specific information functions ########################
-function luci_app_name()
- return "luci-app-radicale"
-end
-
-function service_name()
- return "radicale"
-end
-function service_required()
- return "0.10-1"
-end
-function service_installed()
- local v = ipkg_ver_installed("radicale-py2")
- if not v or #v == 0 then v = ipkg_ver_installed("radicale-py3") end
- if not v or #v == 0 then v = "0" end
- return v
-end
-function service_ok()
- return ipkg_ver_compare(service_installed(),">=",service_required())
-end
-
-function app_title_main()
- return [[<a href="javascript:alert(']]
- .. I18N.translate("Version Information")
- .. [[\n\n]] .. luci_app_name()
- .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
- .. (ipkg_ver_installed(luci_app_name()) == ""
- and I18N.translate("NOT installed")
- or ipkg_ver_installed(luci_app_name()) )
- .. [[\n\n]] .. service_name() .. [[ ]] .. I18N.translate("required") .. [[:]]
- .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
- .. service_required() .. [[ ]] .. I18N.translate("or higher")
- .. [[\n\n]] .. service_name() .. [[ ]] .. I18N.translate("installed") .. [[:]]
- .. [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
- .. (service_installed() == "0"
- and I18N.translate("NOT installed")
- or service_installed())
- .. [[\n\n]]
- .. [[')">]]
- .. I18N.translate("Radicale CalDAV/CardDAV Server")
- .. [[</a>]]
-end
-function app_title_back()
- return [[<a href="]]
- .. DISP.build_url("admin", "services", "radicale")
- .. [[">]]
- .. I18N.translate("Radicale CalDAV/CardDAV Server")
- .. [[</a>]]
-end
-function app_description()
- return I18N.translate("The Radicale Project is a complete CalDAV (calendar) and CardDAV (contact) server solution.") .. [[<br />]]
- .. I18N.translate("Calendars and address books are available for both local and remote access, possibly limited through authentication policies.") .. [[<br />]]
- .. I18N.translate("They can be viewed and edited by calendar and contact clients on mobile phones or computers.")
-end
-
--- other multiused functions ###################################################
-
--return pid of running process
function get_pid()
return tonumber(SYS.exec([[ps | grep "[p]ython.*[r]adicale" 2>/dev/null | awk '{print $1}']])) or 0
end
--- compare versions using "<=" "<" ">" ">=" "=" "<<" ">>"
-function ipkg_ver_compare(ver1, comp, ver2)
- if not ver1 or not ver2
- or not comp or not (#comp > 0) then return nil end
- -- correct compare string
- if comp == "<>" or comp == "><" or comp == "!=" or comp == "~=" then comp = "~="
- elseif comp == "<=" or comp == "<" or comp == "=<" then comp = "<="
- elseif comp == ">=" or comp == ">" or comp == "=>" then comp = ">="
- elseif comp == "=" or comp == "==" then comp = "=="
- elseif comp == "<<" then comp = "<"
- elseif comp == ">>" then comp = ">"
- else return nil end
-
- local av1 = UTIL.split(ver1, "[%.%-]", nil, true)
- local av2 = UTIL.split(ver2, "[%.%-]", nil, true)
-
- for i = 1, math.max(table.getn(av1),table.getn(av2)), 1 do
- local s1 = av1[i] or ""
- local s2 = av2[i] or ""
-
- -- first "not equal" found return true
- if comp == "~=" and (s1 ~= s2) then return true end
- -- first "lower" found return true
- if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
- -- first "greater" found return true
- if (comp == ">" or comp == ">=") and (s1 > s2) then return true end
- -- not equal then return false
- if (s1 ~= s2) then return false end
+-- replacement of build-in parse of "Value"
+-- modified AbstractValue.parse(self, section, novld) from cbi.lua
+-- validate is called if rmempty/optional true or false
+-- before write check if forcewrite, value eq default, and more
+function value_parse(self, section, novld)
+ local fvalue = self:formvalue(section)
+ local fexist = ( fvalue and (#fvalue > 0) ) -- not "nil" and "not empty"
+ local cvalue = self:cfgvalue(section)
+ local rm_opt = ( self.rmempty or self.optional )
+ local eq_cfg -- flag: equal cfgvalue
+
+ -- If favlue and cvalue are both tables and have the same content
+ -- make them identical
+ if type(fvalue) == "table" and type(cvalue) == "table" then
+ eq_cfg = (#fvalue == #cvalue)
+ if eq_cfg then
+ for i=1, #fvalue do
+ if cvalue[i] ~= fvalue[i] then
+ eq_cfg = false
+ end
+ end
+ end
+ if eq_cfg then
+ fvalue = cvalue
+ end
end
- -- all equal and not compare greater or lower then true
- return not (comp == "<" or comp == ">")
-end
+ -- removed parameter "section" from function call because used/accepted nowhere
+ -- also removed call to function "transfer"
+ local vvalue, errtxt = self:validate(fvalue)
--- read version information for given package if installed
-function ipkg_ver_installed(pkg)
- local version = ""
- local control = io.open("/usr/lib/opkg/info/%s.control" % pkg, "r")
- if control then
- local ln
- repeat
- ln = control:read("*l")
- if ln and ln:match("^Version: ") then
- version = ln:gsub("^Version: ", "")
- break
- end
- until not ln
- control:close()
+ -- error handling; validate return "nil"
+ if not vvalue then
+ if novld then -- and "novld" set
+ return -- then exit without raising an error
+ end
+
+ if fexist then -- and there is a formvalue
+ self:add_error(section, "invalid", errtxt)
+ return -- so data are invalid
+ elseif not rm_opt then -- and empty formvalue but NOT (rmempty or optional) set
+ self:add_error(section, "missing", errtxt)
+ return -- so data is missing
+ elseif errtxt then
+ self:add_error(section, "invalid", errtxt)
+ return
+ end
+-- error ("\n option: " .. self.option ..
+-- "\n fvalue: " .. tostring(fvalue) ..
+-- "\n fexist: " .. tostring(fexist) ..
+-- "\n cvalue: " .. tostring(cvalue) ..
+-- "\n vvalue: " .. tostring(vvalue) ..
+-- "\n vexist: " .. tostring(vexist) ..
+-- "\n rm_opt: " .. tostring(rm_opt) ..
+-- "\n eq_cfg: " .. tostring(eq_cfg) ..
+-- "\n eq_def: " .. tostring(eq_def) ..
+-- "\n novld : " .. tostring(novld) ..
+-- "\n errtxt: " .. tostring(errtxt) )
end
- return version
-end
--- replacement of build-in Flag.parse of cbi.lua
--- modified to mark section as changed if value changes
--- current parse did not do this, but it is done AbstaractValue.parse()
-function flag_parse(self, section)
- local fexists = self.map:formvalue(
- luci.cbi.FEXIST_PREFIX .. self.config .. "." .. section .. "." .. self.option)
-
- if fexists then
- local fvalue = self:formvalue(section) and self.enabled or self.disabled
- local cvalue = self:cfgvalue(section)
- if fvalue ~= self.default or (not self.optional and not self.rmempty) then
- self:write(section, fvalue)
- else
- self:remove(section)
+ -- lets continue with value returned from validate
+ eq_cfg = ( vvalue == cvalue ) -- update equal_config flag
+ local vexist = ( vvalue and (#vvalue > 0) ) and true or false -- not "nil" and "not empty"
+ local eq_def = ( vvalue == self.default ) -- equal_default flag
+
+ -- (rmempty or optional) and (no data or equal_default)
+ if rm_opt and (not vexist or eq_def) then
+ if self:remove(section) then -- remove data from UCI
+ self.section.changed = true -- and push events
end
- if (fvalue ~= cvalue) then self.section.changed = true end
- else
- self:remove(section)
+ return
+ end
+
+ -- not forcewrite and no changes, so nothing to write
+ if not self.forcewrite and eq_cfg then
+ return
+ end
+
+ -- we should have a valid value here
+ assert (vvalue, "\n option: " .. self.option ..
+ "\n fvalue: " .. tostring(fvalue) ..
+ "\n fexist: " .. tostring(fexist) ..
+ "\n cvalue: " .. tostring(cvalue) ..
+ "\n vvalue: " .. tostring(vvalue) ..
+ "\n vexist: " .. tostring(vexist) ..
+ "\n rm_opt: " .. tostring(rm_opt) ..
+ "\n eq_cfg: " .. tostring(eq_cfg) ..
+ "\n eq_def: " .. tostring(eq_def) ..
+ "\n errtxt: " .. tostring(errtxt) )
+
+ -- write data to UCI; raise event only on changes
+ if self:write(section, vvalue) and not eq_cfg then
self.section.changed = true
end
end
diff --git a/applications/luci-app-radicale/luasrc/model/cbi/radicale.lua b/applications/luci-app-radicale/luasrc/model/cbi/radicale.lua
index 8abb68869d..c610478bcb 100644
--- a/applications/luci-app-radicale/luasrc/model/cbi/radicale.lua
+++ b/applications/luci-app-radicale/luasrc/model/cbi/radicale.lua
@@ -1,14 +1,43 @@
--- Copyright 2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+-- Copyright 2015-2016 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-- Licensed under the Apache License, Version 2.0
-local NXFS = require("nixio.fs")
-local DISP = require("luci.dispatcher")
-local DTYP = require("luci.cbi.datatypes")
-local HTTP = require("luci.http")
-local UTIL = require("luci.util")
-local UCI = require("luci.model.uci")
-local SYS = require("luci.sys")
-local TOOLS = require("luci.controller.radicale") -- this application's controller and multiused functions
+local NXFS = require("nixio.fs")
+local DISP = require("luci.dispatcher")
+local DTYP = require("luci.cbi.datatypes")
+local HTTP = require("luci.http")
+local UTIL = require("luci.util")
+local UCI = require("luci.model.uci")
+local SYS = require("luci.sys")
+local WADM = require("luci.tools.webadmin")
+local CTRL = require("luci.controller.radicale") -- this application's controller and multiused functions
+
+-- #################################################################################################
+-- Error handling if not installed or wrong version -- #########################
+if not CTRL.service_ok() then
+ local f = SimpleForm("__sf")
+ f.title = CTRL.app_title_main()
+ f.description = CTRL.app_description()
+ f.embedded = true
+ f.submit = false
+ f.reset = false
+
+ local s = f:section(SimpleSection)
+ s.title = [[<font color="red">]] .. [[<strong>]]
+ .. translate("Software update required")
+ .. [[</strong>]] .. [[</font>]]
+
+ local v = s:option(DummyValue, "_dv")
+ v.rawhtml = true
+ v.value = CTRL.app_err_value
+
+ return f
+end
+
+-- #################################################################################################
+-- Error handling if no config, create an empty one -- #########################
+if not NXFS.access("/etc/config/radicale") then
+ NXFS.writefile("/etc/config/radicale", "")
+end
-- #################################################################################################
-- takeover arguments if any -- ################################################
@@ -19,8 +48,8 @@ if arg[1] then
-- SimpleForm ------------------------------------------------
local ft = SimpleForm("_text")
- ft.title = TOOLS.app_title_back()
- ft.description = TOOLS.app_description()
+ ft.title = CTRL.app_title_back()
+ ft.description = CTRL.app_description()
ft.redirect = DISP.build_url("admin", "services", "radicale") .. "#cbi-radicale-" .. argument
if argument == "logger" then
ft.reset = false
@@ -95,54 +124,12 @@ if arg[1] then
end
--- #################################################################################################
--- Error handling if not installed or wrong version -- #########################
-if not TOOLS.service_ok() then
- local f = SimpleForm("_no_config")
- f.title = TOOLS.app_title_main()
- f.description = TOOLS.app_description()
- f.submit = false
- f.reset = false
-
- local s = f:section(SimpleSection)
-
- local v = s:option(DummyValue, "_update_needed")
- v.rawhtml = true
- if TOOLS.service_installed() == "0" then
- v.value = [[<h3><strong><br /><font color="red">&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. translate("Software package '" .. TOOLS.service_name() .. "' is not installed.")
- .. [[</font><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. translate("required") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_required()
- .. [[<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
- .. translate("Please install current version !")
- .. [[</a><br />&nbsp;</strong></h3>]]
- else
- v.value = [[<h3><strong><br /><font color="red">&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. translate("Software package '" .. TOOLS.service_name() .. "' is outdated.")
- .. [[</font><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. translate("installed") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_installed()
- .. [[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. translate("required") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_required()
- .. [[<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;]]
- .. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
- .. translate("Please update to current version !")
- .. [[</a><br />&nbsp;</strong></h3>]]
- end
-
- return f
-end
-
--- #################################################################################################
--- Error handling if no config, create an empty one -- #########################
-if not NXFS.access("/etc/config/radicale") then
- NXFS.writefile("/etc/config/radicale", "")
-end
-
-- cbi-map -- ##################################################################
local m = Map("radicale")
-m.title = TOOLS.app_title_main()
-m.description = TOOLS.app_description()
+m.title = CTRL.app_title_main()
+m.description = CTRL.app_description()
+m.template = "radicale/tabmap_nsections"
+m.tabbed = true
function m.commit_handler(self)
if self.changed then -- changes ?
os.execute("/etc/init.d/radicale reload &") -- reload configuration
@@ -150,11 +137,14 @@ function m.commit_handler(self)
end
-- cbi-section "System" -- #####################################################
-local sys = m:section( NamedSection, "_system" )
+local sys = m:section( NamedSection, "system", "system" )
sys.title = translate("System")
sys.description = nil
function sys.cfgvalue(self, section)
- return "_dummysection"
+ if not self.map:get(section) then -- section might not exist
+ self.map:set(section, nil, self.sectiontype)
+ end
+ return self.map:get(section)
end
-- start/stop button -----------------------------------------------------------
@@ -165,7 +155,7 @@ btn.rmempty = true
btn.title = translate("Start / Stop")
btn.description = translate("Start/Stop Radicale server")
function btn.cfgvalue(self, section)
- local pid = TOOLS.get_pid(true)
+ local pid = CTRL.get_pid(true)
if pid > 0 then
btn.inputtitle = "PID: " .. pid
btn.inputstyle = "reset"
@@ -183,18 +173,39 @@ local ena = sys:option(Flag, "_enabled")
ena.title = translate("Auto-start")
ena.description = translate("Enable/Disable auto-start of Radicale on system start-up and interface events")
ena.orientation = "horizontal" -- put description under the checkbox
-ena.rmempty = false -- we need write
+ena.rmempty = false -- force write() function
function ena.cfgvalue(self, section)
- return (SYS.init.enabled("radicale")) and "1" or "0"
+ return (SYS.init.enabled("radicale")) and self.enabled or self.disabled
end
function ena.write(self, section, value)
- if value == "1" then
+ if value == self.enabled then
return SYS.init.enable("radicale")
else
return SYS.init.disable("radicale")
end
end
+-- boot_delay ------------------------------------------------------------------
+local bd = sys:option(Value, "boot_delay")
+bd.title = translate("Boot delay")
+bd.description = translate("Delay (in seconds) during system boot before Radicale start")
+ .. [[<br />]]
+ .. translate("During delay ifup-events are not monitored !")
+bd.default = "10"
+function bd.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
+function bd.validate(self, value)
+ local val = tonumber(value)
+ if not val then
+ return nil, self.title .. ": " .. translate("Value is not a number")
+ elseif val < 0 or val > 300 then
+ return nil, self.title .. ": " .. translate("Value not between 0 and 300")
+ end
+ return value
+end
+
+
-- cbi-section "Server" -- #####################################################
local srv = m:section( NamedSection, "server", "setting" )
srv.title = translate("Server")
@@ -215,15 +226,17 @@ sh.description = translate("'Hostname:Port' or 'IPv4:Port' or '[IPv6]:Port' Radi
.. [[</strong>]]
sh.placeholder = "0.0.0.0:5232"
sh.rmempty = true
+function sh.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- realm -----------------------------------------------------------------------
local alm = srv:option( Value, "realm" )
alm.title = translate("Logon message")
alm.description = translate("Message displayed in the client when a password is needed.")
alm.default = "Radicale - Password Required"
-alm.rmempty = false
-function alm.parse(self, section)
- AbstractValue.parse(self, section, "true") -- otherwise unspecific validate error
+function alm.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
end
function alm.validate(self, value)
if value then
@@ -232,22 +245,11 @@ function alm.validate(self, value)
return self.default
end
end
-function alm.write(self, section, value)
- if value ~= self.default then
- return self.map:set(section, self.option, value)
- else
- return self.map:del(section, self.option)
- end
-end
-- ssl -------------------------------------------------------------------------
local ssl = srv:option( Flag, "ssl" )
ssl.title = translate("Enable HTTPS")
ssl.description = nil
-ssl.rmempty = false
-function ssl.parse(self, section)
- TOOLS.flag_parse(self, section)
-end
function ssl.write(self, section, value)
if value == "0" then -- delete all if not https enabled
self.map:del(section, "protocol") -- protocol
@@ -273,18 +275,18 @@ prt:value ("PROTOCOL_SSLv3", "SSL v3")
prt:value ("PROTOCOL_TLSv1", "TLS v1")
prt:value ("PROTOCOL_TLSv1_1", "TLS v1.1")
prt:value ("PROTOCOL_TLSv1_2", "TLS v1.2")
+function prt.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- certificate -----------------------------------------------------------------
local crt = srv:option( Value, "certificate" )
crt.title = translate("Certificate file")
crt.description = translate("Full path and file name of certificate")
crt.placeholder = "/etc/radicale/ssl/server.crt"
-crt.rmempty = false -- force validate/write
crt:depends ("ssl", "1")
-function crt.parse(self, section)
- local _ssl = ssl:formvalue(section) or "0"
- local novld = (_ssl == "0")
- AbstractValue.parse(self, section, novld) -- otherwise unspecific validate error
+function crt.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
end
function crt.validate(self, value)
local _ssl = ssl:formvalue(srv.section) or "0"
@@ -295,17 +297,10 @@ function crt.validate(self, value)
if DTYP.file(value) then
return value
else
- return nil, self.title .. " - " .. translate("File not found !")
+ return nil, self.title .. ": " .. translate("File not found !")
end
else
- return nil, self.title .. " - " .. translate("Path/File required !")
- end
-end
-function crt.write(self, section, value)
- if not value or #value == 0 then
- return self.map:del(section, self.option)
- else
- return self.map:set(section, self.option, value)
+ return nil, self.title .. ": " .. translate("Path/File required !")
end
end
@@ -314,12 +309,9 @@ local key = srv:option( Value, "key" )
key.title = translate("Private key file")
key.description = translate("Full path and file name of private key")
key.placeholder = "/etc/radicale/ssl/server.key"
-key.rmempty = false -- force validate/write
key:depends ("ssl", "1")
-function key.parse(self, section)
- local _ssl = ssl:formvalue(section) or "0"
- local novld = (_ssl == "0")
- AbstractValue.parse(self, section, novld) -- otherwise unspecific validate error
+function key.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
end
function key.validate(self, value)
local _ssl = ssl:formvalue(srv.section) or "0"
@@ -330,17 +322,10 @@ function key.validate(self, value)
if DTYP.file(value) then
return value
else
- return nil, self.title .. " - " .. translate("File not found !")
+ return nil, self.title .. ": " .. translate("File not found !")
end
else
- return nil, self.title .. " - " .. translate("Path/File required !")
- end
-end
-function key.write(self, section, value)
- if not value or #value == 0 then
- return self.map:del(section, self.option)
- else
- return self.map:set(section, self.option, value)
+ return nil, self.title .. ": " .. translate("Path/File required !")
end
end
@@ -377,6 +362,9 @@ aty:value ("htpasswd", translate("htpasswd file"))
--aty:value ("HTTP", "HTTP") -- The HTTP authentication module relies on the requests module
--aty:value ("remote_user", "remote_user")
--aty:value ("custom", translate("custom"))
+function aty.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function aty.write(self, section, value)
if value ~= "htpasswd" then
self.map:del(section, "htpasswd_encryption")
@@ -403,9 +391,12 @@ hte:value ("crypt", translate("crypt"))
hte:value ("plain", translate("plain"))
hte:value ("sha1", translate("SHA-1"))
hte:value ("ssha", translate("salted SHA-1"))
+function hte.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- htpasswd_file (dummy) -------------------------------------------------------
-local htf = aut:option( DummyValue, "_htf" )
+local htf = aut:option( Value, "_htf" )
htf.title = translate("htpasswd file")
htf.description = [[<strong>]]
.. translate("Read only!")
@@ -416,9 +407,6 @@ htf.description = [[<strong>]]
.. [[">]]
.. translate("To edit the file follow this link!")
.. [[</a>]]
-htf.keylist = {} -- required by template
-htf.vallist = {} -- required by template
-htf.template = "radicale/ro_value"
htf.readonly = true
htf:depends ("type", "htpasswd")
function htf.cfgvalue()
@@ -448,6 +436,9 @@ rty:value ("owner_only", translate("Full access for Owner only") )
rty:value ("owner_write", translate("Owner allow write, authenticated users allow read") )
rty:value ("from_file", translate("Rights are based on a regexp-based file") )
--rty:value ("custom", "Custom handler")
+function rty.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function rty.write(self, section, value)
if value ~= "custom" then
self.map:del(section, "custom_handler")
@@ -460,7 +451,7 @@ function rty.write(self, section, value)
end
-- from_file (dummy) -----------------------------------------------------------
-local rtf = rig:option( DummyValue, "_rtf" )
+local rtf = rig:option( Value, "_rtf" )
rtf.title = translate("RegExp file")
rtf.description = [[<strong>]]
.. translate("Read only!")
@@ -471,9 +462,6 @@ rtf.description = [[<strong>]]
.. [[">]]
.. translate("To edit the file follow this link!")
.. [[</a>]]
-rtf.keylist = {} -- required by template
-rtf.vallist = {} -- required by template
-rtf.template = "radicale/ro_value"
rtf.readonly = true
rtf:depends ("type", "from_file")
function rtf.cfgvalue()
@@ -501,6 +489,9 @@ sty:value ("filesystem", translate("File-system"))
--sty:value ("multifilesystem", translate("") )
--sty:value ("database", translate("Database") )
--sty:value ("custom", translate("Custom") )
+function sty.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function sty.write(self, section, value)
if value ~= "filesystem" then
self.map:del(section, "filesystem_folder")
@@ -516,13 +507,10 @@ end
local sfi = sto:option( Value, "filesystem_folder" )
sfi.title = translate("Directory")
sfi.description = nil
-sfi.default = "/srv/radicale"
-sfi.rmempty = false -- force validate/write
+sfi.placeholder = "/srv/radicale"
sfi:depends ("type", "filesystem")
-function sfi.parse(self, section)
- local _typ = sty:formvalue(sto.section) or ""
- local novld = (_typ ~= "filesystem")
- AbstractValue.parse(self, section, novld) -- otherwise unspecific validate error
+function sfi.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
end
function sfi.validate(self, value)
local _typ = sty:formvalue(sto.section) or ""
@@ -533,10 +521,10 @@ function sfi.validate(self, value)
if DTYP.directory(value) then
return value
else
- return nil, self.title .. " - " .. translate("Directory not exists/found !")
+ return nil, self.title .. ": " .. translate("Directory not exists/found !")
end
else
- return nil, self.title .. " - " .. translate("Directory required !")
+ return nil, self.title .. ": " .. translate("Directory required !")
end
end
@@ -562,6 +550,9 @@ lco:value ("INFO", translate("Info") )
lco:value ("WARNING", translate("Warning") )
lco:value ("ERROR", translate("Error") )
lco:value ("CRITICAL", translate("Critical") )
+function lco.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function lco.write(self, section, value)
if value ~= self.default then
return self.map:set(section, self.option, value)
@@ -581,6 +572,9 @@ lsl:value ("INFO", translate("Info") )
lsl:value ("WARNING", translate("Warning") )
lsl:value ("ERROR", translate("Error") )
lsl:value ("CRITICAL", translate("Critical") )
+function lsl.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function lsl.write(self, section, value)
if value ~= self.default then
return self.map:set(section, self.option, value)
@@ -600,6 +594,9 @@ lfi:value ("INFO", translate("Info") )
lfi:value ("WARNING", translate("Warning") )
lfi:value ("ERROR", translate("Error") )
lfi:value ("CRITICAL", translate("Critical") )
+function lfi.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function lfi.write(self, section, value)
if value ~= self.default then
return self.map:set(section, self.option, value)
@@ -618,12 +615,14 @@ lfp.description = translate("Directory where the rotating log-files are stored")
.. translate("To view latest log file follow this link!")
.. [[</a>]]
lfp.default = "/var/log/radicale"
-function lfp.write(self, section, value)
- if value ~= self.default then
- return self.map:set(section, self.option, value)
- else
- return self.map:del(section, self.option)
+function lfp.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
+function lfp.validate(self, value)
+ if not value or (#value < 1) or (value:find("/") ~= 1) then
+ return nil, self.title .. ": " .. translate("no valid path given!")
end
+ return value
end
-- file_maxbytes ---------------------------------------------------------------
@@ -634,23 +633,18 @@ lmb.description = translate("Maximum size of each rotation log-file.")
.. translate("Setting this parameter to '0' will disable rotation of log-file.")
.. [[</strong>]]
lmb.default = "8196"
-lmb.rmempty = false
+function lmb.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function lmb.validate(self, value)
if value then -- otherwise errors in datatype check
if DTYP.uinteger(value) then
return value
else
- return nil, self.title .. " - " .. translate("Value is not an Integer >= 0 !")
+ return nil, self.title .. ": " .. translate("Value is not an Integer >= 0 !")
end
else
- return nil, self.title .. " - " .. translate("Value required ! Integer >= 0 !")
- end
-end
-function lmb.write(self, section, value)
- if value ~= self.default then
- return self.map:set(section, self.option, value)
- else
- return self.map:del(section, self.option)
+ return nil, self.title .. ": " .. translate("Value required ! Integer >= 0 !")
end
end
@@ -662,23 +656,18 @@ lbc.description = translate("Number of backup files of log to create.")
.. translate("Setting this parameter to '0' will disable rotation of log-file.")
.. [[</strong>]]
lbc.default = "1"
-lbc.rmempty = false
+function lbc.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
function lbc.validate(self, value)
if value then -- otherwise errors in datatype check
if DTYP.uinteger(value) then
return value
else
- return nil, self.title .. " - " .. translate("Value is not an Integer >= 0 !")
+ return nil, self.title .. ": " .. translate("Value is not an Integer >= 0 !")
end
else
- return nil, self.title .. " - " .. translate("Value required ! Integer >= 0 !")
- end
-end
-function lbc.write(self, section, value)
- if value ~= self.default then
- return self.map:set(section, self.option, value)
- else
- return self.map:del(section, self.option)
+ return nil, self.title .. ": " .. translate("Value required ! Integer >= 0 !")
end
end
@@ -699,14 +688,18 @@ local enr = enc:option( Value, "request" )
enr.title = translate("Response Encoding")
enr.description = translate("Encoding for responding requests.")
enr.default = "utf-8"
-enr.optional = true
+function enr.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- stock -----------------------------------------------------------------------
local ens = enc:option( Value, "stock" )
ens.title = translate("Storage Encoding")
ens.description = translate("Encoding for storing local collections.")
ens.default = "utf-8"
-ens.optional = true
+function ens.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- cbi-section "Headers" -- ####################################################
local hea = m:section( NamedSection, "headers", "setting" )
@@ -724,25 +717,32 @@ end
local heo = hea:option( DynamicList, "Access_Control_Allow_Origin" )
heo.title = translate("Access-Control-Allow-Origin")
heo.description = nil
-heo.default = "*"
-heo.optional = true
+function heo.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- Access_Control_Allow_Methods ------------------------------------------------
local hem = hea:option( DynamicList, "Access_Control_Allow_Methods" )
hem.title = translate("Access-Control-Allow-Methods")
hem.description = nil
-hem.optional = true
+function hem.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- Access_Control_Allow_Headers ------------------------------------------------
local heh = hea:option( DynamicList, "Access_Control_Allow_Headers" )
heh.title = translate("Access-Control-Allow-Headers")
heh.description = nil
-heh.optional = true
+function heh.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
-- Access_Control_Expose_Headers -----------------------------------------------
local hee = hea:option( DynamicList, "Access_Control_Expose_Headers" )
hee.title = translate("Access-Control-Expose-Headers")
hee.description = nil
-hee.optional = true
+function hee.parse(self, section, novld)
+ CTRL.value_parse(self, section, novld)
+end
return m
diff --git a/applications/luci-app-radicale/luasrc/view/radicale/btn_startstop.htm b/applications/luci-app-radicale/luasrc/view/radicale/btn_startstop.htm
index dbf4dddbca..d9ef82214f 100644
--- a/applications/luci-app-radicale/luasrc/view/radicale/btn_startstop.htm
+++ b/applications/luci-app-radicale/luasrc/view/radicale/btn_startstop.htm
@@ -4,7 +4,7 @@
// show XHR.poll/XHR.get response on button
function _data2elements(x) {
- var btn = document.getElementById("cbid.radicale._system._startstop");
+ var btn = document.getElementById("cbid.radicale.<%=section%>._startstop");
if ( ! btn ) { return; } // security check
if (x.responseText == "0") {
btn.value = "<%:Start%>";
@@ -21,12 +21,12 @@
function onclick_startstop(id) {
// do start/stop
var btnXHR = new XHR();
- btnXHR.post('<%=url('admin/services/radicale/startstop')%>', { token: '<%=token%>' },
+ btnXHR.post('<%=url([[admin/services/radicale/startstop]])%>', { token: '<%=token%>' },
function(x) { _data2elements(x); }
);
}
- XHR.poll(5, '<%=url('admin/services/radicale/status')%>', null,
+ XHR.poll(5, '<%=url([[admin/services/radicale/status]])%>', null,
function(x, data) { _data2elements(x); }
);
diff --git a/applications/luci-app-radicale/luasrc/view/radicale/ro_value.htm b/applications/luci-app-radicale/luasrc/view/radicale/ro_value.htm
deleted file mode 100644
index 6e05206aa1..0000000000
--- a/applications/luci-app-radicale/luasrc/view/radicale/ro_value.htm
+++ /dev/null
@@ -1,35 +0,0 @@
-<%+cbi/valueheader%>
- <input type="<%=self.password and 'password" class="cbi-input-password' or 'text" class="cbi-input-text' %>" onchange="cbi_d_update(this.id)"<%=
- attr("name", cbid) .. attr("id", cbid) .. attr("value", self:cfgvalue(section) or self.default) ..
- ifattr(self.size, "size") .. ifattr(self.placeholder, "placeholder") .. ifattr(self.readonly, "readonly")
- %> />
- <% if self.password then %><img src="<%=resource%>/cbi/reload.gif" style="vertical-align:middle" title="<%:Reveal/hide password%>" onclick="var e = document.getElementById('<%=cbid%>'); e.type = (e.type=='password') ? 'text' : 'password';" /><% end %>
- <% if #self.keylist > 0 or self.datatype then -%>
- <script type="text/javascript">//<![CDATA[
- <% if #self.keylist > 0 then -%>
- cbi_combobox_init('<%=cbid%>', {
- <%-
- for i, k in ipairs(self.keylist) do
- -%>
- <%-=string.format("%q", k) .. ":" .. string.format("%q", self.vallist[i])-%>
- <%-if i<#self.keylist then-%>,<%-end-%>
- <%-
- end
- -%>
- }, '<%- if not self.rmempty and not self.optional then -%>
- <%-: -- Please choose -- -%>
- <%- elseif self.placeholder then -%>
- <%-= pcdata(self.placeholder) -%>
- <%- end -%>', '
- <%- if self.combobox_manual then -%>
- <%-=self.combobox_manual-%>
- <%- else -%>
- <%-: -- custom -- -%>
- <%- end -%>');
- <%- end %>
- <% if self.datatype then -%>
- cbi_validate_field('<%=cbid%>', <%=tostring((self.optional or self.rmempty) == true)%>, '<%=self.datatype:gsub("'", "\\'")%>');
- <%- end %>
- //]]></script>
- <% end -%>
-<%+cbi/valuefooter%>
diff --git a/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm b/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm
new file mode 100644
index 0000000000..45fe60cc80
--- /dev/null
+++ b/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm
@@ -0,0 +1,49 @@
+<%- if firstmap and messages then local msg; for _, msg in ipairs(messages) do -%>
+ <div class="errorbox"><%=pcdata(msg)%></div>
+<%- end end -%>
+
+<%-+cbi/apply_xhr-%>
+
+<div class="cbi-map" id="cbi-<%=self.config%>">
+ <% 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 -%>
+
+ <% if self.tabbed then %>
+ <ul class="cbi-tabmenu map">
+ <%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
+ <% for i, section in ipairs(self.children) do %>
+ <%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
+ <li id="tab.m-<%=self.config%>.<%=section.section or 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.section or section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.section or section.sectiontype%>"><%=section.title or section.section 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.section or section.sectiontype%>" /><% end %>
+ </li>
+ <% end %>
+ </ul>
+ <br />
+ <% for i, section in ipairs(self.children) do %>
+ <div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or 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.section or section.sectiontype%>')</script>
+ <% end %>
+
+ <% else %>
+ <%- self:render_children() %>
+ <% end %>
+
+ <% if not self.save then -%>
+ <div class="cbi-section-error">
+ <% for _, section in ipairs(self.children) do %>
+ <% if section.error and section.error[section.section] then -%>
+ <ul><li>
+ <%:One or more missing/invalid fields on tab%>:&nbsp;<%=section.title or section.section or section.sectiontype%>
+ </li></ul>
+ <%- end %>
+ <% end %>
+ </div>
+ <%- end %>
+
+ <br />
+
+</div>
diff --git a/applications/luci-app-radicale/po/de/radicale.po b/applications/luci-app-radicale/po/de/radicale.po
index 57850dc109..ef47988a40 100644
--- a/applications/luci-app-radicale/po/de/radicale.po
+++ b/applications/luci-app-radicale/po/de/radicale.po
@@ -1,15 +1,15 @@
msgid ""
msgstr ""
-"Project-Id-Version: luci-app-radicale\n"
-"POT-Creation-Date: 2015-05-02 19:32+0100\n"
-"PO-Revision-Date: 2015-05-02 22:43+0100\n"
-"Last-Translator: Christian Schoenebeck <christian.schoenebeck@gmail.com>\n"
+"Project-Id-Version: luci-app-radicale 1.1.0-1\n"
+"POT-Creation-Date: 2016-01-30 20:34+0100\n"
+"PO-Revision-Date: 2016-01-31 20:49+0100\n"
+"Last-Translator: Christian Schönebeck <christian.schoenebeck@gmail.com>\n"
"Language-Team: \n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.7.5\n"
+"X-Generator: Poedit 1.8.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
@@ -72,6 +72,9 @@ msgstr ""
msgid "Auto-start"
msgstr "Autostart"
+msgid "Boot delay"
+msgstr "Systemstart-Verzögerung"
+
msgid "CalDAV/CardDAV"
msgstr "CalDAV/CardDAV"
@@ -122,6 +125,10 @@ msgstr "Datenbank"
msgid "Debug"
msgstr "Debug"
+msgid "Delay (in seconds) during system boot before Radicale start"
+msgstr ""
+"Verzögerung (in Sekunden) während des Systemstarts, bevor Radicale startet"
+
msgid "Directory"
msgstr "Verzeichnis"
@@ -135,6 +142,9 @@ msgid "Directory where the rotating log-files are stored"
msgstr ""
"Verzeichnis in dem die rollierenden Protokolldateien gespeichert werden"
+msgid "During delay ifup-events are not monitored !"
+msgstr "Während der Verzögerung werden 'ifup'-Ereignisse nicht überwacht!"
+
msgid "Enable HTTPS"
msgstr "Verwende HTTPS"
@@ -240,6 +250,9 @@ msgstr "Anzahl der Protokoll Backup Dateien, die angelegt werden."
msgid "OPTIONAL: See python's ssl module for available ciphers"
msgstr "OPTIONAL: Siehe Python SSL-Modul Dokumentation"
+msgid "One or more missing/invalid fields on tab"
+msgstr "Ein oder mehrere fehlende/ungültige Felder auf der Registerkarte"
+
msgid "Owner allow write, authenticated users allow read"
msgstr ""
"Besitzer haben Schreibrechte, Authentifizierten Benutzer dürfen nur lesen."
@@ -324,8 +337,14 @@ msgstr ""
"Wenn dieser Parameter auf '0' gesetzt wird, wird die Protokolldatei nicht "
"mehr rolliert!"
-msgid "Software package '"
-msgstr "Software Packet '"
+msgid "Software package '%s' is not installed."
+msgstr "Software Paket '%s' ist nicht installiert."
+
+msgid "Software package '%s' is outdated."
+msgstr "Software Paket '%s' ist nicht aktuell."
+
+msgid "Software update required"
+msgstr "Software-Update erforderlich"
msgid "Start"
msgstr "Start"
@@ -372,9 +391,15 @@ msgid "To view latest log file follow this link!"
msgstr ""
"Zur Anzeige der letzten Protokolldatei, folgen Sie dieser Verknüpfung !"
+msgid "Value is not a number"
+msgstr "Wert ist keine Zahl"
+
msgid "Value is not an Integer >= 0 !"
msgstr "Eingabe ist keine Ganzzahl >= 0 !"
+msgid "Value not between 0 and 300"
+msgstr "Wert nicht zwischen 0 und 300"
+
msgid "Value required ! Integer >= 0 !"
msgstr "Eingabe erforderlich ! Ganzzahl >= 0 !"
@@ -397,6 +422,8 @@ msgid ""
"You can also get groups from the user regex in the collection with {0}, {1}, "
"etc."
msgstr ""
+"Sie können auch Gruppen aus der Benutzer regex in der Sammlung mit {0}, {1} "
+"usw. bekommen."
msgid ""
"You can use Python's ConfigParser interpolation values %(login)s and "
@@ -416,6 +443,9 @@ msgstr "htpasswd Datei"
msgid "installed"
msgstr "installiert"
+msgid "no valid path given!"
+msgstr "Keine gültige Pfadangabe!"
+
msgid "or higher"
msgstr "oder höher"
@@ -427,9 +457,3 @@ msgstr "erforderlich"
msgid "salted SHA-1"
msgstr "Salted SHA-1"
-
-#~ msgid "File"
-#~ msgstr "Datei"
-
-#~ msgid "not found !"
-#~ msgstr "nicht gefunden !"
diff --git a/applications/luci-app-radicale/po/sv/radicale.po b/applications/luci-app-radicale/po/sv/radicale.po
index 3b141a2fe6..cf899d83fe 100644
--- a/applications/luci-app-radicale/po/sv/radicale.po
+++ b/applications/luci-app-radicale/po/sv/radicale.po
@@ -1,5 +1,15 @@
msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8\n"
+msgstr ""
+"Project-Id-Version: luci-app-radicale 1.1.0-1\n"
+"POT-Creation-Date: 2016-01-30 20:34+0100\n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.4\n"
msgid ""
"'AUTO' selects the highest protocol version that client and server support."
@@ -53,6 +63,9 @@ msgstr "Autentiseringsmetod för att tillåta åtkomst till Radicale-servern."
msgid "Auto-start"
msgstr "Starta automatiskt"
+msgid "Boot delay"
+msgstr ""
+
msgid "CalDAV/CardDAV"
msgstr "CalDAV/CardDAV"
@@ -98,6 +111,9 @@ msgstr "Databas"
msgid "Debug"
msgstr "Felsök"
+msgid "Delay (in seconds) during system boot before Radicale start"
+msgstr ""
+
msgid "Directory"
msgstr "Mapp"
@@ -110,6 +126,9 @@ msgstr "Mapp krävs !"
msgid "Directory where the rotating log-files are stored"
msgstr "Mappen där de roterade logg-filerna lagras"
+msgid "During delay ifup-events are not monitored !"
+msgstr ""
+
msgid "Enable HTTPS"
msgstr "Aktivera HTTPS"
@@ -209,6 +228,9 @@ msgstr ""
msgid "OPTIONAL: See python's ssl module for available ciphers"
msgstr "VALFRITT: Kolla in python's ssl-modul för tillgängliga chiffer"
+msgid "One or more missing/invalid fields on tab"
+msgstr ""
+
msgid "Owner allow write, authenticated users allow read"
msgstr ""
@@ -289,8 +311,14 @@ msgstr ""
"Genom att ställa in den här parametern till '0' så kommer du att stänga av "
"rotering av logg-fil."
-msgid "Software package '"
-msgstr "Mjukvaru-paket '"
+msgid "Software package '%s' is not installed."
+msgstr ""
+
+msgid "Software package '%s' is outdated."
+msgstr ""
+
+msgid "Software update required"
+msgstr ""
msgid "Start"
msgstr "Starta"
@@ -332,9 +360,15 @@ msgstr "Följ den här länken för att redigera den här filen!"
msgid "To view latest log file follow this link!"
msgstr "Följ den här länken för att visa den senaste logg-filen"
+msgid "Value is not a number"
+msgstr ""
+
msgid "Value is not an Integer >= 0 !"
msgstr "Värdet är inte ett heltal >= 0 !"
+msgid "Value not between 0 and 300"
+msgstr ""
+
msgid "Value required ! Integer >= 0 !"
msgstr "Värde krävs ! Heltal >= 0 !"
@@ -375,6 +409,9 @@ msgstr "htpasswd-fil"
msgid "installed"
msgstr "installerad"
+msgid "no valid path given!"
+msgstr ""
+
msgid "or higher"
msgstr "eller högre"
diff --git a/applications/luci-app-radicale/po/templates/radicale.pot b/applications/luci-app-radicale/po/templates/radicale.pot
index c5e079715f..1c01c4a176 100644
--- a/applications/luci-app-radicale/po/templates/radicale.pot
+++ b/applications/luci-app-radicale/po/templates/radicale.pot
@@ -53,6 +53,9 @@ msgstr ""
msgid "Auto-start"
msgstr ""
+msgid "Boot delay"
+msgstr ""
+
msgid "CalDAV/CardDAV"
msgstr ""
@@ -96,6 +99,9 @@ msgstr ""
msgid "Debug"
msgstr ""
+msgid "Delay (in seconds) during system boot before Radicale start"
+msgstr ""
+
msgid "Directory"
msgstr ""
@@ -108,6 +114,9 @@ msgstr ""
msgid "Directory where the rotating log-files are stored"
msgstr ""
+msgid "During delay ifup-events are not monitored !"
+msgstr ""
+
msgid "Enable HTTPS"
msgstr ""
@@ -207,6 +216,9 @@ msgstr ""
msgid "OPTIONAL: See python's ssl module for available ciphers"
msgstr ""
+msgid "One or more missing/invalid fields on tab"
+msgstr ""
+
msgid "Owner allow write, authenticated users allow read"
msgstr ""
@@ -284,7 +296,13 @@ msgstr ""
msgid "Setting this parameter to '0' will disable rotation of log-file."
msgstr ""
-msgid "Software package '"
+msgid "Software package '%s' is not installed."
+msgstr ""
+
+msgid "Software package '%s' is outdated."
+msgstr ""
+
+msgid "Software update required"
msgstr ""
msgid "Start"
@@ -327,9 +345,15 @@ msgstr ""
msgid "To view latest log file follow this link!"
msgstr ""
+msgid "Value is not a number"
+msgstr ""
+
msgid "Value is not an Integer >= 0 !"
msgstr ""
+msgid "Value not between 0 and 300"
+msgstr ""
+
msgid "Value required ! Integer >= 0 !"
msgstr ""
@@ -368,6 +392,9 @@ msgstr ""
msgid "installed"
msgstr ""
+msgid "no valid path given!"
+msgstr ""
+
msgid "or higher"
msgstr ""