Merge pull request #548 from chris5560/master
luci-app-ddns: rollup to 2.3.0 to reflect changes on ddns-scripts
This commit is contained in:
commit
1106b9346a
11 changed files with 739 additions and 413 deletions
|
@ -10,28 +10,43 @@ local NX = require "nixio"
|
|||
local NXFS = require "nixio.fs"
|
||||
local DISP = require "luci.dispatcher"
|
||||
local HTTP = require "luci.http"
|
||||
local UCI = require "luci.model.uci"
|
||||
local I18N = require "luci.i18n" -- not globally avalible here
|
||||
local IPKG = require "luci.model.ipkg"
|
||||
local SYS = require "luci.sys"
|
||||
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
||||
local UCI = require "luci.model.uci"
|
||||
local UTIL = require "luci.util"
|
||||
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
||||
|
||||
DDNS_MIN = "2.4.2-1" -- minimum version of service required
|
||||
local srv_name = "ddns-scripts"
|
||||
local srv_ver_min = "2.5.0" -- minimum version of service required
|
||||
local srv_ver_cmd = [[/usr/lib/ddns/dynamic_dns_updater.sh --version | awk {'print $2'}]]
|
||||
local app_name = "luci-app-ddns"
|
||||
local app_title = "Dynamic DNS"
|
||||
local app_version = "2.3.0-1"
|
||||
|
||||
function index()
|
||||
local nxfs = require "nixio.fs" -- global definitions not available
|
||||
local sys = require "luci.sys" -- in function index()
|
||||
local ddns = require "luci.tools.ddns" -- ddns multiused functions
|
||||
local verinst = ddns.ipkg_ver_installed("ddns-scripts")
|
||||
local verok = ddns.ipkg_ver_compare(verinst, ">=", "2.0.0-0")
|
||||
-- do NOT start it not ddns-scripts version 2.x
|
||||
if not verok then
|
||||
return
|
||||
end
|
||||
local muci = require "luci.model.uci"
|
||||
|
||||
-- no config create an empty one
|
||||
if not nxfs.access("/etc/config/ddns") then
|
||||
nxfs.writefile("/etc/config/ddns", "")
|
||||
end
|
||||
|
||||
-- preset new option "lookup_host" if not already defined
|
||||
local uci = muci.cursor()
|
||||
local commit = false
|
||||
uci:foreach("ddns", "service", function (s)
|
||||
if not s["lookup_host"] and s["domain"] then
|
||||
uci:set("ddns", s[".name"], "lookup_host", s["domain"])
|
||||
commit = true
|
||||
end
|
||||
end)
|
||||
if commit then uci:commit("ddns") end
|
||||
uci:unload("ddns")
|
||||
|
||||
entry( {"admin", "services", "ddns"}, cbi("ddns/overview"), _("Dynamic DNS"), 59)
|
||||
entry( {"admin", "services", "ddns", "detail"}, cbi("ddns/detail"), nil ).leaf = true
|
||||
entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints",
|
||||
|
@ -42,7 +57,60 @@ function index()
|
|||
entry( {"admin", "services", "ddns", "status"}, call("status") ).leaf = true
|
||||
end
|
||||
|
||||
-- function to read all sections status and return data array
|
||||
-- Application specific information functions
|
||||
function app_description()
|
||||
return I18N.translate("Dynamic DNS allows that your router can be reached with " ..
|
||||
"a fixed hostname while having a dynamically changing IP address.")
|
||||
.. [[<br />]]
|
||||
.. I18N.translate("OpenWrt Wiki") .. ": "
|
||||
.. [[<a href="http://wiki.openwrt.org/doc/howto/ddns.client" target="_blank">]]
|
||||
.. I18N.translate("DDNS Client Documentation") .. [[</a>]]
|
||||
.. " --- "
|
||||
.. [[<a href="http://wiki.openwrt.org/doc/uci/ddns" target="_blank">]]
|
||||
.. I18N.translate("DDNS Client Configuration") .. [[</a>]]
|
||||
end
|
||||
function app_title_back()
|
||||
return [[<a href="]]
|
||||
.. DISP.build_url("admin", "services", "ddns")
|
||||
.. [[">]]
|
||||
.. I18N.translate(app_title)
|
||||
.. [[</a>]]
|
||||
end
|
||||
|
||||
-- Standardized application/service functions
|
||||
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 service_version()
|
||||
local ver = nil
|
||||
IPKG.list_installed(srv_name, function(n, ver, d)
|
||||
-- nothing to do
|
||||
end
|
||||
)
|
||||
if not ver 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
|
||||
|
||||
-- internal function to read all sections status and return data array
|
||||
local function _get_status()
|
||||
local uci = UCI.cursor()
|
||||
local service = SYS.init.enabled("ddns") and 1 or 0
|
||||
|
@ -118,12 +186,12 @@ local function _get_status()
|
|||
end
|
||||
|
||||
-- try to get registered IP
|
||||
local domain = s["domain"] or "_nodomain_"
|
||||
local lookup_host = s["lookup_host"] or "_nolookup_"
|
||||
local dnsserver = s["dns_server"] or ""
|
||||
local force_ipversion = tonumber(s["force_ipversion"] or 0)
|
||||
local force_dnstcp = tonumber(s["force_dnstcp"] or 0)
|
||||
local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh]]
|
||||
command = command .. [[ get_registered_ip ]] .. domain .. [[ ]] .. use_ipv6 ..
|
||||
command = command .. [[ get_registered_ip ]] .. lookup_host .. [[ ]] .. use_ipv6 ..
|
||||
[[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
|
||||
local reg_ip = SYS.exec(command)
|
||||
if reg_ip == "" then
|
||||
|
@ -135,7 +203,7 @@ local function _get_status()
|
|||
section = section,
|
||||
enabled = enabled,
|
||||
iface = iface,
|
||||
domain = domain,
|
||||
lookup = lookup_host,
|
||||
reg_ip = reg_ip,
|
||||
pid = pid,
|
||||
datelast = datelast,
|
||||
|
@ -235,3 +303,4 @@ function status()
|
|||
HTTP.prepare_content("application/json")
|
||||
HTTP.write_json(data)
|
||||
end
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,18 +5,14 @@ local NX = require "nixio"
|
|||
local NXFS = require "nixio.fs"
|
||||
local DISP = require "luci.dispatcher"
|
||||
local SYS = require "luci.sys"
|
||||
local CTRL = require "luci.controller.ddns" -- this application's controller
|
||||
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
||||
|
||||
-- cbi-map definition -- #######################################################
|
||||
local m = Map("ddns")
|
||||
|
||||
m.title = [[<a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]]
|
||||
.. translate("Dynamic DNS") .. [[</a>]]
|
||||
|
||||
m.description = translate("Dynamic DNS allows that your router can be reached with " ..
|
||||
"a fixed hostname while having a dynamically changing IP address.")
|
||||
|
||||
m.redirect = DISP.build_url("admin", "services", "ddns")
|
||||
m.title = CTRL.app_title_back()
|
||||
m.description = CTRL.app_description()
|
||||
m.redirect = DISP.build_url("admin", "services", "ddns")
|
||||
|
||||
function m.commit_handler(self)
|
||||
if self.changed then -- changes ?
|
||||
|
@ -52,17 +48,7 @@ ali.description = translate("Non-public and by default blocked IP's") .. ":"
|
|||
.. "0/8, 10/8, 100.64/10, 127/8, 169.254/16, 172.16/12, 192.168/16"
|
||||
.. [[<br /><strong>IPv6: </strong>]]
|
||||
.. "::/32, f000::/4"
|
||||
ali.reempty = true
|
||||
ali.default = "0"
|
||||
function ali.parse(self, section)
|
||||
DDNS.flag_parse(self, section)
|
||||
end
|
||||
function ali.validate(self, value)
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
-- date_format -- #############################################################
|
||||
local df = ns:option(Value, "date_format")
|
||||
|
@ -71,7 +57,6 @@ df.description = [[<a href="http://www.cplusplus.com/reference/ctime/strftime/"
|
|||
.. translate("For supported codes look here")
|
||||
.. [[</a>]]
|
||||
df.template = "ddns/global_value"
|
||||
df.rmempty = true
|
||||
df.default = "%F %R"
|
||||
df.date_string = ""
|
||||
function df.cfgvalue(self, section)
|
||||
|
@ -80,55 +65,45 @@ function df.cfgvalue(self, section)
|
|||
self.date_string = DDNS.epoch2date(epoch, value)
|
||||
return value
|
||||
end
|
||||
function df.validate(self, value)
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
function df.parse(self, section, novld)
|
||||
DDNS.value_parse(self, section, novld)
|
||||
end
|
||||
|
||||
-- run_dir -- #################################################################
|
||||
local rd = ns:option(Value, "run_dir")
|
||||
rd.title = translate("Status directory")
|
||||
rd.description = translate("Directory contains PID and other status information for each running section")
|
||||
rd.rmempty = true
|
||||
rd.default = "/var/run/ddns"
|
||||
function rd.validate(self, value)
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
-- no need to validate. if empty default is used everything else created by dns-scripts
|
||||
function rd.parse(self, section, novld)
|
||||
DDNS.value_parse(self, section, novld)
|
||||
end
|
||||
|
||||
-- log_dir -- #################################################################
|
||||
local ld = ns:option(Value, "log_dir")
|
||||
ld.title = translate("Log directory")
|
||||
ld.description = translate("Directory contains Log files for each running section")
|
||||
ld.rmempty = true
|
||||
ld.default = "/var/log/ddns"
|
||||
function ld.validate(self, value)
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
-- no need to validate. if empty default is used everything else created by dns-scripts
|
||||
function ld.parse(self, section, novld)
|
||||
DDNS.value_parse(self, section, novld)
|
||||
end
|
||||
|
||||
-- log_lines -- ###############################################################
|
||||
local ll = ns:option(Value, "log_lines")
|
||||
ll.title = translate("Log length")
|
||||
ll.description = translate("Number of last lines stored in log files")
|
||||
ll.rmempty = true
|
||||
ll.default = "250"
|
||||
function ll.validate(self, value)
|
||||
local n = tonumber(value)
|
||||
if not n or math.floor(n) ~= n or n < 1 then
|
||||
return nil, self.title .. ": " .. translate("minimum value '1'")
|
||||
end
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
end
|
||||
function ll.parse(self, section, novld)
|
||||
DDNS.value_parse(self, section, novld)
|
||||
end
|
||||
|
||||
-- use_curl -- ################################################################
|
||||
if (SYS.call([[ grep -i "\+ssl" /usr/bin/wget >/dev/null 2>&1 ]]) == 0)
|
||||
|
@ -139,17 +114,7 @@ and NXFS.access("/usr/bin/curl") then
|
|||
.. [[<br />]]
|
||||
.. translate("To use cURL activate this option.")
|
||||
pc.orientation = "horizontal"
|
||||
pc.rmempty = true
|
||||
pc.default = "0"
|
||||
function pc.parse(self, section)
|
||||
DDNS.flag_parse(self, section)
|
||||
end
|
||||
function pc.validate(self, value)
|
||||
if value == self.default then
|
||||
return "" -- default = empty
|
||||
end
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
-- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local CTRL = require "luci.controller.ddns" -- this application's controller
|
||||
local DISP = require "luci.dispatcher"
|
||||
local SYS = require "luci.sys"
|
||||
local CTRL = require "luci.controller.ddns" -- this application's controller
|
||||
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
||||
|
||||
-- check supported options -- ##################################################
|
||||
|
@ -11,8 +11,6 @@ local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
|||
has_ssl = DDNS.check_ssl() -- HTTPS support and --bind-network / --interface
|
||||
has_proxy = DDNS.check_proxy() -- Proxy support
|
||||
has_dnstcp = DDNS.check_bind_host() -- DNS TCP support
|
||||
-- correct ddns-scripts version
|
||||
need_update = DDNS.ipkg_ver_compare(DDNS.ipkg_ver_installed("ddns-scripts"), "<<", CTRL.DDNS_MIN)
|
||||
|
||||
-- html constants
|
||||
font_red = [[<font color="red">]]
|
||||
|
@ -22,15 +20,9 @@ bold_off = [[</strong>]]
|
|||
|
||||
-- cbi-map definition -- #######################################################
|
||||
m = Map("ddns")
|
||||
|
||||
m.title = [[<a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]] ..
|
||||
translate("Dynamic DNS") .. [[</a>]]
|
||||
|
||||
m.description = translate("Dynamic DNS allows that your router can be reached with " ..
|
||||
"a fixed hostname while having a dynamically changing " ..
|
||||
"IP address.")
|
||||
|
||||
m.redirect = DISP.build_url("admin", "services", "ddns")
|
||||
m.title = CTRL.app_title_back()
|
||||
m.description = CTRL.app_description()
|
||||
m.redirect = DISP.build_url("admin", "services", "ddns")
|
||||
|
||||
-- SimpleSection definition -- #################################################
|
||||
-- show Hints to optimize installation and script usage
|
||||
|
@ -39,7 +31,7 @@ s = m:section( SimpleSection,
|
|||
translate("Below a list of configuration tips for your system to run Dynamic DNS updates without limitations") )
|
||||
|
||||
-- ddns_scripts needs to be updated for full functionality
|
||||
if need_update then
|
||||
if not CTRL.service_ok() then
|
||||
local dv = s:option(DummyValue, "_update_needed")
|
||||
dv.titleref = DISP.build_url("admin", "system", "packages")
|
||||
dv.rawhtml = true
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local NXFS = require "nixio.fs"
|
||||
local CTRL = require "luci.controller.ddns" -- this application's controller
|
||||
local DISP = require "luci.dispatcher"
|
||||
local HTTP = require "luci.http"
|
||||
local SYS = require "luci.sys"
|
||||
local CTRL = require "luci.controller.ddns" -- this application's controller
|
||||
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
|
||||
|
||||
-- show hints ?
|
||||
|
@ -15,7 +15,7 @@ show_hints = not (DDNS.check_ipv6() -- IPv6 support
|
|||
and DDNS.check_bind_host() -- DNS TCP support
|
||||
)
|
||||
-- correct ddns-scripts version
|
||||
need_update = DDNS.ipkg_ver_compare(DDNS.ipkg_ver_installed("ddns-scripts"), "<<", CTRL.DDNS_MIN)
|
||||
need_update = not CTRL.service_ok()
|
||||
|
||||
-- html constants
|
||||
font_red = [[<font color="red">]]
|
||||
|
@ -25,22 +25,8 @@ bold_off = [[</strong>]]
|
|||
|
||||
-- cbi-map definition -- #######################################################
|
||||
m = Map("ddns")
|
||||
|
||||
m.title = [[<a href="javascript:alert(']]
|
||||
.. translate("Version Information")
|
||||
.. [[\n\nluci-app-ddns]]
|
||||
.. [[\n\t]] .. translate("Version") .. [[:\t]] .. DDNS.ipkg_ver_installed("luci-app-ddns")
|
||||
.. [[\n\nddns-scripts ]] .. translate("required") .. [[:]]
|
||||
.. [[\n\t]] .. translate("Version") .. [[:\t]] .. CTRL.DDNS_MIN .. [[ ]] .. translate("or higher")
|
||||
.. [[\n\nddns-scripts ]] .. translate("installed") .. [[:]]
|
||||
.. [[\n\t]] .. translate("Version") .. [[:\t]] .. DDNS.ipkg_ver_installed("ddns-scripts")
|
||||
.. [[\n\n]]
|
||||
.. [[')">]]
|
||||
.. translate("Dynamic DNS") .. [[</a>]]
|
||||
|
||||
m.description = translate("Dynamic DNS allows that your router can be reached with " ..
|
||||
"a fixed hostname while having a dynamically changing " ..
|
||||
"IP address.")
|
||||
m.title = CTRL.app_title_main()
|
||||
m.description = CTRL.app_description()
|
||||
|
||||
m.on_after_commit = function(self)
|
||||
if self.changed then -- changes ?
|
||||
|
@ -122,21 +108,21 @@ function ts.create(self, name)
|
|||
HTTP.redirect( self.extedit:format(name) )
|
||||
end
|
||||
|
||||
-- Domain and registered IP -- #################################################
|
||||
dom = ts:option(DummyValue, "_domainIP",
|
||||
translate("Hostname/Domain") .. "<br />" .. translate("Registered IP") )
|
||||
-- Lookup_Host and registered IP -- #################################################
|
||||
dom = ts:option(DummyValue, "_lookupIP",
|
||||
translate("Lookup Hostname") .. "<br />" .. translate("Registered IP") )
|
||||
dom.template = "ddns/overview_doubleline"
|
||||
function dom.set_one(self, section)
|
||||
local domain = self.map:get(section, "domain") or ""
|
||||
if domain ~= "" then
|
||||
return domain
|
||||
local lookup = self.map:get(section, "lookup_host") or ""
|
||||
if lookup ~= "" then
|
||||
return lookup
|
||||
else
|
||||
return [[<em>]] .. translate("config error") .. [[</em>]]
|
||||
end
|
||||
end
|
||||
function dom.set_two(self, section)
|
||||
local domain = self.map:get(section, "domain") or ""
|
||||
if domain == "" then return "" end
|
||||
local lookup = self.map:get(section, "lookup_host") or ""
|
||||
if lookup == "" then return "" end
|
||||
local dnsserver = self.map:get(section, "dnsserver") or ""
|
||||
local use_ipv6 = tonumber(self.map:get(section, "use_ipv6") or 0)
|
||||
local force_ipversion = tonumber(self.map:get(section, "force_ipversion") or 0)
|
||||
|
@ -145,7 +131,7 @@ function dom.set_two(self, section)
|
|||
if not NXFS.access(command, "rwx", "rx", "rx") then
|
||||
NXFS.chmod(command, 755)
|
||||
end
|
||||
command = command .. [[ get_registered_ip ]] .. domain .. [[ ]] .. use_ipv6 ..
|
||||
command = command .. [[ get_registered_ip ]] .. lookup .. [[ ]] .. use_ipv6 ..
|
||||
[[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
|
||||
local ip = SYS.exec(command)
|
||||
if ip == "" then ip = translate("no data") end
|
||||
|
@ -157,9 +143,6 @@ ena = ts:option( Flag, "enabled",
|
|||
translate("Enabled"))
|
||||
ena.template = "ddns/overview_enabled"
|
||||
ena.rmempty = false
|
||||
function ena.parse(self, section)
|
||||
DDNS.flag_parse(self, section)
|
||||
end
|
||||
|
||||
-- show PID and next update
|
||||
upd = ts:option( DummyValue, "_update",
|
||||
|
|
|
@ -96,58 +96,6 @@ function get_pid(section)
|
|||
return pid
|
||||
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 = nil
|
||||
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 read of UCI option
|
||||
-- modified AbstractValue.cfgvalue(self, section) from cbi.lua
|
||||
-- needed to read from other option then current value definition
|
||||
|
@ -172,24 +120,77 @@ function read_value(self, section, option)
|
|||
end
|
||||
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)
|
||||
-- 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 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)
|
||||
-- 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 (fvalue ~= cvalue) then self.section.changed = true end
|
||||
else
|
||||
self:remove(section)
|
||||
if eq_cfg then
|
||||
fvalue = cvalue
|
||||
end
|
||||
end
|
||||
|
||||
-- removed parameter "section" from function call because used/accepted nowhere
|
||||
-- also removed call to function "transfer"
|
||||
local vvalue, errtxt = self:validate(fvalue)
|
||||
|
||||
-- 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
|
||||
end
|
||||
end
|
||||
-- for whatever reason errtxt set and not handled above
|
||||
assert( not (errtxt and (#errtxt > 0)), "unhandled validate error" )
|
||||
|
||||
-- lets continue with value returned from validate
|
||||
eq_cfg = ( vvalue == cvalue ) -- update equal_config flag
|
||||
local vexist = ( vvalue and (#vvalue > 0) ) -- not "nil" and "not empty"
|
||||
local eq_def = ( vvalue == self.default ) -- equal_default flag
|
||||
|
||||
-- not forcewrite and (rmempty or optional)
|
||||
-- and (no data or equal_default)
|
||||
if not self.forcewrite and 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
|
||||
return
|
||||
end
|
||||
|
||||
-- not forcewrite and no changes, so nothing to write
|
||||
if not self.forcewrite and eq_cfg then
|
||||
return
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
var txt = document.getElementById("cbid.ddns." + section + "._logview.txt"); // TextArea
|
||||
if ( !txt ) { return; } // security check
|
||||
|
||||
XHR.get('<%=url('admin/services/ddns/logview')%>/' + section, null,
|
||||
XHR.get('<%=url([[admin]], [[services]], [[ddns]], [[logview]])%>/' + section, null,
|
||||
function(x) {
|
||||
if (x.responseText == "_nodata_")
|
||||
txt.value = "<%:File not found or empty%>";
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
var section = data[i].section // Section to handle
|
||||
var cbx = document.getElementById("cbid.ddns." + section + ".enabled"); // Enabled
|
||||
var btn = document.getElementById("cbid.ddns." + section + "._startstop"); // Start/Stop button
|
||||
var rip = document.getElementById("cbid.ddns." + section + "._domainIP.two"); // Registered IP
|
||||
var rip = document.getElementById("cbid.ddns." + section + "._lookupIP.two"); // Registered IP
|
||||
var lup = document.getElementById("cbid.ddns." + section + "._update.one"); // Last Update
|
||||
var nup = document.getElementById("cbid.ddns." + section + "._update.two"); // Next Update
|
||||
if ( !(cbx && btn && rip && lup && nup) ) { return; } // security check
|
||||
|
@ -76,12 +76,12 @@
|
|||
break;
|
||||
}
|
||||
|
||||
// domain
|
||||
// (data[i].domain ignored here
|
||||
// lookup
|
||||
// (data[i].lookup ignored here
|
||||
|
||||
// registered IP
|
||||
// rip.innerHTML = "Registered IP";
|
||||
if (data[i].domain == "_nodomain_")
|
||||
if (data[i].lookup == "_nolookup_")
|
||||
rip.innerHTML = '';
|
||||
else if (data[i].reg_ip == "_nodata_")
|
||||
rip.innerHTML = '<em><%:No data%></em>';
|
||||
|
@ -136,7 +136,7 @@
|
|||
|
||||
// do start/stop
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.post('<%=url('admin/services/ddns/startstop')%>/' + section + '/' + cbx.checked, { token: '<%=token%>' },
|
||||
btnXHR.post('<%=url([[admin]], [[services]], [[ddns]], [[startstop]])%>/' + section + '/' + cbx.checked, { token: '<%=token%>' },
|
||||
function(x, data) {
|
||||
if (x.responseText == "_uncommitted_") {
|
||||
// we need a trick to display Ampersand "&" in stead of "&" or "&"
|
||||
|
@ -155,7 +155,7 @@
|
|||
}
|
||||
|
||||
// force to immediate show status on page load (not waiting for XHR.poll)
|
||||
XHR.get('<%=url('admin/services/ddns/status')%>', null,
|
||||
XHR.get('<%=url([[admin]], [[services]], [[ddns]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
if (data) { _data2elements(data); }
|
||||
}
|
||||
|
@ -164,7 +164,7 @@
|
|||
// define only ONE XHR.poll in a page because if one is running it blocks the other one
|
||||
// optimum is to define on Map or Section Level from here you can reach all elements
|
||||
// we need update every 15 seconds only
|
||||
XHR.poll(15, '<%=url('admin/services/ddns/status')%>', null,
|
||||
XHR.poll(5, '<%=url([[admin]], [[services]], [[ddns]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
if (data) { _data2elements(data); }
|
||||
}
|
||||
|
|
|
@ -69,15 +69,15 @@
|
|||
break;
|
||||
}
|
||||
|
||||
// domain
|
||||
if (data[j].domain == "_nodomain_")
|
||||
// lookup
|
||||
if (data[j].lookup == "_nolookup_")
|
||||
tr.insertCell(-1).innerHTML = '<em><%:config error%></em>';
|
||||
else
|
||||
tr.insertCell(-1).innerHTML = data[j].domain;
|
||||
tr.insertCell(-1).innerHTML = data[j].lookup;
|
||||
|
||||
// registered IP
|
||||
switch (data[j].reg_ip) {
|
||||
case "_nodomain_":
|
||||
case "_nolookup_":
|
||||
tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
|
||||
break;
|
||||
case "_nodata_":
|
||||
|
@ -111,13 +111,13 @@
|
|||
}
|
||||
|
||||
// force to immediate show status (not waiting for XHR.poll)
|
||||
XHR.get('<%=url('admin/services/ddns/status')%>', null,
|
||||
XHR.get('<%=url([[admin]], [[services]], [[ddns]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
if (data) { _data2elements(x, data); }
|
||||
}
|
||||
);
|
||||
|
||||
XHR.poll(5, '<%=url('admin/services/ddns/status')%>', null,
|
||||
XHR.poll(15, '<%=url([[admin]], [[services]], [[ddns]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
if (data) { _data2elements(x, data); }
|
||||
}
|
||||
|
@ -132,7 +132,7 @@
|
|||
<tr class="cbi-section-table-titles">
|
||||
<th class="cbi-section-table-cell"><%:Configuration%></th>
|
||||
<th class="cbi-section-table-cell"><%:Next Update%></th>
|
||||
<th class="cbi-section-table-cell"><%:Hostname/Domain%></th>
|
||||
<th class="cbi-section-table-cell"><%:Lookup Hostname%></th>
|
||||
<th class="cbi-section-table-cell"><%:Registered IP%></th>
|
||||
<th class="cbi-section-table-cell"><%:Network%></th>
|
||||
</tr>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: luci-app-ddns\n"
|
||||
"POT-Creation-Date: 2015-05-08 21:29+0100\n"
|
||||
"PO-Revision-Date: 2015-05-08 21:47+0100\n"
|
||||
"POT-Creation-Date: 2015-11-04 19:10-0100\n"
|
||||
"PO-Revision-Date: 2015-11-14 18:31+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"
|
||||
"X-Generator: Poedit 1.8.6\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
|
@ -70,6 +70,9 @@ msgstr ""
|
|||
msgid "Casual users should not change this setting"
|
||||
msgstr "Standard Benutzer sollten diese Einstellung nicht ändern."
|
||||
|
||||
msgid "Change provider"
|
||||
msgstr "Anbieter wechseln"
|
||||
|
||||
msgid "Check Interval"
|
||||
msgstr "Prüfinterval"
|
||||
|
||||
|
@ -125,6 +128,12 @@ msgstr "Eigenes Update-Skript"
|
|||
msgid "DDNS Autostart disabled"
|
||||
msgstr "DDNS Autostart deaktiviert"
|
||||
|
||||
msgid "DDNS Client Configuration"
|
||||
msgstr "DDNS Client Konfiguration"
|
||||
|
||||
msgid "DDNS Client Documentation"
|
||||
msgstr "DDNS Client Dokumentation"
|
||||
|
||||
msgid "DDNS Service provider"
|
||||
msgstr "DDNS-Dienstanbieter"
|
||||
|
||||
|
@ -196,6 +205,9 @@ msgstr ""
|
|||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
msgid "Domain"
|
||||
msgstr "Domäne"
|
||||
|
||||
msgid "Dynamic DNS"
|
||||
msgstr "Dynamisches DNS"
|
||||
|
||||
|
@ -284,8 +296,10 @@ msgstr "HTTPS nicht unterstützt"
|
|||
msgid "Hints"
|
||||
msgstr "Hinweise"
|
||||
|
||||
msgid "Hostname/Domain"
|
||||
msgstr "Rechnername/Domäne"
|
||||
msgid "Hostname/FQDN to validate, if IP update happen or necessary"
|
||||
msgstr ""
|
||||
"Hostname/FQDN um zu überprüfen, ob eine Aktualisierung stattgefunden hat "
|
||||
"oder notwendig ist"
|
||||
|
||||
msgid "IP address source"
|
||||
msgstr "IP-Adressquelle"
|
||||
|
@ -385,6 +399,12 @@ msgstr "Protokoll in Datei schreiben"
|
|||
msgid "Log to syslog"
|
||||
msgstr "Systemprotokoll verwenden"
|
||||
|
||||
msgid "Lookup Hostname"
|
||||
msgstr "Nachschlage-Hostname"
|
||||
|
||||
msgid "NOT installed"
|
||||
msgstr "NICHT installiert"
|
||||
|
||||
msgid ""
|
||||
"Neither GNU Wget with SSL nor cURL installed to select a network to use for "
|
||||
"communication."
|
||||
|
@ -454,6 +474,21 @@ msgstr ""
|
|||
msgid "On Error the script will stop execution after given number of retrys"
|
||||
msgstr "Das Skript wird nach der gegebenen Anzahl von Fehlversuchen beendet."
|
||||
|
||||
msgid "OpenWrt Wiki"
|
||||
msgstr "OpenWrt Wiki"
|
||||
|
||||
msgid "Optional Encoded Parameter"
|
||||
msgstr "Optionaler codierten Parameter"
|
||||
|
||||
msgid "Optional Parameter"
|
||||
msgstr "Optionaler Parameter"
|
||||
|
||||
msgid "Optional: Replaces [PARAMENC] in Update-URL (URL-encoded)"
|
||||
msgstr "Optional: Ersetzt [PARAMENC] in der Update-URL (URL-codiert)"
|
||||
|
||||
msgid "Optional: Replaces [PARAMOPT] in Update-URL (NOT URL-encoded)"
|
||||
msgstr "Optional: Ersetzt [PARAMENC] in der Update-URL (NICHT URL-codiert)"
|
||||
|
||||
msgid "Overview"
|
||||
msgstr "Übersicht"
|
||||
|
||||
|
@ -484,17 +519,20 @@ msgstr "Prozess ID"
|
|||
msgid "Read / Reread log file"
|
||||
msgstr "Protokolldatei (neu) einlesen"
|
||||
|
||||
msgid "Really change DDNS provider?"
|
||||
msgstr "Wirklich DDNS-Anbieter wechseln?"
|
||||
|
||||
msgid "Registered IP"
|
||||
msgstr "Registrierte IP"
|
||||
|
||||
msgid "Replaces [DOMAIN] in Update-URL"
|
||||
msgstr "Ersetzt [DOMAIN] in der Update-URL"
|
||||
|
||||
msgid "Replaces [PASSWORD] in Update-URL"
|
||||
msgstr "Ersetzt [PASSWORD] in der Update-URL"
|
||||
msgid "Replaces [PASSWORD] in Update-URL (URL-encoded)"
|
||||
msgstr "Ersetzt [PASSWORD] in der Update-URL (URL-codiert)"
|
||||
|
||||
msgid "Replaces [USERNAME] in Update-URL"
|
||||
msgstr "Ersetzt [USERNAME] in der Update-URL"
|
||||
msgid "Replaces [USERNAME] in Update-URL (URL-encoded)"
|
||||
msgstr "Ersetzt [USERNAME] in der Update-URL (URL-codiert)"
|
||||
|
||||
msgid "Run once"
|
||||
msgstr "Einmalig ausführen"
|
||||
|
@ -528,7 +566,7 @@ msgstr ""
|
|||
"Optionen."
|
||||
|
||||
msgid "The default setting of '0' will retry infinite."
|
||||
msgstr "Der Standard-Wert von '0' wird es endlosen erneut versuchen."
|
||||
msgstr "Beim Standard-Wert von '0' wird es endlos erneut versucht."
|
||||
|
||||
msgid "There is no service configured."
|
||||
msgstr "Kein Dienst konfiguriert"
|
||||
|
@ -661,8 +699,8 @@ msgstr "Stunden"
|
|||
msgid "installed"
|
||||
msgstr "installiert"
|
||||
|
||||
msgid "invalid - Sample"
|
||||
msgstr "ungültig - Beispiel"
|
||||
msgid "invalid FQDN / required - Sample"
|
||||
msgstr "ungültige FQDN / Pflichtfeld - Beispiel"
|
||||
|
||||
msgid "minimum value '0'"
|
||||
msgstr "Minimum Wert '0'"
|
||||
|
|
|
@ -50,6 +50,9 @@ msgstr ""
|
|||
msgid "Casual users should not change this setting"
|
||||
msgstr ""
|
||||
|
||||
msgid "Change provider"
|
||||
msgstr ""
|
||||
|
||||
msgid "Check Interval"
|
||||
msgstr ""
|
||||
|
||||
|
@ -96,6 +99,12 @@ msgstr ""
|
|||
msgid "DDNS Autostart disabled"
|
||||
msgstr ""
|
||||
|
||||
msgid "DDNS Client Configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "DDNS Client Documentation"
|
||||
msgstr ""
|
||||
|
||||
msgid "DDNS Service provider"
|
||||
msgstr ""
|
||||
|
||||
|
@ -149,6 +158,9 @@ msgstr ""
|
|||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
msgid "Domain"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dynamic DNS"
|
||||
msgstr ""
|
||||
|
||||
|
@ -230,7 +242,7 @@ msgstr ""
|
|||
msgid "Hints"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostname/Domain"
|
||||
msgid "Hostname/FQDN to validate, if IP update happen or necessary"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP address source"
|
||||
|
@ -315,6 +327,12 @@ msgstr ""
|
|||
msgid "Log to syslog"
|
||||
msgstr ""
|
||||
|
||||
msgid "Lookup Hostname"
|
||||
msgstr ""
|
||||
|
||||
msgid "NOT installed"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Neither GNU Wget with SSL nor cURL installed to select a network to use for "
|
||||
"communication."
|
||||
|
@ -373,6 +391,21 @@ msgstr ""
|
|||
msgid "On Error the script will stop execution after given number of retrys"
|
||||
msgstr ""
|
||||
|
||||
msgid "OpenWrt Wiki"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optional Encoded Parameter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optional Parameter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optional: Replaces [PARAMENC] in Update-URL (URL-encoded)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optional: Replaces [PARAMOPT] in Update-URL (NOT URL-encoded)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Overview"
|
||||
msgstr ""
|
||||
|
||||
|
@ -403,16 +436,19 @@ msgstr ""
|
|||
msgid "Read / Reread log file"
|
||||
msgstr ""
|
||||
|
||||
msgid "Really change DDNS provider?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Registered IP"
|
||||
msgstr ""
|
||||
|
||||
msgid "Replaces [DOMAIN] in Update-URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Replaces [PASSWORD] in Update-URL"
|
||||
msgid "Replaces [PASSWORD] in Update-URL (URL-encoded)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Replaces [USERNAME] in Update-URL"
|
||||
msgid "Replaces [USERNAME] in Update-URL (URL-encoded)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Run once"
|
||||
|
@ -563,7 +599,7 @@ msgstr ""
|
|||
msgid "installed"
|
||||
msgstr ""
|
||||
|
||||
msgid "invalid - Sample"
|
||||
msgid "invalid FQDN / required - Sample"
|
||||
msgstr ""
|
||||
|
||||
msgid "minimum value '0'"
|
||||
|
|
Loading…
Reference in a new issue