Merge pull request #418 from chris5560/for-15.05
[for-15.05] luci-app-radicale: copied from master
This commit is contained in:
commit
8005ecb2b9
8 changed files with 1896 additions and 0 deletions
41
applications/luci-app-radicale/Makefile
Normal file
41
applications/luci-app-radicale/Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Copyright (C) 2008-2015 The LuCI Team <luci@lists.subsignal.org>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-radicale
|
||||
|
||||
# Version == major.minor.patch
|
||||
# increase "minor" on new functionality and "patch" on patches/optimization
|
||||
PKG_VERSION:=1.0.1
|
||||
|
||||
# Release == build
|
||||
# increase on changes of translation files
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
|
||||
|
||||
# LuCI specific settings
|
||||
LUCI_TITLE:=LuCI Support for Radicale CardDAV/CalDAV
|
||||
LUCI_DEPENDS:=+luci-mod-admin-full
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
# shown in make menuconfig <Help>
|
||||
help
|
||||
$(LUCI_TITLE)
|
||||
.
|
||||
!!! Package "radicale-py2" or "radicale-py3" needs to be !!!
|
||||
!!! installed sepearatly. There is no buildin dependency set !!!
|
||||
.
|
||||
Version: $(PKG_VERSION)-$(PKG_RELEASE)
|
||||
$(PKG_MAINTAINER)
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
195
applications/luci-app-radicale/luasrc/controller/radicale.lua
Normal file
195
applications/luci-app-radicale/luasrc/controller/radicale.lua
Normal file
|
@ -0,0 +1,195 @@
|
|||
-- Copyright 2014 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 I18N = require("luci.i18n") -- not globally avalible here
|
||||
local UTIL = require("luci.util")
|
||||
local SYS = require("luci.sys")
|
||||
|
||||
function index()
|
||||
entry( {"admin", "services", "radicale"}, alias("admin", "services", "radicale", "edit"), _("CalDAV/CardDAV"), 58)
|
||||
entry( {"admin", "services", "radicale", "edit"}, cbi("radicale") ).leaf = true
|
||||
entry( {"admin", "services", "radicale", "logview"}, call("_logread") ).leaf = true
|
||||
entry( {"admin", "services", "radicale", "startstop"}, call("_startstop") ).leaf = true
|
||||
entry( {"admin", "services", "radicale", "status"}, call("_status") ).leaf = true
|
||||
end
|
||||
|
||||
-- called by XHR.get from detail_logview.htm
|
||||
function _logread()
|
||||
-- read application settings
|
||||
local uci = UCI.cursor()
|
||||
local logfile = uci:get("radicale", "radicale", "logfile") or "/var/log/radicale"
|
||||
uci:unload("radicale")
|
||||
|
||||
local ldata=NXFS.readfile(logfile)
|
||||
if not ldata or #ldata == 0 then
|
||||
ldata="_nodata_"
|
||||
end
|
||||
HTTP.write(ldata)
|
||||
end
|
||||
|
||||
-- called by XHR.get from detail_startstop.htm
|
||||
function _startstop()
|
||||
local pid = get_pid()
|
||||
if pid > 0 then
|
||||
SYS.call("/etc/init.d/radicale stop")
|
||||
NX.nanosleep(1) -- sleep a second
|
||||
if NX.kill(pid, 0) then -- still running
|
||||
NX.kill(pid, 9) -- send SIGKILL
|
||||
end
|
||||
pid = 0
|
||||
else
|
||||
SYS.call("/etc/init.d/radicale start")
|
||||
NX.nanosleep(1) -- sleep a second
|
||||
pid = get_pid()
|
||||
if pid > 0 and not NX.kill(pid, 0) then
|
||||
pid = 0 -- process did not start
|
||||
end
|
||||
end
|
||||
HTTP.write(tostring(pid)) -- HTTP needs string not number
|
||||
end
|
||||
|
||||
-- called by XHR.poll from detail_startstop.htm
|
||||
function _status()
|
||||
local pid = get_pid()
|
||||
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><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")
|
||||
end
|
||||
function app_title_back()
|
||||
return [[</a><a href="]]
|
||||
.. DISP.build_url("admin", "services", "radicale")
|
||||
.. [[">]]
|
||||
.. I18N.translate("Radicale CalDAV/CardDAV Server")
|
||||
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
|
||||
end
|
||||
|
||||
-- all equal and not compare greater or lower then true
|
||||
return not (comp == "<" or comp == ">")
|
||||
end
|
||||
|
||||
-- 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()
|
||||
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)
|
||||
end
|
||||
if (fvalue ~= cvalue) then self.section.changed = true end
|
||||
else
|
||||
self:remove(section)
|
||||
self.section.changed = true
|
||||
end
|
||||
end
|
748
applications/luci-app-radicale/luasrc/model/cbi/radicale.lua
Normal file
748
applications/luci-app-radicale/luasrc/model/cbi/radicale.lua
Normal file
|
@ -0,0 +1,748 @@
|
|||
-- Copyright 2015 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
|
||||
|
||||
-- #################################################################################################
|
||||
-- takeover arguments if any -- ################################################
|
||||
-- then show/edit selected file
|
||||
if arg[1] then
|
||||
local argument = arg[1]
|
||||
local filename = ""
|
||||
|
||||
-- SimpleForm ------------------------------------------------
|
||||
local ft = SimpleForm("_text")
|
||||
ft.title = TOOLS.app_title_back()
|
||||
ft.description = TOOLS.app_description()
|
||||
ft.redirect = DISP.build_url("admin", "services", "radicale") .. "#cbi-radicale-" .. argument
|
||||
if argument == "logger" then
|
||||
ft.reset = false
|
||||
ft.submit = translate("Reload")
|
||||
local uci = UCI.cursor()
|
||||
filename = uci:get("radicale", "logger", "file_path") or "/var/log/radicale"
|
||||
uci:unload("radicale")
|
||||
filename = filename .. "/radicale"
|
||||
elseif argument == "auth" then
|
||||
ft.submit = translate("Save")
|
||||
filename = "/etc/radicale/users"
|
||||
elseif argument == "rights" then
|
||||
ft.submit = translate("Save")
|
||||
filename = "/etc/radicale/rights"
|
||||
else
|
||||
error("Invalid argument given as section")
|
||||
end
|
||||
if argument ~= "logger" and not NXFS.access(filename) then
|
||||
NXFS.writefile(filename, "")
|
||||
end
|
||||
|
||||
-- SimpleSection ---------------------------------------------
|
||||
local fs = ft:section(SimpleSection)
|
||||
if argument == "logger" then
|
||||
fs.title = translate("Log-file Viewer")
|
||||
fs.description = translate("Please press [Reload] button below to reread the file.")
|
||||
elseif argument == "auth" then
|
||||
fs.title = translate("Authentication")
|
||||
fs.description = translate("Place here the 'user:password' pairs for your users which should have access to Radicale.")
|
||||
.. [[<br /><strong>]]
|
||||
.. translate("Keep in mind to use the correct hashing algorithm !")
|
||||
.. [[</strong>]]
|
||||
else -- rights
|
||||
fs.title = translate("Rights")
|
||||
fs.description = translate("Authentication login is matched against the 'user' key, "
|
||||
.. "and collection's path is matched against the 'collection' key.") .. " "
|
||||
.. translate("You can use Python's ConfigParser interpolation values %(login)s and %(path)s.") .. " "
|
||||
.. translate("You can also get groups from the user regex in the collection with {0}, {1}, etc.")
|
||||
.. [[<br />]]
|
||||
.. translate("For example, for the 'user' key, '.+' means 'authenticated user'" .. " "
|
||||
.. "and '.*' means 'anybody' (including anonymous users).")
|
||||
.. [[<br />]]
|
||||
.. translate("Section names are only used for naming the rule.")
|
||||
.. [[<br />]]
|
||||
.. translate("Leading or ending slashes are trimmed from collection's path.")
|
||||
end
|
||||
|
||||
-- TextValue -------------------------------------------------
|
||||
local tt = fs:option(TextValue, "_textvalue")
|
||||
tt.rmempty = true
|
||||
if argument == "logger" then
|
||||
tt.readonly = true
|
||||
tt.rows = 30
|
||||
function tt.write()
|
||||
HTTP.redirect(DISP.build_url("admin", "services", "radicale", "edit", argument))
|
||||
end
|
||||
else
|
||||
tt.rows = 15
|
||||
function tt.write(self, section, value)
|
||||
if not value then value = "" end
|
||||
NXFS.writefile(filename, value:gsub("\r\n", "\n"))
|
||||
return true --HTTP.redirect(DISP.build_url("admin", "services", "radicale", "edit") .. "#cbi-radicale-" .. argument)
|
||||
end
|
||||
end
|
||||
|
||||
function tt.cfgvalue()
|
||||
return NXFS.readfile(filename) or
|
||||
string.format(translate("File '%s' not found !"), filename)
|
||||
end
|
||||
|
||||
return ft
|
||||
|
||||
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"> ]]
|
||||
.. translate("Software package '" .. TOOLS.service_name() .. "' is not installed.")
|
||||
.. [[</font><br /><br /> ]]
|
||||
.. translate("required") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_required()
|
||||
.. [[<br /><br /> ]]
|
||||
.. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
|
||||
.. translate("Please install current version !")
|
||||
.. [[</a><br /> </strong></h3>]]
|
||||
else
|
||||
v.value = [[<h3><strong><br /><font color="red"> ]]
|
||||
.. translate("Software package '" .. TOOLS.service_name() .. "' is outdated.")
|
||||
.. [[</font><br /><br /> ]]
|
||||
.. translate("installed") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_installed()
|
||||
.. [[<br /> ]]
|
||||
.. translate("required") .. [[: ]] .. TOOLS.service_name() .. [[ ]] .. TOOLS.service_required()
|
||||
.. [[<br /><br /> ]]
|
||||
.. [[<a href="]] .. DISP.build_url("admin", "system", "packages") ..[[">]]
|
||||
.. translate("Please update to current version !")
|
||||
.. [[</a><br /> </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()
|
||||
function m.commit_handler(self)
|
||||
if self.changed then -- changes ?
|
||||
os.execute("/etc/init.d/radicale reload &") -- reload configuration
|
||||
end
|
||||
end
|
||||
|
||||
-- cbi-section "System" -- #####################################################
|
||||
local sys = m:section( NamedSection, "_system" )
|
||||
sys.title = translate("System")
|
||||
sys.description = nil
|
||||
function sys.cfgvalue(self, section)
|
||||
return "_dummysection"
|
||||
end
|
||||
|
||||
-- start/stop button -----------------------------------------------------------
|
||||
local btn = sys:option(DummyValue, "_startstop")
|
||||
btn.template = "radicale/btn_startstop"
|
||||
btn.inputstyle = nil
|
||||
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)
|
||||
if pid > 0 then
|
||||
btn.inputtitle = "PID: " .. pid
|
||||
btn.inputstyle = "reset"
|
||||
btn.disabled = false
|
||||
else
|
||||
btn.inputtitle = translate("Start")
|
||||
btn.inputstyle = "apply"
|
||||
btn.disabled = false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- enabled ---------------------------------------------------------------------
|
||||
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
|
||||
function ena.cfgvalue(self, section)
|
||||
return (SYS.init.enabled("radicale")) and "1" or "0"
|
||||
end
|
||||
function ena.write(self, section, value)
|
||||
if value == "1" then
|
||||
return SYS.init.enable("radicale")
|
||||
else
|
||||
return SYS.init.disable("radicale")
|
||||
end
|
||||
end
|
||||
|
||||
-- cbi-section "Server" -- #####################################################
|
||||
local srv = m:section( NamedSection, "server", "setting" )
|
||||
srv.title = translate("Server")
|
||||
srv.description = nil
|
||||
function srv.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- hosts -----------------------------------------------------------------------
|
||||
local sh = srv:option( DynamicList, "hosts" )
|
||||
sh.title = translate("Address:Port")
|
||||
sh.description = translate("'Hostname:Port' or 'IPv4:Port' or '[IPv6]:Port' Radicale should listen on")
|
||||
.. [[<br /><strong>]]
|
||||
.. translate("Port numbers below 1024 (Privileged ports) are not supported")
|
||||
.. [[</strong>]]
|
||||
sh.placeholder = "0.0.0.0:5232"
|
||||
sh.rmempty = true
|
||||
|
||||
-- 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
|
||||
end
|
||||
function alm.validate(self, value)
|
||||
if value then
|
||||
return value
|
||||
else
|
||||
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
|
||||
self.map:del(section, "certificate") -- certificate
|
||||
self.map:del(section, "key") -- private key
|
||||
self.map:del(section, "ciphers") -- ciphers
|
||||
return self.map:del(section, self.option)
|
||||
else
|
||||
return self.map:set(section, self.option, value)
|
||||
end
|
||||
end
|
||||
|
||||
-- protocol --------------------------------------------------------------------
|
||||
local prt = srv:option( ListValue, "protocol" )
|
||||
prt.title = translate("SSL Protocol")
|
||||
prt.description = translate("'AUTO' selects the highest protocol version that client and server support.")
|
||||
prt.widget = "select"
|
||||
prt.default = "PROTOCOL_SSLv23"
|
||||
prt:depends ("ssl", "1")
|
||||
prt:value ("PROTOCOL_SSLv23", translate("AUTO"))
|
||||
prt:value ("PROTOCOL_SSLv2", "SSL v2")
|
||||
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")
|
||||
|
||||
-- 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
|
||||
end
|
||||
function crt.validate(self, value)
|
||||
local _ssl = ssl:formvalue(srv.section) or "0"
|
||||
if _ssl == "0" then
|
||||
return "" -- ignore if not https enabled
|
||||
end
|
||||
if value then -- otherwise errors in datatype check
|
||||
if DTYP.file(value) then
|
||||
return value
|
||||
else
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
-- key -------------------------------------------------------------------------
|
||||
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
|
||||
end
|
||||
function key.validate(self, value)
|
||||
local _ssl = ssl:formvalue(srv.section) or "0"
|
||||
if _ssl == "0" then
|
||||
return "" -- ignore if not https enabled
|
||||
end
|
||||
if value then -- otherwise errors in datatype check
|
||||
if DTYP.file(value) then
|
||||
return value
|
||||
else
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
-- ciphers ---------------------------------------------------------------------
|
||||
--local cip = srv:option( Value, "ciphers" )
|
||||
--cip.title = translate("Ciphers")
|
||||
--cip.description = translate("OPTIONAL: See python's ssl module for available ciphers")
|
||||
--cip.rmempty = true
|
||||
--cip:depends ("ssl", "1")
|
||||
|
||||
-- cbi-section "Authentication" -- #############################################
|
||||
local aut = m:section( NamedSection, "auth", "setting" )
|
||||
aut.title = translate("Authentication")
|
||||
aut.description = translate("Authentication method to allow access to Radicale server.")
|
||||
function aut.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- type -----------------------------------------------------------------------
|
||||
local aty = aut:option( ListValue, "type" )
|
||||
aty.title = translate("Authentication method")
|
||||
aty.description = nil
|
||||
aty.widget = "select"
|
||||
aty.default = "None"
|
||||
aty:value ("None", translate("None"))
|
||||
aty:value ("htpasswd", translate("htpasswd file"))
|
||||
--aty:value ("IMAP", "IMAP") -- The IMAP authentication module relies on the imaplib module.
|
||||
--aty:value ("LDAP", "LDAP") -- The LDAP authentication module relies on the python-ldap module.
|
||||
--aty:value ("PAM", "PAM") -- The PAM authentication module relies on the python-pam module.
|
||||
--aty:value ("courier", "courier")
|
||||
--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.write(self, section, value)
|
||||
if value ~= "htpasswd" then
|
||||
self.map:del(section, "htpasswd_encryption")
|
||||
elseif value ~= "IMAP" then
|
||||
self.map:del(section, "imap_hostname")
|
||||
self.map:del(section, "imap_port")
|
||||
self.map:del(section, "imap_ssl")
|
||||
end
|
||||
if value ~= self.default then
|
||||
return self.map:set(section, self.option, value)
|
||||
else
|
||||
return self.map:del(section, self.option)
|
||||
end
|
||||
end
|
||||
|
||||
-- htpasswd_encryption ---------------------------------------------------------
|
||||
local hte = aut:option( ListValue, "htpasswd_encryption" )
|
||||
hte.title = translate("Encryption method")
|
||||
hte.description = nil
|
||||
hte.widget = "select"
|
||||
hte.default = "crypt"
|
||||
hte:depends ("type", "htpasswd")
|
||||
hte:value ("crypt", translate("crypt"))
|
||||
hte:value ("plain", translate("plain"))
|
||||
hte:value ("sha1", translate("SHA-1"))
|
||||
hte:value ("ssha", translate("salted SHA-1"))
|
||||
|
||||
-- htpasswd_file (dummy) -------------------------------------------------------
|
||||
local htf = aut:option( DummyValue, "_htf" )
|
||||
htf.title = translate("htpasswd file")
|
||||
htf.description = [[<strong>]]
|
||||
.. translate("Read only!")
|
||||
.. [[</strong> ]]
|
||||
.. translate("Radicale uses '/etc/radicale/users' as htpasswd file.")
|
||||
.. [[<br /><a href="]]
|
||||
.. DISP.build_url("admin", "services", "radicale", "edit") .. [[/auth]]
|
||||
.. [[">]]
|
||||
.. 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()
|
||||
return "/etc/radicale/users"
|
||||
end
|
||||
|
||||
-- cbi-section "Rights" -- #####################################################
|
||||
local rig = m:section( NamedSection, "rights", "setting" )
|
||||
rig.title = translate("Rights")
|
||||
rig.description = translate("Control the access to data collections.")
|
||||
function rig.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- type -----------------------------------------------------------------------
|
||||
local rty = rig:option( ListValue, "type" )
|
||||
rty.title = translate("Rights backend")
|
||||
rty.description = nil
|
||||
rty.widget = "select"
|
||||
rty.default = "None"
|
||||
rty:value ("None", translate("Full access for everybody (including anonymous)"))
|
||||
rty:value ("authenticated", translate("Full access for authenticated Users") )
|
||||
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.write(self, section, value)
|
||||
if value ~= "custom" then
|
||||
self.map:del(section, "custom_handler")
|
||||
end
|
||||
if value ~= self.default then
|
||||
return self.map:set(section, self.option, value)
|
||||
else
|
||||
return self.map:del(section, self.option)
|
||||
end
|
||||
end
|
||||
|
||||
-- from_file (dummy) -----------------------------------------------------------
|
||||
local rtf = rig:option( DummyValue, "_rtf" )
|
||||
rtf.title = translate("RegExp file")
|
||||
rtf.description = [[<strong>]]
|
||||
.. translate("Read only!")
|
||||
.. [[</strong> ]]
|
||||
.. translate("Radicale uses '/etc/radicale/rights' as regexp-based file.")
|
||||
.. [[<br /><a href="]]
|
||||
.. DISP.build_url("admin", "services", "radicale", "edit") .. [[/rights]]
|
||||
.. [[">]]
|
||||
.. 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()
|
||||
return "/etc/radicale/rights"
|
||||
end
|
||||
|
||||
-- cbi-section "Storage" -- ####################################################
|
||||
local sto = m:section( NamedSection, "storage", "setting" )
|
||||
sto.title = translate("Storage")
|
||||
sto.description = nil
|
||||
function sto.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- type -----------------------------------------------------------------------
|
||||
local sty = sto:option( ListValue, "type" )
|
||||
sty.title = translate("Storage backend")
|
||||
sty.description = translate("WARNING: Only 'File-system' is documented and tested by Radicale development")
|
||||
sty.widget = "select"
|
||||
sty.default = "filesystem"
|
||||
sty:value ("filesystem", translate("File-system"))
|
||||
--sty:value ("multifilesystem", translate("") )
|
||||
--sty:value ("database", translate("Database") )
|
||||
--sty:value ("custom", translate("Custom") )
|
||||
function sty.write(self, section, value)
|
||||
if value ~= "filesystem" then
|
||||
self.map:del(section, "filesystem_folder")
|
||||
end
|
||||
if value ~= self.default then
|
||||
return self.map:set(section, self.option, value)
|
||||
else
|
||||
return self.map:del(section, self.option)
|
||||
end
|
||||
end
|
||||
|
||||
--filesystem_folder ------------------------------------------------------------
|
||||
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: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
|
||||
end
|
||||
function sfi.validate(self, value)
|
||||
local _typ = sty:formvalue(sto.section) or ""
|
||||
if _typ ~= "filesystem" then
|
||||
return "" -- ignore if not htpasswd
|
||||
end
|
||||
if value then -- otherwise errors in datatype check
|
||||
if DTYP.directory(value) then
|
||||
return value
|
||||
else
|
||||
return nil, self.title .. " - " .. translate("Directory not exists/found !")
|
||||
end
|
||||
else
|
||||
return nil, self.title .. " - " .. translate("Directory required !")
|
||||
end
|
||||
end
|
||||
|
||||
-- cbi-section "Logging" -- ####################################################
|
||||
local log = m:section( NamedSection, "logger", "logging" )
|
||||
log.title = translate("Logging")
|
||||
log.description = nil
|
||||
function log.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- console_level ---------------------------------------------------------------
|
||||
local lco = log:option( ListValue, "console_level" )
|
||||
lco.title = translate("Console Log level")
|
||||
lco.description = nil
|
||||
lco.widget = "select"
|
||||
lco.default = "ERROR"
|
||||
lco:value ("DEBUG", translate("Debug"))
|
||||
lco:value ("INFO", translate("Info") )
|
||||
lco:value ("WARNING", translate("Warning") )
|
||||
lco:value ("ERROR", translate("Error") )
|
||||
lco:value ("CRITICAL", translate("Critical") )
|
||||
function lco.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
|
||||
|
||||
-- syslog_level ----------------------------------------------------------------
|
||||
local lsl = log:option( ListValue, "syslog_level" )
|
||||
lsl.title = translate("Syslog Log level")
|
||||
lsl.description = nil
|
||||
lsl.widget = "select"
|
||||
lsl.default = "WARNING"
|
||||
lsl:value ("DEBUG", translate("Debug"))
|
||||
lsl:value ("INFO", translate("Info") )
|
||||
lsl:value ("WARNING", translate("Warning") )
|
||||
lsl:value ("ERROR", translate("Error") )
|
||||
lsl:value ("CRITICAL", translate("Critical") )
|
||||
function lsl.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
|
||||
|
||||
-- file_level ------------------------------------------------------------------
|
||||
local lfi = log:option( ListValue, "file_level" )
|
||||
lfi.title = translate("File Log level")
|
||||
lfi.description = nil
|
||||
lfi.widget = "select"
|
||||
lfi.default = "INFO"
|
||||
lfi:value ("DEBUG", translate("Debug"))
|
||||
lfi:value ("INFO", translate("Info") )
|
||||
lfi:value ("WARNING", translate("Warning") )
|
||||
lfi:value ("ERROR", translate("Error") )
|
||||
lfi:value ("CRITICAL", translate("Critical") )
|
||||
function lfi.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
|
||||
|
||||
-- file_path -------------------------------------------------------------------
|
||||
local lfp = log:option( Value, "file_path" )
|
||||
lfp.title = translate("Log-file directory")
|
||||
lfp.description = translate("Directory where the rotating log-files are stored")
|
||||
.. [[<br /><a href="]]
|
||||
.. DISP.build_url("admin", "services", "radicale", "edit") .. [[/logger]]
|
||||
.. [[">]]
|
||||
.. 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)
|
||||
end
|
||||
end
|
||||
|
||||
-- file_maxbytes ---------------------------------------------------------------
|
||||
local lmb = log:option( Value, "file_maxbytes" )
|
||||
lmb.title = translate("Log-file size")
|
||||
lmb.description = translate("Maximum size of each rotation log-file.")
|
||||
.. [[<br /><strong>]]
|
||||
.. translate("Setting this parameter to '0' will disable rotation of log-file.")
|
||||
.. [[</strong>]]
|
||||
lmb.default = "8196"
|
||||
lmb.rmempty = false
|
||||
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 !")
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
-- file_backupcount ------------------------------------------------------------
|
||||
local lbc = log:option( Value, "file_backupcount" )
|
||||
lbc.title = translate("Log-backup Count")
|
||||
lbc.description = translate("Number of backup files of log to create.")
|
||||
.. [[<br /><strong>]]
|
||||
.. translate("Setting this parameter to '0' will disable rotation of log-file.")
|
||||
.. [[</strong>]]
|
||||
lbc.default = "1"
|
||||
lbc.rmempty = false
|
||||
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 !")
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
-- cbi-section "Encoding" -- ###################################################
|
||||
local enc = m:section( NamedSection, "encoding", "setting" )
|
||||
enc.title = translate("Encoding")
|
||||
enc.description = translate("Change here the encoding Radicale will use instead of 'UTF-8' "
|
||||
.. "for responses to the client and/or to store data inside collections.")
|
||||
function enc.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- request ---------------------------------------------------------------------
|
||||
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
|
||||
|
||||
-- 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
|
||||
|
||||
-- cbi-section "Headers" -- ####################################################
|
||||
local hea = m:section( NamedSection, "headers", "setting" )
|
||||
hea.title = translate("Additional HTTP headers")
|
||||
hea.description = translate("Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts, JavaScript, etc.) "
|
||||
.. "on a web page to be requested from another domain outside the domain from which the resource originated.")
|
||||
function hea.cfgvalue(self, section)
|
||||
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
|
||||
|
||||
-- Access_Control_Allow_Origin -------------------------------------------------
|
||||
local heo = hea:option( DynamicList, "Access_Control_Allow_Origin" )
|
||||
heo.title = translate("Access-Control-Allow-Origin")
|
||||
heo.description = nil
|
||||
heo.default = "*"
|
||||
heo.optional = true
|
||||
|
||||
-- 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
|
||||
|
||||
-- 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
|
||||
|
||||
-- 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
|
||||
|
||||
return m
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
<!-- ++ BEGIN ++ Radicale ++ btn_startstop.htm ++ -->
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
// show XHR.poll/XHR.get response on button
|
||||
function _data2elements(x) {
|
||||
var btn = document.getElementById("cbid.radicale._system._startstop");
|
||||
if ( ! btn ) { return; } // security check
|
||||
if (x.responseText == "0") {
|
||||
btn.value = "<%:Start%>";
|
||||
btn.className = "cbi-button cbi-button-apply";
|
||||
btn.disabled = false;
|
||||
} else {
|
||||
btn.value = "PID: " + x.responseText;
|
||||
btn.className = "cbi-button cbi-button-reset";
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// event handler for start/stop button
|
||||
function onclick_startstop(id) {
|
||||
// do start/stop
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.get('<%=luci.dispatcher.build_url("admin", "services", "radicale", "startstop")%>', null,
|
||||
function(x) { _data2elements(x); }
|
||||
);
|
||||
}
|
||||
|
||||
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "radicale", "status")%>', null,
|
||||
function(x, data) { _data2elements(x); }
|
||||
);
|
||||
|
||||
//]]></script>
|
||||
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<% if self:cfgvalue(section) ~= false then
|
||||
-- We need to garantie that function cfgvalue run first to set missing parameters
|
||||
%>
|
||||
<!-- style="font-size: 100%;" needed for openwrt theme to fix font size -->
|
||||
<!-- type="button" onclick="..." enable standard onclick functionalty -->
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="font-size: 100%;" type="button" onclick="onclick_startstop(this.id)"
|
||||
<%=
|
||||
attr("name", section) .. attr("id", cbid) .. attr("value", self.inputtitle) .. ifattr(self.disabled, "disabled")
|
||||
%> />
|
||||
<% end %>
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
<!-- ++ END ++ Radicale ++ btn_startstop.htm ++ -->
|
|
@ -0,0 +1,35 @@
|
|||
<%+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%>
|
435
applications/luci-app-radicale/po/de/radicale.po
Normal file
435
applications/luci-app-radicale/po/de/radicale.po
Normal file
|
@ -0,0 +1,435 @@
|
|||
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"
|
||||
"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"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
|
||||
msgid ""
|
||||
"'AUTO' selects the highest protocol version that client and server support."
|
||||
msgstr ""
|
||||
"'AUTO' wählt die höchste Protokollversion, die Client und Server "
|
||||
"unterstützen."
|
||||
|
||||
msgid ""
|
||||
"'Hostname:Port' or 'IPv4:Port' or '[IPv6]:Port' Radicale should listen on"
|
||||
msgstr ""
|
||||
"'Hostname:Port' oder 'IPv4:Port' oder '[IPv6]:Port' die Radicale überwachen "
|
||||
"soll."
|
||||
|
||||
msgid "-- Please choose --"
|
||||
msgstr "-- Bitte auswählen --"
|
||||
|
||||
msgid "-- custom --"
|
||||
msgstr "-- benutzerdefiniert --"
|
||||
|
||||
msgid "AUTO"
|
||||
msgstr "AUTO"
|
||||
|
||||
msgid "Access-Control-Allow-Headers"
|
||||
msgstr "Access-Control-Allow-Headers"
|
||||
|
||||
msgid "Access-Control-Allow-Methods"
|
||||
msgstr "Access-Control-Allow-Methods"
|
||||
|
||||
msgid "Access-Control-Allow-Origin"
|
||||
msgstr "Access-Control-Allow-Origin"
|
||||
|
||||
msgid "Access-Control-Expose-Headers"
|
||||
msgstr "Access-Control-Expose-Headers"
|
||||
|
||||
msgid "Additional HTTP headers"
|
||||
msgstr "Zusätzliche HTTP headers"
|
||||
|
||||
msgid "Address:Port"
|
||||
msgstr "Adresse:Port"
|
||||
|
||||
msgid "Authentication"
|
||||
msgstr "Authentifizierung"
|
||||
|
||||
msgid ""
|
||||
"Authentication login is matched against the 'user' key, and collection's "
|
||||
"path is matched against the 'collection' key."
|
||||
msgstr ""
|
||||
"Der Login wird gegen die 'user' Schlüssel und die Pfadsammlung gegen die "
|
||||
"'collection' Schlüssel abgestimmt."
|
||||
|
||||
msgid "Authentication method"
|
||||
msgstr "Authentifizierungsmethode"
|
||||
|
||||
msgid "Authentication method to allow access to Radicale server."
|
||||
msgstr ""
|
||||
"Authentifizierungsmethode um den Zugang zum Radicale Server zu kontrollieren."
|
||||
|
||||
msgid "Auto-start"
|
||||
msgstr "Autostart"
|
||||
|
||||
msgid "CalDAV/CardDAV"
|
||||
msgstr "CalDAV/CardDAV"
|
||||
|
||||
msgid ""
|
||||
"Calendars and address books are available for both local and remote access, "
|
||||
"possibly limited through authentication policies."
|
||||
msgstr ""
|
||||
"Auf Kalender und Adressbücher kann sowohl Lokal als auch Remote zugegriffen "
|
||||
"werden, soweit nicht durch Authentifizierungsrichtlinien begrenzt."
|
||||
|
||||
msgid "Certificate file"
|
||||
msgstr "Zertifikat Datei"
|
||||
|
||||
msgid ""
|
||||
"Change here the encoding Radicale will use instead of 'UTF-8' for responses "
|
||||
"to the client and/or to store data inside collections."
|
||||
msgstr ""
|
||||
"Ändern Sie hier die Zeichenkodierung die Radicale anstelle von \"UTF-8\" für "
|
||||
"Antworten an den Client und/oder zum Speichern von Daten in einer Sammlung "
|
||||
"verwendet."
|
||||
|
||||
msgid "Ciphers"
|
||||
msgstr "Chiffren"
|
||||
|
||||
msgid "Console Log level"
|
||||
msgstr "Konsole Protokoll Level"
|
||||
|
||||
msgid "Control the access to data collections."
|
||||
msgstr "Kontrolliert den Zugriff auf die Daten Sammlungen."
|
||||
|
||||
msgid "Critical"
|
||||
msgstr "Kritisch"
|
||||
|
||||
msgid ""
|
||||
"Cross-origin resource sharing (CORS) is a mechanism that allows restricted "
|
||||
"resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from "
|
||||
"another domain outside the domain from which the resource originated."
|
||||
msgstr ""
|
||||
"Cross-Origin Resource Sharing (CORS) ist ein Mechanismus, um Webbrowsern "
|
||||
"oder auch anderen Webclients Cross-Origin-Requests zu ermöglichen."
|
||||
|
||||
msgid "Custom"
|
||||
msgstr "Benutzerdefiniert"
|
||||
|
||||
msgid "Database"
|
||||
msgstr "Datenbank"
|
||||
|
||||
msgid "Debug"
|
||||
msgstr "Debug"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr "Verzeichnis"
|
||||
|
||||
msgid "Directory not exists/found !"
|
||||
msgstr "Verzeichnis nicht gefunden / existiert nicht !"
|
||||
|
||||
msgid "Directory required !"
|
||||
msgstr "Verzeichnis benötigt !"
|
||||
|
||||
msgid "Directory where the rotating log-files are stored"
|
||||
msgstr ""
|
||||
"Verzeichnis in dem die rollierenden Protokolldateien gespeichert werden"
|
||||
|
||||
msgid "Enable HTTPS"
|
||||
msgstr "Verwende HTTPS"
|
||||
|
||||
msgid ""
|
||||
"Enable/Disable auto-start of Radicale on system start-up and interface events"
|
||||
msgstr ""
|
||||
"Aktiviert/Deaktiviert den Autostart von Radicale beim Systemstart und bei "
|
||||
"Schnittstellenereignissen."
|
||||
|
||||
msgid "Encoding"
|
||||
msgstr "Zeichenkodierung"
|
||||
|
||||
msgid "Encoding for responding requests."
|
||||
msgstr "Zeichenkodierung für die Beantwortung von Anfragen."
|
||||
|
||||
msgid "Encoding for storing local collections."
|
||||
msgstr "Zeichenkodierung für die Speicherung von lokalen Sammlungen."
|
||||
|
||||
msgid "Encryption method"
|
||||
msgstr "Verschlüsselungsmethode"
|
||||
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
msgid "File '%s' not found !"
|
||||
msgstr "Datei '%s' wurde nicht gefunden!"
|
||||
|
||||
msgid "File Log level"
|
||||
msgstr "Datei Protokoll Level"
|
||||
|
||||
msgid "File not found !"
|
||||
msgstr "Datei nicht gefunden !"
|
||||
|
||||
msgid "File-system"
|
||||
msgstr "Dateisystem"
|
||||
|
||||
msgid ""
|
||||
"For example, for the 'user' key, '.+' means 'authenticated user' and '.*' "
|
||||
"means 'anybody' (including anonymous users)."
|
||||
msgstr ""
|
||||
"Beispiel für den 'user' Schlüssel: '. +' bedeutet 'authentifizierten "
|
||||
"Benutzer' und '. *' bedeutet 'jeder' (einschließlich anonyme Benutzer)."
|
||||
|
||||
msgid "Full access for Owner only"
|
||||
msgstr "Voller Zugriff nur für den Besitzer"
|
||||
|
||||
msgid "Full access for authenticated Users"
|
||||
msgstr "Voller Zugriff für authentifizierte Benutzer"
|
||||
|
||||
msgid "Full access for everybody (including anonymous)"
|
||||
msgstr "Vollzugriff für jedermann (auch anonyme)"
|
||||
|
||||
msgid "Full path and file name of certificate"
|
||||
msgstr "Vollständiger Pfad und Dateiname der Zertifikat Datei"
|
||||
|
||||
msgid "Full path and file name of private key"
|
||||
msgstr "Vollständiger Pfad und Dateiname der Privaten Schlüsseldatei"
|
||||
|
||||
msgid "Info"
|
||||
msgstr "Informationen"
|
||||
|
||||
msgid "Keep in mind to use the correct hashing algorithm !"
|
||||
msgstr "Denken Sie daran, den korrekten Hash-Algorithmus zu verwenden!"
|
||||
|
||||
msgid "Leading or ending slashes are trimmed from collection's path."
|
||||
msgstr ""
|
||||
"Schrägstriche ('/') am Anfang und Ende der Pfadangabe der Sammlung werden "
|
||||
"von der Pfadangabe abgeschnitten."
|
||||
|
||||
msgid "Log-backup Count"
|
||||
msgstr "Protokoll Backup Zähler"
|
||||
|
||||
msgid "Log-file Viewer"
|
||||
msgstr "Protokolldatei Betrachter"
|
||||
|
||||
msgid "Log-file directory"
|
||||
msgstr "Protokoll-Datei Verzeichnis"
|
||||
|
||||
msgid "Log-file size"
|
||||
msgstr "Protokoll Dateigröße"
|
||||
|
||||
msgid "Logging"
|
||||
msgstr "Protokollierung"
|
||||
|
||||
msgid "Logon message"
|
||||
msgstr "Anmelde-Hinweis"
|
||||
|
||||
msgid "Maximum size of each rotation log-file."
|
||||
msgstr "Maximale Größe jeder rollierenden Protokoll-Datei."
|
||||
|
||||
msgid "Message displayed in the client when a password is needed."
|
||||
msgstr "Meldung im Client, wenn ein Kennwort erforderlich ist."
|
||||
|
||||
msgid "NOT installed"
|
||||
msgstr "nicht installiert"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
msgid "Number of backup files of log to create."
|
||||
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 "Owner allow write, authenticated users allow read"
|
||||
msgstr ""
|
||||
"Besitzer haben Schreibrechte, Authentifizierten Benutzer dürfen nur lesen."
|
||||
|
||||
msgid "Path/File required !"
|
||||
msgstr "Pfad/Datei erforderlich!"
|
||||
|
||||
msgid ""
|
||||
"Place here the 'user:password' pairs for your users which should have access "
|
||||
"to Radicale."
|
||||
msgstr ""
|
||||
"Speichern Sie hier die 'user: password' Paare für die Benutzer, die Zugriff "
|
||||
"auf Radicale haben sollte."
|
||||
|
||||
msgid "Please install current version !"
|
||||
msgstr "Installieren Sie bitte die aktuelle Version!"
|
||||
|
||||
msgid "Please press [Reload] button below to reread the file."
|
||||
msgstr ""
|
||||
"Bitte drücken Sie die [Neu laden]-Schaltfläche unten, um die Datei neu "
|
||||
"einzulesen."
|
||||
|
||||
msgid "Please update to current version !"
|
||||
msgstr "Aktualisieren Sie bitte auf die aktuelle Version!"
|
||||
|
||||
msgid "Port numbers below 1024 (Privileged ports) are not supported"
|
||||
msgstr "Port Nummern unter 1024 (Privileged Ports) werden nicht unterstützt."
|
||||
|
||||
msgid "Private key file"
|
||||
msgstr "Private Schlüssel Datei"
|
||||
|
||||
msgid "Radicale CalDAV/CardDAV Server"
|
||||
msgstr "Radicale CalDAV/CardDAV Dienst"
|
||||
|
||||
msgid "Radicale uses '/etc/radicale/rights' as regexp-based file."
|
||||
msgstr "Radicale verwendet '/etc/radicale/rights' als RegExp-basierte Datei."
|
||||
|
||||
msgid "Radicale uses '/etc/radicale/users' as htpasswd file."
|
||||
msgstr "Radicale verwendet 'etc/radicale/users' als htpasswd Datei."
|
||||
|
||||
msgid "Read only!"
|
||||
msgstr "Nur lesbar!"
|
||||
|
||||
msgid "RegExp file"
|
||||
msgstr "RegExp Datei"
|
||||
|
||||
msgid "Reload"
|
||||
msgstr "Neu laden"
|
||||
|
||||
msgid "Response Encoding"
|
||||
msgstr "Antwort Zeichenkodierung"
|
||||
|
||||
msgid "Reveal/hide password"
|
||||
msgstr "Passwort zeigen/verstecken"
|
||||
|
||||
msgid "Rights"
|
||||
msgstr "Zugriffsrechte"
|
||||
|
||||
msgid "Rights are based on a regexp-based file"
|
||||
msgstr "Zugriff basiert auf RegExp-basierter Datei."
|
||||
|
||||
msgid "Rights backend"
|
||||
msgstr "Zugagsverwaltung"
|
||||
|
||||
msgid "SHA-1"
|
||||
msgstr "SHA-1"
|
||||
|
||||
msgid "SSL Protocol"
|
||||
msgstr "SSL Protokol"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
msgid "Section names are only used for naming the rule."
|
||||
msgstr "Abschnittsnamen werden nur für die Benennung der Regel verwendet."
|
||||
|
||||
msgid "Server"
|
||||
msgstr "Server"
|
||||
|
||||
msgid "Setting this parameter to '0' will disable rotation of log-file."
|
||||
msgstr ""
|
||||
"Wenn dieser Parameter auf '0' gesetzt wird, wird die Protokolldatei nicht "
|
||||
"mehr rolliert!"
|
||||
|
||||
msgid "Software package '"
|
||||
msgstr "Software Packet '"
|
||||
|
||||
msgid "Start"
|
||||
msgstr "Start"
|
||||
|
||||
msgid "Start / Stop"
|
||||
msgstr "Start / Stopp"
|
||||
|
||||
msgid "Start/Stop Radicale server"
|
||||
msgstr "Start / Stopp Radicale Dienst"
|
||||
|
||||
msgid "Storage"
|
||||
msgstr "Datenspeicher"
|
||||
|
||||
msgid "Storage Encoding"
|
||||
msgstr "Datenspeicher Kodierung"
|
||||
|
||||
msgid "Storage backend"
|
||||
msgstr "Datenspeicher Verwaltung"
|
||||
|
||||
msgid "Syslog Log level"
|
||||
msgstr "Systemlog Level"
|
||||
|
||||
msgid "System"
|
||||
msgstr "System"
|
||||
|
||||
msgid ""
|
||||
"The Radicale Project is a complete CalDAV (calendar) and CardDAV (contact) "
|
||||
"server solution."
|
||||
msgstr ""
|
||||
"Das Raidcale Projekt bietet eine vollständige CalDAV (Kalender) und CardDAV "
|
||||
"(Adressbuch) Server Lösung."
|
||||
|
||||
msgid ""
|
||||
"They can be viewed and edited by calendar and contact clients on mobile "
|
||||
"phones or computers."
|
||||
msgstr ""
|
||||
"Diese können von Kalender- und Adressbuch-Anwendungen auf mobilen Endgeräten "
|
||||
"und Computern angezeigt und bearbeitet werden."
|
||||
|
||||
msgid "To edit the file follow this link!"
|
||||
msgstr "Um die Datei zu bearbeiten, folgend Sie dieser Verknüpfung!"
|
||||
|
||||
msgid "To view latest log file follow this link!"
|
||||
msgstr ""
|
||||
"Zur Anzeige der letzten Protokolldatei, folgen Sie dieser Verknüpfung !"
|
||||
|
||||
msgid "Value is not an Integer >= 0 !"
|
||||
msgstr "Eingabe ist keine Ganzzahl >= 0 !"
|
||||
|
||||
msgid "Value required ! Integer >= 0 !"
|
||||
msgstr "Eingabe erforderlich ! Ganzzahl >= 0 !"
|
||||
|
||||
msgid "Version"
|
||||
msgstr "Version"
|
||||
|
||||
msgid "Version Information"
|
||||
msgstr "Versionsinformationen"
|
||||
|
||||
msgid ""
|
||||
"WARNING: Only 'File-system' is documented and tested by Radicale development"
|
||||
msgstr ""
|
||||
"WARNUNG: Nur 'File-system' ist vom Radicale Entwicklerteam derzeit "
|
||||
"dokumentiert und getestet."
|
||||
|
||||
msgid "Warning"
|
||||
msgstr "Warnung"
|
||||
|
||||
msgid ""
|
||||
"You can also get groups from the user regex in the collection with {0}, {1}, "
|
||||
"etc."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"You can use Python's ConfigParser interpolation values %(login)s and "
|
||||
"%(path)s."
|
||||
msgstr ""
|
||||
"Sie können Python ConfigParser Werte '%(login)s' und '%(path)s' verwenden."
|
||||
|
||||
msgid "crypt"
|
||||
msgstr "crypt"
|
||||
|
||||
msgid "custom"
|
||||
msgstr "benutzerdefiniert"
|
||||
|
||||
msgid "htpasswd file"
|
||||
msgstr "htpasswd Datei"
|
||||
|
||||
msgid "installed"
|
||||
msgstr "installiert"
|
||||
|
||||
msgid "or higher"
|
||||
msgstr "oder höher"
|
||||
|
||||
msgid "plain"
|
||||
msgstr "unverschlüsselt"
|
||||
|
||||
msgid "required"
|
||||
msgstr "erforderlich"
|
||||
|
||||
msgid "salted SHA-1"
|
||||
msgstr "Salted SHA-1"
|
||||
|
||||
#~ msgid "File"
|
||||
#~ msgstr "Datei"
|
||||
|
||||
#~ msgid "not found !"
|
||||
#~ msgstr "nicht gefunden !"
|
381
applications/luci-app-radicale/po/templates/radicale.pot
Normal file
381
applications/luci-app-radicale/po/templates/radicale.pot
Normal file
|
@ -0,0 +1,381 @@
|
|||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid ""
|
||||
"'AUTO' selects the highest protocol version that client and server support."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"'Hostname:Port' or 'IPv4:Port' or '[IPv6]:Port' Radicale should listen on"
|
||||
msgstr ""
|
||||
|
||||
msgid "-- Please choose --"
|
||||
msgstr ""
|
||||
|
||||
msgid "-- custom --"
|
||||
msgstr ""
|
||||
|
||||
msgid "AUTO"
|
||||
msgstr ""
|
||||
|
||||
msgid "Access-Control-Allow-Headers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Access-Control-Allow-Methods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Access-Control-Allow-Origin"
|
||||
msgstr ""
|
||||
|
||||
msgid "Access-Control-Expose-Headers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Additional HTTP headers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Address:Port"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Authentication login is matched against the 'user' key, and collection's "
|
||||
"path is matched against the 'collection' key."
|
||||
msgstr ""
|
||||
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authentication method to allow access to Radicale server."
|
||||
msgstr ""
|
||||
|
||||
msgid "Auto-start"
|
||||
msgstr ""
|
||||
|
||||
msgid "CalDAV/CardDAV"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Calendars and address books are available for both local and remote access, "
|
||||
"possibly limited through authentication policies."
|
||||
msgstr ""
|
||||
|
||||
msgid "Certificate file"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Change here the encoding Radicale will use instead of 'UTF-8' for responses "
|
||||
"to the client and/or to store data inside collections."
|
||||
msgstr ""
|
||||
|
||||
msgid "Ciphers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Console Log level"
|
||||
msgstr ""
|
||||
|
||||
msgid "Control the access to data collections."
|
||||
msgstr ""
|
||||
|
||||
msgid "Critical"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Cross-origin resource sharing (CORS) is a mechanism that allows restricted "
|
||||
"resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from "
|
||||
"another domain outside the domain from which the resource originated."
|
||||
msgstr ""
|
||||
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
msgid "Database"
|
||||
msgstr ""
|
||||
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory not exists/found !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory required !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory where the rotating log-files are stored"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable HTTPS"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Enable/Disable auto-start of Radicale on system start-up and interface events"
|
||||
msgstr ""
|
||||
|
||||
msgid "Encoding"
|
||||
msgstr ""
|
||||
|
||||
msgid "Encoding for responding requests."
|
||||
msgstr ""
|
||||
|
||||
msgid "Encoding for storing local collections."
|
||||
msgstr ""
|
||||
|
||||
msgid "Encryption method"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
msgid "File '%s' not found !"
|
||||
msgstr ""
|
||||
|
||||
msgid "File Log level"
|
||||
msgstr ""
|
||||
|
||||
msgid "File not found !"
|
||||
msgstr ""
|
||||
|
||||
msgid "File-system"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"For example, for the 'user' key, '.+' means 'authenticated user' and '.*' "
|
||||
"means 'anybody' (including anonymous users)."
|
||||
msgstr ""
|
||||
|
||||
msgid "Full access for Owner only"
|
||||
msgstr ""
|
||||
|
||||
msgid "Full access for authenticated Users"
|
||||
msgstr ""
|
||||
|
||||
msgid "Full access for everybody (including anonymous)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Full path and file name of certificate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Full path and file name of private key"
|
||||
msgstr ""
|
||||
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
|
||||
msgid "Keep in mind to use the correct hashing algorithm !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Leading or ending slashes are trimmed from collection's path."
|
||||
msgstr ""
|
||||
|
||||
msgid "Log-backup Count"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log-file Viewer"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log-file directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Log-file size"
|
||||
msgstr ""
|
||||
|
||||
msgid "Logging"
|
||||
msgstr ""
|
||||
|
||||
msgid "Logon message"
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum size of each rotation log-file."
|
||||
msgstr ""
|
||||
|
||||
msgid "Message displayed in the client when a password is needed."
|
||||
msgstr ""
|
||||
|
||||
msgid "NOT installed"
|
||||
msgstr ""
|
||||
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
msgid "Number of backup files of log to create."
|
||||
msgstr ""
|
||||
|
||||
msgid "OPTIONAL: See python's ssl module for available ciphers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Owner allow write, authenticated users allow read"
|
||||
msgstr ""
|
||||
|
||||
msgid "Path/File required !"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Place here the 'user:password' pairs for your users which should have access "
|
||||
"to Radicale."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please install current version !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Please press [Reload] button below to reread the file."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please update to current version !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Port numbers below 1024 (Privileged ports) are not supported"
|
||||
msgstr ""
|
||||
|
||||
msgid "Private key file"
|
||||
msgstr ""
|
||||
|
||||
msgid "Radicale CalDAV/CardDAV Server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Radicale uses '/etc/radicale/rights' as regexp-based file."
|
||||
msgstr ""
|
||||
|
||||
msgid "Radicale uses '/etc/radicale/users' as htpasswd file."
|
||||
msgstr ""
|
||||
|
||||
msgid "Read only!"
|
||||
msgstr ""
|
||||
|
||||
msgid "RegExp file"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reload"
|
||||
msgstr ""
|
||||
|
||||
msgid "Response Encoding"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reveal/hide password"
|
||||
msgstr ""
|
||||
|
||||
msgid "Rights"
|
||||
msgstr ""
|
||||
|
||||
msgid "Rights are based on a regexp-based file"
|
||||
msgstr ""
|
||||
|
||||
msgid "Rights backend"
|
||||
msgstr ""
|
||||
|
||||
msgid "SHA-1"
|
||||
msgstr ""
|
||||
|
||||
msgid "SSL Protocol"
|
||||
msgstr ""
|
||||
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
msgid "Section names are only used for naming the rule."
|
||||
msgstr ""
|
||||
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Setting this parameter to '0' will disable rotation of log-file."
|
||||
msgstr ""
|
||||
|
||||
msgid "Software package '"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start / Stop"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start/Stop Radicale server"
|
||||
msgstr ""
|
||||
|
||||
msgid "Storage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Storage Encoding"
|
||||
msgstr ""
|
||||
|
||||
msgid "Storage backend"
|
||||
msgstr ""
|
||||
|
||||
msgid "Syslog Log level"
|
||||
msgstr ""
|
||||
|
||||
msgid "System"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The Radicale Project is a complete CalDAV (calendar) and CardDAV (contact) "
|
||||
"server solution."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"They can be viewed and edited by calendar and contact clients on mobile "
|
||||
"phones or computers."
|
||||
msgstr ""
|
||||
|
||||
msgid "To edit the file follow this link!"
|
||||
msgstr ""
|
||||
|
||||
msgid "To view latest log file follow this link!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Value is not an Integer >= 0 !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Value required ! Integer >= 0 !"
|
||||
msgstr ""
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Version Information"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"WARNING: Only 'File-system' is documented and tested by Radicale development"
|
||||
msgstr ""
|
||||
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"You can also get groups from the user regex in the collection with {0}, {1}, "
|
||||
"etc."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"You can use Python's ConfigParser interpolation values %(login)s and "
|
||||
"%(path)s."
|
||||
msgstr ""
|
||||
|
||||
msgid "crypt"
|
||||
msgstr ""
|
||||
|
||||
msgid "custom"
|
||||
msgstr ""
|
||||
|
||||
msgid "htpasswd file"
|
||||
msgstr ""
|
||||
|
||||
msgid "installed"
|
||||
msgstr ""
|
||||
|
||||
msgid "or higher"
|
||||
msgstr ""
|
||||
|
||||
msgid "plain"
|
||||
msgstr ""
|
||||
|
||||
msgid "required"
|
||||
msgstr ""
|
||||
|
||||
msgid "salted SHA-1"
|
||||
msgstr ""
|
12
applications/luci-app-radicale/root/etc/uci-defaults/luci-radicale
Executable file
12
applications/luci-app-radicale/root/etc/uci-defaults/luci-radicale
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# no longer needed for "Save and Apply" to restart radicale
|
||||
# luci-app-radicale calls /etc/init.d/radicale reload
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@radicale[-1]
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
|
||||
exit 0
|
Loading…
Reference in a new issue