From 83e8252f92b8c4c515d984f682991ad7d5f5857a Mon Sep 17 00:00:00 2001 From: gSpot Date: Sun, 12 May 2024 18:50:13 +0300 Subject: [PATCH] Minor fixes & improvements. --- autoinstall/current/autoinstall.sh | 4 +- luci-app-ruantiblock/Makefile | 2 +- .../resources/view/ruantiblock/info.js | 6 +- .../view/ruantiblock/log-abstract.js | 154 ++++++++++++++++++ .../resources/view/ruantiblock/log-base.js | 19 ++- .../resources/view/ruantiblock/log-widget.js | 4 +- .../resources/view/ruantiblock/log.js | 137 +--------------- ruantiblock/Makefile | 2 +- .../files/etc/ruantiblock/ruantiblock.conf | 2 +- ruantiblock/files/usr/bin/ruantiblock | 2 +- 10 files changed, 182 insertions(+), 150 deletions(-) create mode 100644 luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-abstract.js diff --git a/autoinstall/current/autoinstall.sh b/autoinstall/current/autoinstall.sh index 08acec9..5657b82 100755 --- a/autoinstall/current/autoinstall.sh +++ b/autoinstall/current/autoinstall.sh @@ -9,9 +9,9 @@ LUA_MODULE=0 LUCI_APP=1 OWRT_VERSION="current" -RUAB_VERSION="1.5-0" +RUAB_VERSION="1.5-1" RUAB_MOD_LUA_VERSION="1.5-0" -RUAB_LUCI_APP_VERSION="1.5-0" +RUAB_LUCI_APP_VERSION="1.5-1" BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master" PKG_DIR="/tmp" diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile index b7260ab..caba127 100644 --- a/luci-app-ruantiblock/Makefile +++ b/luci-app-ruantiblock/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk -PKG_VERSION:=1.5-0 +PKG_VERSION:=1.5-1 LUCI_TITLE:=LuCI support for ruantiblock LUCI_DEPENDS:=+ruantiblock LUCI_PKGARCH:=all diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js index 105ca1d..b10ea54 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js @@ -89,13 +89,15 @@ return view.extend({ let lines = `${_('No entries available...')}`; let ipTable = E('table', { 'id': 'ipTable', 'class': 'table' }); + ipDataArray.sort((a, b) => a[1] - b[1]); + if(ipDataArray.length > 0) { lines = []; ipDataArray.forEach((e, i) => { if(e) { lines.push( `${e[0]}` + - `${(e[1]) ? this.secToTimeString(e[1]) : ''}` + `${this.secToTimeString(e[1] | 0)}` ); }; }); @@ -104,7 +106,7 @@ return view.extend({ ipTable.append( E('tr', { 'class': 'tr table-titles' }, [ E('th', { 'class': 'th left', 'style': 'min-width:33%' }, _('IP address')), - (ipDataArray[0][1]) ? E('th', { 'class': 'th left' }, _('Timeout')) : '' + E('th', { 'class': 'th left' }, _('Timeout')), ]) ); }; diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-abstract.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-abstract.js new file mode 100644 index 0000000..a68e51e --- /dev/null +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-abstract.js @@ -0,0 +1,154 @@ +'use strict'; +'require baseclass'; +'require fs'; +'require view.ruantiblock.log-widget as widget'; + +return baseclass.extend({ + view: widget.view.extend({ + /** + * Pattern for picking application-specific entries from the log. + * + * @property {string} appPattern + */ + appPattern : '^', + + /** + * Enable "tail" option for the logread (logread -l). + * Must be disabled for application-specific log. + * + * @property {bool} loggerTail + */ + loggerTail : false, + + logdRegexp : new RegExp(/^([^\s]{3}\s+[^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+\d{4})\s+([a-z0-9]+)\.([a-z]+)\s+(.*)$/), + + syslog_ngRegexp: new RegExp(/^([^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2})\s+([^\s]+)\s+(.*)$/), + + entryRegexp : null, + + isLoggerChecked: false, + + entriesHandler : null, + + logger : null, + + getLogHash() { + return this.getLogData(1, true).then(data => { + return data || ''; + }); + }, + + // logd + logdHandler(strArray, lineNum) { + return [ + lineNum, // # (Number) + strArray[1], // Timestamp (String) + null, // Host (String) + strArray[2], // Facility (String) + strArray[3], // Level (String) + this.htmlEntities(strArray[4]) || ' ', // Message (String) + ]; + }, + + // syslog-ng + syslog_ngHandler(strArray, lineNum) { + if(!(strArray[2] in this.logHosts)) { + this.logHosts[strArray[2]] = this.makeLogHostsDropdownItem(strArray[2]); + }; + return [ + lineNum, // # (Number) + strArray[1], // Timestamp (String) + strArray[2], // Host (String) + null, // Facility (String) + null, // Level (String) + this.htmlEntities(strArray[3]) || ' ', // Message (String) + ]; + }, + + checkLogread() { + return Promise.all([ + L.resolveDefault(fs.stat('/sbin/logread'), null), + L.resolveDefault(fs.stat('/usr/sbin/logread'), null), + ]).then(stat => { + let logger = (stat[0]) ? stat[0].path : (stat[1]) ? stat[1].path : null; + if(logger) { + this.logger = logger; + } else { + throw new Error(_('Logread not found')); + }; + }); + }, + + async getLogData(tail, extraTstamp=false) { + if(!this.logger) { + await this.checkLogread(); + }; + let loggerArgs = []; + if(this.loggerTail && tail) { + loggerArgs.push('-l', String(tail)); + }; + loggerArgs.push('-e', this.appPattern); + if(extraTstamp) { + loggerArgs.push('-t'); + }; + return fs.exec_direct(this.logger, loggerArgs, 'text').catch(err => { + throw new Error(_('Unable to load log data:') + ' ' + err.message); + }); + }, + + parseLogData(logdata, tail) { + if(!logdata) { + return []; + }; + + let unsupportedLog = false; + let strings = logdata.trim().split(/\n/); + + if(!this.loggerTail && tail && tail > 0 && strings) { + strings = strings.slice(-tail); + }; + + this.totalLogLines = strings.length; + + let entriesArray = strings.map((e, i) => { + if(!this.isLoggerChecked) { + if(this.logdRegexp.test(e)) { + this.entryRegexp = this.logdRegexp; + this.isFacilities = true; + this.isLevels = true; + this.logHosts = {}; + this.entriesHandler = this.logdHandler; + } + else if(this.syslog_ngRegexp.test(e)) { + this.entryRegexp = this.syslog_ngRegexp; + this.isHosts = true; + this.logFacilities = {}; + this.logLevels = {}; + this.entriesHandler = this.syslog_ngHandler; + } else { + unsupportedLog = true; + return; + }; + this.isLoggerChecked = true; + }; + + let strArray = e.match(this.entryRegexp); + if(strArray) { + return this.entriesHandler(strArray, i + 1); + } else { + unsupportedLog = true; + return; + }; + }); + + if(unsupportedLog) { + throw new Error(_('Unable to load log data:') + ' ' + _('Unsupported log format')); + } else { + if(this.logSortingValue === 'desc') { + entriesArray.reverse(); + }; + return entriesArray; + }; + }, + }), +}); diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-base.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-base.js index 610b56f..8bb4747 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-base.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-base.js @@ -171,6 +171,13 @@ return baseclass.extend({ */ title : null, + /** + * Enable auto refresh log. + * + * @property {bool} autoRefresh + */ + autoRefresh : false, + pollInterval : L.env.pollinterval, logFacilities : { @@ -443,7 +450,7 @@ return baseclass.extend({ * @param {string} logdata * @param {number} tail * @returns {Array} - * Returns an array of values: [ #, Timestamp, Host, Level, Facility, Message ]. + * Returns an array of values: [ #, Timestamp, Host, Facility, Level, Message ]. */ parseLogData(logdata, tail) { throw new Error('parseLogData must be overridden by a subclass'); @@ -885,7 +892,7 @@ return baseclass.extend({ load() { this.restoreSettingsFromLocalStorage(); - if(typeof(this.getLogHash) != 'function') { + if(!this.autoRefresh || typeof(this.getLogHash) != 'function') { this.isAutorefresh = false; this.autoRefreshValue = false; }; @@ -1026,13 +1033,7 @@ return baseclass.extend({ if(this.fastTailValue > 0) { this.fastTailValue += this.fastTailIncrement; }; - return this.reloadLog(this.fastTailValue)/*.then(() => { - if(this.logSortingValue == 'desc') { - this.scrollToBottom(); - } else { - this.scrollToTop(); - }; - });*/ + return this.reloadLog(this.fastTailValue); }), }, `+${this.fastTailIncrement}`); diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-widget.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-widget.js index b2cdbc1..5a8e6c5 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-widget.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log-widget.js @@ -1,7 +1,7 @@ 'use strict'; 'require baseclass'; 'require ui'; -'require view.ruantiblock.log-base as abc'; +'require view.ruantiblock.log-base as base'; document.head.append(E('style', {'type': 'text/css'}, ` @@ -26,7 +26,7 @@ document.head.append(E('style', {'type': 'text/css'}, `)); return baseclass.extend({ - view: abc.view.extend({ + view: base.view.extend({ filterHighlightFunc(match) { return `${match}`; diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log.js index fe610cf..c899dd3 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/log.js @@ -1,135 +1,10 @@ -'require fs'; -'require rpc'; -'require ui'; -'require view.ruantiblock.log-widget as abc'; +'use strict'; +'require view.ruantiblock.log-abstract as abc'; 'require view.ruantiblock.tools as tools'; return abc.view.extend({ - viewName : 'ruantiblock', - - title : _('Ruantiblock') + ' - ' + _('Log'), - - logdRegexp : new RegExp(/^([^\s]{3}\s+[^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+\d{4})\s+([a-z]+)\.([a-z]+)\s+(.*)$/), - - syslog_ngRegexp: new RegExp(/^([^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2})\s+([^\s]+)\s+(.*)$/), - - entryRegexp : null, - - isLoggerChecked: false, - - entriesHandler : null, - - logger : null, - - getLogHash : null, - - // logd - logdHandler(strArray, lineNum) { - return [ - lineNum, // # (Number) - strArray[1], // Timestamp (String) - null, // Host (String) - strArray[2], // Facility (String) - strArray[3], // Level (String) - this.htmlEntities(strArray[4]) || ' ', // Message (String) - ]; - }, - - // syslog-ng - syslog_ngHandler(strArray, lineNum) { - if(!(strArray[2] in this.logHosts)) { - this.logHosts[strArray[2]] = this.makeLogHostsDropdownItem(strArray[2]); - }; - return [ - lineNum, // # (Number) - strArray[1], // Timestamp (String) - strArray[2], // Host (String) - null, // Facility (String) - null, // Level (String) - this.htmlEntities(strArray[3]) || ' ', // Message (String) - ]; - }, - - checkLogread() { - return Promise.all([ - L.resolveDefault(fs.stat('/sbin/logread'), null), - L.resolveDefault(fs.stat('/usr/sbin/logread'), null), - ]).then(stat => { - let logger = (stat[0]) ? stat[0].path : (stat[1]) ? stat[1].path : null; - if(logger) { - this.logger = logger; - } else { - throw new Error(_('Logread not found')); - }; - }); - }, - - async getLogData(tail, extraTstamp=false) { - if(!this.logger) { - await this.checkLogread(); - }; - let loggerArgs = []; - loggerArgs.push('-e', tools.appName + ':'); - if(extraTstamp) { - loggerArgs.push('-t'); - }; - return fs.exec_direct(this.logger, loggerArgs, 'text').catch(err => { - throw new Error(_('Unable to load log data:') + ' ' + err.message); - }); - }, - - parseLogData(logdata, tail) { - if(!logdata) { - return []; - }; - - let unsupportedLog = false; - let strings = logdata.trim().split(/\n/); - - if(tail && tail > 0 && strings) { - strings = strings.slice(-tail); - }; - - this.totalLogLines = strings.length; - - let entriesArray = strings.map((e, i) => { - if(!this.isLoggerChecked) { - if(this.logdRegexp.test(e)) { - this.entryRegexp = this.logdRegexp; - this.isFacilities = true; - this.isLevels = true; - this.logHosts = {}; - this.entriesHandler = this.logdHandler; - } - else if(this.syslog_ngRegexp.test(e)) { - this.entryRegexp = this.syslog_ngRegexp; - this.isHosts = true; - this.logFacilities = {}; - this.logLevels = {}; - this.entriesHandler = this.syslog_ngHandler; - } else { - unsupportedLog = true; - return; - }; - this.isLoggerChecked = true; - }; - - let strArray = e.match(this.entryRegexp); - if(strArray) { - return this.entriesHandler(strArray, i + 1); - } else { - unsupportedLog = true; - return; - }; - }); - - if(unsupportedLog) { - throw new Error(_('Unable to load log data:') + ' ' + _('Unsupported log format')); - } else { - if(this.logSortingValue === 'desc') { - entriesArray.reverse(); - }; - return entriesArray; - }; - }, + viewName : 'ruantiblock', + title : _('Ruantiblock') + ' - ' + _('Log'), + autoRefresh: false, + appPattern : tools.appName + ':', }); diff --git a/ruantiblock/Makefile b/ruantiblock/Makefile index ca661dc..8ecb44a 100644 --- a/ruantiblock/Makefile +++ b/ruantiblock/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock PKG_VERSION:=1.5 -PKG_RELEASE:=0 +PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot include $(INCLUDE_DIR)/package.mk diff --git a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf index 7164f7b..64a904b 100644 --- a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf +++ b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf @@ -60,7 +60,7 @@ NFTSET_POLICY_CIDR="memory" NFTSET_POLICY_IP="memory" NFTSET_POLICY_DNSMASQ="performance" ### Таймаут для записей в сете $NFTSET_DNSMASQ -NFTSET_DNSMASQ_TIMEOUT="3h" +NFTSET_DNSMASQ_TIMEOUT="150m" ### Динамическое обновление таймаута записей в сете $NFTSET_DNSMASQ (0 - выкл, 1 - вкл) NFTSET_DNSMASQ_TIMEOUT_UPDATE=1 ### Приоритет правила отбора пакетов nftables для конфигупации Tor или прозрачного прокси diff --git a/ruantiblock/files/usr/bin/ruantiblock b/ruantiblock/files/usr/bin/ruantiblock index fc233aa..2638900 100755 --- a/ruantiblock/files/usr/bin/ruantiblock +++ b/ruantiblock/files/usr/bin/ruantiblock @@ -77,7 +77,7 @@ export NFTSET_POLICY_CIDR="memory" export NFTSET_POLICY_IP="memory" export NFTSET_POLICY_DNSMASQ="performance" ### Таймаут для записей в сете $NFTSET_DNSMASQ -export NFTSET_DNSMASQ_TIMEOUT="3h" +export NFTSET_DNSMASQ_TIMEOUT="150m" ### Динамическое обновление таймаута записей в сете $NFTSET_DNSMASQ (0 - выкл, 1 - вкл) export NFTSET_DNSMASQ_TIMEOUT_UPDATE=1 ### Приоритет правила отбора пакетов nftables для конфигупации Tor или прозрачного прокси