v1.1. mod_public_ip: public-ip-script

This commit is contained in:
gSpot
2024-01-13 23:29:09 +03:00
parent 259f4cf122
commit be0912d7ae
11 changed files with 481 additions and 430 deletions

View File

@@ -19,15 +19,15 @@ Internet-detector is an application for checking the availability of the Interne
**OpenWrt >= 21.02:** **OpenWrt >= 21.02:**
opkg update opkg update
wget --no-check-certificate -O /tmp/internet-detector_1.0-3_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.0-3_all.ipk wget --no-check-certificate -O /tmp/internet-detector_1.1-0_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/internet-detector_1.1-0_all.ipk
opkg install /tmp/internet-detector_1.0-3_all.ipk opkg install /tmp/internet-detector_1.1-0_all.ipk
rm /tmp/internet-detector_1.0-3_all.ipk rm /tmp/internet-detector_1.1-0_all.ipk
/etc/init.d/internet-detector start /etc/init.d/internet-detector start
/etc/init.d/internet-detector enable /etc/init.d/internet-detector enable
wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.0-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.0-1_all.ipk wget --no-check-certificate -O /tmp/luci-app-internet-detector_1.1-0_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-internet-detector_1.1-0_all.ipk
opkg install /tmp/luci-app-internet-detector_1.0-1_all.ipk opkg install /tmp/luci-app-internet-detector_1.1-0_all.ipk
rm /tmp/luci-app-internet-detector_1.0-1_all.ipk rm /tmp/luci-app-internet-detector_1.1-0_all.ipk
/etc/init.d/rpcd restart /etc/init.d/rpcd restart
Email notification: Email notification:
@@ -36,9 +36,9 @@ Email notification:
i18n-ru: i18n-ru:
wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.0-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.0-1_all.ipk wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_1.1-0_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-i18n-internet-detector-ru_1.1-0_all.ipk
opkg install /tmp/luci-i18n-internet-detector-ru_1.0-1_all.ipk opkg install /tmp/luci-i18n-internet-detector-ru_1.1-0_all.ipk
rm /tmp/luci-i18n-internet-detector-ru_1.0-1_all.ipk rm /tmp/luci-i18n-internet-detector-ru_1.1-0_all.ipk
**[OpenWrt 19.07](https://github.com/gSpotx2f/luci-app-internet-detector/tree/19.07)** **[OpenWrt 19.07](https://github.com/gSpotx2f/luci-app-internet-detector/tree/19.07)**

View File

@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector PKG_NAME:=internet-detector
PKG_VERSION:=1.0 PKG_VERSION:=1.1
PKG_RELEASE:=3 PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector> PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
@@ -30,6 +30,7 @@ define Package/$(PKG_NAME)/conffiles
/etc/config/internet-detector /etc/config/internet-detector
/etc/internet-detector/down-script.internet /etc/internet-detector/down-script.internet
/etc/internet-detector/up-script.internet /etc/internet-detector/up-script.internet
/etc/internet-detector/public-ip-script.internet
endef endef
define Build/Configure define Build/Configure
@@ -44,6 +45,7 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/internet-detector $(INSTALL_DIR) $(1)/etc/internet-detector
$(INSTALL_DATA) ./files/etc/internet-detector/down-script.internet $(1)/etc/internet-detector/down-script.internet $(INSTALL_DATA) ./files/etc/internet-detector/down-script.internet $(1)/etc/internet-detector/down-script.internet
$(INSTALL_DATA) ./files/etc/internet-detector/up-script.internet $(1)/etc/internet-detector/up-script.internet $(INSTALL_DATA) ./files/etc/internet-detector/up-script.internet $(1)/etc/internet-detector/up-script.internet
$(INSTALL_DATA) ./files/etc/internet-detector/public-ip-script.internet $(1)/etc/internet-detector/public-ip-script.internet
$(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/internet-detector $(1)/etc/init.d/internet-detector $(INSTALL_BIN) ./files/etc/init.d/internet-detector $(1)/etc/init.d/internet-detector
$(INSTALL_DIR) $(1)/usr/bin $(INSTALL_DIR) $(1)/usr/bin

View File

@@ -38,6 +38,7 @@ config instance 'internet'
option mod_public_ip_qtype '0' option mod_public_ip_qtype '0'
option mod_public_ip_interval '600' option mod_public_ip_interval '600'
option mod_public_ip_timeout '3' option mod_public_ip_timeout '3'
option mod_public_ip_enable_ip_script '0'
option mod_email_enabled '0' option mod_email_enabled '0'
option mod_email_alive_period '0' option mod_email_alive_period '0'
option mod_email_mail_smtp 'smtp.gmail.com' option mod_email_mail_smtp 'smtp.gmail.com'

View File

@@ -0,0 +1,2 @@
# Shell commands that run when the public IP address changes.
# New IP is available as value of the $PUBLIC_IP variable.

View File

@@ -1,5 +1,6 @@
local socket = require("posix.sys.socket") local socket = require("posix.sys.socket")
local stdlib = require("posix.stdlib")
local unistd = require("posix.unistd") local unistd = require("posix.unistd")
local Module = { local Module = {
@@ -51,6 +52,8 @@ local Module = {
port = 53, queryType = "TXT", queryType6 = "TXT", port = 53, queryType = "TXT", queryType6 = "TXT",
}, },
}, },
ipScript = "",
enableIpScript = false,
status = nil, status = nil,
_provider = nil, _provider = nil,
_qtype = false, _qtype = false,
@@ -61,6 +64,13 @@ local Module = {
_DNSPacket = nil, _DNSPacket = nil,
} }
function Module:runIpScript()
if self.enableIpScript and unistd.access(self.ipScript, "r") then
stdlib.setenv("PUBLIC_IP", self.status)
os.execute(string.format('/bin/sh "%s" &', self.ipScript))
end
end
function Module:getQueryType(type) function Module:getQueryType(type)
local types = { local types = {
A = 1, A = 1,
@@ -214,6 +224,7 @@ function Module:parseParts(message, start, parts)
end end
local partEnd = partStart + (tonumber(partLen, 16) * 2) local partEnd = partStart + (tonumber(partLen, 16) * 2)
parts[#parts + 1] = message:sub(partStart, partEnd - 1) parts[#parts + 1] = message:sub(partStart, partEnd - 1)
if message:sub(partEnd, partEnd + 1) == "00" or partEnd > #message then if message:sub(partEnd, partEnd + 1) == "00" or partEnd > #message then
return parts return parts
@@ -224,7 +235,6 @@ end
function Module:decodeMessage(message) function Module:decodeMessage(message)
local retTable = {} local retTable = {}
local t = {} local t = {}
for i = 1, #message do for i = 1, #message do
t[#t + 1] = string.format("%.2x", string.byte(message, i)) t[#t + 1] = string.format("%.2x", string.byte(message, i))
@@ -333,6 +343,13 @@ function Module:init(t)
else else
self._provider = self.providers.opendns1 self._provider = self.providers.opendns1
end end
if self.config.configDir then
self.ipScript = string.format(
"%s/public-ip-script.%s", self.config.configDir, self.config.serviceConfig.instance)
if t.enable_ip_script then
self.enableIpScript = (tonumber(t.enable_ip_script) ~= 0)
end
end
self._qtype = (tonumber(t.qtype) ~= 0) self._qtype = (tonumber(t.qtype) ~= 0)
self._currentIp = nil self._currentIp = nil
self._DNSPacket = nil self._DNSPacket = nil
@@ -350,7 +367,7 @@ function Module:run(currentStatus, lastStatus, timeDiff)
local ip = self:resolveIP() local ip = self:resolveIP()
if not ip then if not ip then
ip = "Undefined" ip = ""
self._interval = self.runIntervalFailed self._interval = self.runIntervalFailed
else else
self._interval = self.runInterval self._interval = self.runInterval
@@ -360,8 +377,11 @@ function Module:run(currentStatus, lastStatus, timeDiff)
self.status = ip self.status = ip
self.syslog( self.syslog(
"notice", "notice",
string.format("%s: public IP address %s", self.name, ip) string.format("%s: public IP address %s", self.name, (ip == "") and "Undefined" or ip)
) )
if self._counter > 0 then
self:runIpScript()
end
else else
self.status = nil self.status = nil
end end

View File

@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_VERSION:=1.0-1 PKG_VERSION:=1.1-0
LUCI_TITLE:=LuCI support for internet-detector LUCI_TITLE:=LuCI support for internet-detector
LUCI_DEPENDS:=+internet-detector LUCI_DEPENDS:=+internet-detector
LUCI_PKGARCH:=all LUCI_PKGARCH:=all

View File

@@ -213,9 +213,9 @@ return view.extend({
className = 'id-label-status id-undefined spinning'; className = 'id-label-status id-undefined spinning';
}; };
let publicIp = (i.mod_public_ip) ? ' | %s: %s'.format( let publicIp = (i.mod_public_ip !== undefined) ?
_('Public IP'), _(i.mod_public_ip) ' | %s: %s'.format(_('Public IP'), (i.mod_public_ip === '') ? _('Undefined') : _(i.mod_public_ip))
) : ''; : '';
this.inetStatusArea.append( this.inetStatusArea.append(
E('span', { 'class': className }, '%s%s%s'.format( E('span', { 'class': className }, '%s%s%s'.format(
@@ -271,11 +271,9 @@ return view.extend({
return fs.exec(this.execPath, [ 'poll' ]).then(res => { return fs.exec(this.execPath, [ 'poll' ]).then(res => {
let inetStatData = this.inetStatusFromJson(res); let inetStatData = this.inetStatusFromJson(res);
if(inetStatData.instances[0]) { if(inetStatData.instances[0]) {
this.uiPollState = inetStatData.instances[0].inet; this.uiPollState = inetStatData.instances[0].inet;
}; };
this.inetStatus = inetStatData; this.inetStatus = inetStatData;
this.setInternetStatus(); this.setInternetStatus();
}); });
@@ -576,52 +574,7 @@ return view.extend({
ss.nodescriptions = true; ss.nodescriptions = true;
ss.addbtntitle = _('Add instance'); ss.addbtntitle = _('Add instance');
ss.addModalOptions = (s, section_id, ev) => { ss.tab('main', _('Main settings'));
// User scripts
// enabled
o = s.taboption('user_scripts', form.Flag, 'mod_user_scripts_enabled',
_('Enabled'));
o.rmempty = false;
o.modalonly = true;
// up_script edit dialog
o = s.taboption('user_scripts', this.CBIBlockFileEdit, this,
'up_script',
this.configDir + '/up-script.' + s.section,
_('Edit up-script'),
_('Shell commands that run when connected to the Internet.')
);
o.modalonly = true;
// alive_period
o = s.taboption('user_scripts', this.CBITimeInput,
'mod_user_scripts_alive_period', _('Alive period'),
_('Longest period of time after connecting to Internet before "up-script" runs.')
);
o.default = '0';
o.rmempty = false;
o.modalonly = true;
// down_script edit dialog
o = s.taboption('user_scripts', this.CBIBlockFileEdit, this,
'down_script',
this.configDir + '/down-script.' + s.section,
_('Edit down-script'),
_('Shell commands to run when disconnected from the Internet.')
);
o.modalonly = true;
// dead_period
o = s.taboption('user_scripts', this.CBITimeInput,
'mod_user_scripts_dead_period', _('Dead period'),
_('Longest period of time after disconnecting from Internet before "down-script" runs.')
);
o.default = '0';
o.rmempty = false;
o.modalonly = true;
};
function makeIntervalOptions(list) { function makeIntervalOptions(list) {
list.value(2, '2 ' + _('sec')); list.value(2, '2 ' + _('sec'));
@@ -637,8 +590,6 @@ return view.extend({
list.value(600, '10 ' + _('min')); list.value(600, '10 ' + _('min'));
} }
ss.tab('main', _('Main settings'));
// enabled // enabled
o = ss.taboption('main', form.Flag, 'enabled', o = ss.taboption('main', form.Flag, 'enabled',
_('Enabled'), _('Enabled'),
@@ -653,7 +604,6 @@ return view.extend({
'hosts', _('Hosts'), 'hosts', _('Hosts'),
_('Hosts to check Internet availability. Hosts are polled (in list order) until at least one of them responds.') _('Hosts to check Internet availability. Hosts are polled (in list order) until at least one of them responds.')
); );
//o.datatype = 'or(host,hostport)';
o.datatype = 'or(or(host,hostport),ipaddrport(1))'; o.datatype = 'or(or(host,hostport),ipaddrport(1))';
o.default = this.defaultHosts; o.default = this.defaultHosts;
o.rmempty = false; o.rmempty = false;
@@ -750,11 +700,19 @@ return view.extend({
/* Modules */ /* Modules */
ss.tab('led_control', _('LED control'));
ss.tab('reboot_device', _('Reboot device'));
ss.tab('restart_network', _('Restart network'));
ss.tab('restart_modem', _('Restart modem'));
ss.tab('public_ip', _('Public IP address'));
ss.tab('email', _('Email notification'));
ss.tab('user_scripts', _('User scripts'));
ss.addModalOptions = (s, section_id, ev) => {
// LED control // LED control
ss.tab('led_control', _('LED control')); o = s.taboption('led_control', form.DummyValue, '_dummy');
o = ss.taboption('led_control', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('<abbr title="Light Emitting Diode">LED</abbr> indicates the Internet status.') + _('<abbr title="Light Emitting Diode">LED</abbr> indicates the Internet status.') +
@@ -765,30 +723,31 @@ return view.extend({
this.leds.sort((a, b) => a.name > b.name); this.leds.sort((a, b) => a.name > b.name);
// enabled // enabled
o = ss.taboption('led_control', form.Flag, 'mod_led_control_enabled', o = s.taboption('led_control', form.Flag, 'mod_led_control_enabled',
_('Enabled')); _('Enabled'));
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// led_name // led_name
o = ss.taboption('led_control', form.ListValue, 'mod_led_control_led_name', o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_name',
_('<abbr title="Light Emitting Diode">LED</abbr> Name')); _('<abbr title="Light Emitting Diode">LED</abbr> Name'));
o.depends({ mod_led_control_enabled: '1' }); o.depends({ mod_led_control_enabled: '1' });
o.modalonly = true; o.modalonly = true;
this.leds.forEach(e => o.value(e.name)); this.leds.forEach(e => o.value(e.name));
// led_action_1 // led_action_1
o = ss.taboption('led_control', form.ListValue, 'mod_led_control_led_action_1', o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_action_1',
_('Action when connected')); _('Action when connected'));
o.depends({ mod_led_control_enabled: '1' }); o.depends({ mod_led_control_enabled: '1' });
o.modalonly = true; o.modalonly = true;
//o.value(0, _('Nothing'));
o.value(1, _('Off')); o.value(1, _('Off'));
o.value(2, _('On')); o.value(2, _('On'));
o.value(3, _('Blink')); o.value(3, _('Blink'));
o.default = '2'; o.default = '2';
// led_action_2 // led_action_2
o = ss.taboption('led_control', form.ListValue, 'mod_led_control_led_action_2', o = s.taboption('led_control', form.ListValue, 'mod_led_control_led_action_2',
_('Action when disconnected')); _('Action when disconnected'));
o.depends({ mod_led_control_enabled: '1' }); o.depends({ mod_led_control_enabled: '1' });
o.modalonly = true; o.modalonly = true;
@@ -797,7 +756,7 @@ return view.extend({
o.value(3, _('Blink')); o.value(3, _('Blink'));
o.default = '1'; o.default = '1';
} else { } else {
o = ss.taboption('led_control', form.DummyValue, '_dummy'); o = s.taboption('led_control', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' + o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' +
_('No <abbr title="Light Emitting Diode">LED</abbr>s available...') + _('No <abbr title="Light Emitting Diode">LED</abbr>s available...') +
@@ -807,9 +766,7 @@ return view.extend({
// Reboot device // Reboot device
ss.tab('reboot_device', _('Reboot device')); o = s.taboption('reboot_device', form.DummyValue, '_dummy');
o = ss.taboption('reboot_device', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('Device will be rebooted when the Internet is disconnected.') + _('Device will be rebooted when the Internet is disconnected.') +
@@ -817,13 +774,13 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// enabled // enabled
o = ss.taboption('reboot_device', form.Flag, 'mod_reboot_enabled', o = s.taboption('reboot_device', form.Flag, 'mod_reboot_enabled',
_('Enabled')); _('Enabled'));
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// dead_period // dead_period
o = ss.taboption('reboot_device', this.CBITimeInput, o = s.taboption('reboot_device', this.CBITimeInput,
'mod_reboot_dead_period', _('Dead period'), 'mod_reboot_dead_period', _('Dead period'),
_('Longest period of time without Internet access until the device is rebooted.') _('Longest period of time without Internet access until the device is rebooted.')
); );
@@ -832,7 +789,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// force_reboot_delay // force_reboot_delay
o = ss.taboption('reboot_device', form.ListValue, o = s.taboption('reboot_device', form.ListValue,
'mod_reboot_force_reboot_delay', _('Forced reboot delay'), 'mod_reboot_force_reboot_delay', _('Forced reboot delay'),
_('Waiting for a reboot to complete before performing a forced reboot.') _('Waiting for a reboot to complete before performing a forced reboot.')
); );
@@ -848,9 +805,7 @@ return view.extend({
// Restart network // Restart network
ss.tab('restart_network', _('Restart network')); o = s.taboption('restart_network', form.DummyValue, '_dummy');
o = ss.taboption('restart_network', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('Network will be restarted when the Internet is disconnected.') + _('Network will be restarted when the Internet is disconnected.') +
@@ -858,13 +813,13 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// enabled // enabled
o = ss.taboption('restart_network', form.Flag, 'mod_network_restart_enabled', o = s.taboption('restart_network', form.Flag, 'mod_network_restart_enabled',
_('Enabled')); _('Enabled'));
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// dead_period // dead_period
o = ss.taboption('restart_network', this.CBITimeInput, o = s.taboption('restart_network', this.CBITimeInput,
'mod_network_restart_dead_period', _('Dead period'), 'mod_network_restart_dead_period', _('Dead period'),
_('Longest period of time without Internet access before network restart.') _('Longest period of time without Internet access before network restart.')
); );
@@ -873,7 +828,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// attempts // attempts
o = ss.taboption('restart_network', form.ListValue, o = s.taboption('restart_network', form.ListValue,
'mod_network_restart_attempts', _('Restart attempts'), 'mod_network_restart_attempts', _('Restart attempts'),
_('Maximum number of network restart attempts before Internet access is available.') _('Maximum number of network restart attempts before Internet access is available.')
); );
@@ -886,14 +841,14 @@ return view.extend({
o.default = '1'; o.default = '1';
// iface // iface
o = ss.taboption('restart_network', widgets.DeviceSelect, 'mod_network_restart_iface', o = s.taboption('restart_network', widgets.DeviceSelect, 'mod_network_restart_iface',
_('Interface'), _('Interface'),
_('Network interface to restart. If not specified, then the network service is restarted.') _('Network interface to restart. If not specified, then the network service is restarted.')
); );
o.modalonly = true; o.modalonly = true;
// restart_timeout // restart_timeout
o = ss.taboption('restart_network', form.ListValue, o = s.taboption('restart_network', form.ListValue,
'mod_network_restart_restart_timeout', _('Restart timeout'), 'mod_network_restart_restart_timeout', _('Restart timeout'),
_('Timeout between stopping and starting the interface.') _('Timeout between stopping and starting the interface.')
); );
@@ -913,9 +868,7 @@ return view.extend({
// Restart modem // Restart modem
ss.tab('restart_modem', _('Restart modem')); o = s.taboption('restart_modem', form.DummyValue, '_dummy');
o = ss.taboption('restart_modem', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('Modem will be restarted when the Internet is disconnected.') + _('Modem will be restarted when the Internet is disconnected.') +
@@ -925,14 +878,14 @@ return view.extend({
if(this.mm) { if(this.mm) {
// enabled // enabled
o = ss.taboption('restart_modem', form.Flag, 'mod_modem_restart_enabled', o = s.taboption('restart_modem', form.Flag, 'mod_modem_restart_enabled',
_('Enabled'), _('Enabled'),
); );
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// dead_period // dead_period
o = ss.taboption('restart_modem', this.CBITimeInput, o = s.taboption('restart_modem', this.CBITimeInput,
'mod_modem_restart_dead_period', _('Dead period'), 'mod_modem_restart_dead_period', _('Dead period'),
_('Longest period of time without Internet access before modem restart.') _('Longest period of time without Internet access before modem restart.')
); );
@@ -941,7 +894,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// any_band // any_band
o = ss.taboption('restart_modem', form.Flag, o = s.taboption('restart_modem', form.Flag,
'mod_modem_restart_any_band', _('Unlock modem bands'), 'mod_modem_restart_any_band', _('Unlock modem bands'),
_('Set the modem to be allowed to use any band.') _('Set the modem to be allowed to use any band.')
); );
@@ -949,7 +902,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// iface // iface
o = ss.taboption('restart_modem', widgets.NetworkSelect, 'mod_modem_restart_iface', o = s.taboption('restart_modem', widgets.NetworkSelect, 'mod_modem_restart_iface',
_('Interface'), _('Interface'),
_('ModemManger interface. If specified, it will be restarted after restarting ModemManager.') _('ModemManger interface. If specified, it will be restarted after restarting ModemManager.')
); );
@@ -958,7 +911,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
} else { } else {
o = ss.taboption('restart_modem', form.DummyValue, '_dummy'); o = s.taboption('restart_modem', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' + o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' +
_('ModemManager is not available...') + _('ModemManager is not available...') +
@@ -968,9 +921,7 @@ return view.extend({
// Public IP address // Public IP address
ss.tab('public_ip', _('Public IP address')); o = s.taboption('public_ip', form.DummyValue, '_dummy');
o = ss.taboption('public_ip', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('Checking the real public IP address.') + _('Checking the real public IP address.') +
@@ -978,13 +929,13 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// enabled // enabled
o = ss.taboption('public_ip', form.Flag, 'mod_public_ip_enabled', o = s.taboption('public_ip', form.Flag, 'mod_public_ip_enabled',
_('Enabled')); _('Enabled'));
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// provider // provider
o = ss.taboption('public_ip', form.ListValue, o = s.taboption('public_ip', form.ListValue,
'mod_public_ip_provider', _('DNS provider'), 'mod_public_ip_provider', _('DNS provider'),
_('Service for determining the public IP address through DNS.') _('Service for determining the public IP address through DNS.')
); );
@@ -998,7 +949,7 @@ return view.extend({
o.default = 'opendns1'; o.default = 'opendns1';
// ipv6 // ipv6
o = ss.taboption('public_ip', form.ListValue, o = s.taboption('public_ip', form.ListValue,
'mod_public_ip_qtype', _('DNS query type'), 'mod_public_ip_qtype', _('DNS query type'),
_('The type of record requested in the DNS query (if the service supports it).') _('The type of record requested in the DNS query (if the service supports it).')
); );
@@ -1008,7 +959,7 @@ return view.extend({
o.default = '0'; o.default = '0';
// interval // interval
o = ss.taboption('public_ip', form.ListValue, o = s.taboption('public_ip', form.ListValue,
'mod_public_ip_interval', _('Polling interval'), 'mod_public_ip_interval', _('Polling interval'),
_('Interval between IP address requests.') _('Interval between IP address requests.')
); );
@@ -1022,7 +973,7 @@ return view.extend({
o.value(10800, '3' + ' ' + _('hour')); o.value(10800, '3' + ' ' + _('hour'));
// timeout // timeout
o = ss.taboption('public_ip', form.ListValue, o = s.taboption('public_ip', form.ListValue,
'mod_public_ip_timeout', _('Server response timeout') 'mod_public_ip_timeout', _('Server response timeout')
); );
o.default = '3' o.default = '3'
@@ -1031,11 +982,24 @@ return view.extend({
o.value(i, i + ' ' + _('sec')); o.value(i, i + ' ' + _('sec'));
}; };
// enable_ip_script
o = s.taboption('public_ip', form.Flag, 'mod_public_ip_enable_ip_script',
_('Enable public-ip-script'));
o.rmempty = false;
o.modalonly = true;
// public-ip-script edit dialog
o = s.taboption('public_ip', this.CBIBlockFileEdit, this,
'public-ip-script',
this.configDir + '/public-ip-script.' + s.section,
_('Edit public-ip-script'),
_('Shell commands that run when the public IP address changes. New IP is available as value of the <code>$PUBLIC_IP</code> variable (empty string if undefined).')
);
o.modalonly = true;
// Email notification // Email notification
ss.tab('email', _('Email notification')); o = s.taboption('email', form.DummyValue, '_dummy');
o = ss.taboption('email', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('An email will be sent when the internet connection is restored after being disconnected.') + _('An email will be sent when the internet connection is restored after being disconnected.') +
@@ -1045,13 +1009,13 @@ return view.extend({
if(this.mta) { if(this.mta) {
// enabled // enabled
o = ss.taboption('email', form.Flag, 'mod_email_enabled', o = s.taboption('email', form.Flag, 'mod_email_enabled',
_('Enabled')); _('Enabled'));
o.rmempty = false; o.rmempty = false;
o.modalonly = true; o.modalonly = true;
// alive_period // alive_period
o = ss.taboption('email', this.CBITimeInput, o = s.taboption('email', this.CBITimeInput,
'mod_email_alive_period', _('Alive period'), 'mod_email_alive_period', _('Alive period'),
_('Longest period of time after connecting to the Internet before sending a message.') _('Longest period of time after connecting to the Internet before sending a message.')
); );
@@ -1059,38 +1023,38 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// host_alias // host_alias
o = ss.taboption('email', form.Value, 'mod_email_host_alias', o = s.taboption('email', form.Value, 'mod_email_host_alias',
_('Host alias'), _('Host alias'),
_('Host identifier in messages. If not specified, hostname will be used.')); _('Host identifier in messages. If not specified, hostname will be used.'));
o.modalonly = true; o.modalonly = true;
// mail_recipient // mail_recipient
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_recipient', _('Recipient')); 'mod_email_mail_recipient', _('Recipient'));
o.description = _('Email address of the recipient.'); o.description = _('Email address of the recipient.');
o.modalonly = true; o.modalonly = true;
// mail_sender // mail_sender
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_sender', _('Sender')); 'mod_email_mail_sender', _('Sender'));
o.description = _('Email address of the sender.'); o.description = _('Email address of the sender.');
o.modalonly = true; o.modalonly = true;
// mail_user // mail_user
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_user', _('User')); 'mod_email_mail_user', _('User'));
o.description = _('Username for SMTP authentication.'); o.description = _('Username for SMTP authentication.');
o.modalonly = true; o.modalonly = true;
// mail_password // mail_password
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_password', _('Password')); 'mod_email_mail_password', _('Password'));
o.description = _('Password for SMTP authentication.'); o.description = _('Password for SMTP authentication.');
o.password = true; o.password = true;
o.modalonly = true; o.modalonly = true;
// mail_smtp // mail_smtp
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_smtp', _('SMTP server')); 'mod_email_mail_smtp', _('SMTP server'));
o.description = _('Hostname/IP address of the SMTP server.'); o.description = _('Hostname/IP address of the SMTP server.');
o.datatype = 'host'; o.datatype = 'host';
@@ -1098,14 +1062,14 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
// mail_smtp_port // mail_smtp_port
o = ss.taboption('email', form.Value, o = s.taboption('email', form.Value,
'mod_email_mail_smtp_port', _('SMTP server port')); 'mod_email_mail_smtp_port', _('SMTP server port'));
o.datatype = 'port'; o.datatype = 'port';
o.default = '587'; o.default = '587';
o.modalonly = true; o.modalonly = true;
// mail_security // mail_security
o = ss.taboption('email', form.ListValue, o = s.taboption('email', form.ListValue,
'mod_email_mail_security', _('Security')); 'mod_email_mail_security', _('Security'));
o.description = '%s<br />%s'.format( o.description = '%s<br />%s'.format(
_('TLS: use STARTTLS if the server supports it.'), _('TLS: use STARTTLS if the server supports it.'),
@@ -1117,7 +1081,7 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
} else { } else {
o = ss.taboption('email', form.DummyValue, '_dummy'); o = s.taboption('email', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' + o.default = '<label class="cbi-value-title"></label><div class="cbi-value-field"><em>' +
_('Mailsend is not available...') + _('Mailsend is not available...') +
@@ -1126,15 +1090,57 @@ return view.extend({
}; };
// User scripts // User scripts
ss.tab('user_scripts', _('User scripts'));
o = ss.taboption('user_scripts', form.DummyValue, '_dummy'); o = s.taboption('user_scripts', form.DummyValue, '_dummy');
o.rawhtml = true; o.rawhtml = true;
o.default = '<div class="cbi-section-descr">' + o.default = '<div class="cbi-section-descr">' +
_('Shell commands to run when connected or disconnected from the Internet.') + _('Shell commands to run when connected or disconnected from the Internet.') +
'</div>'; '</div>';
o.modalonly = true; o.modalonly = true;
// enabled
o = s.taboption('user_scripts', form.Flag, 'mod_user_scripts_enabled',
_('Enabled'));
o.rmempty = false;
o.modalonly = true;
// up_script edit dialog
o = s.taboption('user_scripts', this.CBIBlockFileEdit, this,
'up_script',
this.configDir + '/up-script.' + s.section,
_('Edit up-script'),
_('Shell commands that run when connected to the Internet.')
);
o.modalonly = true;
// alive_period
o = s.taboption('user_scripts', this.CBITimeInput,
'mod_user_scripts_alive_period', _('Alive period'),
_('Longest period of time after connecting to Internet before "up-script" runs.')
);
o.default = '0';
o.rmempty = false;
o.modalonly = true;
// down_script edit dialog
o = s.taboption('user_scripts', this.CBIBlockFileEdit, this,
'down_script',
this.configDir + '/down-script.' + s.section,
_('Edit down-script'),
_('Shell commands to run when disconnected from the Internet.')
);
o.modalonly = true;
// dead_period
o = s.taboption('user_scripts', this.CBITimeInput,
'mod_user_scripts_dead_period', _('Dead period'),
_('Longest period of time after disconnecting from Internet before "down-script" runs.')
);
o.default = '0';
o.rmempty = false;
o.modalonly = true;
};
/* UI detector configuration */ /* UI detector configuration */

View File

@@ -133,9 +133,9 @@ return baseclass.extend({
className = 'id-label-status id-undefined spinning'; className = 'id-label-status id-undefined spinning';
}; };
let publicIp = (i.mod_public_ip) ? ' | %s: %s'.format( let publicIp = (i.mod_public_ip !== undefined) ?
_('Public IP'), _(i.mod_public_ip) ' | %s: %s'.format(_('Public IP'), (i.mod_public_ip === '') ? _('Undefined') : _(i.mod_public_ip))
) : ''; : '';
inetStatusArea.append( inetStatusArea.append(
E('span', { 'class': className }, '%s%s%s'.format( E('span', { 'class': className }, '%s%s%s'.format(

View File

@@ -50,7 +50,7 @@ msgid "Big: 248 bytes"
msgstr "Большой: 248 байт" msgstr "Большой: 248 байт"
msgid "Blink" msgid "Blink"
msgstr "Мигать" msgstr "Мигание"
msgid "Check type" msgid "Check type"
msgstr "Тип проверки" msgstr "Тип проверки"
@@ -115,6 +115,9 @@ msgstr "Изменить"
msgid "Edit down-script" msgid "Edit down-script"
msgstr "Изменить down-script" msgstr "Изменить down-script"
msgid "Edit public-ip-script"
msgstr "Изменить public-ip-script"
msgid "Edit up-script" msgid "Edit up-script"
msgstr "Изменить up-script" msgstr "Изменить up-script"
@@ -133,6 +136,9 @@ msgstr "Включить"
msgid "Enable logging" msgid "Enable logging"
msgstr "Запись событий в лог" msgstr "Запись событий в лог"
msgid "Enable public-ip-script"
msgstr "Включить public-ip-script"
msgid "Enabled" msgid "Enabled"
msgstr "Включен" msgstr "Включен"
@@ -392,6 +398,9 @@ msgstr "Разрешить модему использование любой ч
msgid "Shell commands that run when connected to the Internet." msgid "Shell commands that run when connected to the Internet."
msgstr "Команды shell выполняемые при подключении к Интернет." msgstr "Команды shell выполняемые при подключении к Интернет."
msgid "Shell commands that run when the public IP address changes. New IP is available as value of the <code>$PUBLIC_IP</code> variable (empty string if undefined)."
msgstr "Команды shell выполняемые при изменении публичного IP адреса. Новый IP доступен как значение переменной <code>$PUBLIC_IP</code> (пустая строка если не определён)."
msgid "Shell commands to run when connected or disconnected from the Internet." msgid "Shell commands to run when connected or disconnected from the Internet."
msgstr "Команды shell выполняемые при подключении или отключении Интернет." msgstr "Команды shell выполняемые при подключении или отключении Интернет."

View File

@@ -103,6 +103,9 @@ msgstr ""
msgid "Edit down-script" msgid "Edit down-script"
msgstr "" msgstr ""
msgid "Edit public-ip-script"
msgstr ""
msgid "Edit up-script" msgid "Edit up-script"
msgstr "" msgstr ""
@@ -121,6 +124,9 @@ msgstr ""
msgid "Enable logging" msgid "Enable logging"
msgstr "" msgstr ""
msgid "Enable public-ip-script"
msgstr ""
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr ""
@@ -362,6 +368,9 @@ msgstr ""
msgid "Shell commands that run when connected to the Internet." msgid "Shell commands that run when connected to the Internet."
msgstr "" msgstr ""
msgid "Shell commands that run when the public IP address changes. New IP is available as value of the <code>$PUBLIC_IP</code> variable (empty string if undefined)."
msgstr ""
msgid "Shell commands to run when connected or disconnected from the Internet." msgid "Shell commands to run when connected or disconnected from the Internet."
msgstr "" msgstr ""

View File

@@ -6,6 +6,7 @@
"/sys/class/leds": [ "list" ], "/sys/class/leds": [ "list" ],
"/etc/internet-detector/up-script*": [ "read" ], "/etc/internet-detector/up-script*": [ "read" ],
"/etc/internet-detector/down-script*": [ "read" ], "/etc/internet-detector/down-script*": [ "read" ],
"/etc/internet-detector/public-ip-script*": [ "read" ],
"/usr/bin/internet-detector*": [ "exec" ], "/usr/bin/internet-detector*": [ "exec" ],
"/usr/bin/mailsend": [ "exec" ] "/usr/bin/mailsend": [ "exec" ]
}, },
@@ -17,7 +18,8 @@
"write": { "write": {
"file": { "file": {
"/etc/internet-detector/up-script*": [ "write" ], "/etc/internet-detector/up-script*": [ "write" ],
"/etc/internet-detector/down-script*": [ "write" ] "/etc/internet-detector/down-script*": [ "write" ],
"/etc/internet-detector/public-ip-script*": [ "write" ]
}, },
"uci": [ "internet-detector" ] "uci": [ "internet-detector" ]
} }