diff --git a/README.md b/README.md index 5191764..2e2e422 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Internet-detector is an application for checking the availability of the Interne /etc/init.d/internet-detector start /etc/init.d/internet-detector enable - wget --no-check-certificate -O /tmp/luci-app-internet-detector_0.5-0_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/19.07/luci-app-internet-detector_0.5-0_all.ipk - opkg install /tmp/luci-app-internet-detector_0.5-0_all.ipk - rm /tmp/luci-app-internet-detector_0.5-0_all.ipk + wget --no-check-certificate -O /tmp/luci-app-internet-detector_0.5-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/19.07/luci-app-internet-detector_0.5-1_all.ipk + opkg install /tmp/luci-app-internet-detector_0.5-1_all.ipk + rm /tmp/luci-app-internet-detector_0.5-1_all.ipk /etc/init.d/rpcd restart Email notification: @@ -35,9 +35,9 @@ Email notification: i18n-ru: - wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_0.5-0_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/19.07/luci-i18n-internet-detector-ru_0.5-0_all.ipk - opkg install /tmp/luci-i18n-internet-detector-ru_0.5-0_all.ipk - rm /tmp/luci-i18n-internet-detector-ru_0.5-0_all.ipk + wget --no-check-certificate -O /tmp/luci-i18n-internet-detector-ru_0.5-1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/19.07/luci-i18n-internet-detector-ru_0.5-1_all.ipk + opkg install /tmp/luci-i18n-internet-detector-ru_0.5-1_all.ipk + rm /tmp/luci-i18n-internet-detector-ru_0.5-1_all.ipk ## Screenshots: diff --git a/internet-detector/files/etc/config/internet-detector b/internet-detector/files/etc/config/internet-detector index 82f70bc..70a385e 100644 --- a/internet-detector/files/etc/config/internet-detector +++ b/internet-detector/files/etc/config/internet-detector @@ -31,7 +31,7 @@ config module 'mod_network_restart' config module 'mod_modem_restart' option enabled '0' option dead_period '600' - option any_band '1' + option any_band '0' config module 'mod_email' option enabled '0' diff --git a/luci-app-internet-detector/Makefile b/luci-app-internet-detector/Makefile index df28ee1..8f4acf1 100644 --- a/luci-app-internet-detector/Makefile +++ b/luci-app-internet-detector/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=0.5 -PKG_RELEASE:=0 +PKG_RELEASE:=1 LUCI_TITLE:=LuCI support for internet-detector LUCI_DEPENDS:=+internet-detector LUCI_PKGARCH:=all diff --git a/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js index e89b9c1..c7ec837 100644 --- a/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js +++ b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js @@ -86,9 +86,8 @@ return L.view.extend({ initStatus : null, inetStatus : null, inetStatusLabel : E('span', { 'class': 'label' }), - inetStatusSpinner : E('span', { 'class': 'spinning', 'style': 'margin-top:1em' }, ' '), + inetStatusSpinner : E('span', { 'style': 'margin-top:1em' }, ' '), serviceStatusLabel : E('em'), - serviceButton : null, initButton : null, uiPollCounter : 0, uiPollState : null, @@ -138,6 +137,90 @@ return L.view.extend({ }); }, + setInetStatusSpinner: function() { + this.inetStatusSpinner.className = 'spinning'; + }, + + unsetInetStatusSpinner: function() { + this.inetStatusSpinner.className = ''; + }, + + setInternetStatus: function() { + if(this.inetStatus === 'up') { + this.inetStatusLabel.style.background = '#46a546'; + this.inetStatusLabel.textContent = _('Connected'); + this.inetStatusLabel.style.color = '#ffffff'; + this.unsetInetStatusSpinner(); + } + else if(this.inetStatus === 'down') { + this.inetStatusLabel.textContent = _('Disconnected'); + this.inetStatusLabel.style.background = '#ff4953'; + this.inetStatusLabel.style.color = '#ffffff'; + this.unsetInetStatusSpinner(); + } + else { + this.inetStatusLabel.textContent = _('Undefined'); + this.inetStatusLabel.style.background = '#9b9b9b'; + this.inetStatusLabel.style.color = '#ffffff'; + + if(this.currentAppMode !== '0' && this.appStatus !== 'stoped') { + this.setInetStatusSpinner(); + }; + }; + + if(this.appStatus === 'running') { + this.serviceStatusLabel.textContent = _('Running'); + } else { + this.serviceStatusLabel.textContent = _('Stopped'); + }; + }, + + servicePoll: function() { + return Promise.all([ + fs.exec(this.execPath, [ 'status' ]), + fs.exec(this.execPath, [ 'inet-status' ]), + ]).then(stat => { + let curAppStatus = (stat[0].code === 0) ? stat[0].stdout.trim() : null; + let curInetStatus = (stat[1].code === 0) ? stat[1].stdout.trim() : null; + if(this.inetStatus === curInetStatus && this.appStatus === curAppStatus) { + return; + }; + this.appStatus = curAppStatus; + this.inetStatus = curInetStatus; + this.setInternetStatus(); + }).catch(e => { + this.appStatus = 'stoped'; + this.inetStatus = null; + }); + }, + + uiPoll: function() { + let curInetStatus = null; + this.uiPollCounter = ++this.uiPollCounter; + + if((this.uiPollState === 0 && this.uiPollCounter % this.uiCheckIntervalUp) || + (this.uiPollState === 1 && this.uiPollCounter % this.uiCheckIntervalDown)) { + return; + }; + + this.uiPollCounter = 0; + + return fs.exec(this.execPath, [ 'inet-status' ]).then(res => { + this.uiPollState = (res.code === 0 && res.stdout.trim() === 'up') ? 0 : 1; + + if(this.uiPollState === 0) { + curInetStatus = 'up'; + } else { + curInetStatus = 'down'; + }; + + if(this.inetStatus !== curInetStatus) { + this.inetStatus = (this.currentAppMode === '0') ? null : curInetStatus; + this.setInternetStatus(); + }; + }); + }, + serviceRestart: function(ev) { L.Poll.stop(); return this.handleServiceAction('restart').then(() => { @@ -170,10 +253,10 @@ return L.view.extend({ }, }), - CBIBlockService: form.Value.extend({ - __name__ : 'CBI.BlockService', + CBIBlockInetStatus: form.Value.extend({ + __name__ : 'CBI.BlockInetStatus', - __init__ : function(map, section, ctx) { + __init__ : function(map, section, ctx) { this.map = map; this.section = section; this.ctx = ctx; @@ -182,11 +265,56 @@ return L.view.extend({ }, renderWidget: function(section_id, option_index, cfgvalue) { - this.ctx.serviceButton = E('button', { - 'class': btnStyleApply, - 'click': ui.createHandlerFn(this.ctx, this.ctx.serviceRestart), - }, _('Restart')); - this.ctx.initButton = E('button', { + this.ctx.setInternetStatus(); + + return E([ + E('label', { 'class': 'cbi-value-title' }, + _('Internet status') + ), + E('div', { 'class': 'cbi-value-field' }, [ + this.ctx.inetStatusLabel, + this.ctx.inetStatusSpinner + ]), + ]) + }, + }), + + CBIBlockServiceStatus: form.Value.extend({ + __name__ : 'CBI.BlockServiceStatus', + + __init__ : function(map, section, ctx) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.optional = true; + this.rmempty = true; + }, + + renderWidget: function(section_id, option_index, cfgvalue) { + return E([ + E('label', { 'class': 'cbi-value-title' }, + _('Service') + ), + E('div', { 'class': 'cbi-value-field' }, + this.ctx.serviceStatusLabel + ), + ]); + }, + }), + + CBIBlockInitButton: form.Value.extend({ + __name__ : 'CBI.BlockInitButton', + + __init__ : function(map, section, ctx) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.optional = true; + this.rmempty = true; + }, + + renderWidget: function(section_id, option_index, cfgvalue) { + this.ctx.initButton = E('button', { 'class': (!this.ctx.initStatus) ? btnStyleDisabled : btnStyleEnabled, 'click': ui.createHandlerFn(this, () => { return this.ctx.handleServiceAction( @@ -209,56 +337,14 @@ return L.view.extend({ }), }, (!this.ctx.initStatus) ? _('Disabled') : _('Enabled')); - this.ctx.setInternetStatus(true); - - let serviceItems = ''; - if(this.ctx.currentAppMode === '2') { - serviceItems = E([ - E('div', { 'class': 'cbi-value' }, [ - E('label', { 'class': 'cbi-value-title' }, - _('Service') - ), - E('div', { 'class': 'cbi-value-field' }, - this.ctx.serviceStatusLabel - ), - ]), - E('div', { 'class': 'cbi-value' }, [ - E('label', { 'class': 'cbi-value-title' }, - _('Restart service') - ), - E('div', { 'class': 'cbi-value-field' }, - this.ctx.serviceButton - ), - ]), - E('div', { 'class': 'cbi-value' }, [ - E('label', { 'class': 'cbi-value-title' }, - _('Run service at startup') - ), - E('div', { 'class': 'cbi-value-field' }, - this.ctx.initButton - ), - ]), - ]); - }; - - let internetStatus = (this.ctx.currentAppMode !== '0') ? - E('div', { 'class': 'cbi-value' }, [ - E('label', { 'class': 'cbi-value-title' }, - _('Internet status') - ), - E('div', { 'class': 'cbi-value-field' }, [ - this.ctx.inetStatusLabel, - (!this.ctx.inetStatus) ? this.ctx.inetStatusSpinner : '', - ]), - ]) - : ''; - - return E('div', { 'class': 'cbi-section' }, - E('div', { 'class': 'cbi-section-node' }, [ - internetStatus, - serviceItems, - ]) - ); + return E( [ + E('label', { 'class': 'cbi-value-title' }, + _('Run service at startup') + ), + E('div', { 'class': 'cbi-value-field' }, + this.ctx.initButton + ), + ]); }, }), @@ -282,11 +368,11 @@ return L.view.extend({ E('div', { 'class': 'cbi-section' }, E('p', {}, E('textarea', { - 'id': 'widget.modal_content', + 'id' : 'widget.modal_content', 'class': 'cbi-input-textarea', 'style': 'width:100% !important', - 'rows': 10, - 'wrap': 'off', + 'rows' : 10, + 'wrap' : 'off', 'spellcheck': 'false', }, content) @@ -310,7 +396,7 @@ return L.view.extend({ handleSave: function(ev) { let textarea = document.getElementById('widget.modal_content'); - let value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n'; + let value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n'; return fs.write(this.file, value).then(rc => { textarea.value = value; @@ -360,77 +446,6 @@ return L.view.extend({ }, }), - setInternetStatus: function(initial=false) { - if(this.inetStatus === 'up') { - this.inetStatusLabel.style.background = '#46a546'; - this.inetStatusLabel.textContent = _('Connected'); - } - else if(this.inetStatus === 'down') { - this.inetStatusLabel.textContent = _('Disconnected'); - this.inetStatusLabel.style.background = '#ff6c74'; - } - else { - this.inetStatusLabel.textContent = _('Undefined'); - this.inetStatusLabel.style.background = '#cccccc'; - }; - - if(!initial && this.inetStatusSpinner) { - this.inetStatusSpinner.remove(); - }; - - if(this.appStatus === 'running') { - this.serviceStatusLabel.textContent = _('Running'); - } else { - this.serviceStatusLabel.textContent = _('Stopped'); - }; - }, - - servicePoll: function() { - return Promise.all([ - fs.exec(this.execPath, [ 'status' ]), - fs.exec(this.execPath, [ 'inet-status' ]), - ]).then(stat => { - let curAppStatus = (stat[0].code === 0) ? stat[0].stdout.trim() : null; - let curInetStatus = (stat[1].code === 0) ? stat[1].stdout.trim() : null; - if(this.inetStatus === curInetStatus && this.appStatus === curAppStatus) { - return; - }; - this.appStatus = curAppStatus; - this.inetStatus = curInetStatus; - this.setInternetStatus(); - }).catch(e => { - this.appStatus = 'stoped'; - this.inetStatus = null; - }); - }, - - uiPoll: function() { - let curInetStatus = null; - this.uiPollCounter = ++this.uiPollCounter; - - if((this.uiPollState === 0 && this.uiPollCounter % this.uiCheckIntervalUp) || - (this.uiPollState === 1 && this.uiPollCounter % this.uiCheckIntervalDown)) { - return; - }; - - this.uiPollCounter = 0; - - return fs.exec(this.execPath, [ 'inet-status' ]).then(res => { - this.uiPollState = (res.code === 0 && res.stdout.trim() === 'up') ? 0 : 1; - - if(this.uiPollState === 0) { - curInetStatus = 'up'; - } else { - curInetStatus = 'down'; - }; - - if(this.inetStatus !== curInetStatus) { - this.inetStatus = (this.currentAppMode === '0') ? null : curInetStatus; - this.setInternetStatus(); - }; - }); - }, - load: function() { return Promise.all([ fs.exec(this.execPath, [ 'status' ]), @@ -469,13 +484,28 @@ return L.view.extend({ /* Service widget */ - s = m.section(form.NamedSection, 'config', 'main'); - o = s.option(this.CBIBlockService, this); + s = m.section(form.NamedSection, 'config', 'main'); + o = s.option(this.CBIBlockInetStatus, this); + + if(this.currentAppMode === '2') { + o = s.option(this.CBIBlockServiceStatus, this); + + // restart button + o = s.option(form.Button, + '_restart_btn', _('Restart service') + ); + o.onclick = () => this.serviceRestart(); + o.inputtitle = _('Restart'); + o.inputstyle = btnStyleApply; + + // init button + o = s.option(this.CBIBlockInitButton, this); + }; /* Main settings */ - s = m.section(form.NamedSection, 'config', 'main'); + s = m.section(form.NamedSection, 'config', 'main'); s.tab('main_configuration', _('Main settings')); @@ -650,7 +680,7 @@ return L.view.extend({ /* Modules */ - s = m.section(form.NamedSection, 'config', 'main', + s = m.section(form.NamedSection, 'mod_led_control', 'module', _('Service modules'), _('Performing actions when connecting and disconnecting the Internet (available in the "Service" mode).')); @@ -658,27 +688,27 @@ return L.view.extend({ s.tab('led_control', _('LED control')); - o = s.taboption('led_control', form.SectionValue, 'mod_led_control', form.NamedSection, - 'mod_led_control', 'mod_led_control', - _('LED control'), - _('LED is on when Internet is available.')) - ss = o.subsection; + o = s.taboption('led_control', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '