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:
Christian Schoenebeck 2015-11-15 21:36:11 +01:00
commit 1106b9346a
11 changed files with 739 additions and 413 deletions

View file

@ -10,28 +10,43 @@ local NX = require "nixio"
local NXFS = require "nixio.fs" local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher" local DISP = require "luci.dispatcher"
local HTTP = require "luci.http" 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 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 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() function index()
local nxfs = require "nixio.fs" -- global definitions not available local nxfs = require "nixio.fs" -- global definitions not available
local sys = require "luci.sys" -- in function index() local sys = require "luci.sys" -- in function index()
local ddns = require "luci.tools.ddns" -- ddns multiused functions local ddns = require "luci.tools.ddns" -- ddns multiused functions
local verinst = ddns.ipkg_ver_installed("ddns-scripts") local muci = require "luci.model.uci"
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
-- no config create an empty one -- no config create an empty one
if not nxfs.access("/etc/config/ddns") then if not nxfs.access("/etc/config/ddns") then
nxfs.writefile("/etc/config/ddns", "") nxfs.writefile("/etc/config/ddns", "")
end 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"}, cbi("ddns/overview"), _("Dynamic DNS"), 59)
entry( {"admin", "services", "ddns", "detail"}, cbi("ddns/detail"), nil ).leaf = true entry( {"admin", "services", "ddns", "detail"}, cbi("ddns/detail"), nil ).leaf = true
entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints", entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints",
@ -42,7 +57,60 @@ function index()
entry( {"admin", "services", "ddns", "status"}, call("status") ).leaf = true entry( {"admin", "services", "ddns", "status"}, call("status") ).leaf = true
end 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 function _get_status()
local uci = UCI.cursor() local uci = UCI.cursor()
local service = SYS.init.enabled("ddns") and 1 or 0 local service = SYS.init.enabled("ddns") and 1 or 0
@ -118,12 +186,12 @@ local function _get_status()
end end
-- try to get registered IP -- 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 dnsserver = s["dns_server"] or ""
local force_ipversion = tonumber(s["force_ipversion"] or 0) local force_ipversion = tonumber(s["force_ipversion"] or 0)
local force_dnstcp = tonumber(s["force_dnstcp"] or 0) local force_dnstcp = tonumber(s["force_dnstcp"] or 0)
local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh]] 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 [[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
local reg_ip = SYS.exec(command) local reg_ip = SYS.exec(command)
if reg_ip == "" then if reg_ip == "" then
@ -135,7 +203,7 @@ local function _get_status()
section = section, section = section,
enabled = enabled, enabled = enabled,
iface = iface, iface = iface,
domain = domain, lookup = lookup_host,
reg_ip = reg_ip, reg_ip = reg_ip,
pid = pid, pid = pid,
datelast = datelast, datelast = datelast,
@ -235,3 +303,4 @@ function status()
HTTP.prepare_content("application/json") HTTP.prepare_content("application/json")
HTTP.write_json(data) HTTP.write_json(data)
end end

File diff suppressed because it is too large Load diff

View file

@ -5,17 +5,13 @@ local NX = require "nixio"
local NXFS = require "nixio.fs" local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher" local DISP = require "luci.dispatcher"
local SYS = require "luci.sys" local SYS = require "luci.sys"
local CTRL = require "luci.controller.ddns" -- this application's controller
local DDNS = require "luci.tools.ddns" -- ddns multiused functions local DDNS = require "luci.tools.ddns" -- ddns multiused functions
-- cbi-map definition -- ####################################################### -- cbi-map definition -- #######################################################
local m = Map("ddns") local m = Map("ddns")
m.title = CTRL.app_title_back()
m.title = [[<a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]] m.description = CTRL.app_description()
.. 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.redirect = DISP.build_url("admin", "services", "ddns")
function m.commit_handler(self) function m.commit_handler(self)
@ -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" .. "0/8, 10/8, 100.64/10, 127/8, 169.254/16, 172.16/12, 192.168/16"
.. [[<br /><strong>IPv6: </strong>]] .. [[<br /><strong>IPv6: </strong>]]
.. "::/32, f000::/4" .. "::/32, f000::/4"
ali.reempty = true
ali.default = "0" 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 -- ############################################################# -- date_format -- #############################################################
local df = ns:option(Value, "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") .. translate("For supported codes look here")
.. [[</a>]] .. [[</a>]]
df.template = "ddns/global_value" df.template = "ddns/global_value"
df.rmempty = true
df.default = "%F %R" df.default = "%F %R"
df.date_string = "" df.date_string = ""
function df.cfgvalue(self, section) function df.cfgvalue(self, section)
@ -80,55 +65,45 @@ function df.cfgvalue(self, section)
self.date_string = DDNS.epoch2date(epoch, value) self.date_string = DDNS.epoch2date(epoch, value)
return value return value
end end
function df.validate(self, value) function df.parse(self, section, novld)
if value == self.default then DDNS.value_parse(self, section, novld)
return "" -- default = empty
end
return value
end end
-- run_dir -- ################################################################# -- run_dir -- #################################################################
local rd = ns:option(Value, "run_dir") local rd = ns:option(Value, "run_dir")
rd.title = translate("Status directory") rd.title = translate("Status directory")
rd.description = translate("Directory contains PID and other status information for each running section") rd.description = translate("Directory contains PID and other status information for each running section")
rd.rmempty = true
rd.default = "/var/run/ddns" rd.default = "/var/run/ddns"
function rd.validate(self, value) -- no need to validate. if empty default is used everything else created by dns-scripts
if value == self.default then function rd.parse(self, section, novld)
return "" -- default = empty DDNS.value_parse(self, section, novld)
end
return value
end end
-- log_dir -- ################################################################# -- log_dir -- #################################################################
local ld = ns:option(Value, "log_dir") local ld = ns:option(Value, "log_dir")
ld.title = translate("Log directory") ld.title = translate("Log directory")
ld.description = translate("Directory contains Log files for each running section") ld.description = translate("Directory contains Log files for each running section")
ld.rmempty = true
ld.default = "/var/log/ddns" ld.default = "/var/log/ddns"
function ld.validate(self, value) -- no need to validate. if empty default is used everything else created by dns-scripts
if value == self.default then function ld.parse(self, section, novld)
return "" -- default = empty DDNS.value_parse(self, section, novld)
end
return value
end end
-- log_lines -- ############################################################### -- log_lines -- ###############################################################
local ll = ns:option(Value, "log_lines") local ll = ns:option(Value, "log_lines")
ll.title = translate("Log length") ll.title = translate("Log length")
ll.description = translate("Number of last lines stored in log files") ll.description = translate("Number of last lines stored in log files")
ll.rmempty = true
ll.default = "250" ll.default = "250"
function ll.validate(self, value) function ll.validate(self, value)
local n = tonumber(value) local n = tonumber(value)
if not n or math.floor(n) ~= n or n < 1 then if not n or math.floor(n) ~= n or n < 1 then
return nil, self.title .. ": " .. translate("minimum value '1'") return nil, self.title .. ": " .. translate("minimum value '1'")
end end
if value == self.default then
return "" -- default = empty
end
return value return value
end end
function ll.parse(self, section, novld)
DDNS.value_parse(self, section, novld)
end
-- use_curl -- ################################################################ -- use_curl -- ################################################################
if (SYS.call([[ grep -i "\+ssl" /usr/bin/wget >/dev/null 2>&1 ]]) == 0) 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 />]] .. [[<br />]]
.. translate("To use cURL activate this option.") .. translate("To use cURL activate this option.")
pc.orientation = "horizontal" pc.orientation = "horizontal"
pc.rmempty = true
pc.default = "0" 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 end
return m return m

View file

@ -1,9 +1,9 @@
-- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com> -- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-- Licensed to the public under the Apache License 2.0. -- 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 DISP = require "luci.dispatcher"
local SYS = require "luci.sys" local SYS = require "luci.sys"
local CTRL = require "luci.controller.ddns" -- this application's controller
local DDNS = require "luci.tools.ddns" -- ddns multiused functions local DDNS = require "luci.tools.ddns" -- ddns multiused functions
-- check supported options -- ################################################## -- 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_ssl = DDNS.check_ssl() -- HTTPS support and --bind-network / --interface
has_proxy = DDNS.check_proxy() -- Proxy support has_proxy = DDNS.check_proxy() -- Proxy support
has_dnstcp = DDNS.check_bind_host() -- DNS TCP 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 -- html constants
font_red = [[<font color="red">]] font_red = [[<font color="red">]]
@ -22,14 +20,8 @@ bold_off = [[</strong>]]
-- cbi-map definition -- ####################################################### -- cbi-map definition -- #######################################################
m = Map("ddns") m = Map("ddns")
m.title = CTRL.app_title_back()
m.title = [[<a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]] .. m.description = CTRL.app_description()
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.redirect = DISP.build_url("admin", "services", "ddns")
-- SimpleSection definition -- ################################################# -- SimpleSection definition -- #################################################
@ -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") ) 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 -- 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") local dv = s:option(DummyValue, "_update_needed")
dv.titleref = DISP.build_url("admin", "system", "packages") dv.titleref = DISP.build_url("admin", "system", "packages")
dv.rawhtml = true dv.rawhtml = true

View file

@ -2,10 +2,10 @@
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
local NXFS = require "nixio.fs" local NXFS = require "nixio.fs"
local CTRL = require "luci.controller.ddns" -- this application's controller
local DISP = require "luci.dispatcher" local DISP = require "luci.dispatcher"
local HTTP = require "luci.http" local HTTP = require "luci.http"
local SYS = require "luci.sys" local SYS = require "luci.sys"
local CTRL = require "luci.controller.ddns" -- this application's controller
local DDNS = require "luci.tools.ddns" -- ddns multiused functions local DDNS = require "luci.tools.ddns" -- ddns multiused functions
-- show hints ? -- show hints ?
@ -15,7 +15,7 @@ show_hints = not (DDNS.check_ipv6() -- IPv6 support
and DDNS.check_bind_host() -- DNS TCP support and DDNS.check_bind_host() -- DNS TCP support
) )
-- correct ddns-scripts version -- 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 -- html constants
font_red = [[<font color="red">]] font_red = [[<font color="red">]]
@ -25,22 +25,8 @@ bold_off = [[</strong>]]
-- cbi-map definition -- ####################################################### -- cbi-map definition -- #######################################################
m = Map("ddns") m = Map("ddns")
m.title = CTRL.app_title_main()
m.title = [[<a href="javascript:alert(']] m.description = CTRL.app_description()
.. 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.on_after_commit = function(self) m.on_after_commit = function(self)
if self.changed then -- changes ? if self.changed then -- changes ?
@ -122,21 +108,21 @@ function ts.create(self, name)
HTTP.redirect( self.extedit:format(name) ) HTTP.redirect( self.extedit:format(name) )
end end
-- Domain and registered IP -- ################################################# -- Lookup_Host and registered IP -- #################################################
dom = ts:option(DummyValue, "_domainIP", dom = ts:option(DummyValue, "_lookupIP",
translate("Hostname/Domain") .. "<br />" .. translate("Registered IP") ) translate("Lookup Hostname") .. "<br />" .. translate("Registered IP") )
dom.template = "ddns/overview_doubleline" dom.template = "ddns/overview_doubleline"
function dom.set_one(self, section) function dom.set_one(self, section)
local domain = self.map:get(section, "domain") or "" local lookup = self.map:get(section, "lookup_host") or ""
if domain ~= "" then if lookup ~= "" then
return domain return lookup
else else
return [[<em>]] .. translate("config error") .. [[</em>]] return [[<em>]] .. translate("config error") .. [[</em>]]
end end
end end
function dom.set_two(self, section) function dom.set_two(self, section)
local domain = self.map:get(section, "domain") or "" local lookup = self.map:get(section, "lookup_host") or ""
if domain == "" then return "" end if lookup == "" then return "" end
local dnsserver = self.map:get(section, "dnsserver") or "" local dnsserver = self.map:get(section, "dnsserver") or ""
local use_ipv6 = tonumber(self.map:get(section, "use_ipv6") or 0) local use_ipv6 = tonumber(self.map:get(section, "use_ipv6") or 0)
local force_ipversion = tonumber(self.map:get(section, "force_ipversion") 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 if not NXFS.access(command, "rwx", "rx", "rx") then
NXFS.chmod(command, 755) NXFS.chmod(command, 755)
end end
command = command .. [[ get_registered_ip ]] .. domain .. [[ ]] .. use_ipv6 .. command = command .. [[ get_registered_ip ]] .. lookup .. [[ ]] .. use_ipv6 ..
[[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver [[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
local ip = SYS.exec(command) local ip = SYS.exec(command)
if ip == "" then ip = translate("no data") end if ip == "" then ip = translate("no data") end
@ -157,9 +143,6 @@ ena = ts:option( Flag, "enabled",
translate("Enabled")) translate("Enabled"))
ena.template = "ddns/overview_enabled" ena.template = "ddns/overview_enabled"
ena.rmempty = false ena.rmempty = false
function ena.parse(self, section)
DDNS.flag_parse(self, section)
end
-- show PID and next update -- show PID and next update
upd = ts:option( DummyValue, "_update", upd = ts:option( DummyValue, "_update",

View file

@ -96,58 +96,6 @@ function get_pid(section)
return pid return pid
end 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 -- replacement of build-in read of UCI option
-- modified AbstractValue.cfgvalue(self, section) from cbi.lua -- modified AbstractValue.cfgvalue(self, section) from cbi.lua
-- needed to read from other option then current value definition -- needed to read from other option then current value definition
@ -172,24 +120,77 @@ function read_value(self, section, option)
end end
end end
-- replacement of build-in Flag.parse of cbi.lua -- replacement of build-in parse of "Value"
-- modified to mark section as changed if value changes -- modified AbstractValue.parse(self, section, novld) from cbi.lua
-- current parse did not do this, but it is done AbstaractValue.parse() -- validate is called if rmempty/optional true or false
function flag_parse(self, section) -- before write check if forcewrite, value eq default, and more
local fexists = self.map:formvalue( function value_parse(self, section, novld)
luci.cbi.FEXIST_PREFIX .. self.config .. "." .. section .. "." .. self.option) local fvalue = self:formvalue(section)
local fexist = ( fvalue and (#fvalue > 0) ) -- not "nil" and "not empty"
if fexists then
local fvalue = self:formvalue(section) and self.enabled or self.disabled
local cvalue = self:cfgvalue(section) local cvalue = self:cfgvalue(section)
if fvalue ~= self.default or (not self.optional and not self.rmempty) then local rm_opt = ( self.rmempty or self.optional )
self:write(section, fvalue) local eq_cfg -- flag: equal cfgvalue
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
if (fvalue ~= cvalue) then self.section.changed = true end end
else end
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 self.section.changed = true
end end
end end

View file

@ -6,7 +6,7 @@
var txt = document.getElementById("cbid.ddns." + section + "._logview.txt"); // TextArea var txt = document.getElementById("cbid.ddns." + section + "._logview.txt"); // TextArea
if ( !txt ) { return; } // security check 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) { function(x) {
if (x.responseText == "_nodata_") if (x.responseText == "_nodata_")
txt.value = "<%:File not found or empty%>"; txt.value = "<%:File not found or empty%>";

View file

@ -19,7 +19,7 @@
var section = data[i].section // Section to handle var section = data[i].section // Section to handle
var cbx = document.getElementById("cbid.ddns." + section + ".enabled"); // Enabled var cbx = document.getElementById("cbid.ddns." + section + ".enabled"); // Enabled
var btn = document.getElementById("cbid.ddns." + section + "._startstop"); // Start/Stop button 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 lup = document.getElementById("cbid.ddns." + section + "._update.one"); // Last Update
var nup = document.getElementById("cbid.ddns." + section + "._update.two"); // Next Update var nup = document.getElementById("cbid.ddns." + section + "._update.two"); // Next Update
if ( !(cbx && btn && rip && lup && nup) ) { return; } // security check if ( !(cbx && btn && rip && lup && nup) ) { return; } // security check
@ -76,12 +76,12 @@
break; break;
} }
// domain // lookup
// (data[i].domain ignored here // (data[i].lookup ignored here
// registered IP // registered IP
// rip.innerHTML = "Registered IP"; // rip.innerHTML = "Registered IP";
if (data[i].domain == "_nodomain_") if (data[i].lookup == "_nolookup_")
rip.innerHTML = ''; rip.innerHTML = '';
else if (data[i].reg_ip == "_nodata_") else if (data[i].reg_ip == "_nodata_")
rip.innerHTML = '<em><%:No data%></em>'; rip.innerHTML = '<em><%:No data%></em>';
@ -136,7 +136,7 @@
// do start/stop // do start/stop
var btnXHR = new XHR(); 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) { function(x, data) {
if (x.responseText == "_uncommitted_") { if (x.responseText == "_uncommitted_") {
// we need a trick to display Ampersand "&" in stead of "&#38;" or "&amp;" // we need a trick to display Ampersand "&" in stead of "&#38;" or "&amp;"
@ -155,7 +155,7 @@
} }
// force to immediate show status on page load (not waiting for XHR.poll) // 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) { function(x, data) {
if (data) { _data2elements(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 // 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 // optimum is to define on Map or Section Level from here you can reach all elements
// we need update every 15 seconds only // 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) { function(x, data) {
if (data) { _data2elements(data); } if (data) { _data2elements(data); }
} }

View file

@ -69,15 +69,15 @@
break; break;
} }
// domain // lookup
if (data[j].domain == "_nodomain_") if (data[j].lookup == "_nolookup_")
tr.insertCell(-1).innerHTML = '<em><%:config error%></em>'; tr.insertCell(-1).innerHTML = '<em><%:config error%></em>';
else else
tr.insertCell(-1).innerHTML = data[j].domain; tr.insertCell(-1).innerHTML = data[j].lookup;
// registered IP // registered IP
switch (data[j].reg_ip) { switch (data[j].reg_ip) {
case "_nodomain_": case "_nolookup_":
tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>'; tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
break; break;
case "_nodata_": case "_nodata_":
@ -111,13 +111,13 @@
} }
// force to immediate show status (not waiting for XHR.poll) // 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) { function(x, data) {
if (data) { _data2elements(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) { function(x, data) {
if (data) { _data2elements(x, data); } if (data) { _data2elements(x, data); }
} }
@ -132,7 +132,7 @@
<tr class="cbi-section-table-titles"> <tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Configuration%></th> <th class="cbi-section-table-cell"><%:Configuration%></th>
<th class="cbi-section-table-cell"><%:Next Update%></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"><%:Registered IP%></th>
<th class="cbi-section-table-cell"><%:Network%></th> <th class="cbi-section-table-cell"><%:Network%></th>
</tr> </tr>

View file

@ -1,15 +1,15 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: luci-app-ddns\n" "Project-Id-Version: luci-app-ddns\n"
"POT-Creation-Date: 2015-05-08 21:29+0100\n" "POT-Creation-Date: 2015-11-04 19:10-0100\n"
"PO-Revision-Date: 2015-05-08 21:47+0100\n" "PO-Revision-Date: 2015-11-14 18:31+0100\n"
"Last-Translator: Christian Schoenebeck <christian.schoenebeck@gmail.com>\n" "Last-Translator: Christian Schoenebeck <christian.schoenebeck@gmail.com>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\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" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: .\n" "X-Poedit-Basepath: .\n"
@ -70,6 +70,9 @@ msgstr ""
msgid "Casual users should not change this setting" msgid "Casual users should not change this setting"
msgstr "Standard Benutzer sollten diese Einstellung nicht ändern." msgstr "Standard Benutzer sollten diese Einstellung nicht ändern."
msgid "Change provider"
msgstr "Anbieter wechseln"
msgid "Check Interval" msgid "Check Interval"
msgstr "Prüfinterval" msgstr "Prüfinterval"
@ -125,6 +128,12 @@ msgstr "Eigenes Update-Skript"
msgid "DDNS Autostart disabled" msgid "DDNS Autostart disabled"
msgstr "DDNS Autostart deaktiviert" msgstr "DDNS Autostart deaktiviert"
msgid "DDNS Client Configuration"
msgstr "DDNS Client Konfiguration"
msgid "DDNS Client Documentation"
msgstr "DDNS Client Dokumentation"
msgid "DDNS Service provider" msgid "DDNS Service provider"
msgstr "DDNS-Dienstanbieter" msgstr "DDNS-Dienstanbieter"
@ -196,6 +205,9 @@ msgstr ""
msgid "Disabled" msgid "Disabled"
msgstr "Deaktiviert" msgstr "Deaktiviert"
msgid "Domain"
msgstr "Domäne"
msgid "Dynamic DNS" msgid "Dynamic DNS"
msgstr "Dynamisches DNS" msgstr "Dynamisches DNS"
@ -284,8 +296,10 @@ msgstr "HTTPS nicht unterstützt"
msgid "Hints" msgid "Hints"
msgstr "Hinweise" msgstr "Hinweise"
msgid "Hostname/Domain" msgid "Hostname/FQDN to validate, if IP update happen or necessary"
msgstr "Rechnername/Domäne" msgstr ""
"Hostname/FQDN um zu überprüfen, ob eine Aktualisierung stattgefunden hat "
"oder notwendig ist"
msgid "IP address source" msgid "IP address source"
msgstr "IP-Adressquelle" msgstr "IP-Adressquelle"
@ -385,6 +399,12 @@ msgstr "Protokoll in Datei schreiben"
msgid "Log to syslog" msgid "Log to syslog"
msgstr "Systemprotokoll verwenden" msgstr "Systemprotokoll verwenden"
msgid "Lookup Hostname"
msgstr "Nachschlage-Hostname"
msgid "NOT installed"
msgstr "NICHT installiert"
msgid "" msgid ""
"Neither GNU Wget with SSL nor cURL installed to select a network to use for " "Neither GNU Wget with SSL nor cURL installed to select a network to use for "
"communication." "communication."
@ -454,6 +474,21 @@ msgstr ""
msgid "On Error the script will stop execution after given number of retrys" msgid "On Error the script will stop execution after given number of retrys"
msgstr "Das Skript wird nach der gegebenen Anzahl von Fehlversuchen beendet." 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" msgid "Overview"
msgstr "Übersicht" msgstr "Übersicht"
@ -484,17 +519,20 @@ msgstr "Prozess ID"
msgid "Read / Reread log file" msgid "Read / Reread log file"
msgstr "Protokolldatei (neu) einlesen" msgstr "Protokolldatei (neu) einlesen"
msgid "Really change DDNS provider?"
msgstr "Wirklich DDNS-Anbieter wechseln?"
msgid "Registered IP" msgid "Registered IP"
msgstr "Registrierte IP" msgstr "Registrierte IP"
msgid "Replaces [DOMAIN] in Update-URL" msgid "Replaces [DOMAIN] in Update-URL"
msgstr "Ersetzt [DOMAIN] in der Update-URL" msgstr "Ersetzt [DOMAIN] in der Update-URL"
msgid "Replaces [PASSWORD] in Update-URL" msgid "Replaces [PASSWORD] in Update-URL (URL-encoded)"
msgstr "Ersetzt [PASSWORD] in der Update-URL" msgstr "Ersetzt [PASSWORD] in der Update-URL (URL-codiert)"
msgid "Replaces [USERNAME] in Update-URL" msgid "Replaces [USERNAME] in Update-URL (URL-encoded)"
msgstr "Ersetzt [USERNAME] in der Update-URL" msgstr "Ersetzt [USERNAME] in der Update-URL (URL-codiert)"
msgid "Run once" msgid "Run once"
msgstr "Einmalig ausführen" msgstr "Einmalig ausführen"
@ -528,7 +566,7 @@ msgstr ""
"Optionen." "Optionen."
msgid "The default setting of '0' will retry infinite." 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." msgid "There is no service configured."
msgstr "Kein Dienst konfiguriert" msgstr "Kein Dienst konfiguriert"
@ -661,8 +699,8 @@ msgstr "Stunden"
msgid "installed" msgid "installed"
msgstr "installiert" msgstr "installiert"
msgid "invalid - Sample" msgid "invalid FQDN / required - Sample"
msgstr "ungültig - Beispiel" msgstr "ungültige FQDN / Pflichtfeld - Beispiel"
msgid "minimum value '0'" msgid "minimum value '0'"
msgstr "Minimum Wert '0'" msgstr "Minimum Wert '0'"

View file

@ -50,6 +50,9 @@ msgstr ""
msgid "Casual users should not change this setting" msgid "Casual users should not change this setting"
msgstr "" msgstr ""
msgid "Change provider"
msgstr ""
msgid "Check Interval" msgid "Check Interval"
msgstr "" msgstr ""
@ -96,6 +99,12 @@ msgstr ""
msgid "DDNS Autostart disabled" msgid "DDNS Autostart disabled"
msgstr "" msgstr ""
msgid "DDNS Client Configuration"
msgstr ""
msgid "DDNS Client Documentation"
msgstr ""
msgid "DDNS Service provider" msgid "DDNS Service provider"
msgstr "" msgstr ""
@ -149,6 +158,9 @@ msgstr ""
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
msgid "Domain"
msgstr ""
msgid "Dynamic DNS" msgid "Dynamic DNS"
msgstr "" msgstr ""
@ -230,7 +242,7 @@ msgstr ""
msgid "Hints" msgid "Hints"
msgstr "" msgstr ""
msgid "Hostname/Domain" msgid "Hostname/FQDN to validate, if IP update happen or necessary"
msgstr "" msgstr ""
msgid "IP address source" msgid "IP address source"
@ -315,6 +327,12 @@ msgstr ""
msgid "Log to syslog" msgid "Log to syslog"
msgstr "" msgstr ""
msgid "Lookup Hostname"
msgstr ""
msgid "NOT installed"
msgstr ""
msgid "" msgid ""
"Neither GNU Wget with SSL nor cURL installed to select a network to use for " "Neither GNU Wget with SSL nor cURL installed to select a network to use for "
"communication." "communication."
@ -373,6 +391,21 @@ msgstr ""
msgid "On Error the script will stop execution after given number of retrys" msgid "On Error the script will stop execution after given number of retrys"
msgstr "" 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" msgid "Overview"
msgstr "" msgstr ""
@ -403,16 +436,19 @@ msgstr ""
msgid "Read / Reread log file" msgid "Read / Reread log file"
msgstr "" msgstr ""
msgid "Really change DDNS provider?"
msgstr ""
msgid "Registered IP" msgid "Registered IP"
msgstr "" msgstr ""
msgid "Replaces [DOMAIN] in Update-URL" msgid "Replaces [DOMAIN] in Update-URL"
msgstr "" msgstr ""
msgid "Replaces [PASSWORD] in Update-URL" msgid "Replaces [PASSWORD] in Update-URL (URL-encoded)"
msgstr "" msgstr ""
msgid "Replaces [USERNAME] in Update-URL" msgid "Replaces [USERNAME] in Update-URL (URL-encoded)"
msgstr "" msgstr ""
msgid "Run once" msgid "Run once"
@ -563,7 +599,7 @@ msgstr ""
msgid "installed" msgid "installed"
msgstr "" msgstr ""
msgid "invalid - Sample" msgid "invalid FQDN / required - Sample"
msgstr "" msgstr ""
msgid "minimum value '0'" msgid "minimum value '0'"