diff --git a/autoinstall/autoinstall.sh b/autoinstall/autoinstall.sh index 7a061ba..88c2338 100755 --- a/autoinstall/autoinstall.sh +++ b/autoinstall/autoinstall.sh @@ -11,7 +11,7 @@ LUCI_APP=1 OWRT_VERSION="19.07" RUAB_VERSION="0.9.0-2" RUAB_MOD_LUA_VERSION="0.9.0-2" -RUAB_LUCI_APP_VERSION="0.9.0-4" +RUAB_LUCI_APP_VERSION="0.9.0-5" BASE_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_openwrt/master" PKG_DIR="/tmp" diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile index 833340a..6c6a7d5 100644 --- a/luci-app-ruantiblock/Makefile +++ b/luci-app-ruantiblock/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=0.9.0 -PKG_RELEASE:=4 +PKG_RELEASE:=5 LUCI_TITLE:=LuCI support for ruantiblock LUCI_DEPENDS:=+ruantiblock +luci-mod-admin-full LUCI_PKGARCH:=all diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/baselog.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/abstract-log.js similarity index 81% rename from luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/baselog.js rename to luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/abstract-log.js index f6b13cf..b4d08da 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/baselog.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/abstract-log.js @@ -1,217 +1,7 @@ 'use strict'; 'require ui'; -return L.Class.extend({ - view: L.view.extend({ - viewName: null, - - title: null, - - logFacilities: [ - 'kern', - 'user', - 'mail', - 'daemon', - 'auth', - 'syslog', - 'lpr', - 'news', - ], - - logLevels: { - 'emerg': E('span', { 'class': 'zonebadge log-emerg' }, E('strong', _('Emergency'))), - 'alert': E('span', { 'class': 'zonebadge log-alert' }, E('strong', _('Alert'))), - 'crit': E('span', { 'class': 'zonebadge log-crit' }, E('strong', _('Critical'))), - 'err': E('span', { 'class': 'zonebadge log-err' }, E('strong', _('Error'))), - 'warn': E('span', { 'class': 'zonebadge log-warn' }, E('strong', _('Warning'))), - 'notice': E('span', { 'class': 'zonebadge log-notice' }, E('strong', _('Notice'))), - 'info': E('span', { 'class': 'zonebadge log-info' }, E('strong', _('Info'))), - 'debug': E('span', { 'class': 'zonebadge log-debug' }, E('strong', _('Debug'))), - }, - - tailValue: 25, - - logSortingValue: 'asc', - - logLevelsStat: {}, - - logLevelsDropdown: null, - - totalLogLines: 0, - - htmlEntities: function(str) { - return String(str).replace( - /&/g, '&').replace( - //g, '>').replace( - /"/g, '"').replace( - /'/g, '''); - }, - - /** - * - * @param {number} tail - * @returns {string} - * Returns the raw content of the log - * - */ - getLogData: function(tail) { - throw new Error('getLogData needs to be reloaded in subclass'); - }, - - /** - * - * @param {string} logdata - * @param {number} tail - * @returns {Array} - * Returns an array of values: [ #, Timestamp, Level, Facility, Message ] - * - */ - parseLogData: function(logdata, tail) { - throw new Error('parseLogData needs to be reloaded in subclass'); - }, - - setLevelFilter: function(cArr) { - let logLevelsKeys = Object.keys(this.logLevels); - if(logLevelsKeys.length > 0) { - let selectedLevels = this.logLevelsDropdown.getValue(); - if(logLevelsKeys.length === selectedLevels.length) { - return cArr; - }; - return cArr.filter(s => selectedLevels.length === 0 || selectedLevels.includes(s[2])); - }; - return cArr; - }, - - setRegexpFilter: function(cArr) { - let fPattern = document.getElementById('logFilter').value; - if(!fPattern) { - return cArr; - }; - let fArr = []; - try { - let regExp = new RegExp(`(${fPattern})`, 'giu'); - cArr.forEach((e, i) => { - if(e[4] !== null && regExp.test(e[4])) { - e[4] = e[4].replace(regExp, '$1'); - fArr.push(e); - }; - }); - } catch(err) { - if(err.name === 'SyntaxError') { - ui.addNotification(null, - E('p', {}, _('Invalid regular expression') + ': ' + err.message)); - return cArr; - } else { - throw err; - }; - }; - return fArr; - }, - - makeLogArea: function(logdataArray) { - let lines = `
${_('No entries available...')}
`; - let logTable = E('div', { 'id': 'logTable', 'class': 'table' }); - - for(let level of Object.keys(this.logLevels)) { - this.logLevelsStat[level] = 0; - }; - - if(logdataArray.length > 0) { - lines = []; - logdataArray.forEach((e, i) => { - if(e[2] in this.logLevels) { - this.logLevelsStat[e[2]] = this.logLevelsStat[e[2]] + 1; - }; - - lines.push( - `
${e[0]}
` + - ((e[1]) ? `
${e[1]}
` : '') + - ((e[2]) ? `
${e[2]}
` : '') + - ((e[3]) ? `
${e[3]}
` : '') + - ((e[4]) ? `
${e[4]}
` : '') + - `
` - ); - }); - lines = lines.join(''); - - logTable.append( - E('div', { 'class': 'tr table-titles' }, [ - E('div', { 'class': 'th left log-entry-number' }, '#'), - (logdataArray[0][1]) ? E('div', { 'class': 'th left log-entry-time' }, _('Timestamp')) : '', - (logdataArray[0][2]) ? E('div', { 'class': 'th left log-entry-log-level' }, _('Level')) : '', - (logdataArray[0][3]) ? E('div', { 'class': 'th left log-entry-facility' }, _('Facility')) : '', - (logdataArray[0][4]) ? E('div', { 'class': 'th left log-entry-message' }, _('Message')) : '', - ]) - ); - }; - - try { - logTable.insertAdjacentHTML('beforeend', lines); - } catch(err) { - if(err.name === 'SyntaxError') { - ui.addNotification(null, - E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error'); - }; - throw err; - }; - - let levelsStatString = ''; - if((Object.values(this.logLevelsStat).reduce((s,c) => s + c, 0)) > 0) { - Object.entries(this.logLevelsStat).forEach(e => { - if(e[0] in this.logLevels && e[1] > 0) { - levelsStatString += `${e[1]}`; - }; - }); - }; - - return E([ - E('div', { 'class': 'log-entries-count' }, - `${_('Entries')}: ${logdataArray.length} / ${this.totalLogLines}${levelsStatString}` - ), - logTable - ]); - }, - - downloadLog: function(ev) { - let formElems = Array.from(document.forms.logForm.elements); - formElems.forEach(e => e.disabled = true); - - return this.getLogData(0).then(logdata => { - logdata = logdata || ''; - let link = E('a', { - 'download': this.viewName + '.log', - 'href': URL.createObjectURL( - new Blob([ logdata ], { type: 'text/plain' })), - }); - link.click(); - URL.revokeObjectURL(link.href); - }).catch(() => { - ui.addNotification(null, - E('p', {}, _('Download error') + ': ' + err.message)); - }).finally(() => { - formElems.forEach(e => e.disabled = false); - }); - }, - - load: function() { - - // Restoring settings from localStorage - let tailValueLocal = localStorage.getItem(`luci-app-${this.viewName}-tailValue`); - if(tailValueLocal) { - this.tailValue = Number(tailValueLocal); - }; - let logSortingLocal = localStorage.getItem(`luci-app-${this.viewName}-logSorting`); - if(logSortingLocal) { - this.logSortingValue = logSortingLocal; - }; - - return this.getLogData(this.tailValue); - }, - - render: function(logdata) { - - document.head.append(E('style', {'type': 'text/css'}, +document.head.append(E('style', {'type': 'text/css'}, ` .log-entry-empty { } @@ -221,6 +11,13 @@ return L.Class.extend({ .log-entry-time { min-width: 14em !important; } +.log-entry-host { + min-width: 10em !important; +} +.log-entry-host-cell { + word-break: break-all !important; + word-wrap: break-word !important; +} .log-entry-log-level { max-width: 5em !important; } @@ -291,9 +88,234 @@ log-emerg td { border: 1px solid #ccc; font-weight: normal; } -` - )); +.log-host-dropdown-item { +} +`)); +return L.Class.extend({ + view: L.view.extend({ + viewName: null, + + title: null, + + logLevels: { + 'emerg': E('span', { 'class': 'zonebadge log-emerg' }, E('strong', _('Emergency'))), + 'alert': E('span', { 'class': 'zonebadge log-alert' }, E('strong', _('Alert'))), + 'crit': E('span', { 'class': 'zonebadge log-crit' }, E('strong', _('Critical'))), + 'err': E('span', { 'class': 'zonebadge log-err' }, E('strong', _('Error'))), + 'warn': E('span', { 'class': 'zonebadge log-warn' }, E('strong', _('Warning'))), + 'notice': E('span', { 'class': 'zonebadge log-notice' }, E('strong', _('Notice'))), + 'info': E('span', { 'class': 'zonebadge log-info' }, E('strong', _('Info'))), + 'debug': E('span', { 'class': 'zonebadge log-debug' }, E('strong', _('Debug'))), + }, + + tailValue: 25, + + logSortingValue: 'asc', + + logLevelsStat: {}, + + logHosts: {}, + + logHostsDropdown: null, + + logLevelsDropdown: null, + + totalLogLines: 0, + + htmlEntities: function(str) { + return String(str).replace( + /&/g, '&').replace( + //g, '>').replace( + /"/g, '"').replace( + /'/g, '''); + }, + + makelogHostsDropdownItem: function(host) { + return E( + 'span', + { 'class': 'zonebadge log-host-dropdown-item' }, + E('strong', host) + ); + }, + + /** + * + * @param {number} tail + * @returns {string} + * Returns the raw content of the log + * + */ + getLogData: function(tail) { + throw new Error('getLogData must be overridden by a subclass'); + }, + + /** + * + * @param {string} logdata + * @param {number} tail + * @returns {Array} + * Returns an array of values: [ #, Timestamp, Host, Level, Facility, Message ] + * + */ + parseLogData: function(logdata, tail) { + throw new Error('parseLogData must be overridden by a subclass'); + }, + + setHostFilter: function(cArr) { + let logHostsKeys = Object.keys(this.logHosts); + if(logHostsKeys.length > 0) { + let selectedHosts = this.logHostsDropdown.getValue(); + this.logHostsDropdown.addChoices(Object.keys(this.logHosts), this.logHosts); + if(selectedHosts.length === 0 || logHostsKeys.length === selectedHosts.length) { + return cArr; + }; + return cArr.filter(e => selectedHosts.includes(e[2])); + }; + return cArr; + }, + + setLevelFilter: function(cArr) { + let logLevelsKeys = Object.keys(this.logLevels); + if(logLevelsKeys.length > 0) { + let selectedLevels = this.logLevelsDropdown.getValue(); + if(selectedLevels.length === 0 || logLevelsKeys.length === selectedLevels.length) { + return cArr; + }; + return cArr.filter(e => selectedLevels.includes(e[3])); + }; + return cArr; + }, + + setRegexpFilter: function(cArr) { + let fPattern = document.getElementById('logFilter').value; + if(!fPattern) { + return cArr; + }; + let fArr = []; + try { + let regExp = new RegExp(`(${fPattern})`, 'giu'); + cArr.forEach((e, i) => { + if(e[5] !== null && regExp.test(e[5])) { + e[5] = e[5].replace(regExp, '$1'); + fArr.push(e); + }; + }); + } catch(err) { + if(err.name === 'SyntaxError') { + ui.addNotification(null, + E('p', {}, _('Invalid regular expression') + ': ' + err.message)); + return cArr; + } else { + throw err; + }; + }; + return fArr; + }, + + makeLogArea: function(logdataArray) { + let lines = `
${_('No entries available...')}
`; + let logTable = E('div', { 'id': 'logTable', 'class': 'table' }); + + for(let level of Object.keys(this.logLevels)) { + this.logLevelsStat[level] = 0; + }; + + if(logdataArray.length > 0) { + lines = []; + logdataArray.forEach((e, i) => { + if(e[3] in this.logLevels) { + this.logLevelsStat[e[3]] = this.logLevelsStat[e[3]] + 1; + }; + + lines.push( + `
${e[0]}
` + + ((e[1]) ? `
${e[1]}
` : '') + + ((e[2]) ? `
${e[2]}
` : '') + + ((e[3]) ? `
${e[3]}
` : '') + + ((e[4]) ? `
${e[4]}
` : '') + + ((e[5]) ? `
${e[5]}
` : '') + + `
` + ); + }); + lines = lines.join(''); + + logTable.append( + E('div', { 'class': 'tr table-titles' }, [ + E('div', { 'class': 'th left log-entry-number' }, '#'), + (logdataArray[0][1]) ? E('div', { 'class': 'th left log-entry-time' }, _('Timestamp')) : '', + (logdataArray[0][2]) ? E('div', { 'class': 'th left log-entry-host' }, _('Host')) : '', + (logdataArray[0][3]) ? E('div', { 'class': 'th left log-entry-log-level' }, _('Level')) : '', + (logdataArray[0][4]) ? E('div', { 'class': 'th left log-entry-facility' }, _('Facility')) : '', + (logdataArray[0][5]) ? E('div', { 'class': 'th left log-entry-message' }, _('Message')) : '', + ]) + ); + }; + + try { + logTable.insertAdjacentHTML('beforeend', lines); + } catch(err) { + if(err.name === 'SyntaxError') { + ui.addNotification(null, + E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error'); + }; + throw err; + }; + + let levelsStatString = ''; + if((Object.values(this.logLevelsStat).reduce((s,c) => s + c, 0)) > 0) { + Object.entries(this.logLevelsStat).forEach(e => { + if(e[0] in this.logLevels && e[1] > 0) { + levelsStatString += `${e[1]}`; + }; + }); + }; + + return E([ + E('div', { 'class': 'log-entries-count' }, + `${_('Entries')}: ${logdataArray.length} / ${this.totalLogLines}${levelsStatString}` + ), + logTable + ]); + }, + + downloadLog: function(ev) { + let formElems = Array.from(document.forms.logForm.elements); + formElems.forEach(e => e.disabled = true); + + return this.getLogData(0).then(logdata => { + logdata = logdata || ''; + let link = E('a', { + 'download': this.viewName + '.log', + 'href': URL.createObjectURL( + new Blob([ logdata ], { type: 'text/plain' })), + }); + link.click(); + URL.revokeObjectURL(link.href); + }).catch(() => { + ui.addNotification(null, + E('p', {}, _('Download error') + ': ' + err.message)); + }).finally(() => { + formElems.forEach(e => e.disabled = false); + }); + }, + + load: function() { + // Restoring settings from localStorage + let tailValueLocal = localStorage.getItem(`luci-app-${this.viewName}-tailValue`); + if(tailValueLocal) { + this.tailValue = Number(tailValueLocal); + }; + let logSortingLocal = localStorage.getItem(`luci-app-${this.viewName}-logSorting`); + if(logSortingLocal) { + this.logSortingValue = logSortingLocal; + }; + + return this.getLogData(this.tailValue); + }, + + render: function(logdata) { let logWrapper = E('div', { 'id': 'logWrapper', 'style': 'width:100%; min-height:20em; padding: 0 0 0 45px; font-size:0.9em !important' @@ -324,6 +346,31 @@ log-emerg td { 'style': 'max-width:4em !important', }); + let logHostsDropdownElem = ''; + let logHostsKeys = Object.keys(this.logHosts); + if(logHostsKeys.length > 0) { + this.logHostsDropdown = new ui.Dropdown( + null, + this.logHosts, + { + id: 'logHostsDropdown', + multiple: true, + select_placeholder: _('All'), + } + ); + logHostsDropdownElem = E( + 'div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for': 'logHostsDropdown', + }, _('Hosts')), + E('div', { 'class': 'cbi-value-field' }, + this.logHostsDropdown.render() + ), + ] + ); + }; + let logLevelsDropdownElem = ''; let logLevelsKeys = Object.keys(this.logLevels); if(logLevelsKeys.length > 0) { @@ -335,8 +382,6 @@ log-emerg td { sort: logLevelsKeys, multiple: true, select_placeholder: _('All'), - display_items: 3, - dropdown_items: -1, } ); logLevelsDropdownElem = E( @@ -405,6 +450,7 @@ log-emerg td { ]), ]), + logHostsDropdownElem, logLevelsDropdownElem, E('div', { 'class': 'cbi-value' }, [ @@ -427,7 +473,7 @@ log-emerg td { E('label', { 'class': 'cbi-value-title', 'for': 'logFilter', - }), + }, _('Refresh log')), E('div', { 'class': 'cbi-value-field' }, [ logFormSubmitBtn, E('form', { @@ -455,18 +501,18 @@ log-emerg td { let tail = (tailInput.value && tailInput.value > 0) ? tailInput.value : 0 return this.getLogData(tail).then(logdata => { logdata = logdata || ''; - - let loglines = this.makeLogArea( - this.setRegexpFilter( - this.setLevelFilter( - this.parseLogData(logdata, tail) + logWrapper.innerHTML = ''; + logWrapper.append( + this.makeLogArea( + this.setRegexpFilter( + this.setLevelFilter( + this.setHostFilter( + this.parseLogData(logdata, tail) + ) + ) ) ) ); - - logWrapper.innerHTML = ''; - logWrapper.append(loglines); - }).finally(() => { formElems.forEach(e => e.disabled = false); logDownloadBtn.disabled = false; 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 ad21c26..f3be49d 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,9 +1,9 @@ 'require fs'; 'require ui'; -'require view.log.baselog as baselog'; +'require view.log.abstract-log as abc'; 'require view.ruantiblock.tools as tools'; -return baselog.view.extend({ +return abc.view.extend({ viewName: 'ruantiblock', title: _('Ruantiblock') + ' - ' + _('Log'), @@ -22,6 +22,7 @@ return baselog.view.extend({ return [ lineNum, // # (Number) strArray.slice(0, 5).join(' '), // Timestamp (String) + null, // Host (String) logLevel[1], // Level (String) logLevel[0], // Facility (String) this.htmlEntities(strArray.slice(6).join(' ')), // Message (String) @@ -30,9 +31,14 @@ return baselog.view.extend({ // syslog-ng syslog_ngHandler: function(strArray, lineNum) { + if(!(strArray[3] in this.logHosts)) { + this.logHosts[strArray[3]] = this.makelogHostsDropdownItem(strArray[3]); + }; + return [ lineNum, // # (Number) strArray.slice(0, 3).join(' '), // Timestamp (String) + strArray[3], // Host (String) null, // Level (String) null, // Facility (String) this.htmlEntities(strArray.slice(4).join(' ')), // Message (String) @@ -48,7 +54,7 @@ return baselog.view.extend({ if(logger) { return fs.exec_direct(logger, [ '-e', tools.app_name ]).catch(err => { - ui.addNotification(null, E('p', {}, _('Unable to load log data: ' + err.message))); + ui.addNotification(null, E('p', {}, _('Unable to load log data:') + ' ' + err.message)); return ''; }); }; diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js index b215abc..25730f2 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js @@ -250,8 +250,6 @@ return L.view.extend({ let proxy_local_clients = (typeof(section) === 'object') ? section.proxy_local_clients : null; status_token_value = (Array.isArray(status_array)) ? tools.normalize_value(status_array[4]) : null; - document.head.append(E('style', {'type': 'text/css'}, tools.css)); - let status_string = E('div', { 'id': 'status', 'name': 'status', diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js index 671498a..48444c4 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js @@ -2,30 +2,8 @@ 'require fs'; 'require ui'; -return L.Class.extend({ - app_name: 'ruantiblock', - exec_path: '/usr/bin/ruantiblock', - init_path: '/etc/init.d/ruantiblock', - token_file: '/var/run/ruantiblock.token', - parsers_dir: '/usr/bin', - torrc_file: '/etc/tor/torrc', - user_entries_file: '/etc/ruantiblock/user_entries', - fqdn_filter_file: '/etc/ruantiblock/fqdn_filter', - ip_filter_file: '/etc/ruantiblock/ip_filter', - crontab_file: '/etc/crontabs/root', - info_label_starting: '' + _('Starting') + '', - info_label_running: '' + _('Enabled') + '', - info_label_updating: '' + _('Updating') + '', - info_label_stopped: '' + _('Disabled') + '', - info_label_error: '' + _('Error') + '', - - blacklist_sources: { - 'rublacklist': 'https://rublacklist.net', - 'zapret-info': 'https://github.com/zapret-info/z-i', - 'antifilter': 'https://antifilter.download', - }, - - css: ` +document.head.append(E('style', {'type': 'text/css'}, +` .label-status { display: inline; margin: 0px 2px 0px 0 !important; @@ -53,7 +31,31 @@ return L.Class.extend({ } .total-proxy { background-color: #ffb937 !important; -}`, +} +`)); + +return L.Class.extend({ + app_name: 'ruantiblock', + exec_path: '/usr/bin/ruantiblock', + init_path: '/etc/init.d/ruantiblock', + token_file: '/var/run/ruantiblock.token', + parsers_dir: '/usr/bin', + torrc_file: '/etc/tor/torrc', + user_entries_file: '/etc/ruantiblock/user_entries', + fqdn_filter_file: '/etc/ruantiblock/fqdn_filter', + ip_filter_file: '/etc/ruantiblock/ip_filter', + crontab_file: '/etc/crontabs/root', + info_label_starting: '' + _('Starting') + '', + info_label_running: '' + _('Enabled') + '', + info_label_updating: '' + _('Updating') + '', + info_label_stopped: '' + _('Disabled') + '', + info_label_error: '' + _('Error') + '', + + blacklist_sources: { + 'rublacklist': 'https://rublacklist.net', + 'zapret-info': 'https://github.com/zapret-info/z-i', + 'antifilter': 'https://antifilter.download', + }, normalize_value: function(v) { return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v; diff --git a/luci-app-ruantiblock/po/ru/ruantiblock.po b/luci-app-ruantiblock/po/ru/ruantiblock.po index aac0bc3..da57d17 100644 --- a/luci-app-ruantiblock/po/ru/ruantiblock.po +++ b/luci-app-ruantiblock/po/ru/ruantiblock.po @@ -386,6 +386,12 @@ msgstr "Записи" msgid "Facility" msgstr "Категория" +msgid "Host" +msgstr "Хост" + +msgid "Hosts" +msgstr "Хосты" + msgid "Info" msgstr "Информация" @@ -413,6 +419,9 @@ msgstr "Нет доступных записей..." msgid "Notice" msgstr "Сообщение" +msgid "Refresh log" +msgstr "Обновить лог" + msgid "Sorting entries" msgstr "Сортировка записей" diff --git a/luci-app-ruantiblock/po/templates/ruantiblock.pot b/luci-app-ruantiblock/po/templates/ruantiblock.pot index 069ba5c..f3a858d 100644 --- a/luci-app-ruantiblock/po/templates/ruantiblock.pot +++ b/luci-app-ruantiblock/po/templates/ruantiblock.pot @@ -113,6 +113,9 @@ msgstr "" msgid "Hour" msgstr "" +msgid "Hour" +msgstr "" + msgid "Interval" msgstr "" @@ -356,6 +359,12 @@ msgstr "" msgid "Facility" msgstr "" +msgid "Host" +msgstr "" + +msgid "Hosts" +msgstr "" + msgid "Info" msgstr "" @@ -383,6 +392,9 @@ msgstr "" msgid "Notice" msgstr "" +msgid "Refresh log" +msgstr "" + msgid "Sorting entries" msgstr "" diff --git a/packages/19.07/luci-app-ruantiblock_0.9.0-4_all.ipk b/packages/19.07/luci-app-ruantiblock_0.9.0-4_all.ipk deleted file mode 100644 index 6d91ce6..0000000 Binary files a/packages/19.07/luci-app-ruantiblock_0.9.0-4_all.ipk and /dev/null differ diff --git a/packages/19.07/luci-app-ruantiblock_0.9.0-5_all.ipk b/packages/19.07/luci-app-ruantiblock_0.9.0-5_all.ipk new file mode 100644 index 0000000..bc3acdf Binary files /dev/null and b/packages/19.07/luci-app-ruantiblock_0.9.0-5_all.ipk differ diff --git a/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-4_all.ipk b/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-4_all.ipk deleted file mode 100644 index 00b3f45..0000000 Binary files a/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-4_all.ipk and /dev/null differ diff --git a/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-5_all.ipk b/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-5_all.ipk new file mode 100644 index 0000000..cb13414 Binary files /dev/null and b/packages/19.07/luci-i18n-ruantiblock-ru_0.9.0-5_all.ipk differ diff --git a/packages/19.07/ruantiblock-mod-lua_0.9.0-2_all.ipk b/packages/19.07/ruantiblock-mod-lua_0.9.0-2_all.ipk index 8ab8f73..971a8b2 100644 Binary files a/packages/19.07/ruantiblock-mod-lua_0.9.0-2_all.ipk and b/packages/19.07/ruantiblock-mod-lua_0.9.0-2_all.ipk differ diff --git a/packages/19.07/ruantiblock-mod-py_0.9.0-2_all.ipk b/packages/19.07/ruantiblock-mod-py_0.9.0-2_all.ipk index cd4489c..0e0e3cf 100644 Binary files a/packages/19.07/ruantiblock-mod-py_0.9.0-2_all.ipk and b/packages/19.07/ruantiblock-mod-py_0.9.0-2_all.ipk differ diff --git a/ruantiblock-mod-lua/files/usr/bin/ruab_parser.lua b/ruantiblock-mod-lua/files/usr/bin/ruab_parser.lua index 36b7539..fde97a1 100755 --- a/ruantiblock-mod-lua/files/usr/bin/ruab_parser.lua +++ b/ruantiblock-mod-lua/files/usr/bin/ruab_parser.lua @@ -317,8 +317,8 @@ function BlackListParser:fill_domain_tables(val) end function BlackListParser:sink() - -- Needs to be reloaded in subclass - error("Method BlackListParser:sink() needs to be reloaded in subclass!") + -- Must be overridden by a subclass + error("Method BlackListParser:sink() must be overridden by a subclass!") end function BlackListParser:optimize_ip_table() diff --git a/ruantiblock-mod-py/files/usr/bin/ruab_parser.py b/ruantiblock-mod-py/files/usr/bin/ruab_parser.py index e64652a..240611b 100755 --- a/ruantiblock-mod-py/files/usr/bin/ruab_parser.py +++ b/ruantiblock-mod-py/files/usr/bin/ruab_parser.py @@ -294,7 +294,7 @@ class BlackListParser(Config): raise FieldValueError() def parser_func(self): - """Needs to be reloaded in subclass""" + """Must be overridden by a subclass""" raise NotImplementedError() def _check_sld_masks(self, sld):