mirror of
https://github.com/gSpotx2f/ruantiblock_openwrt.git
synced 2026-05-14 14:40:58 +00:00
luci-app: updated log.
This commit is contained in:
@@ -11,7 +11,7 @@ LUCI_APP=1
|
|||||||
OWRT_VERSION="current"
|
OWRT_VERSION="current"
|
||||||
RUAB_VERSION="1.3-1"
|
RUAB_VERSION="1.3-1"
|
||||||
RUAB_MOD_LUA_VERSION="1.3-2"
|
RUAB_MOD_LUA_VERSION="1.3-2"
|
||||||
RUAB_LUCI_APP_VERSION="1.3-3"
|
RUAB_LUCI_APP_VERSION="1.3-4"
|
||||||
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
|
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
|
||||||
PKG_DIR="/tmp"
|
PKG_DIR="/tmp"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_VERSION:=1.3-3
|
PKG_VERSION:=1.3-4
|
||||||
LUCI_TITLE:=LuCI support for ruantiblock
|
LUCI_TITLE:=LuCI support for ruantiblock
|
||||||
LUCI_DEPENDS:=+ruantiblock
|
LUCI_DEPENDS:=+ruantiblock
|
||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
'require poll';
|
||||||
'require baseclass';
|
'require baseclass';
|
||||||
'require ui';
|
'require ui';
|
||||||
'require view';
|
'require view';
|
||||||
@@ -161,6 +162,8 @@ return baseclass.extend({
|
|||||||
*/
|
*/
|
||||||
title : null,
|
title : null,
|
||||||
|
|
||||||
|
pollInterval : L.env.pollinterval,
|
||||||
|
|
||||||
logFacilities : {
|
logFacilities : {
|
||||||
'kern' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'kern')),
|
'kern' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'kern')),
|
||||||
'user' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'user')),
|
'user' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'user')),
|
||||||
@@ -203,8 +206,20 @@ return baseclass.extend({
|
|||||||
|
|
||||||
fastTailValue : null,
|
fastTailValue : null,
|
||||||
|
|
||||||
|
timeFilterValue : null,
|
||||||
|
|
||||||
|
hostFilterValue : [],
|
||||||
|
|
||||||
|
facilityFilterValue : [],
|
||||||
|
|
||||||
|
levelFilterValue : [],
|
||||||
|
|
||||||
|
msgFilterValue : null,
|
||||||
|
|
||||||
logSortingValue : 'asc',
|
logSortingValue : 'asc',
|
||||||
|
|
||||||
|
autoRefreshValue : true,
|
||||||
|
|
||||||
isHosts : false,
|
isHosts : false,
|
||||||
|
|
||||||
isFacilities : false,
|
isFacilities : false,
|
||||||
@@ -223,6 +238,10 @@ return baseclass.extend({
|
|||||||
|
|
||||||
totalLogLines : 0,
|
totalLogLines : 0,
|
||||||
|
|
||||||
|
lastBytes : null,
|
||||||
|
|
||||||
|
actionButtons : [],
|
||||||
|
|
||||||
htmlEntities(str) {
|
htmlEntities(str) {
|
||||||
return String(str).replace(
|
return String(str).replace(
|
||||||
/&/g, '&').replace(
|
/&/g, '&').replace(
|
||||||
@@ -232,6 +251,10 @@ return baseclass.extend({
|
|||||||
/'/g, ''');
|
/'/g, ''');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkZeroValue(value) {
|
||||||
|
return (/^[0-9]+$/.test(value)) ? value : 0
|
||||||
|
},
|
||||||
|
|
||||||
makeLogHostsDropdownItem(host) {
|
makeLogHostsDropdownItem(host) {
|
||||||
return E(
|
return E(
|
||||||
'span',
|
'span',
|
||||||
@@ -311,6 +334,47 @@ return baseclass.extend({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setFilterSettings() {
|
||||||
|
this.tailValue = this.checkZeroValue(this.tailInput.value);
|
||||||
|
this.timeFilterValue = this.timeFilter.value;
|
||||||
|
if(this.isHosts) {
|
||||||
|
this.hostFilterValue = this.logHostsDropdown.getValue();
|
||||||
|
};
|
||||||
|
if(this.isFacilities) {
|
||||||
|
this.facilityFilterValue = this.logFacilitiesDropdown.getValue();
|
||||||
|
};
|
||||||
|
if(this.isLevels) {
|
||||||
|
this.levelFilterValue = this.logLevelsDropdown.getValue();
|
||||||
|
};
|
||||||
|
this.msgFilterValue = this.msgFilter.value;
|
||||||
|
this.logSortingValue = this.logSorting.value;
|
||||||
|
this.autoRefreshValue = this.autoRefresh.checked;
|
||||||
|
if(this.autoRefreshValue) {
|
||||||
|
poll.add(this.pollFuncWrapper, this.pollInterval);
|
||||||
|
this.refreshBtn.style.visibility = 'hidden';
|
||||||
|
} else {
|
||||||
|
poll.remove(this.pollFuncWrapper);
|
||||||
|
this.refreshBtn.style.visibility = 'visible';
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
resetFormValues() {
|
||||||
|
this.tailInput.value = this.tailValue;
|
||||||
|
this.timeFilter.value = this.timeFilterValue;
|
||||||
|
if(this.isHosts) {
|
||||||
|
this.logHostsDropdown.setValue(this.hostFilterValue);
|
||||||
|
};
|
||||||
|
if(this.isFacilities) {
|
||||||
|
this.logFacilitiesDropdown.setValue(this.facilityFilterValue);
|
||||||
|
};
|
||||||
|
if(this.isLevels) {
|
||||||
|
this.logLevelsDropdown.setValue(this.levelFilterValue);
|
||||||
|
};
|
||||||
|
this.msgFilter.value = this.msgFilterValue;
|
||||||
|
this.logSorting.value = this.logSortingValue;
|
||||||
|
this.autoRefresh.checked = this.autoRefreshValue;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives raw log data.
|
* Receives raw log data.
|
||||||
* Abstract method, must be overridden by a subclass!
|
* Abstract method, must be overridden by a subclass!
|
||||||
@@ -374,7 +438,7 @@ return baseclass.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setDateFilter(entriesArray) {
|
setDateFilter(entriesArray) {
|
||||||
let fPattern = this.timeFilter.value;
|
let fPattern = this.timeFilterValue;
|
||||||
if(!fPattern) {
|
if(!fPattern) {
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
@@ -384,12 +448,11 @@ return baseclass.extend({
|
|||||||
setHostFilter(entriesArray) {
|
setHostFilter(entriesArray) {
|
||||||
let logHostsKeys = Object.keys(this.logHosts);
|
let logHostsKeys = Object.keys(this.logHosts);
|
||||||
if(logHostsKeys.length > 0 && this.logHostsDropdown) {
|
if(logHostsKeys.length > 0 && this.logHostsDropdown) {
|
||||||
let selectedHosts = this.logHostsDropdown.getValue();
|
|
||||||
this.logHostsDropdown.addChoices(logHostsKeys, this.logHosts);
|
this.logHostsDropdown.addChoices(logHostsKeys, this.logHosts);
|
||||||
if(selectedHosts.length === 0 || logHostsKeys.length === selectedHosts.length) {
|
if(this.hostFilterValue.length === 0 || logHostsKeys.length === this.hostFilterValue.length) {
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
return entriesArray.filter(e => selectedHosts.includes(e[2]));
|
return entriesArray.filter(e => this.hostFilterValue.includes(e[2]));
|
||||||
};
|
};
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
},
|
},
|
||||||
@@ -397,11 +460,10 @@ return baseclass.extend({
|
|||||||
setFacilityFilter(entriesArray) {
|
setFacilityFilter(entriesArray) {
|
||||||
let logFacilitiesKeys = Object.keys(this.logFacilities);
|
let logFacilitiesKeys = Object.keys(this.logFacilities);
|
||||||
if(logFacilitiesKeys.length > 0 && this.logFacilitiesDropdown) {
|
if(logFacilitiesKeys.length > 0 && this.logFacilitiesDropdown) {
|
||||||
let selectedFacilities = this.logFacilitiesDropdown.getValue();
|
if(this.facilityFilterValue.length === 0 || logFacilitiesKeys.length === this.facilityFilterValue.length) {
|
||||||
if(selectedFacilities.length === 0 || logFacilitiesKeys.length === selectedFacilities.length) {
|
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
return entriesArray.filter(e => selectedFacilities.includes(e[3]));
|
return entriesArray.filter(e => this.facilityFilterValue.includes(e[3]));
|
||||||
};
|
};
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
},
|
},
|
||||||
@@ -409,17 +471,16 @@ return baseclass.extend({
|
|||||||
setLevelFilter(entriesArray) {
|
setLevelFilter(entriesArray) {
|
||||||
let logLevelsKeys = Object.keys(this.logLevels);
|
let logLevelsKeys = Object.keys(this.logLevels);
|
||||||
if(logLevelsKeys.length > 0 && this.logLevelsDropdown) {
|
if(logLevelsKeys.length > 0 && this.logLevelsDropdown) {
|
||||||
let selectedLevels = this.logLevelsDropdown.getValue();
|
if(this.levelFilterValue.length === 0 || logLevelsKeys.length === this.levelFilterValue.length) {
|
||||||
if(selectedLevels.length === 0 || logLevelsKeys.length === selectedLevels.length) {
|
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
return entriesArray.filter(e => selectedLevels.includes(e[4]));
|
return entriesArray.filter(e => this.levelFilterValue.includes(e[4]));
|
||||||
};
|
};
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
},
|
},
|
||||||
|
|
||||||
setMsgFilter(entriesArray) {
|
setMsgFilter(entriesArray) {
|
||||||
let fPattern = this.msgFilter.value;
|
let fPattern = this.msgFilterValue;
|
||||||
if(!fPattern) {
|
if(!fPattern) {
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
@@ -438,10 +499,22 @@ return baseclass.extend({
|
|||||||
throw new Error('makeLogArea must be overridden by a subclass');
|
throw new Error('makeLogArea must be overridden by a subclass');
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadLog(ev) {
|
disableFormElems() {
|
||||||
let formElems = Array.from(this.logForm.elements);
|
Array.from(this.logFilterForm.elements).forEach(
|
||||||
formElems.forEach(e => e.disabled = true);
|
e => e.disabled = true
|
||||||
|
);
|
||||||
|
this.actionButtons.forEach(e => e.disabled = true);
|
||||||
|
},
|
||||||
|
|
||||||
|
enableFormElems() {
|
||||||
|
Array.from(this.logFilterForm.elements).forEach(
|
||||||
|
e => e.disabled = false
|
||||||
|
);
|
||||||
|
this.actionButtons.forEach(e => e.disabled = false);
|
||||||
|
},
|
||||||
|
|
||||||
|
downloadLog(ev) {
|
||||||
|
this.disableFormElems();
|
||||||
return this.getLogData(0).then(logdata => {
|
return this.getLogData(0).then(logdata => {
|
||||||
logdata = logdata || '';
|
logdata = logdata || '';
|
||||||
let link = E('a', {
|
let link = E('a', {
|
||||||
@@ -455,41 +528,47 @@ return baseclass.extend({
|
|||||||
ui.addNotification(null,
|
ui.addNotification(null,
|
||||||
E('p', {}, _('Download error') + ': ' + err.message));
|
E('p', {}, _('Download error') + ': ' + err.message));
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
formElems.forEach(e => e.disabled = false);
|
this.enableFormElems();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreSettings() {
|
restoreSettingsFromLocalStorage() {
|
||||||
let tailValueLocal = localStorage.getItem(`luci-app-${this.viewName}-tailValue`);
|
let tailValueLocal = localStorage.getItem(`luci-app-${this.viewName}-tailValue`);
|
||||||
if(tailValueLocal) {
|
if(tailValueLocal) {
|
||||||
this.tailValue = Number(tailValueLocal);
|
this.tailValue = Number(tailValueLocal);
|
||||||
};
|
};
|
||||||
let logSortingLocal = localStorage.getItem(`luci-app-${this.viewName}-logSorting`);
|
let logSortingLocal = localStorage.getItem(`luci-app-${this.viewName}-logSortingValue`);
|
||||||
if(logSortingLocal) {
|
if(logSortingLocal) {
|
||||||
this.logSortingValue = logSortingLocal;
|
this.logSortingValue = logSortingLocal;
|
||||||
};
|
};
|
||||||
|
let autoRefreshLocal = localStorage.getItem(`luci-app-${this.viewName}-autoRefreshValue`);
|
||||||
|
if(autoRefreshLocal) {
|
||||||
|
this.autoRefreshValue = Boolean(Number(autoRefreshLocal));
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettings(tailValue, logSortingValue) {
|
saveSettingsToLocalStorage(tailValue, logSortingValue, autoRefreshValue) {
|
||||||
|
tailValue = this.checkZeroValue(tailValue);
|
||||||
if(this.tailValue != tailValue) {
|
if(this.tailValue != tailValue) {
|
||||||
this.tailValue = (/^[0-9]+$/.test(tailValue)) ? tailValue : 0;
|
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
`luci-app-${this.viewName}-tailValue`, String(this.tailValue));
|
`luci-app-${this.viewName}-tailValue`, String(tailValue));
|
||||||
};
|
};
|
||||||
if(this.logSortingValue != logSortingValue) {
|
if(this.logSortingValue != logSortingValue) {
|
||||||
this.logSortingValue = logSortingValue;
|
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
`luci-app-${this.viewName}-logSorting`, this.logSortingValue);
|
`luci-app-${this.viewName}-logSortingValue`, logSortingValue);
|
||||||
|
};
|
||||||
|
if(this.autoRefreshValue != autoRefreshValue) {
|
||||||
|
localStorage.setItem(
|
||||||
|
`luci-app-${this.viewName}-autoRefreshValue`, String(Number(autoRefreshValue)));
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onSubmitForm(tail) {
|
reloadLog(tail, modal=false, autorefresh=false) {
|
||||||
let formElems = Array.from(this.logForm.elements);
|
|
||||||
formElems.forEach(e => e.disabled = true);
|
|
||||||
this.logDownloadBtn.disabled = true;
|
|
||||||
tail = (tail && tail > 0) ? tail : 0;
|
tail = (tail && tail > 0) ? tail : 0;
|
||||||
this.logSortingValue = this.logSorting.value;
|
if(!autorefresh) {
|
||||||
|
this.disableFormElems();
|
||||||
|
poll.stop();
|
||||||
|
};
|
||||||
return this.getLogData(tail).then(logdata => {
|
return this.getLogData(tail).then(logdata => {
|
||||||
logdata = logdata || '';
|
logdata = logdata || '';
|
||||||
this.logWrapper.innerHTML = '';
|
this.logWrapper.innerHTML = '';
|
||||||
@@ -508,7 +587,6 @@ return baseclass.extend({
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if(logdata && logdata !== '') {
|
if(logdata && logdata !== '') {
|
||||||
if(this.isFacilities && !this.logFacilitiesDropdown) {
|
if(this.isFacilities && !this.logFacilitiesDropdown) {
|
||||||
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
|
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
|
||||||
@@ -521,10 +599,13 @@ return baseclass.extend({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
formElems.forEach(e => e.disabled = false);
|
if(modal) {
|
||||||
this.logDownloadBtn.disabled = false;
|
|
||||||
this.fastTailValue = this.totalLogLines;
|
|
||||||
ui.hideModal();
|
ui.hideModal();
|
||||||
|
};
|
||||||
|
if(!autorefresh) {
|
||||||
|
this.enableFormElems();
|
||||||
|
poll.start();
|
||||||
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -549,11 +630,9 @@ return baseclass.extend({
|
|||||||
}, _('Timestamp filter')),
|
}, _('Timestamp filter')),
|
||||||
E('div', { 'class': 'cbi-value-field' }, this.timeFilter),
|
E('div', { 'class': 'cbi-value-field' }, this.timeFilter),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
this.logHostsDropdownElem,
|
this.logHostsDropdownElem,
|
||||||
this.logFacilitiesDropdownElem,
|
this.logFacilitiesDropdownElem,
|
||||||
this.logLevelsDropdownElem,
|
this.logLevelsDropdownElem,
|
||||||
|
|
||||||
E('div', { 'class': 'cbi-value' }, [
|
E('div', { 'class': 'cbi-value' }, [
|
||||||
E('label', {
|
E('label', {
|
||||||
'class': 'cbi-value-title',
|
'class': 'cbi-value-title',
|
||||||
@@ -569,50 +648,106 @@ return baseclass.extend({
|
|||||||
}, _('Sorting entries')),
|
}, _('Sorting entries')),
|
||||||
E('div', { 'class': 'cbi-value-field' }, this.logSorting),
|
E('div', { 'class': 'cbi-value-field' }, this.logSorting),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
E('div', { 'class': 'cbi-value' }, [
|
||||||
|
E('label', {
|
||||||
|
'class': 'cbi-value-title',
|
||||||
|
'for' : 'autoRefresh',
|
||||||
|
}, _('Auto refresh')),
|
||||||
|
E('div', { 'class': 'cbi-value-field' },
|
||||||
|
E('div', { 'class': 'cbi-checkbox' }, [
|
||||||
|
this.autoRefresh,
|
||||||
|
E('label', {})
|
||||||
|
])
|
||||||
|
),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
E('div', { 'class': 'right' }, [
|
E('div', { 'class': 'right' }, [
|
||||||
this.logForm,
|
this.logFilterForm,
|
||||||
E('input', {
|
|
||||||
'type' : 'submit',
|
|
||||||
'form' : 'logForm',
|
|
||||||
'class': 'btn cbi-button-positive important',
|
|
||||||
'value': _('Apply'),
|
|
||||||
}),
|
|
||||||
' ',
|
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'btn',
|
'class': 'btn',
|
||||||
'click': ui.hideModal,
|
'click': ev => {
|
||||||
}, _('Close')),
|
ev.target.blur();
|
||||||
|
ui.hideModal();
|
||||||
|
this.resetFormValues();
|
||||||
|
},
|
||||||
|
}, _('Dismiss')),
|
||||||
|
' ',
|
||||||
|
E('button', {
|
||||||
|
'type' : 'submit',
|
||||||
|
'form' : 'logFilterForm',
|
||||||
|
'class': 'btn cbi-button-positive important',
|
||||||
|
'click': ui.createHandlerFn(this, function(ev) {
|
||||||
|
ev.target.blur();
|
||||||
|
ev.preventDefault();
|
||||||
|
return this.onSubmitFilter();
|
||||||
|
}),
|
||||||
|
}, _('Apply')),
|
||||||
]),
|
]),
|
||||||
], 'cbi-modal');
|
], 'cbi-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateLog(autorefresh=false) {
|
||||||
|
let tail = (Number(this.tailValue) == 0 || Number(this.fastTailValue) == 0)
|
||||||
|
? 0 : Math.max(Number(this.tailValue), this.fastTailValue)
|
||||||
|
return this.reloadLog(tail, false, autorefresh);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a promise for the RPC request.
|
||||||
|
* Abstract method, must be overridden by a subclass!
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
* Returns a promise that returns the size of the log in bytes.
|
||||||
|
*/
|
||||||
|
getLogSize() {
|
||||||
|
throw new Error('getLogSize must be overridden by a subclass');
|
||||||
|
},
|
||||||
|
|
||||||
|
async pollFunc() {
|
||||||
|
await this.getLogSize().then(async bytes => {
|
||||||
|
if(this.lastBytes != bytes) {
|
||||||
|
this.lastBytes = bytes;
|
||||||
|
return await this.updateLog(true);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSubmitFilter() {
|
||||||
|
this.saveSettingsToLocalStorage(
|
||||||
|
this.tailInput.value, this.logSorting.value, this.autoRefresh.checked);
|
||||||
|
this.setFilterSettings();
|
||||||
|
this.fastTailValue = Number(this.tailValue);
|
||||||
|
return this.reloadLog(Number(this.tailValue), true);
|
||||||
|
},
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
// Restoring settings from localStorage
|
this.restoreSettingsFromLocalStorage();
|
||||||
this.restoreSettings();
|
|
||||||
return this.getLogData(this.tailValue);
|
return this.getLogData(this.tailValue);
|
||||||
},
|
},
|
||||||
|
|
||||||
render(logdata) {
|
render(logdata) {
|
||||||
|
this.pollFuncWrapper = L.bind(this.pollFunc, this);
|
||||||
|
|
||||||
this.logWrapper = E('div', {
|
this.logWrapper = E('div', {
|
||||||
'id' : 'logWrapper',
|
'id' : 'logWrapper',
|
||||||
'style': 'width:100%; min-height:20em'
|
'style': 'width:100%; min-height:20em'
|
||||||
}, this.makeLogArea(this.parseLogData(logdata, this.tailValue)));
|
}, this.makeLogArea(this.parseLogData(logdata, this.tailValue)));
|
||||||
|
|
||||||
this.fastTailValue = this.totalLogLines;
|
this.fastTailValue = this.tailValue
|
||||||
|
|
||||||
this.tailInput = E('input', {
|
this.tailInput = E('input', {
|
||||||
'id' : 'tailInput',
|
'id' : 'tailInput',
|
||||||
'name' : 'tailInput',
|
'name' : 'tailInput',
|
||||||
'type' : 'text',
|
'type' : 'text',
|
||||||
'form' : 'logForm',
|
'form' : 'logFilterForm',
|
||||||
'class' : 'cbi-input-text',
|
'class' : 'cbi-input-text',
|
||||||
'style' : 'width:4em !important; min-width:4em !important',
|
'style' : 'width:4em !important; min-width:4em !important',
|
||||||
'maxlength': 5,
|
'maxlength': 5,
|
||||||
});
|
});
|
||||||
this.tailInput.value = (this.tailValue === 0) ? null : this.tailValue;
|
this.tailInput.value = this.tailValue;
|
||||||
ui.addValidator(this.tailInput, 'uinteger', true);
|
ui.addValidator(this.tailInput, 'uinteger', true);
|
||||||
|
|
||||||
this.logHostsDropdownElem = '';
|
this.logHostsDropdownElem = '';
|
||||||
@@ -632,7 +767,7 @@ return baseclass.extend({
|
|||||||
'id' : 'timeFilter',
|
'id' : 'timeFilter',
|
||||||
'name' : 'timeFilter',
|
'name' : 'timeFilter',
|
||||||
'type' : 'text',
|
'type' : 'text',
|
||||||
'form' : 'logForm',
|
'form' : 'logFilterForm',
|
||||||
'class' : 'cbi-input-text',
|
'class' : 'cbi-input-text',
|
||||||
'placeholder': _('Type an expression...'),
|
'placeholder': _('Type an expression...'),
|
||||||
});
|
});
|
||||||
@@ -641,7 +776,7 @@ return baseclass.extend({
|
|||||||
'id' : 'msgFilter',
|
'id' : 'msgFilter',
|
||||||
'name' : 'msgFilter',
|
'name' : 'msgFilter',
|
||||||
'type' : 'text',
|
'type' : 'text',
|
||||||
'form' : 'logForm',
|
'form' : 'logFilterForm',
|
||||||
'class' : 'cbi-input-text',
|
'class' : 'cbi-input-text',
|
||||||
'placeholder': _('Type an expression...'),
|
'placeholder': _('Type an expression...'),
|
||||||
});
|
});
|
||||||
@@ -649,7 +784,7 @@ return baseclass.extend({
|
|||||||
this.logSorting = E('select', {
|
this.logSorting = E('select', {
|
||||||
'id' : 'logSorting',
|
'id' : 'logSorting',
|
||||||
'name' : 'logSorting',
|
'name' : 'logSorting',
|
||||||
'form' : 'logForm',
|
'form' : 'logFilterForm',
|
||||||
'class': "cbi-input-select",
|
'class': "cbi-input-select",
|
||||||
}, [
|
}, [
|
||||||
E('option', { 'value': 'asc' }, _('ascending')),
|
E('option', { 'value': 'asc' }, _('ascending')),
|
||||||
@@ -657,6 +792,28 @@ return baseclass.extend({
|
|||||||
]);
|
]);
|
||||||
this.logSorting.value = this.logSortingValue;
|
this.logSorting.value = this.logSortingValue;
|
||||||
|
|
||||||
|
this.autoRefresh = E('input', {
|
||||||
|
'id' : 'autoRefresh',
|
||||||
|
'name' : 'autoRefresh',
|
||||||
|
'type' : 'checkbox',
|
||||||
|
'form' : 'logFilterForm',
|
||||||
|
});
|
||||||
|
this.autoRefresh.checked = this.autoRefreshValue;
|
||||||
|
|
||||||
|
this.filterEditsBtn = E('button', {
|
||||||
|
'class': 'cbi-button btn cbi-button-action',
|
||||||
|
'click': L.bind(this.filterSettingsModal, this),
|
||||||
|
}, _('Edit'));
|
||||||
|
|
||||||
|
this.logFilterForm = E('form', {
|
||||||
|
'id' : 'logFilterForm',
|
||||||
|
'name' : 'logFilterForm',
|
||||||
|
'submit': ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
return this.onSubmitFilter();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
this.logDownloadBtn = E('button', {
|
this.logDownloadBtn = E('button', {
|
||||||
'id' : 'logDownloadBtn',
|
'id' : 'logDownloadBtn',
|
||||||
'name' : 'logDownloadBtn',
|
'name' : 'logDownloadBtn',
|
||||||
@@ -664,34 +821,17 @@ return baseclass.extend({
|
|||||||
'click': ui.createHandlerFn(this, this.downloadLog),
|
'click': ui.createHandlerFn(this, this.downloadLog),
|
||||||
}, _('Download log'));
|
}, _('Download log'));
|
||||||
|
|
||||||
this.logForm = E('form', {
|
this.refreshBtn = E('button', {
|
||||||
'id' : 'logForm',
|
|
||||||
'name' : 'logForm',
|
|
||||||
'style' : 'display:inline-block; margin-top:0.5em',
|
|
||||||
'submit': ui.createHandlerFn(this, function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
// Saving settings to localStorage
|
|
||||||
this.saveSettings(this.tailInput.value, this.logSorting.value);
|
|
||||||
return this.onSubmitForm(Number(this.tailInput.value));
|
|
||||||
}),
|
|
||||||
}, E('span', {}, ' '));
|
|
||||||
|
|
||||||
document.body.append(
|
|
||||||
E('div', {
|
|
||||||
'align': 'right',
|
|
||||||
'class': 'log-side-block',
|
|
||||||
'style': `right:1px; top:${window.innerHeight / 2 - 60}px`,
|
|
||||||
}, [
|
|
||||||
E('button', {
|
|
||||||
'title' : _('Refresh log'),
|
'title' : _('Refresh log'),
|
||||||
'class' : 'btn log-side-btn',
|
'class' : 'btn log-side-btn',
|
||||||
|
'style' : `visibility:${(this.autoRefreshValue) ? 'hidden' : 'visible'}`,
|
||||||
'click' : ui.createHandlerFn(this, function(ev) {
|
'click' : ui.createHandlerFn(this, function(ev) {
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
return this.onSubmitForm(
|
return this.updateLog();
|
||||||
Math.max(Number(this.tailValue), this.fastTailValue));
|
|
||||||
}),
|
}),
|
||||||
}, '🗘'),
|
}, '⟳');
|
||||||
E('button', {
|
|
||||||
|
this.moreEntriesBtn = E('button', {
|
||||||
'title': _('Get more entries'),
|
'title': _('Get more entries'),
|
||||||
'class': 'btn log-side-btn',
|
'class': 'btn log-side-btn',
|
||||||
'style': 'margin-top:1px !important',
|
'style': 'margin-top:1px !important',
|
||||||
@@ -699,21 +839,26 @@ return baseclass.extend({
|
|||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
if(this.fastTailValue === null) {
|
if(this.fastTailValue === null) {
|
||||||
this.fastTailValue = Number(this.tailValue);
|
this.fastTailValue = Number(this.tailValue);
|
||||||
};
|
}
|
||||||
|
if(this.fastTailValue > 0) {
|
||||||
this.fastTailValue += this.fastTailIncrement;
|
this.fastTailValue += this.fastTailIncrement;
|
||||||
return this.onSubmitForm(this.fastTailValue);
|
};
|
||||||
|
return this.reloadLog(this.fastTailValue);
|
||||||
}),
|
}),
|
||||||
}, `+${this.fastTailIncrement}`),
|
}, `+${this.fastTailIncrement}`);
|
||||||
E('button', {
|
|
||||||
|
this.allEntriesBtn = E('button', {
|
||||||
'title': _('Get all entries'),
|
'title': _('Get all entries'),
|
||||||
'class': 'btn log-side-btn',
|
'class': 'btn log-side-btn',
|
||||||
'style': 'margin-top:1px !important',
|
'style': 'margin-top:1px !important',
|
||||||
'click': ui.createHandlerFn(this, function(ev) {
|
'click': ui.createHandlerFn(this, function(ev) {
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
return this.onSubmitForm(0);
|
this.fastTailValue = 0;
|
||||||
|
return this.reloadLog(0);
|
||||||
}),
|
}),
|
||||||
}, '𝍤'),
|
}, _('All'));
|
||||||
E('button', {
|
|
||||||
|
this.filterModalBtn = E('button', {
|
||||||
'title': _('Filter settings'),
|
'title': _('Filter settings'),
|
||||||
'class': 'btn log-side-btn',
|
'class': 'btn log-side-btn',
|
||||||
'style': 'margin-top:10px !important',
|
'style': 'margin-top:10px !important',
|
||||||
@@ -721,8 +866,22 @@ return baseclass.extend({
|
|||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
this.filterSettingsModal();
|
this.filterSettingsModal();
|
||||||
},
|
},
|
||||||
}, '🗔'),
|
}, '▢');
|
||||||
|
|
||||||
|
this.actionButtons.push(this.filterEditsBtn, this.logDownloadBtn,
|
||||||
|
this.refreshBtn,this.moreEntriesBtn,
|
||||||
|
this.allEntriesBtn, this.filterModalBtn);
|
||||||
|
|
||||||
|
document.body.append(
|
||||||
|
E('div', {
|
||||||
|
'align': 'right',
|
||||||
|
'class': 'log-side-block',
|
||||||
|
'style': `right:1px; top:${window.innerHeight / 2 - 60}px`,
|
||||||
|
}, [
|
||||||
|
this.refreshBtn,
|
||||||
|
this.moreEntriesBtn,
|
||||||
|
this.allEntriesBtn,
|
||||||
|
this.filterModalBtn,
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'btn log-side-btn',
|
'class': 'btn log-side-btn',
|
||||||
'style': 'margin-top:10px !important',
|
'style': 'margin-top:10px !important',
|
||||||
@@ -742,6 +901,10 @@ return baseclass.extend({
|
|||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(this.autoRefreshValue) {
|
||||||
|
poll.add(this.pollFuncWrapper, this.pollInterval);
|
||||||
|
};
|
||||||
|
|
||||||
return E([
|
return E([
|
||||||
E('h2', { 'id': 'logTitle', 'class': 'fade-in' }, this.title),
|
E('h2', { 'id': 'logTitle', 'class': 'fade-in' }, this.title),
|
||||||
E('div', { 'class': 'cbi-section-descr fade-in' }),
|
E('div', { 'class': 'cbi-section-descr fade-in' }),
|
||||||
@@ -753,12 +916,7 @@ return baseclass.extend({
|
|||||||
'for' : 'filterSettings',
|
'for' : 'filterSettings',
|
||||||
}, _('Filter settings')),
|
}, _('Filter settings')),
|
||||||
E('div', { 'class': 'cbi-value-field' }, [
|
E('div', { 'class': 'cbi-value-field' }, [
|
||||||
E('div', {},
|
E('div', {}, this.filterEditsBtn),
|
||||||
E('button', {
|
|
||||||
'class': 'cbi-button btn cbi-button-action',
|
|
||||||
'click': L.bind(this.filterSettingsModal, this),
|
|
||||||
}, _('Edit'))
|
|
||||||
),
|
|
||||||
E('input', {
|
E('input', {
|
||||||
'id' : 'filterSettings',
|
'id' : 'filterSettings',
|
||||||
'type': 'hidden',
|
'type': 'hidden',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
'require fs';
|
'require fs';
|
||||||
|
'require rpc';
|
||||||
'require ui';
|
'require ui';
|
||||||
'require view.ruantiblock.log-widget as abc';
|
'require view.ruantiblock.log-widget as abc';
|
||||||
'require view.ruantiblock.tools as tools';
|
'require view.ruantiblock.tools as tools';
|
||||||
@@ -14,6 +15,24 @@ return abc.view.extend({
|
|||||||
|
|
||||||
entriesHandler : null,
|
entriesHandler : null,
|
||||||
|
|
||||||
|
lastBytes : 0,
|
||||||
|
|
||||||
|
callLogSize: rpc.declare({
|
||||||
|
object: 'luci.ruantiblock',
|
||||||
|
method: 'getLogSize',
|
||||||
|
expect: { '': {} }
|
||||||
|
}),
|
||||||
|
|
||||||
|
getLogSize() {
|
||||||
|
return this.callLogSize().then((data) => {
|
||||||
|
if(data.bytes) {
|
||||||
|
return Number(data.bytes);
|
||||||
|
} else {
|
||||||
|
throw new Error(_('An error occurred while trying to get the log size!'));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// logd
|
// logd
|
||||||
logdHandler(strArray, lineNum) {
|
logdHandler(strArray, lineNum) {
|
||||||
let logLevel = strArray[5].split('.');
|
let logLevel = strArray[5].split('.');
|
||||||
|
|||||||
@@ -37,12 +37,18 @@ msgstr "Весь трафик указанных хостов проходит
|
|||||||
msgid "Allows you to limit the hosts that are allowed to bypass blocking"
|
msgid "Allows you to limit the hosts that are allowed to bypass blocking"
|
||||||
msgstr "Позволяет ограничить хосты, которым разрешено обходить блокировки"
|
msgstr "Позволяет ограничить хосты, которым разрешено обходить блокировки"
|
||||||
|
|
||||||
|
msgid "An error occurred while trying to get the log size!"
|
||||||
|
msgstr "Произошла ошибка при попытке получить размер лога!"
|
||||||
|
|
||||||
msgid "Apply"
|
msgid "Apply"
|
||||||
msgstr "Применить"
|
msgstr "Применить"
|
||||||
|
|
||||||
msgid "Apply proxy rules to router application traffic"
|
msgid "Apply proxy rules to router application traffic"
|
||||||
msgstr "Применять правила прокси к трафику приложений роутера"
|
msgstr "Применять правила прокси к трафику приложений роутера"
|
||||||
|
|
||||||
|
msgid "Auto refresh"
|
||||||
|
msgstr "Автообновление"
|
||||||
|
|
||||||
msgid "Blacklist module"
|
msgid "Blacklist module"
|
||||||
msgstr "Модуль блэклиста"
|
msgstr "Модуль блэклиста"
|
||||||
|
|
||||||
@@ -114,7 +120,7 @@ msgid "Download error"
|
|||||||
msgstr "Ошибка загрузки"
|
msgstr "Ошибка загрузки"
|
||||||
|
|
||||||
msgid "Download log"
|
msgid "Download log"
|
||||||
msgstr "Скачать лог"
|
msgstr "Скачать журнал"
|
||||||
|
|
||||||
msgid "Downloading a blacklist via proxy"
|
msgid "Downloading a blacklist via proxy"
|
||||||
msgstr "Скачивать блэклист через прокси"
|
msgstr "Скачивать блэклист через прокси"
|
||||||
|
|||||||
@@ -22,12 +22,18 @@ msgstr ""
|
|||||||
msgid "All traffic of the specified hosts passes through the proxy, without a blacklist"
|
msgid "All traffic of the specified hosts passes through the proxy, without a blacklist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "An error occurred while trying to get the log size!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apply"
|
msgid "Apply"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apply proxy rules to router application traffic"
|
msgid "Apply proxy rules to router application traffic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Auto refresh"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blacklist module"
|
msgid "Blacklist module"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
. /usr/share/libubox/jshn.sh
|
||||||
|
|
||||||
|
readonly LOGREAD_CMD="logread -e ruantiblock:"
|
||||||
|
|
||||||
|
make_size_value() {
|
||||||
|
json_init
|
||||||
|
json_add_string 'bytes' "$1"
|
||||||
|
json_dump
|
||||||
|
json_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
get_log_size() {
|
||||||
|
make_size_value "`$LOGREAD_CMD | wc -c`"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
list)
|
||||||
|
json_init
|
||||||
|
json_add_object "getLogSize"
|
||||||
|
json_close_object
|
||||||
|
json_dump
|
||||||
|
json_cleanup
|
||||||
|
;;
|
||||||
|
call)
|
||||||
|
case "$2" in
|
||||||
|
getLogSize)
|
||||||
|
get_log_size
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -18,7 +18,8 @@
|
|||||||
},
|
},
|
||||||
"uci": [ "network", "ruantiblock" ],
|
"uci": [ "network", "ruantiblock" ],
|
||||||
"ubus": {
|
"ubus": {
|
||||||
"luci": [ "getInitList", "setInitAction" ]
|
"luci": [ "getInitList", "setInitAction" ],
|
||||||
|
"luci.ruantiblock": [ "getLogSize" ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"write": {
|
"write": {
|
||||||
|
|||||||
Reference in New Issue
Block a user