Merge pull request #4471 from Ansuel/ddns-refresh
luci-app-ddns: rework with new ddns changes
This commit is contained in:
commit
d61a1c1241
3 changed files with 780 additions and 583 deletions
|
@ -1,4 +1,5 @@
|
|||
'use strict';
|
||||
'require ui';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
|
@ -8,43 +9,40 @@
|
|||
'require form';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
var callGetLogServices, callInitAction, callDDnsGetStatus;
|
||||
return view.extend({
|
||||
|
||||
var NextUpdateStrings = {};
|
||||
|
||||
NextUpdateStrings = {
|
||||
NextUpdateStrings : {
|
||||
'Verify' : _("Verify"),
|
||||
'Run once' : _("Run once"),
|
||||
'Disabled' : _("Disabled"),
|
||||
'Stopped' : _("Stopped")
|
||||
}
|
||||
},
|
||||
|
||||
var time_res = {};
|
||||
time_res['seconds'] = 1;
|
||||
time_res['minutes'] = 60;
|
||||
time_res['hours'] = 3600;
|
||||
time_res : {
|
||||
seconds : 1,
|
||||
minutes : 60,
|
||||
hours : 3600,
|
||||
},
|
||||
|
||||
callGetLogServices = rpc.declare({
|
||||
callGetLogServices: rpc.declare({
|
||||
object: 'luci.ddns',
|
||||
method: 'get_services_log',
|
||||
params: [ 'service_name' ],
|
||||
expect: { },
|
||||
});
|
||||
}),
|
||||
|
||||
callInitAction = rpc.declare({
|
||||
callInitAction: rpc.declare({
|
||||
object: 'luci',
|
||||
method: 'setInitAction',
|
||||
params: [ 'name', 'action' ],
|
||||
expect: { result: false }
|
||||
});
|
||||
}),
|
||||
|
||||
callDDnsGetStatus = rpc.declare({
|
||||
callDDnsGetStatus: rpc.declare({
|
||||
object: 'luci.ddns',
|
||||
method: 'get_ddns_state',
|
||||
expect: { }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
}),
|
||||
|
||||
callDDnsGetEnv: rpc.declare({
|
||||
object: 'luci.ddns',
|
||||
|
@ -58,14 +56,137 @@ return view.extend({
|
|||
expect: { }
|
||||
}),
|
||||
|
||||
services: {},
|
||||
|
||||
/*
|
||||
* Services list is gen by 3 different source:
|
||||
* 1. /usr/share/ddns/default contains the service installed by opkg
|
||||
* 2. /usr/share/ddns/custom contains any service installed by the
|
||||
* user or the ddns script (for example when service are
|
||||
* downloaded)
|
||||
* 3. /usr/share/ddns/list contains all the service that can be
|
||||
* downloaded by using the ddns script ('service on demand' feature)
|
||||
*
|
||||
* (Special services that requires a dedicated package ARE NOT
|
||||
* supported by the 'service on demand' feature)
|
||||
*/
|
||||
callGenServiceList: function(m, ev) {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.list('/usr/share/ddns/default'), []),
|
||||
L.resolveDefault(fs.list('/usr/share/ddns/custom'), []),
|
||||
L.resolveDefault(fs.read('/usr/share/ddns/list'), null)
|
||||
]).then(L.bind(function (data) {
|
||||
var default_service = data[0],
|
||||
custom_service = data[1],
|
||||
list_service = data[2] && data[2].split("\n") || [],
|
||||
_this = this;
|
||||
|
||||
this.services = {};
|
||||
|
||||
default_service.forEach(function (service) {
|
||||
_this.services[service.name.replace('.json','')] = true
|
||||
});
|
||||
|
||||
custom_service.forEach(function (service) {
|
||||
_this.services[service.name.replace('.json','')] = true
|
||||
});
|
||||
|
||||
list_service.forEach(function (service) {
|
||||
if (!_this.services[service])
|
||||
_this.services[service] = false;
|
||||
});
|
||||
}, this))
|
||||
},
|
||||
|
||||
/*
|
||||
* Check if the service is supported.
|
||||
* If the script doesn't find any json assume a 'service on demand' install.
|
||||
* If a json is found check if the ip type is supported.
|
||||
* Invalidate the service_name if is not supported.
|
||||
*/
|
||||
handleCheckService : function(s, service_name, ipv6, ev, section_id) {
|
||||
|
||||
var value = service_name.formvalue(section_id);
|
||||
s.service_supported = null;
|
||||
service_name.triggerValidation(section_id);
|
||||
|
||||
return this.handleGetServiceData(value)
|
||||
.then(L.bind(function (service_data) {
|
||||
if (value != '-' && service_data) {
|
||||
service_data = JSON.parse(service_data);
|
||||
if (ipv6.formvalue(section_id) == "1" && !service_data.ipv6) {
|
||||
s.service_supported = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
s.service_supported = true;
|
||||
}, service_name))
|
||||
.then(L.bind(service_name.triggerValidation, service_name, section_id))
|
||||
},
|
||||
|
||||
handleGetServiceData: function(service) {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.read('/usr/share/ddns/custom/'+service+'.json'), null),
|
||||
L.resolveDefault(fs.read('/usr/share/ddns/default/'+service+'.json'), null)
|
||||
]).then(function(data) {
|
||||
return data[0] || data[1] || null;
|
||||
})
|
||||
},
|
||||
|
||||
handleInstallService: function(m, service_name, section_id, section, _this, ev) {
|
||||
var service = service_name.formvalue(section_id)
|
||||
return fs.exec('/usr/bin/ddns', ['service', 'install', service])
|
||||
.then(L.bind(_this.callGenServiceList, _this))
|
||||
.then(L.bind(m.render, m))
|
||||
.then(L.bind(this.renderMoreOptionsModal, this, section))
|
||||
.catch(function(e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
handleRefreshServicesList: function(m, ev) {
|
||||
return fs.exec('/usr/bin/ddns', ['service', 'update'])
|
||||
.then(L.bind(this.load, this))
|
||||
.then(L.bind(this.render, this))
|
||||
.catch(function(e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
handleReloadDDnsRule: function(m, section_id, ev) {
|
||||
return fs.exec('/usr/lib/ddns/dynamic_dns_lucihelper.sh',
|
||||
[ '-S', section_id, '--', 'start' ])
|
||||
.then(L.bind(m.load, m))
|
||||
.then(L.bind(m.render, m))
|
||||
.catch(function(e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
HandleStopDDnsRule: function(m, section_id, ev) {
|
||||
return fs.exec('/usr/lib/ddns/dynamic_dns_lucihelper.sh',
|
||||
[ '-S', section_id, '--', 'start' ])
|
||||
.then(L.bind(m.render, m))
|
||||
.catch(function(e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
handleToggleDDns: function(m, ev) {
|
||||
return this.callInitAction('ddns', 'enabled')
|
||||
.then(L.bind(function (action) { return this.callInitAction('ddns', action ? 'disable' : 'enable')}, this))
|
||||
.then(L.bind(function (action) { return this.callInitAction('ddns', action ? 'stop' : 'start')}, this))
|
||||
.then(L.bind(m.render, m))
|
||||
.catch(function(e) { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
|
||||
handleRestartDDns: function(m, ev) {
|
||||
return this.callInitAction('ddns', 'restart')
|
||||
.then(L.bind(m.render, m));
|
||||
},
|
||||
|
||||
poll_status: function(map, data) {
|
||||
var status = data[1] || [], service = data[0] || [], rows = map.querySelectorAll('.cbi-section-table-row[data-sid]'),
|
||||
section_id, cfg_detail_ip, cfg_update, cfg_status, host, ip, last_update,
|
||||
next_update, service_status, reload, cfg_enabled, stop,
|
||||
ddns_enabled = map.querySelector('[data-name="_enabled"]').querySelector('.cbi-value-field'),
|
||||
ddns_toggle = map.querySelector('[data-name="_toggle"]').querySelector('button');
|
||||
ddns_toggle = map.querySelector('[data-name="_toggle"]').querySelector('button'),
|
||||
services_list = map.querySelector('[data-name="_services_list"]').querySelector('.cbi-value-field');
|
||||
|
||||
ddns_toggle.innerHTML = status['_enabled'] ? _('Stop DDNS') : _('Start DDNS')
|
||||
services_list.innerHTML = status['_services_list'];
|
||||
|
||||
dom.content(ddns_enabled, function() {
|
||||
return E([], [
|
||||
|
@ -101,7 +222,7 @@ return view.extend({
|
|||
if (service[section_id].last_update)
|
||||
last_update = service[section_id].last_update;
|
||||
if (service[section_id].next_update)
|
||||
next_update = NextUpdateStrings[service[section_id].next_update] || service[section_id].next_update;
|
||||
next_update = this.NextUpdateStrings[service[section_id].next_update] || service[section_id].next_update;
|
||||
if (service[section_id].pid)
|
||||
service_status = '<b>' + _('Running') + '</b> : ' + service[section_id].pid;
|
||||
}
|
||||
|
@ -117,10 +238,9 @@ return view.extend({
|
|||
load: function() {
|
||||
return Promise.all([
|
||||
this.callDDnsGetServicesStatus(),
|
||||
callDDnsGetStatus(),
|
||||
this.callDDnsGetStatus(),
|
||||
this.callDDnsGetEnv(),
|
||||
fs.lines('/etc/ddns/services'),
|
||||
fs.lines('/etc/ddns/services_ipv6'),
|
||||
this.callGenServiceList(),
|
||||
uci.load('ddns')
|
||||
]);
|
||||
},
|
||||
|
@ -131,20 +251,7 @@ return view.extend({
|
|||
var env = data[2] || [];
|
||||
var logdir = uci.get('ddns', 'global', 'ddns_logdir') || "/var/log/ddns";
|
||||
|
||||
var services4 = [];
|
||||
var services6 = [];
|
||||
|
||||
data[3].forEach(function(item) {
|
||||
if (!item.startsWith("#")) {
|
||||
services4.push(item.split('\t')[0].slice(1,-1));
|
||||
}
|
||||
});
|
||||
|
||||
data[4].forEach(function(item) {
|
||||
if (!item.startsWith("#")) {
|
||||
services6.push(item.split('\t')[0].slice(1,-1));
|
||||
}
|
||||
});
|
||||
var _this = this;
|
||||
|
||||
var m, s, o;
|
||||
|
||||
|
@ -170,32 +277,28 @@ return view.extend({
|
|||
return res ? _('DDNS Autostart enabled') : _('DDNS Autostart disabled')
|
||||
};
|
||||
|
||||
o = s.taboption('info', form.DummyValue, '_toggle', ' ');
|
||||
o = s.taboption('info', form.Button, '_toggle');
|
||||
o.title = ' ';
|
||||
o.inputtitle = _((status['_enabled'] ? 'stop' : 'start').toUpperCase() + ' DDns');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleToggleDDns, this, m);
|
||||
|
||||
o = s.taboption('info', form.Button, '_restart');
|
||||
o.title = ' ';
|
||||
o.inputtitle = _('Restart DDns');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleRestartDDns, this, m);
|
||||
|
||||
o = s.taboption('info', form.DummyValue, '_services_list', _('Services list last update'));
|
||||
o.cfgvalue = function() {
|
||||
var action = status['_enabled'] ? 'stop' : 'start';
|
||||
return E([], [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': L.ui.createHandlerFn(this, function() {
|
||||
return callDDnsGetStatus().then(L.bind(function(data) {
|
||||
return callInitAction('ddns', action == 'stop' ? 'disable' : 'enable').then(function() {
|
||||
return callInitAction('ddns', action);
|
||||
});
|
||||
}, this)).then(L.bind(m.render, m));
|
||||
})
|
||||
}, _(action.toUpperCase() + ' DDns'))]);
|
||||
return status[this.option];
|
||||
};
|
||||
|
||||
o = s.taboption('info', form.DummyValue, '_restart', ' ');
|
||||
o.cfgvalue = function() {
|
||||
return E([], [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': L.ui.createHandlerFn(this, function() {
|
||||
return callInitAction('ddns', 'restart').then(L.bind(m.render, m));
|
||||
})
|
||||
}, _('Restart DDns'))]);
|
||||
};
|
||||
o = s.taboption('info', form.Button, '_refresh_services');
|
||||
o.title = ' ';
|
||||
o.inputtitle = _('Update DDns Services List');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(this.handleRefreshServicesList, this, m);
|
||||
|
||||
// DDns hints
|
||||
|
||||
|
@ -344,6 +447,14 @@ return view.extend({
|
|||
|
||||
}
|
||||
|
||||
o = s.taboption('global', form.Value, 'cacert', _('Ca Certs path'));
|
||||
o.description = _('Ca Certs path that will be used to download services data. Set IGNORE to skip certificate validation.');
|
||||
o.placeholder = 'IGNORE';
|
||||
|
||||
o = s.taboption('global', form.Value, 'services_url', _('Services URL Download'));
|
||||
o.description = _('Url used to download services file. By default is the master openwrt ddns package repo.');
|
||||
o.placeholder = 'https://raw.githubusercontent.com/openwrt/packages/master/net/ddns-scripts/files';
|
||||
|
||||
// DDns services
|
||||
s = m.section(form.GridSection, 'service', _('Services'));
|
||||
s.anonymous = true;
|
||||
|
@ -354,9 +465,25 @@ return view.extend({
|
|||
s.addremove = true;
|
||||
s.sortable = true;
|
||||
|
||||
s.handleCreateDDnsRule = function(m, name, service_name, ipv6, ev) {
|
||||
var section_id = name.isValid('_new_') ? name.formvalue('_new_') : null,
|
||||
service_value = service_name.isValid('_new_') ? service_name.formvalue('_new_') : null,
|
||||
ipv6_value = ipv6.isValid('_new_') ? ipv6.formvalue('_new_') : null;
|
||||
|
||||
if (section_id == null || section_id == '' || service_value == null || section_id == '' || ipv6_value == null || ipv6_value == '')
|
||||
return;
|
||||
|
||||
return m.save(function() {
|
||||
uci.add('ddns', 'service', section_id);
|
||||
uci.set('ddns', section_id, 'service_name', service_value);
|
||||
uci.set('ddns', section_id, 'use_ipv6', ipv6_value);
|
||||
}).then(L.bind(m.children[1].renderMoreOptionsModal, m.children[1], section_id));
|
||||
};
|
||||
|
||||
s.handleAdd = function(ev) {
|
||||
var m2 = new form.Map('ddns'),
|
||||
s2 = m2.section(form.NamedSection, '_new_');
|
||||
s2 = m2.section(form.NamedSection, '_new_'),
|
||||
name, ipv6, service_name;
|
||||
|
||||
s2.render = function() {
|
||||
return Promise.all([
|
||||
|
@ -376,26 +503,41 @@ return view.extend({
|
|||
return true;
|
||||
};
|
||||
|
||||
ipv6 = s2.option( form.ListValue, 'use_ipv6',
|
||||
_("IP address version"),
|
||||
_("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider"));
|
||||
ipv6.default = '0';
|
||||
ipv6.value("0", _("IPv4-Address"))
|
||||
if (env["has_ipv6"]) {
|
||||
ipv6.value("1", _("IPv6-Address"))
|
||||
}
|
||||
|
||||
service_name = s2.option(form.ListValue, 'service_name',
|
||||
String.format('%s', _("DDNS Service provider")));
|
||||
service_name.value('-',"-- " + _("custom") + " --");
|
||||
for (var elem in _this.services)
|
||||
service_name.value(elem);
|
||||
service_name.validate = function(section_id, value) {
|
||||
if (value == '') return _("Select a service");
|
||||
if (s2.service_supported == null) return _("Checking the service support...");
|
||||
if (!s2.service_supported) return _("Service doesn't support this ip type");
|
||||
return true;
|
||||
};
|
||||
|
||||
ipv6.onchange = L.bind(_this.handleCheckService, _this, s2, service_name, ipv6);
|
||||
service_name.onchange = L.bind(_this.handleCheckService, _this, s2, service_name, ipv6);
|
||||
|
||||
m2.render().then(L.bind(function(nodes) {
|
||||
L.ui.showModal(_('Add new services...'), [
|
||||
ui.showModal(_('Add new services...'), [
|
||||
nodes,
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.ui.hideModal
|
||||
'click': ui.hideModal
|
||||
}, _('Cancel')), ' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-positive important',
|
||||
'click': L.ui.createHandlerFn(this, function(ev) {
|
||||
var nameval = name.isValid('_new_') ? name.formvalue('_new_') : null;
|
||||
|
||||
if (nameval == null || nameval == '')
|
||||
return;
|
||||
|
||||
return m.save(function() {
|
||||
uci.add('ddns', 'service', nameval);
|
||||
}).then(L.bind(m.children[1].renderMoreOptionsModal, m.children[1], nameval));
|
||||
})
|
||||
'click': ui.createHandlerFn(this, 'handleCreateDDnsRule', m, name, service_name, ipv6)
|
||||
}, _('Create service'))
|
||||
])
|
||||
], 'cbi-modal');
|
||||
|
@ -409,18 +551,12 @@ return view.extend({
|
|||
cfg_enabled = uci.get('ddns', section_id, 'enabled'),
|
||||
reload_opt = {
|
||||
'class': 'cbi-button cbi-button-neutral reload',
|
||||
'click': L.ui.createHandlerFn(this, function() {
|
||||
return fs.exec('/usr/lib/ddns/dynamic_dns_lucihelper.sh',
|
||||
[ '-S', section_id, '--', 'start' ]).then(L.bind(m.render, m));
|
||||
}),
|
||||
'click': ui.createHandlerFn(_this, 'handleReloadDDnsRule', m, section_id),
|
||||
'title': _('Reload this service'),
|
||||
},
|
||||
stop_opt = {
|
||||
'class': 'cbi-button cbi-button-neutral stop',
|
||||
'click': L.ui.createHandlerFn(this, function() {
|
||||
return fs.exec('/usr/lib/ddns/dynamic_dns_lucihelper.sh',
|
||||
[ '-S', section_id, '--', 'start' ]).then(L.bind(m.render, m));
|
||||
}),
|
||||
'click': ui.createHandlerFn(_this, 'HandleStopDDnsRule', m, section_id),
|
||||
'title': _('Stop this service'),
|
||||
};
|
||||
|
||||
|
@ -442,59 +578,28 @@ return view.extend({
|
|||
return tdEl;
|
||||
};
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_name', _('Name'));
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
return '<b>' + section_id + '</b>';
|
||||
}
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_detail_ip', _('Lookup Hostname') + "<br />" + _('Registered IP'));
|
||||
o.rawhtml = true;
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var host = uci.get('ddns', section_id, 'lookup_host') || _('Configuration Error'),
|
||||
ip = _('No Data');
|
||||
if (resolved[section_id] && resolved[section_id].ip)
|
||||
ip = resolved[section_id].ip;
|
||||
|
||||
return host + '<br />' + ip;
|
||||
};
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||
o.rmempty = false;
|
||||
o.editable = true;
|
||||
o.modalonly = false;
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_update', _('Last Update') + "<br />" + _('Next Update'));
|
||||
o.rawhtml = true;
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var last_update = _('Never'), next_update = _('Unknown');
|
||||
if (resolved[section_id]) {
|
||||
if (resolved[section_id].last_update)
|
||||
last_update = resolved[section_id].last_update;
|
||||
if (resolved[section_id].next_update)
|
||||
next_update = NextUpdateStrings[resolved[section_id].next_update] || resolved[section_id].next_update;
|
||||
}
|
||||
|
||||
return last_update + '<br />' + next_update;
|
||||
};
|
||||
|
||||
s.modaltitle = function(section_id) {
|
||||
return _('DDns Service') + ' » ' + section_id;
|
||||
};
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_status', _('Status'));
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var text = '<b>' + _('Not Running') + '</b>';
|
||||
s.addModalOptions = function(s, section_id) {
|
||||
|
||||
if (resolved[section_id] && resolved[section_id].pid)
|
||||
text = '<b>' + _('Running') + '</b> : ' + resolved[section_id].pid;
|
||||
var service = uci.get('ddns', section_id, 'service_name') || '-',
|
||||
ipv6 = uci.get('ddns', section_id, 'use_ipv6'), service_name, use_ipv6;
|
||||
|
||||
return text;
|
||||
return _this.handleGetServiceData(service).then(L.bind(function (service_data) {
|
||||
s.service_available = true;
|
||||
s.service_supported = true;
|
||||
|
||||
if (service != '-') {
|
||||
if (!service_data)
|
||||
s.service_available = false;
|
||||
else {
|
||||
service_data = JSON.parse(service_data);
|
||||
if (ipv6 == "1" && !service_data.ipv6)
|
||||
s.service_supported = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s.tab('basic', _('Basic Settings'));
|
||||
s.tab('advanced', _('Advanced Settings'));
|
||||
|
@ -518,62 +623,77 @@ return view.extend({
|
|||
o.datatype = 'and(minlength(3),hostname("strict"))';
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'use_ipv6',
|
||||
use_ipv6 = s.taboption('basic', form.ListValue, 'use_ipv6',
|
||||
_("IP address version"),
|
||||
_("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider"));
|
||||
o.default = '0';
|
||||
o.modalonly = true;
|
||||
o.rmempty = false;
|
||||
o.value("0", _("IPv4-Address"))
|
||||
use_ipv6.default = '0';
|
||||
use_ipv6.modalonly = true;
|
||||
use_ipv6.rmempty = false;
|
||||
use_ipv6.value("0", _("IPv4-Address"))
|
||||
if (env["has_ipv6"]) {
|
||||
o.value("1", _("IPv6-Address"))
|
||||
use_ipv6.value("1", _("IPv6-Address"))
|
||||
}
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'ipv4_service_name',
|
||||
String.format('%s %s', _("DDNS Service provider"), "[IPv4]"));
|
||||
o.depends("use_ipv6", "0")
|
||||
o.modalonly = true;
|
||||
o.value('-',"-- " + _("custom") + " --");
|
||||
for (var i = 0; i < services4.length; i++)
|
||||
o.value(services4[i]);
|
||||
o.cfgvalue = function(section_id) {
|
||||
service_name = s.taboption('basic', form.ListValue, 'service_name',
|
||||
String.format('%s', _("DDNS Service provider")));
|
||||
service_name.modalonly = true;
|
||||
service_name.value('-',"-- " + _("custom") + " --");
|
||||
for (var elem in _this.services)
|
||||
service_name.value(elem);
|
||||
service_name.cfgvalue = function(section_id) {
|
||||
return uci.get('ddns', section_id, 'service_name') || '-';
|
||||
};
|
||||
o.write = function(section_id, formvalue) {
|
||||
if (formvalue != '-') {
|
||||
service_name.write = function(section_id, service) {
|
||||
if (service != '-') {
|
||||
uci.set('ddns', section_id, 'update_url', null);
|
||||
uci.set('ddns', section_id, 'update_script', null);
|
||||
return uci.set('ddns', section_id, 'service_name', formvalue);
|
||||
return uci.set('ddns', section_id, 'service_name', service);
|
||||
}
|
||||
return uci.set('ddns', section_id, 'service_name', null);
|
||||
};
|
||||
service_name.validate = function(section_id, value) {
|
||||
if (value == '') return _("Select a service");
|
||||
if (s.service_available == null) return _("Checking the service support...");
|
||||
if (!s.service_available) return _('Service not installed');
|
||||
if (!s.service_supported) return _("Service doesn't support this ip type");
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'ipv6_service_name',
|
||||
String.format('%s %s', _("DDNS Service provider"), "[IPv6]"));
|
||||
o.depends("use_ipv6", "1")
|
||||
service_name.onchange = L.bind(_this.handleCheckService, _this, s, service_name, use_ipv6);
|
||||
use_ipv6.onchange = L.bind(_this.handleCheckService, _this, s, service_name, use_ipv6);
|
||||
|
||||
if (!s.service_available) {
|
||||
o = s.taboption('basic', form.Button, '_download_service');
|
||||
o.modalonly = true;
|
||||
o.value('-',"-- " + _("custom") + " --");
|
||||
for (var i = 0; i < services6.length; i++) {
|
||||
o.value(services6[i]);
|
||||
o.title = _('Service not installed');
|
||||
o.inputtitle = _('Install Service');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(_this.handleInstallService,
|
||||
this, m, service_name, section_id, s.section, _this)
|
||||
}
|
||||
o.cfgvalue = function(section_id) {
|
||||
var service = uci.get('ddns', section_id, 'service_name'),
|
||||
update_script = uci.get('ddns', section_id, 'update_script'),
|
||||
update_url = uci.get('ddns', section_id, 'update_url');
|
||||
|
||||
if (!service && (update_script || update_url))
|
||||
return "-";
|
||||
|
||||
return service;
|
||||
if (!s.service_supported) {
|
||||
o = s.taboption('basic', form.DummyValue, '_not_supported', ' ');
|
||||
o.cfgvalue = function () {
|
||||
return _("Service doesn't support this ip type")
|
||||
};
|
||||
o.write = function(section_id, formvalue) {
|
||||
if (formvalue != '-') {
|
||||
uci.set('ddns', section_id, 'update_url', null);
|
||||
uci.set('ddns', section_id, 'update_script', null);
|
||||
return uci.set('ddns', section_id, 'service_name', formvalue);
|
||||
}
|
||||
return uci.set('ddns', section_id, 'service_name', null);
|
||||
};
|
||||
|
||||
var service_switch = s.taboption('basic', form.Button, '_switch_proto');
|
||||
service_switch.modalonly = true;
|
||||
service_switch.title = _('Really switch service?');
|
||||
service_switch.inputtitle = _('Switch service');
|
||||
service_switch.inputstyle = 'apply';
|
||||
service_switch.onclick = L.bind(function(ev) {
|
||||
if (!s.service_supported) return;
|
||||
|
||||
return s.map.save()
|
||||
.then(L.bind(m.load, m))
|
||||
.then(L.bind(m.render, m))
|
||||
.then(L.bind(this.renderMoreOptionsModal, this, s.section));
|
||||
}, this);
|
||||
|
||||
if (s.service_available && s.service_supported) {
|
||||
|
||||
o = s.taboption('basic', form.Value, 'update_url',
|
||||
_("Custom update-URL"),
|
||||
|
@ -583,8 +703,7 @@ return view.extend({
|
|||
o.modalonly = true;
|
||||
o.rmempty = true;
|
||||
o.optional = true;
|
||||
o.depends("ipv6_service_name","-");
|
||||
o.depends("ipv4_service_name","-");
|
||||
o.depends("service_name","-");
|
||||
o.validate = function(section_id, value) {
|
||||
var other = this.section.children.filter(function(o) { return o.option == 'update_script' })[0].formvalue(section_id);
|
||||
|
||||
|
@ -601,8 +720,7 @@ return view.extend({
|
|||
o.modalonly = true;
|
||||
o.rmempty = true;
|
||||
o.optional = true;
|
||||
o.depends("ipv6_service_name","-");
|
||||
o.depends("ipv4_service_name","-");
|
||||
o.depends("service_name","-");
|
||||
o.validate = function(section_id, value) {
|
||||
var other = this.section.children.filter(function(o) { return o.option == 'update_url' })[0].formvalue(section_id);
|
||||
|
||||
|
@ -847,7 +965,7 @@ return view.extend({
|
|||
o.datatype = 'uinteger';
|
||||
o.validate = function(section_id, formvalue) {
|
||||
var unit = this.section.children.filter(function(o) { return o.option == 'check_unit' })[0].formvalue(section_id),
|
||||
time_to_sec = time_res[unit || 'minutes'] * formvalue;
|
||||
time_to_sec = _this.time_res[unit || 'minutes'] * formvalue;
|
||||
|
||||
if (formvalue && time_to_sec < 300)
|
||||
return _('Values below 5 minutes == 300 seconds are not supported');
|
||||
|
@ -881,8 +999,8 @@ return view.extend({
|
|||
var check_unit = this.section.children.filter(function(o) { return o.option == 'check_unit' })[0].formvalue(section_id),
|
||||
check_val = this.section.children.filter(function(o) { return o.option == 'check_interval' })[0].formvalue(section_id),
|
||||
force_unit = this.section.children.filter(function(o) { return o.option == 'force_unit' })[0].formvalue(section_id),
|
||||
check_to_sec = time_res[check_unit || 'minutes'] * ( check_val || '30'),
|
||||
force_to_sec = time_res[force_unit || 'minutes'] * formvalue;
|
||||
check_to_sec = _this.time_res[check_unit || 'minutes'] * ( check_val || '30'),
|
||||
force_to_sec = _this.time_res[force_unit || 'minutes'] * formvalue;
|
||||
|
||||
if (force_to_sec != 0 && force_to_sec < check_to_sec)
|
||||
return _("Values lower 'Check Interval' except '0' are not supported");
|
||||
|
@ -929,41 +1047,113 @@ return view.extend({
|
|||
o.value("seconds", _("seconds"));
|
||||
o.value("minutes", _("minutes"));
|
||||
|
||||
|
||||
o = s.taboption("logview", form.DummyValue, '_read_log', '');
|
||||
o = s.taboption('logview', form.Button, '_read_log');
|
||||
o.title = '';
|
||||
o.depends('use_logfile','1');
|
||||
o.modalonly = true;
|
||||
o.cfgvalue = function(section_id) {
|
||||
return E([], [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': L.ui.createHandlerFn(this, function() {
|
||||
var o = this.section.children.filter(function(o) { return o.option == '_logview' })[0];
|
||||
return callGetLogServices(section_id).then(L.bind(o.update_log, o));
|
||||
})
|
||||
}, _('Read / Reread log file'))]);
|
||||
};
|
||||
o.inputtitle = _('Read / Reread log file');
|
||||
o.inputstyle = 'apply';
|
||||
o.onclick = L.bind(function(ev, section_id) {
|
||||
return _this.callGetLogServices(section_id).then(L.bind(log_box.update_log, log_box));
|
||||
}, this);
|
||||
|
||||
o = s.taboption("logview", form.DummyValue, "_logview");
|
||||
o.depends('use_logfile','1');
|
||||
o.modalonly = true;
|
||||
var log_box = s.taboption("logview", form.DummyValue, "_logview");
|
||||
log_box.depends('use_logfile','1');
|
||||
log_box.modalonly = true;
|
||||
|
||||
o.update_log = L.bind(function(view, log_data) {
|
||||
log_box.update_log = L.bind(function(view, log_data) {
|
||||
return document.getElementById('log_area').textContent = log_data.result;
|
||||
}, o, this)
|
||||
}, o, this);
|
||||
|
||||
o.render = L.bind(function() {
|
||||
log_box.render = L.bind(function() {
|
||||
return E([
|
||||
E('p', {}, _('This is the current content of the log file in ') + logdir + ' for this service.'),
|
||||
E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 20, 'readonly' : 'readonly', 'id' : 'log_area' }, _('Please press [Read] button') ))
|
||||
]);
|
||||
}, o, this)
|
||||
}, o, this);
|
||||
}
|
||||
|
||||
for (var i = 0; i < s.children.length; i++) {
|
||||
o = s.children[i];
|
||||
switch (o.option) {
|
||||
case '_switch_proto':
|
||||
o.depends({ service_name : service, use_ipv6: ipv6, "!reverse": true })
|
||||
continue;
|
||||
case 'enabled':
|
||||
case 'service_name':
|
||||
case 'use_ipv6':
|
||||
case 'update_script':
|
||||
case 'update_url':
|
||||
case 'lookup_host':
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (o.deps.length)
|
||||
for (var j = 0; j < o.deps.length; j++) {
|
||||
o.deps[j].service_name = service;
|
||||
o.deps[j].use_ipv6 = ipv6;
|
||||
}
|
||||
else
|
||||
o.depends({service_name: service, use_ipv6: ipv6 });
|
||||
}
|
||||
}
|
||||
}, this)
|
||||
)};
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_status', _('Status'));
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var text = '<b>' + _('Not Running') + '</b>';
|
||||
|
||||
if (resolved[section_id] && resolved[section_id].pid)
|
||||
text = '<b>' + _('Running') + '</b> : ' + resolved[section_id].pid;
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_name', _('Name'));
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
return '<b>' + section_id + '</b>';
|
||||
};
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_detail_ip', _('Lookup Hostname') + "<br />" + _('Registered IP'));
|
||||
o.rawhtml = true;
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var host = uci.get('ddns', section_id, 'lookup_host') || _('Configuration Error'),
|
||||
ip = _('No Data');
|
||||
if (resolved[section_id] && resolved[section_id].ip)
|
||||
ip = resolved[section_id].ip;
|
||||
|
||||
return host + '<br />' + ip;
|
||||
};
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||
o.rmempty = false;
|
||||
o.editable = true;
|
||||
o.modalonly = false;
|
||||
|
||||
o = s.option(form.DummyValue, '_cfg_update', _('Last Update') + "<br />" + _('Next Update'));
|
||||
o.rawhtml = true;
|
||||
o.modalonly = false;
|
||||
o.textvalue = function(section_id) {
|
||||
var last_update = _('Never'), next_update = _('Unknown');
|
||||
if (resolved[section_id]) {
|
||||
if (resolved[section_id].last_update)
|
||||
last_update = resolved[section_id].last_update;
|
||||
if (resolved[section_id].next_update)
|
||||
next_update = _this.NextUpdateStrings[resolved[section_id].next_update] || resolved[section_id].next_update;
|
||||
}
|
||||
|
||||
return last_update + '<br />' + next_update;
|
||||
};
|
||||
|
||||
return m.render().then(L.bind(function(m, nodes) {
|
||||
poll.add(L.bind(function() {
|
||||
return Promise.all([
|
||||
this.callDDnsGetServicesStatus(),
|
||||
callDDnsGetStatus()
|
||||
this.callDDnsGetStatus()
|
||||
]).then(L.bind(this.poll_status, this, nodes));
|
||||
}, this), 5);
|
||||
return nodes;
|
||||
|
|
|
@ -7,6 +7,7 @@ local UCI = require "luci.model.uci"
|
|||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
|
||||
local ddns_package_path = "/usr/share/ddns"
|
||||
local luci_helper = "/usr/lib/ddns/dynamic_dns_lucihelper.sh"
|
||||
local srv_name = "ddns-scripts"
|
||||
|
||||
|
@ -155,6 +156,7 @@ local methods = {
|
|||
local ipkg = require "luci.model.ipkg"
|
||||
local uci = UCI.cursor()
|
||||
local dateformat = uci:get("ddns", "global", "ddns_dateformat") or "%F %R"
|
||||
local services_mtime = fs.stat(ddns_package_path .. "/list", 'mtime')
|
||||
uci:unload("ddns")
|
||||
local ver, srv_ver_cmd
|
||||
local res = {}
|
||||
|
@ -169,6 +171,7 @@ local methods = {
|
|||
res['_version'] = ver and #ver > 0 and ver or nil
|
||||
res['_enabled'] = sys.init.enabled("ddns")
|
||||
res['_curr_dateformat'] = os.date(dateformat)
|
||||
res['_services_list'] = services_mtime and os.date(dateformat, services_mtime) or 'NO_LIST'
|
||||
|
||||
return res
|
||||
end
|
||||
|
|
|
@ -7,8 +7,12 @@
|
|||
"luci": [ "setInitAction" ]
|
||||
},
|
||||
"file": {
|
||||
"/etc/ddns/services": [ "read" ],
|
||||
"/etc/ddns/services_ipv6": [ "read" ],
|
||||
"/usr/share/ddns/default": [ "list" ],
|
||||
"/usr/share/ddns/default/*": [ "read" ],
|
||||
"/usr/share/ddns/custom": [ "list" ],
|
||||
"/usr/share/ddns/custom/*": [ "read" ],
|
||||
"/usr/share/ddns/list": [ "read" ],
|
||||
"/usr/bin/ddns": [ "exec" ],
|
||||
"/usr/lib/ddns/dynamic_dns_lucihelper.sh": [ "exec" ]
|
||||
},
|
||||
"uci": [ "ddns" ]
|
||||
|
|
Loading…
Reference in a new issue