[19.07] luci-app-adblock: release 4.0.3
* sync with adblock 4.0.3 in 19.07 package branch Signed-off-by: Dirk Brenken <dev@brenken.org>
This commit is contained in:
parent
f3817c0fb4
commit
1856ff3e09
50 changed files with 22192 additions and 14257 deletions
|
@ -1,12 +1,14 @@
|
|||
# Copyright 2017 Dirk Brenken (dev@brenken.org)
|
||||
# Copyright 2017-2020 Dirk Brenken (dev@brenken.org)
|
||||
# This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for Adblock
|
||||
LUCI_DEPENDS:=+luci-compat +adblock +luci-lib-jsonc
|
||||
LUCI_DEPENDS:=+adblock +luci-lib-jsonc
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
include ../../luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.read_direct('/etc/adblock/adblock.blacklist'), '');
|
||||
},
|
||||
handleSave: function(ev) {
|
||||
var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n').replace(/[^a-z0-9\.\-\#\n]/g, '')) + '\n';
|
||||
return fs.write('/etc/adblock/adblock.blacklist', value)
|
||||
.then(function(rc) {
|
||||
document.querySelector('textarea').value = value;
|
||||
ui.addNotification(null, E('p', _('Blacklist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
|
||||
}).catch(function(e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save changes: %s').format(e.message)));
|
||||
});
|
||||
},
|
||||
render: function(blacklist) {
|
||||
return E([
|
||||
E('p', {},
|
||||
_('This is the local adblock blacklist to always-deny certain (sub) domains.<br /> \
|
||||
Please note: add only one domain per line. Comments introduced with \'#\' are allowed - ip addresses, wildcards and regex are not.')),
|
||||
E('p', {},
|
||||
E('textarea', {
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'spellcheck': 'false',
|
||||
'wrap': 'off',
|
||||
'rows': 25
|
||||
}, [ blacklist != null ? blacklist : '' ])
|
||||
)
|
||||
]);
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
|
@ -0,0 +1,342 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
/*
|
||||
button handling
|
||||
*/
|
||||
function handleAction(ev) {
|
||||
if (ev.target && ev.target.getAttribute('name') === 'blacklist') {
|
||||
L.ui.showModal(_('Add Blacklist Domain'), [
|
||||
E('p', _('Add this (sub-)domain to your local blacklist.')),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'blacklist', 'value': ev.target.getAttribute('value') }, [])
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.hideModal
|
||||
}, _('Cancel')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'click': ui.createHandlerFn(this, function(ev) {
|
||||
L.resolveDefault(fs.read_direct('/etc/adblock/adblock.blacklist'), '')
|
||||
.then(function(res) {
|
||||
var domain = document.getElementById('blacklist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
|
||||
var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
|
||||
if (res.search(pattern) === -1) {
|
||||
var blacklist = res + domain + '\n';
|
||||
fs.write('/etc/adblock/adblock.blacklist', blacklist);
|
||||
ui.addNotification(null, E('p', _('Blacklist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
|
||||
}
|
||||
L.hideModal();
|
||||
});
|
||||
})
|
||||
}, _('Save'))
|
||||
])
|
||||
]);
|
||||
document.getElementById('blacklist').focus();
|
||||
}
|
||||
|
||||
if (ev.target && ev.target.getAttribute('name') === 'whitelist') {
|
||||
L.ui.showModal(_('Add Whitelist Domain'), [
|
||||
E('p', _('Add this (sub-)domain to your local whitelist.')),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'whitelist', 'value': ev.target.getAttribute('value') }, [])
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.hideModal
|
||||
}, _('Cancel')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'click': ui.createHandlerFn(this, function(ev) {
|
||||
L.resolveDefault(fs.read_direct('/etc/adblock/adblock.whitelist'), '')
|
||||
.then(function(res) {
|
||||
var domain = document.getElementById('whitelist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
|
||||
var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
|
||||
if (res.search(pattern) === -1) {
|
||||
var whitelist = res + domain + '\n';
|
||||
fs.write('/etc/adblock/adblock.whitelist', whitelist);
|
||||
ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
|
||||
}
|
||||
L.hideModal();
|
||||
});
|
||||
})
|
||||
}, _('Save'))
|
||||
])
|
||||
]);
|
||||
document.getElementById('whitelist').focus();
|
||||
}
|
||||
|
||||
if (ev === 'query') {
|
||||
L.ui.showModal(_('Blocklist Query'), [
|
||||
E('p', _('Query active blocklists and backups for a specific domain.')),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
|
||||
E('input', {
|
||||
'class': 'cbi-input-text',
|
||||
'placeholder': 'google.com',
|
||||
'style': 'width:300px',
|
||||
'id': 'search'
|
||||
})
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
'\xa0',
|
||||
E('h5', _('Result')),
|
||||
E('textarea', {
|
||||
'id': 'result',
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': 20
|
||||
})
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.hideModal
|
||||
}, _('Cancel')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'click': ui.createHandlerFn(this, function(ev) {
|
||||
var domain = document.getElementById('search').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
|
||||
if (domain) {
|
||||
document.getElementById('run').classList.add("spinning");
|
||||
document.getElementById('search').value = domain;
|
||||
document.getElementById('result').textContent = 'The query is running, please wait...';
|
||||
L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['query', domain])).then(function(res) {
|
||||
var result = document.getElementById('result');
|
||||
if (res) {
|
||||
result.textContent = res.trim();
|
||||
} else {
|
||||
result.textContent = _('No Query results!');
|
||||
}
|
||||
document.getElementById('run').classList.remove("spinning");
|
||||
document.getElementById('search').value = '';
|
||||
})
|
||||
}
|
||||
document.getElementById('search').focus();
|
||||
})
|
||||
}, _('Query'))
|
||||
])
|
||||
]);
|
||||
document.getElementById('search').focus();
|
||||
}
|
||||
|
||||
if (ev === 'refresh') {
|
||||
L.ui.showModal(_('Refresh DNS Report'), [
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
|
||||
E('select', { 'class': 'cbi-input-select', 'id': 'count' }, [
|
||||
E('option', { 'value': '50' }, '50'),
|
||||
E('option', { 'value': '100' }, '100'),
|
||||
E('option', { 'value': '150' }, '150'),
|
||||
E('option', { 'value': '250' }, '250'),
|
||||
E('option', { 'value': '500' }, '500')
|
||||
]),
|
||||
'\xa0\xa0\xa0',
|
||||
_('max. result set size')
|
||||
])
|
||||
]),
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'id': 'search' }, [
|
||||
]),
|
||||
'\xa0\xa0\xa0',
|
||||
_('Filter criteria like date, domain or client (optional)')
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.hideModal
|
||||
}, _('Cancel')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'id': 'refresh',
|
||||
'click': ui.createHandlerFn(this, async function(ev) {
|
||||
var count = document.getElementById('count').value;
|
||||
var search = document.getElementById('search').value.trim().replace(/[^a-z0-9\.\-]/g,'') || '+';
|
||||
L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', search, count, 'true', 'json']),'');
|
||||
var running = 1;
|
||||
while (running === 1) {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
L.resolveDefault(fs.read_direct('/var/run/adblock.pid')).then(function(res) {
|
||||
if (!res) {
|
||||
running = 0;
|
||||
}
|
||||
})
|
||||
}
|
||||
L.hideModal();
|
||||
location.reload();
|
||||
})
|
||||
}, _('Refresh'))
|
||||
])
|
||||
]);
|
||||
document.getElementById('refresh').focus();
|
||||
}
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', '+', '50', 'false', 'json']),'');
|
||||
},
|
||||
|
||||
render: function(dnsreport) {
|
||||
if (!dnsreport) {
|
||||
dnsreport = '{ "data": "" }';
|
||||
};
|
||||
var content;
|
||||
content = JSON.parse(dnsreport);
|
||||
|
||||
var rows_top = [];
|
||||
var tbl_top = E('div', { 'class': 'table', 'id': 'top_10' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th right' }, _('Count')),
|
||||
E('div', { 'class': 'th' }, _('Name / IP Address')),
|
||||
E('div', { 'class': 'th right' }, _('Count')),
|
||||
E('div', { 'class': 'th' }, _('Domain')),
|
||||
E('div', { 'class': 'th right' }, _('Count')),
|
||||
E('div', { 'class': 'th' }, _('Blocked Domain'))
|
||||
])
|
||||
]);
|
||||
|
||||
var max = 0;
|
||||
if (content.data.top_clients && content.data.top_domains && content.data.top_blocked) {
|
||||
max = Math.max(content.data.top_clients.length, content.data.top_domains.length, content.data.top_blocked.length);
|
||||
}
|
||||
for (var i = 0; i < max; i++) {
|
||||
var a_cnt = '\xa0', a_addr = '\xa0', b_cnt = '\xa0', b_addr = '\xa0', c_cnt = '\xa0', c_addr = '\xa0';
|
||||
if (content.data.top_clients[i]) {
|
||||
a_cnt = content.data.top_clients[i].count;
|
||||
}
|
||||
if (content.data.top_clients[i]) {
|
||||
a_addr = content.data.top_clients[i].address;
|
||||
}
|
||||
if (content.data.top_domains[i]) {
|
||||
b_cnt = content.data.top_domains[i].count;
|
||||
}
|
||||
if (content.data.top_domains[i]) {
|
||||
b_addr = content.data.top_domains[i].address;
|
||||
}
|
||||
if (content.data.top_blocked[i]) {
|
||||
c_cnt = content.data.top_blocked[i].count;
|
||||
}
|
||||
if (content.data.top_blocked[i]) {
|
||||
c_addr = content.data.top_blocked[i].address;
|
||||
}
|
||||
rows_top.push([
|
||||
a_cnt,
|
||||
a_addr,
|
||||
b_cnt,
|
||||
b_addr,
|
||||
c_cnt,
|
||||
c_addr
|
||||
]);
|
||||
}
|
||||
cbi_update_table(tbl_top, rows_top);
|
||||
|
||||
var rows_requests = [];
|
||||
var tbl_requests = E('div', { 'class': 'table', 'id': 'requests' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th' }, _('Date')),
|
||||
E('div', { 'class': 'th' }, _('Time')),
|
||||
E('div', { 'class': 'th' }, _('Client')),
|
||||
E('div', { 'class': 'th' }, _('Domain')),
|
||||
E('div', { 'class': 'th' }, _('Answer')),
|
||||
E('div', { 'class': 'th' }, _('Action'))
|
||||
])
|
||||
]);
|
||||
|
||||
max = 0;
|
||||
if (content.data.requests) {
|
||||
var button;
|
||||
max = content.data.requests.length;
|
||||
for (var i = 0; i < max; i++) {
|
||||
if (content.data.requests[i].rc === 'NX') {
|
||||
button = E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'style': 'word-break: inherit',
|
||||
'name': 'whitelist',
|
||||
'value': content.data.requests[i].domain,
|
||||
'click': handleAction
|
||||
}, [ _('Whitelist...') ]);
|
||||
} else {
|
||||
button = E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'style': 'word-break: inherit',
|
||||
'name': 'blacklist',
|
||||
'value': content.data.requests[i].domain,
|
||||
'click': handleAction
|
||||
}, [ _('Blacklist...') ]);
|
||||
}
|
||||
rows_requests.push([
|
||||
content.data.requests[i].date,
|
||||
content.data.requests[i].time,
|
||||
content.data.requests[i].client,
|
||||
content.data.requests[i].domain,
|
||||
content.data.requests[i].rc,
|
||||
button
|
||||
]);
|
||||
}
|
||||
}
|
||||
cbi_update_table(tbl_requests, rows_requests);
|
||||
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Start Date')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'start', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.start_date || '-') + ', ' + (content.data.start_time || '-'))]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('End Date')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'end', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.end_date || '-') + ', ' + (content.data.end_time || '-'))]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (total)')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'total', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, content.data.total || '-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (blocked)')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'blocked', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.blocked || '-') + ' (' + (content.data.percent || '-') + ')')]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
return handleAction('query');
|
||||
})
|
||||
}, [ _('Blocklist Query...') ]),
|
||||
'\xa0\xa0\xa0',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
return handleAction('refresh');
|
||||
})
|
||||
}, [ _('Refresh...') ])
|
||||
]),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h3', _('Top 10 Statistics')),
|
||||
tbl_top
|
||||
])
|
||||
]),
|
||||
E('br'),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h3', _('Latest DNS Requests')),
|
||||
tbl_requests
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/sbin/logread'), null),
|
||||
L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
|
||||
]);
|
||||
},
|
||||
render: function(stat) {
|
||||
var logger = stat[0] ? stat[0].path : stat[1] ? stat[1].path : null;
|
||||
L.Poll.add(function() {
|
||||
return L.resolveDefault(fs.exec_direct(logger, ['-e', 'adblock-'])).then(function(res) {
|
||||
var log = document.getElementById("logfile");
|
||||
if (res) {
|
||||
log.value = res.trim();
|
||||
} else {
|
||||
log.value = _('No adblock related logs yet!');
|
||||
}
|
||||
log.scrollTop = log.scrollHeight;
|
||||
});
|
||||
});
|
||||
return E('div', { class: 'cbi-map' },
|
||||
E('div', { class: 'cbi-section' }, [
|
||||
E('div', { class: 'cbi-section-descr' }, _('The syslog output, pre-filtered for adblock related messages only.')),
|
||||
E('textarea', {
|
||||
'id': 'logfile',
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': 25
|
||||
})
|
||||
]));
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
|
@ -0,0 +1,481 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require uci';
|
||||
'require form';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
/*
|
||||
button handling
|
||||
*/
|
||||
async function handleAction(ev) {
|
||||
if (ev === 'timer') {
|
||||
L.ui.showModal(_('Refresh Timer'), [
|
||||
E('p', _('To keep your adblock lists up-to-date, you should setup an automatic update job for these lists.')),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('h5', _('Existing job(s)')),
|
||||
E('textarea', {
|
||||
'id': 'cronView',
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': 5
|
||||
})
|
||||
]),
|
||||
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
|
||||
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
|
||||
E('h5', _('Set/Replace a new adblock job')),
|
||||
E('select', { 'class': 'cbi-input-select', 'id': 'timerA' }, [
|
||||
E('option', { 'value': 'start' }, 'Start'),
|
||||
E('option', { 'value': 'reload' }, 'Reload'),
|
||||
E('option', { 'value': 'restart' }, 'Restart')
|
||||
]),
|
||||
'\xa0\xa0\xa0',
|
||||
_('Adblock action')
|
||||
]),
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'id': 'timerH', 'maxlength': '2' }, [
|
||||
]),
|
||||
'\xa0\xa0\xa0',
|
||||
_('The hours portition (req., range: 0-23)')
|
||||
]),
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'id': 'timerM', 'maxlength': '2' }),
|
||||
'\xa0\xa0\xa0',
|
||||
_('The minutes portion (opt., range: 0-59)')
|
||||
]),
|
||||
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
|
||||
E('input', { 'class': 'cbi-input-text', 'id': 'timerD', 'maxlength': '13' }),
|
||||
'\xa0\xa0\xa0',
|
||||
_('The day of the week (opt., values: 1-7 possibly sep. by , or -)')
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': L.hideModal
|
||||
}, _('Cancel')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'click': ui.createHandlerFn(this, function(ev) {
|
||||
var action = document.getElementById('timerA').value;
|
||||
var hours = document.getElementById('timerH').value;
|
||||
var minutes = document.getElementById('timerM').value || '0';
|
||||
var days = document.getElementById('timerD').value || '*';
|
||||
if (hours) {
|
||||
L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['timer', action, hours, minutes, days]))
|
||||
.then(function(res) {
|
||||
if (res) {
|
||||
ui.addNotification(null, E('p', _('The Refresh Timer could not been updated.')), 'error');
|
||||
} else {
|
||||
ui.addNotification(null, E('p', _('The Refresh Timer has been updated.')), 'info');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
document.getElementById('timerH').focus();
|
||||
return
|
||||
}
|
||||
L.hideModal();
|
||||
})
|
||||
}, _('Save'))
|
||||
])
|
||||
]);
|
||||
L.resolveDefault(fs.read_direct('/etc/crontabs/root'), ' ')
|
||||
.then(function(res) {
|
||||
document.getElementById('cronView').value = res.trim();
|
||||
});
|
||||
document.getElementById('timerH').focus();
|
||||
return
|
||||
}
|
||||
|
||||
if (ev === 'suspend') {
|
||||
if (document.getElementById('status') && document.getElementById('btn_suspend') && document.getElementById('status').textContent.substr(0,6) === 'paused') {
|
||||
document.querySelector('#btn_suspend').textContent = 'Suspend';
|
||||
ev = 'resume';
|
||||
} else if (document.getElementById('status') && document.getElementById('btn_suspend')) {
|
||||
document.querySelector('#btn_suspend').textContent = 'Resume';
|
||||
}
|
||||
}
|
||||
|
||||
L.Poll.start();
|
||||
fs.exec_direct('/etc/init.d/adblock', [ev])
|
||||
var running = 1;
|
||||
while (running === 1) {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
L.resolveDefault(fs.read_direct('/var/run/adblock.pid')).then(function(res) {
|
||||
if (!res) {
|
||||
running = 0;
|
||||
}
|
||||
})
|
||||
}
|
||||
L.Poll.stop();
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['list']), {}),
|
||||
uci.load('adblock')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function(result) {
|
||||
var m, s, o;
|
||||
|
||||
m = new form.Map('adblock', 'Adblock', _('Configuration of the adblock package to block ad/abuse domains by using DNS. \
|
||||
For further information <a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank" rel="noreferrer noopener" >check the online documentation</a>'));
|
||||
|
||||
/*
|
||||
poll runtime information
|
||||
*/
|
||||
pollData: L.Poll.add(function() {
|
||||
return L.resolveDefault(fs.read_direct('/tmp/adb_runtime.json'), 'null').then(function(res) {
|
||||
var info = JSON.parse(res);
|
||||
var status = document.getElementById('status');
|
||||
if (status && info) {
|
||||
status.textContent = (info.data.adblock_status || '-') + ' / ' + (info.data.adblock_version || '-');
|
||||
if (info.data.adblock_status === "running") {
|
||||
if (!status.classList.contains("spinning")) {
|
||||
status.classList.add("spinning");
|
||||
}
|
||||
} else {
|
||||
if (status.classList.contains("spinning")) {
|
||||
status.classList.remove("spinning");
|
||||
L.Poll.stop();
|
||||
}
|
||||
}
|
||||
if (status.textContent.substr(0,6) === 'paused' && document.getElementById('btn_suspend')) {
|
||||
document.querySelector('#btn_suspend').textContent = 'Resume';
|
||||
}
|
||||
} else if (status) {
|
||||
status.textContent = '-';
|
||||
if (status.classList.contains("spinning")) {
|
||||
status.classList.remove("spinning");
|
||||
}
|
||||
}
|
||||
var domains = document.getElementById('domains');
|
||||
if (domains && info) {
|
||||
domains.textContent = parseInt(info.data.blocked_domains, 10).toLocaleString() || '-';
|
||||
}
|
||||
var sources = document.getElementById('sources');
|
||||
var src_array = [];
|
||||
if (sources && info) {
|
||||
for (var i = 0; i < info.data.active_sources.length; i++) {
|
||||
if (i < info.data.active_sources.length-1) {
|
||||
src_array += info.data.active_sources[i].source + ', ';
|
||||
} else {
|
||||
src_array += info.data.active_sources[i].source
|
||||
}
|
||||
}
|
||||
sources.textContent = src_array || '-';
|
||||
}
|
||||
var backend = document.getElementById('backend');
|
||||
if (backend && info) {
|
||||
backend.textContent = info.data.dns_backend || '-';
|
||||
}
|
||||
var utils = document.getElementById('utils');
|
||||
if (utils && info) {
|
||||
utils.textContent = info.data.run_utils || '-';
|
||||
}
|
||||
var ifaces = document.getElementById('ifaces');
|
||||
if (ifaces && info) {
|
||||
ifaces.textContent = info.data.run_ifaces || '-';
|
||||
}
|
||||
var dirs = document.getElementById('dirs');
|
||||
if (dirs && info) {
|
||||
dirs.textContent = info.data.run_directories || '-';
|
||||
}
|
||||
var flags = document.getElementById('flags');
|
||||
if (flags && info) {
|
||||
flags.textContent = info.data.run_flags || '-';
|
||||
}
|
||||
var run = document.getElementById('run');
|
||||
if (run && info) {
|
||||
run.textContent = info.data.last_run || '-';
|
||||
}
|
||||
});
|
||||
}, 1);
|
||||
|
||||
/*
|
||||
runtime information and buttons
|
||||
*/
|
||||
s = m.section(form.NamedSection, 'global');
|
||||
s.render = L.bind(function(view, section_id) {
|
||||
return E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', _('Information')),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Status / Version')),
|
||||
E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'\xa0')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Blocked Domains')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'domains', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Sources')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'sources', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Backend')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'backend', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Run Utils')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'utils', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Run Interfaces')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'ifaces', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Run Directories')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'dirs', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Run Flags')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'flags', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
|
||||
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Last Run')),
|
||||
E('div', { 'class': 'cbi-value-field', 'id': 'run', 'style': 'font-weight: bold;margin-bottom:5px;color:#37c' },'-')]),
|
||||
E('div', { class: 'right' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
return handleAction('timer');
|
||||
})
|
||||
}, [ _('Refresh Timer...') ]),
|
||||
'\xa0\xa0\xa0',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'id': 'btn_suspend',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
return handleAction('suspend');
|
||||
})
|
||||
}, [ _('Suspend') ]),
|
||||
'\xa0\xa0\xa0',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
return handleAction('start');
|
||||
})
|
||||
}, [ _('Refresh') ])
|
||||
])
|
||||
]);
|
||||
}, o, this);
|
||||
this.pollData;
|
||||
|
||||
/*
|
||||
tabbed config section
|
||||
*/
|
||||
s = m.section(form.NamedSection, 'global', 'adblock', _('Settings'));
|
||||
s.addremove = false;
|
||||
s.tab('general', _('General Settings'));
|
||||
s.tab('additional', _('Additional Settings'));
|
||||
s.tab('adv_dns', _('Advanced DNS Settings'));
|
||||
s.tab('adv_report', _('Advanced Report Settings'));
|
||||
s.tab('adv_email', _('Advanced E-Mail Settings'));
|
||||
s.tab('sources', _('Blocklist Sources'), _('List of supported and fully pre-configured adblock sources, already active sources are pre-selected.<br /> \
|
||||
<b><em>To avoid OOM errors, please do not select too many lists!</em></b><br /> \
|
||||
List size information with the respective domain ranges as follows:<br /> \
|
||||
• <b>S</b> (-10k), <b>M</b> (10k-30k) and <b>L</b> (30k-80k) should work for 128 MByte devices,<br /> \
|
||||
• <b>XL</b> (80k-200k) should work for 256-512 MByte devices,<br /> \
|
||||
• <b>XXL</b> (200k-) needs more RAM and Multicore support, e.g. x86 or raspberry devices.<br /> \
|
||||
<p> </p>'));
|
||||
|
||||
/*
|
||||
general settings tab
|
||||
*/
|
||||
o = s.taboption('general', form.Flag, 'adb_enabled', _('Enabled'), _('Enable the adblock service.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', widgets.NetworkSelect, 'adb_trigger', _('Startup Trigger Interface'), _('List of available network interfaces to trigger the adblock start. \
|
||||
Choose \'unspecified\' to use a classic startup timeout instead of a network trigger.'));
|
||||
o.unspecified = true;
|
||||
o.nocreate = true;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'adb_forcedns', _('Force Local DNS'), _('Redirect all DNS queries from \'lan\' zone to the local DNS resolver, applies to UDP and TCP protocol.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Value, 'adb_portlist', _('Local DNS Ports'), _('Space separated list of DNS-related firewall ports which should be forced locally.'));
|
||||
o.depends('adb_forcedns', '1');
|
||||
o.placeholder = '53 853 5353';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'adb_safesearch', _('Enable SafeSearch'), _('Enforcing SafeSearch for google, bing, duckduckgo, yandex, youtube and pixabay.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'adb_safesearchmod', _('SafeSearch Moderate'), _('Enable moderate SafeSearch filters for youtube.'));
|
||||
o.depends('adb_safesearch', '1');
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'adb_report', _('DNS Report'), _('Gather DNS related network traffic via tcpdump and provide a DNS Report on demand. \
|
||||
Please note: this needs additional \'tcpdump-mini\' package installation and a full adblock service restart to take effect.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'adb_mail', _('E-Mail Notification'), _('Send adblock related notification e-mails. \
|
||||
Please note: this needs additional \'msmtp\' package installation.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Value, 'adb_mailreceiver', _('E-Mail Receiver Address'), _('Receiver address for adblock notification e-mails.'));
|
||||
o.depends('adb_mail', '1');
|
||||
o.placeholder = 'name@example.com';
|
||||
o.rmempty = true;
|
||||
|
||||
/*
|
||||
additional settings tab
|
||||
*/
|
||||
o = s.taboption('additional', form.Flag, 'adb_debug', _('Verbose Debug Logging'), _('Enable verbose debug logging in case of any processing errors.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('additional', form.Flag, 'adb_nice', _('Low Priority Service'), _('Reduce the priority of the adblock background processing to take fewer resources from the system. \
|
||||
Please note: This change requires a full adblock service restart to take effect.'));
|
||||
o.enabled = '10';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('additional', form.Value, 'adb_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds before adblock processing begins.'));
|
||||
o.placeholder = '2';
|
||||
o.datatype = 'range(1,120)';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('additional', form.ListValue, 'adb_maxqueue', _('Download Queue'), _('Size of the download queue for download processing (incl. sorting, merging etc.) in parallel.'));
|
||||
o.value('4');
|
||||
o.value('8');
|
||||
o.value('16');
|
||||
o.value('32');
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('additional', form.Value, 'adb_tmpbase', _('Base Temp Directory'), _('Base Temp Directory for all adblock related runtime operations, \
|
||||
e.g. downloading, sorting, merging etc.'));
|
||||
o.placeholder = '/tmp';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('additional', form.Flag, 'adb_backup', _('Blocklist Backup'), _('Create compressed blocklist backups, they will be used in case of download errors or during startup.'));
|
||||
o.default = 1
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('additional', form.Value, 'adb_backupdir', _('Backup Directory'), _('Target directory for blocklist backups. \
|
||||
Default is \'/tmp\', please use preferably an usb stick or another local disk.'));
|
||||
o.depends('adb_backup', '1');
|
||||
o.placeholder = '/tmp';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('additional', form.ListValue, 'adb_fetchutil', _('Download Utility'), _('List of supported and fully pre-configured download utilities.'));
|
||||
o.value('uclient-fetch');
|
||||
o.value('wget');
|
||||
o.value('curl');
|
||||
o.value('aria2c');
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('additional', form.Value, 'adb_fetchparm', _('Download Parameters'), _('Special config options for the selected download utility.'))
|
||||
o.rmempty = true;
|
||||
|
||||
/*
|
||||
advanced dns settings tab
|
||||
*/
|
||||
o = s.taboption('adv_dns', form.ListValue, 'adb_dns', _('DNS Backend'), _('List of supported DNS backends with their default list directory. \
|
||||
To overwrite the default path use the \'DNS Directory\' option.'));
|
||||
o.value('dnsmasq', _('dnsmasq (/tmp/dnsmasq.d)'));
|
||||
o.value('unbound', _('unbound (/var/lib/unbound)'));
|
||||
o.value('named', _('named (/var/lib/bind)'));
|
||||
o.value('kresd', _('kresd (/etc/kresd)'));
|
||||
o.value('raw', _('raw (/tmp)'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('adv_dns', form.Value, 'adb_dnsdir', _('DNS Directory'), _('Target directory for the generated blocklist \'adb_list.overall\'.'));
|
||||
o.placeholder = '/tmp';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Value, 'adb_dnstimeout', _('DNS Restart Timeout'), _('Timeout to wait for a successful DNS backend restart.'));
|
||||
o.placeholder = '20';
|
||||
o.datatype = 'range(1,60)';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Value, 'adb_lookupdomain', _('External DNS Lookup Domain'), _('External domain to check for a successful DNS backend restart. \
|
||||
Please note: To disable this check set this option to \'false\'.'));
|
||||
o.placeholder = 'example.com';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsfilereset', _('DNS File Reset'), _('Resets the final DNS blocklist \'adb_list.overall\' after DNS backend loading. \
|
||||
Please note: This option starts a small ubus/adblock monitor in the background.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsflush', _('Flush DNS Cache'), _('Flush the DNS Cache before adblock processing as well.'));
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsallow', _('Disable DNS Allow'), _('Disable selective DNS whitelisting (RPZ pass through).'));
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Flag, 'adb_jail', _('Additional Jail Blocklist'), _('Builds an additional DNS blocklist to block access to all domains except those listed in the whitelist. \
|
||||
Please note: You can use this restrictive blocklist e.g. for guest wifi or kidsafe configurations.'));
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Value, 'adb_jaildir', _('Jail Directory'), _('Target directory for the generated jail blocklist \'adb_list.jail\'.'));
|
||||
o.depends('adb_jail', '1');
|
||||
o.placeholder = '/tmp';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsinotify', _('Disable DNS Restarts'), _('Disable adblock triggered restarts for dns backends with autoload/inotify functions.'));
|
||||
o.depends('adb_dnsflush', '0');
|
||||
o.rmempty = true;
|
||||
|
||||
/*
|
||||
advanced report settings tab
|
||||
*/
|
||||
o = s.taboption('adv_report', widgets.DeviceSelect, 'adb_repiface', _('Report Interface'), _('List of available network devices used by tcpdump.'));
|
||||
o.unspecified = true;
|
||||
o.nocreate = false;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_report', form.Value, 'adb_reportdir', _('Report Directory'), _('Target directory for DNS related report files. \
|
||||
Default is \'/tmp\', please use preferably an usb stick or another local disk.'));
|
||||
o.placeholder = '/tmp';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_report', form.Value, 'adb_repchunkcnt', _('Report Chunk Count'), _('Report chunk count used by tcpdump.'));
|
||||
o.placeholder = '5';
|
||||
o.datatype = 'range(1,10)';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_report', form.Value, 'adb_repchunksize', _('Report Chunk Size'), _('Report chunk size used by tcpdump in MByte.'));
|
||||
o.placeholder = '1';
|
||||
o.datatype = 'range(1,10)';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_report', form.Value, 'adb_replisten', _('Report Ports'), _('Space separated list of ports used by tcpdump.'));
|
||||
o.placeholder = '53';
|
||||
o.rmempty = true;
|
||||
|
||||
/*
|
||||
advanced email settings tab
|
||||
*/
|
||||
o = s.taboption('adv_email', form.Value, 'adb_mailsender', _('E-Mail Sender Address'), _('Sender address for adblock notification E-Mails.'));
|
||||
o.placeholder = 'no-reply@adblock';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_email', form.Value, 'adb_mailtopic', _('E-Mail Topic'), _('Topic for adblock notification E-Mails.'));
|
||||
o.placeholder = 'adblock notification';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_email', form.Value, 'adb_mailprofile', _('E-Mail Profile'), _('Profile used by \'msmtp\' for adblock notification E-Mails.'));
|
||||
o.placeholder = 'adb_notify';
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('adv_email', form.Value, 'adb_mailcnt', _('E-Mail Notification Count'), _('Raise the notification count, to get E-Mails if the overall blocklist count is less or equal to the given limit.'));
|
||||
o.placeholder = '0';
|
||||
o.datatype = 'min(0)';
|
||||
o.rmempty = true;
|
||||
|
||||
/*
|
||||
blocklist sources tab
|
||||
*/
|
||||
o = s.taboption('sources', form.MultiValue, 'adb_sources', _('Sources (Size, Focus)'));
|
||||
var lines, name, size, focus;
|
||||
lines = result[0].trim().split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(/^\s+\+/)) {
|
||||
name = lines[i].match(/^\s+\+\s(\w+)\s/)[1] || '-';
|
||||
size = lines[i].match(/^\s+\+\s\w+[\sx]+(\w+)/)[1] || '-';
|
||||
focus = lines[i].match(/^\s+\+\s\w+[\sx]+\w+\s+([\w\+]+)/)[1] || '-';
|
||||
o.value(name, name + ' (' + size + ', ' + focus + ')');
|
||||
}
|
||||
}
|
||||
o.rmempty = false;
|
||||
return m.render();
|
||||
},
|
||||
handleReset: null
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
return L.view.extend({
|
||||
load: function() {
|
||||
return L.resolveDefault(fs.read_direct('/etc/adblock/adblock.whitelist'), '');
|
||||
},
|
||||
handleSave: function(ev) {
|
||||
var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n').replace(/[^a-z0-9\.\-\#\n]/g, '')) + '\n';
|
||||
return fs.write('/etc/adblock/adblock.whitelist', value)
|
||||
.then(function(rc) {
|
||||
document.querySelector('textarea').value = value;
|
||||
ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
|
||||
}).catch(function(e) {
|
||||
ui.addNotification(null, E('p', _('Unable to save changes: %s').format(e.message)));
|
||||
});
|
||||
},
|
||||
render: function(whitelist) {
|
||||
return E([
|
||||
E('p', {},
|
||||
_('This is the local adblock whitelist to always allow certain (sub) domains.<br /> \
|
||||
Please note: add only one domain per line. Comments introduced with \'#\' are allowed - ip addresses, wildcards and regex are not.')),
|
||||
E('p', {},
|
||||
E('textarea', {
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'spellcheck': 'false',
|
||||
'wrap': 'off',
|
||||
'rows': 25
|
||||
}, [ whitelist != null ? whitelist : '' ])
|
||||
)
|
||||
]);
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
|
@ -1,175 +1,12 @@
|
|||
-- Copyright 2017-2019 Dirk Brenken (dev@brenken.org)
|
||||
-- This is free software, licensed under the Apache License, Version 2.0
|
||||
-- stub lua controller for 19.07 backward compatibility
|
||||
|
||||
module("luci.controller.adblock", package.seeall)
|
||||
|
||||
local sys = require("luci.sys")
|
||||
local util = require("luci.util")
|
||||
local http = require("luci.http")
|
||||
local i18n = require("luci.i18n")
|
||||
local json = require("luci.jsonc")
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/adblock") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "adblock"}, firstchild(), _("Adblock"), 30).dependent = false
|
||||
entry({"admin", "services", "adblock", "tab_from_cbi"}, cbi("adblock/overview_tab", {hideresetbtn=true, hidesavebtn=true}), _("Overview"), 10).leaf = true
|
||||
if nixio.fs.access("/usr/sbin/tcpdump") then
|
||||
entry({"admin", "services", "adblock", "report"}, template("adblock/report"), _("DNS Query Report"), 20).leaf = true
|
||||
end
|
||||
entry({"admin", "services", "adblock", "log"}, template("adblock/logread"), _("Logfile"), 30).leaf = true
|
||||
entry({"admin", "services", "adblock", "advanced"}, firstchild(), _("Advanced"), 100)
|
||||
entry({"admin", "services", "adblock", "advanced", "blacklist"}, form("adblock/blacklist_tab"), _("Edit Blacklist"), 110).leaf = true
|
||||
entry({"admin", "services", "adblock", "advanced", "whitelist"}, form("adblock/whitelist_tab"), _("Edit Whitelist"), 120).leaf = true
|
||||
entry({"admin", "services", "adblock", "advanced", "configuration"}, form("adblock/configuration_tab"), _("Edit Configuration"), 130).leaf = true
|
||||
entry({"admin", "services", "adblock", "advanced", "query"}, template("adblock/query"), _("Query domains"), 140).leaf = true
|
||||
entry({"admin", "services", "adblock", "advanced", "result"}, call("queryData"), nil, 150).leaf = true
|
||||
entry({"admin", "services", "adblock", "logread"}, call("logread"), nil).leaf = true
|
||||
entry({"admin", "services", "adblock", "status_update"}, call("status_update"), nil).leaf = true
|
||||
entry({"admin", "services", "adblock", "report_json"}, call("report_json"), nil).leaf = true
|
||||
entry({"admin", "services", "adblock", "report_text"}, call("report_text"), nil).leaf = true
|
||||
entry({"admin", "services", "adblock", "action"}, call("adb_action"), nil).leaf = true
|
||||
end
|
||||
|
||||
function adb_action(name, ...)
|
||||
local domain = select(1, ...) or ""
|
||||
local search = select(2, ...) or "+"
|
||||
local count = select(3, ...) or "50"
|
||||
local filter = select(4, ...) or "false"
|
||||
local print = select(5, ...) or "false"
|
||||
|
||||
local report_params = {
|
||||
search,
|
||||
count,
|
||||
filter,
|
||||
print
|
||||
}
|
||||
|
||||
if name == "do_suspend" then
|
||||
luci.sys.call("/etc/init.d/adblock suspend >/dev/null 2>&1")
|
||||
elseif name == "do_resume" then
|
||||
luci.sys.call("/etc/init.d/adblock resume >/dev/null 2>&1")
|
||||
elseif name == "do_refresh" then
|
||||
luci.sys.call("/etc/init.d/adblock reload >/dev/null 2>&1")
|
||||
elseif name == "do_report" then
|
||||
luci.sys.call("/etc/init.d/adblock report " ..table.concat(report_params, " ").. " >/dev/null 2>&1")
|
||||
local rep_dir = uci:get("adblock", "extra", "adb_repdir") or "/tmp"
|
||||
repeat
|
||||
nixio.nanosleep(1)
|
||||
until not nixio.fs.access(rep_dir.. "/adb_report.raw")
|
||||
elseif name == "do_filter" then
|
||||
luci.sys.call("/etc/init.d/adblock report " ..table.concat(report_params, " ").. " >/dev/null 2>&1")
|
||||
local rep_dir = uci:get("adblock", "extra", "adb_repdir") or "/tmp"
|
||||
repeat
|
||||
nixio.nanosleep(1)
|
||||
until nixio.fs.access(rep_dir.. "/adb_report.final")
|
||||
elseif name == "add_blacklist" then
|
||||
local file = uci:get("adblock", "blacklist", "adb_src") or "/etc/adblock/adblock.blacklist"
|
||||
if nixio.fs.access(file) then
|
||||
local blacklist = nixio.fs.readfile(file)
|
||||
if not string.find(blacklist, domain, 1, true)
|
||||
then
|
||||
nixio.fs.writefile(file, blacklist.. domain.. "\n")
|
||||
end
|
||||
end
|
||||
elseif name == "add_whitelist" then
|
||||
local file = uci:get("adblock", "global", "adb_whitelist") or "/etc/adblock/adblock.whitelist"
|
||||
if nixio.fs.access(file) then
|
||||
local whitelist = nixio.fs.readfile(file)
|
||||
if not string.find(whitelist, domain, 1, true)
|
||||
then
|
||||
nixio.fs.writefile(file, whitelist.. domain.. "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
if name == "do_suspend" or name == "do_resume" or name == "do_refresh" then
|
||||
local pid_file = "/var/run/adblock.pid"
|
||||
if nixio.fs.access(pid_file) then
|
||||
repeat
|
||||
nixio.nanosleep(1)
|
||||
until nixio.fs.readfile(pid_file) == ""
|
||||
end
|
||||
end
|
||||
luci.http.prepare_content("text/plain")
|
||||
luci.http.write("0")
|
||||
end
|
||||
|
||||
function status_update()
|
||||
local rt_file
|
||||
local content
|
||||
|
||||
rt_file = uci:get("adblock", "global", "adb_rtfile") or "/tmp/adb_runtime.json"
|
||||
|
||||
if nixio.fs.access(rt_file) then
|
||||
content = json.parse(nixio.fs.readfile(rt_file) or "")
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(content)
|
||||
end
|
||||
end
|
||||
|
||||
function report_json()
|
||||
local rep_dir
|
||||
local rep_file
|
||||
local content
|
||||
|
||||
rep_dir = uci:get("adblock", "extra", "adb_repdir") or "/tmp"
|
||||
rep_file = rep_dir.. "/adb_report.json"
|
||||
http.prepare_content("application/json")
|
||||
|
||||
if nixio.fs.access(rep_file) then
|
||||
content = json.parse(nixio.fs.readfile(rep_file) or "")
|
||||
http.write_json(content)
|
||||
else
|
||||
http.write_json("{}")
|
||||
end
|
||||
end
|
||||
|
||||
function report_text()
|
||||
local file
|
||||
local rep_dir
|
||||
local rep_file
|
||||
local content
|
||||
|
||||
rep_dir = uci:get("adblock", "extra", "adb_repdir") or "/tmp"
|
||||
rep_file = rep_dir.. "/adb_report.final"
|
||||
http.prepare_content("text/plain")
|
||||
|
||||
if nixio.fs.access(rep_file) then
|
||||
file = io.open(rep_file, "r")
|
||||
content = file:read("*all")
|
||||
file:close()
|
||||
http.write(content)
|
||||
else
|
||||
http.write("")
|
||||
end
|
||||
end
|
||||
|
||||
function logread()
|
||||
local content = util.trim(util.exec("logread -e 'adblock-'")) or ""
|
||||
|
||||
if content == "" then
|
||||
content = "No adblock related logs yet!"
|
||||
end
|
||||
http.write(content)
|
||||
end
|
||||
|
||||
function queryData(domain)
|
||||
if domain then
|
||||
luci.http.prepare_content("text/plain")
|
||||
local cmd = "/etc/init.d/adblock query %s 2>&1"
|
||||
local util = io.popen(cmd % util.shellquote(domain))
|
||||
if util then
|
||||
while true do
|
||||
local line = util:read("*l")
|
||||
if not line then
|
||||
break
|
||||
end
|
||||
luci.http.write(line)
|
||||
luci.http.write("\n")
|
||||
end
|
||||
util:close()
|
||||
end
|
||||
end
|
||||
entry({"admin", "services", "adblock"}, firstchild(), _("Adblock"), 60)
|
||||
entry({"admin", "services", "adblock", "overview"}, view("adblock/overview"), _("Overview"), 10)
|
||||
entry({"admin", "services", "adblock", "dnsreport"}, view("adblock/dnsreport"), _("DNS Report"), 20)
|
||||
entry({"admin", "services", "adblock", "blacklist"}, view("adblock/blacklist"), _("Edit Blacklist"), 30)
|
||||
entry({"admin", "services", "adblock", "whitelist"}, view("adblock/whitelist"), _("Edit Whitelist"), 40)
|
||||
entry({"admin", "services", "adblock", "logread"}, view("adblock/logread"), _("Log View"), 50)
|
||||
end
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
-- This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
local fs = require("nixio.fs")
|
||||
local util = require("luci.util")
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
local input = uci:get("adblock", "blacklist", "adb_src") or "/etc/adblock/adblock.blacklist"
|
||||
|
||||
if not fs.access(input) then
|
||||
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
if fs.stat(input).size >= 102400 then
|
||||
m = SimpleForm("error", nil,
|
||||
translate("The file size is too large for online editing in LuCI (≥ 100 KB). ")
|
||||
.. translate("Please edit this file directly in a terminal session."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
m = SimpleForm("input", nil)
|
||||
m:append(Template("adblock/adblock_css"))
|
||||
m.submit = translate("Save")
|
||||
m.reset = false
|
||||
|
||||
s = m:section(SimpleSection, nil,
|
||||
translatef("This form allows you to modify the content of the adblock blacklist (%s). ", input)
|
||||
.. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards and regex are not."))
|
||||
|
||||
f = s:option(TextValue, "data")
|
||||
f.datatype = "string"
|
||||
f.rows = 20
|
||||
f.rmempty = true
|
||||
|
||||
function f.cfgvalue()
|
||||
return fs.readfile(input) or ""
|
||||
end
|
||||
|
||||
function f.write(self, section, data)
|
||||
return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
|
||||
end
|
||||
|
||||
function f.remove(self, section, value)
|
||||
return fs.writefile(input, "")
|
||||
end
|
||||
|
||||
function s.handle(self, state, data)
|
||||
return true
|
||||
end
|
||||
|
||||
return m
|
|
@ -1,52 +0,0 @@
|
|||
-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
-- This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
local fs = require("nixio.fs")
|
||||
local util = require("luci.util")
|
||||
local input = "/etc/config/adblock"
|
||||
|
||||
if not fs.access(input) then
|
||||
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
if fs.stat(input).size >= 102400 then
|
||||
m = SimpleForm("error", nil,
|
||||
translate("The file size is too large for online editing in LuCI (≥ 100 KB). ")
|
||||
.. translate("Please edit this file directly in a terminal session."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
m = SimpleForm("input", nil)
|
||||
m:append(Template("adblock/adblock_css"))
|
||||
m.submit = translate("Save")
|
||||
m.reset = false
|
||||
|
||||
s = m:section(SimpleSection, nil,
|
||||
translate("This form allows you to modify the content of the main adblock configuration file (/etc/config/adblock)."))
|
||||
|
||||
f = s:option(TextValue, "data")
|
||||
f.rows = 20
|
||||
f.rmempty = true
|
||||
|
||||
function f.cfgvalue()
|
||||
return fs.readfile(input) or ""
|
||||
end
|
||||
|
||||
function f.write(self, section, data)
|
||||
return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
|
||||
end
|
||||
|
||||
function f.remove(self, section, value)
|
||||
return fs.writefile(input, "")
|
||||
end
|
||||
|
||||
function s.handle(self, state, data)
|
||||
return true
|
||||
end
|
||||
|
||||
return m
|
|
@ -1,267 +0,0 @@
|
|||
-- Copyright 2017-2019 Dirk Brenken (dev@brenken.org)
|
||||
-- This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
local fs = require("nixio.fs")
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
local util = require("luci.util")
|
||||
local net = require "luci.model.network".init()
|
||||
local dump = util.ubus("network.interface", "dump", {})
|
||||
|
||||
m = Map("adblock", translate("Adblock"),
|
||||
translate("Configuration of the adblock package to block ad/abuse domains by using DNS. ")
|
||||
..translatef("For further information "
|
||||
.. "<a href=\"%s\" target=\"_blank\">"
|
||||
.. "check the online documentation</a>", "https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md"))
|
||||
|
||||
-- Main adblock options
|
||||
|
||||
s = m:section(NamedSection, "global", "adblock")
|
||||
|
||||
o1 = s:option(Flag, "adb_enabled", translate("Enable Adblock"))
|
||||
o1.default = o1.disabled
|
||||
o1.rmempty = false
|
||||
|
||||
o2 = s:option(ListValue, "adb_dns", translate("DNS Backend (DNS Directory)"),
|
||||
translate("List of supported DNS backends with their default list export directory. ")
|
||||
..translate("To overwrite the default path use the 'DNS Directory' option in the extra section below."))
|
||||
o2:value("dnsmasq", "dnsmasq (/tmp)")
|
||||
o2:value("unbound", "unbound (/var/lib/unbound)")
|
||||
o2:value("named", "named (/var/lib/bind)")
|
||||
o2:value("kresd", "kresd (/etc/kresd)")
|
||||
o2.default = "dnsmasq (/tmp)"
|
||||
o2.rmempty = false
|
||||
|
||||
o3 = s:option(ListValue, "adb_dnsvariant", translate("DNS Blocking Variant"),
|
||||
translate("List of supported DNS blocking variants. By default 'nxdomain' will be used for all DNS backends. ")
|
||||
..translate("Dnsmasq also supports 'null' block variants, which may provide better response times."))
|
||||
o3:value("nxdomain", "nxdomain, all DNS backends")
|
||||
o3:value("null (IPv4)", "null (IPv4), dnsmasq only")
|
||||
o3:value("null (IPv4/IPv6)", "null (IPv4/IPv6), dnsmasq only")
|
||||
o3.default = "nxdomain, all DNS backends"
|
||||
o3.rmempty = false
|
||||
|
||||
o4 = s:option(ListValue, "adb_fetchutil", translate("Download Utility"),
|
||||
translate("List of supported and fully pre-configured download utilities."))
|
||||
o4:value("uclient-fetch")
|
||||
o4:value("wget")
|
||||
o4:value("curl")
|
||||
o4:value("aria2c")
|
||||
o4:value("wget-nossl", "wget-nossl (noSSL)")
|
||||
o4:value("busybox", "wget-busybox (noSSL)")
|
||||
o4.default = "uclient-fetch"
|
||||
o4.rmempty = false
|
||||
|
||||
o5 = s:option(ListValue, "adb_trigger", translate("Startup Trigger"),
|
||||
translate("List of available network interfaces. Usually the startup will be triggered by the 'wan' interface. ")
|
||||
..translate("Choose 'none' to disable automatic startups, 'timed' to use a classic timeout (default 30 sec.) or select another trigger interface."))
|
||||
o5:value("none")
|
||||
o5:value("timed")
|
||||
if dump then
|
||||
local i, v
|
||||
for i, v in ipairs(dump.interface) do
|
||||
if v.interface ~= "loopback" then
|
||||
local device = v.l3_device or v.device or "-"
|
||||
o5:value(v.interface, v.interface.. " (" ..device.. ")")
|
||||
end
|
||||
end
|
||||
end
|
||||
o5.rmempty = false
|
||||
|
||||
-- Runtime information
|
||||
|
||||
ds = s:option(DummyValue, "_dummy")
|
||||
ds.template = "adblock/runtime"
|
||||
|
||||
-- Blocklist table
|
||||
|
||||
bl = m:section(TypedSection, "source", translate("Blocklist Sources"),
|
||||
translate("<b>Caution:</b> To prevent OOM exceptions on low memory devices with less than 64 MB free RAM, please only select a few of them!"))
|
||||
bl.template = "adblock/blocklist"
|
||||
|
||||
name = bl:option(Flag, "enabled", translate("Enabled"))
|
||||
name.rmempty = false
|
||||
|
||||
ssl = bl:option(DummyValue, "adb_src", translate("SSL req."))
|
||||
function ssl.cfgvalue(self, section)
|
||||
local source = self.map:get(section, "adb_src")
|
||||
if source and source:match("https://") then
|
||||
return translate("Yes")
|
||||
else
|
||||
return translate("No")
|
||||
end
|
||||
end
|
||||
|
||||
des = bl:option(DummyValue, "adb_src_desc", translate("Description"))
|
||||
|
||||
cat = bl:option(DynamicList, "adb_src_cat", translate("Archive Categories"))
|
||||
cat.datatype = "uciname"
|
||||
cat.optional = true
|
||||
|
||||
-- Extra options
|
||||
|
||||
e = m:section(NamedSection, "extra", "adblock", translate("Extra Options"),
|
||||
translate("Options for further tweaking in case the defaults are not suitable for you."))
|
||||
|
||||
e1 = e:option(Flag, "adb_debug", translate("Verbose Debug Logging"),
|
||||
translate("Enable verbose debug logging in case of any processing error."))
|
||||
e1.rmempty = false
|
||||
|
||||
e2 = e:option(Flag, "adb_nice", translate("Low Priority Service"),
|
||||
translate("Set the nice level to 'low priority' and the adblock background processing will take fewer resources from the system. ")
|
||||
..translate("This change requires a manual service stop/re-start to take effect."))
|
||||
e2.disabled = "0"
|
||||
e2.enabled = "10"
|
||||
e2.rmempty = false
|
||||
|
||||
e3 = e:option(Flag, "adb_forcedns", translate("Force Local DNS"),
|
||||
translate("Redirect all DNS queries from 'lan' zone to the local resolver, applies to udp and tcp protocol on ports 53, 853 and 5353."))
|
||||
e3.rmempty = false
|
||||
|
||||
e4 = e:option(Value, "adb_maxqueue", translate("Max. Download Queue"),
|
||||
translate("Size of the download queue to handle downloads & list processing in parallel (default '4'). ")
|
||||
..translate("For further performance improvements you can raise this value, e.g. '8' or '16' should be safe."))
|
||||
e4.default = 4
|
||||
e4.datatype = "range(1,32)"
|
||||
e4.rmempty = false
|
||||
|
||||
e5 = e:option(Flag, "adb_dnsfilereset", translate("DNS File Reset"),
|
||||
translate("Resets the final DNS blockfile 'adb_list.overall' after loading through the DNS backend. ")
|
||||
..translate("This option saves an enormous amount of storage space, but starts a small ubus/adblock monitor in the background."))
|
||||
e5.disabled = "false"
|
||||
e5.enabled = "true"
|
||||
e5.rmempty = false
|
||||
|
||||
e6 = e:option(Flag, "adb_report", translate("DNS Query Report"),
|
||||
translate("Gather dns related network traffic via tcpdump to provide a DNS Query Report on demand. ")
|
||||
..translate("Please note: this needs manual 'tcpdump-mini' package installation."))
|
||||
e6.rmempty = false
|
||||
|
||||
e7 = e:option(Value, "adb_repdir", translate("Report Directory"),
|
||||
translate("Target directory for dns related report files. Default is '/tmp', please use preferably a non-volatile disk if available."))
|
||||
e7:depends("adb_report", 1)
|
||||
e7.datatype = "directory"
|
||||
e7.default = "/tmp"
|
||||
e7.rmempty = true
|
||||
|
||||
e8 = e:option(Value, "adb_backupdir", translate("Backup Directory"),
|
||||
translate("Target directory for adblock source backups. Default is '/tmp', please use preferably a non-volatile disk if available."))
|
||||
e8.datatype = "directory"
|
||||
e8.default = "/tmp"
|
||||
e8.rmempty = true
|
||||
|
||||
e9 = e:option(Flag, "adb_mail", translate("E-Mail Notification"),
|
||||
translate("Send notification E-Mails in case of a processing error or if domain count is ≤ 0. ")
|
||||
.. translate("Please note: this needs manual 'msmtp' package installation and setup."))
|
||||
e9.rmempty = true
|
||||
|
||||
e10 = e:option(Value, "adb_mreceiver", translate("E-Mail Receiver Address"),
|
||||
translate("Receiver address for adblock notification E-Mails."))
|
||||
e10:depends("adb_mail", 1)
|
||||
e10.rmempty = true
|
||||
|
||||
-- Optional Extra Options
|
||||
|
||||
e20 = e:option(Value, "adb_dnsdir", translate("DNS Directory"),
|
||||
translate("Target directory for the generated blocklist 'adb_list.overall'."))
|
||||
e20.datatype = "directory"
|
||||
e20.optional = true
|
||||
|
||||
e21 = e:option(Value, "adb_blacklist", translate("Blacklist File"),
|
||||
translate("Full path to the blacklist file."))
|
||||
e21.datatype = "file"
|
||||
e21.default = "/etc/adblock/adblock.blacklist"
|
||||
e21.optional = true
|
||||
|
||||
e22 = e:option(Value, "adb_whitelist", translate("Whitelist File"),
|
||||
translate("Full path to the whitelist file."))
|
||||
e22.datatype = "file"
|
||||
e22.default = "/etc/adblock/adblock.whitelist"
|
||||
e22.optional = true
|
||||
|
||||
e23 = e:option(Value, "adb_triggerdelay", translate("Trigger Delay"),
|
||||
translate("Additional trigger delay in seconds before adblock processing begins."))
|
||||
e23.datatype = "range(1,60)"
|
||||
e23.optional = true
|
||||
|
||||
e24 = e:option(Value, "adb_maxtld", translate("TLD Compression Threshold"),
|
||||
translate("Disable the toplevel domain compression, if the number of blocked domains is greater than this threshold."))
|
||||
e24.datatype = "min(0)"
|
||||
e24.default = 100000
|
||||
e24.optional = true
|
||||
|
||||
e25 = e:option(Value, "adb_portlist", translate("Local FW/DNS Ports"),
|
||||
translate("Space separated list of firewall ports which should be redirected locally."))
|
||||
e25.default = "53 853 5353"
|
||||
e25.optional = true
|
||||
|
||||
e26 = e:option(Flag, "adb_dnsinotify", translate("DNS Inotify"),
|
||||
translate("Disable adblock triggered restarts and the 'DNS File Reset' for dns backends with autoload features."))
|
||||
e26.default = nil
|
||||
e26.enabled = "true"
|
||||
e26.optional = true
|
||||
|
||||
e27 = e:option(Flag, "adb_dnsflush", translate("Flush DNS Cache"),
|
||||
translate("Flush DNS Cache after adblock processing."))
|
||||
e27.default = nil
|
||||
e27.optional = true
|
||||
|
||||
e28 = e:option(ListValue, "adb_repiface", translate("Report Interface"),
|
||||
translate("Reporting interface used by tcpdump, set to 'any' for multiple interfaces (default 'br-lan'). ")
|
||||
..translate("This change requires a manual service stop/re-start to take effect."))
|
||||
if dump then
|
||||
local i, v
|
||||
for i, v in ipairs(dump.interface) do
|
||||
if v.interface ~= "loopback" then
|
||||
local device = v.device
|
||||
if device then
|
||||
e28:value(device)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
e28:value("any")
|
||||
e28.optional = true
|
||||
|
||||
e29 = e:option(Value, "adb_replisten", translate("Report Listen Port(s)"),
|
||||
translate("Space separated list of reporting port(s) used by tcpdump (default: '53'). ")
|
||||
..translate("This change requires a manual service stop/re-start to take effect."))
|
||||
e29.default = 53
|
||||
e29.optional = true
|
||||
|
||||
e30 = e:option(Value, "adb_repchunkcnt", translate("Report Chunk Count"),
|
||||
translate("Report chunk count used by tcpdump (default '5'). ")
|
||||
..translate("This change requires a manual service stop/re-start to take effect."))
|
||||
e30.datatype = "range(1,10)"
|
||||
e30.default = 5
|
||||
e30.optional = true
|
||||
|
||||
e31 = e:option(Value, "adb_repchunksize", translate("Report Chunk Size"),
|
||||
translate("Report chunk size used by tcpdump in MB (default '1'). ")
|
||||
..translate("This change requires a manual service stop/re-start to take effect."))
|
||||
e31.datatype = "range(1,10)"
|
||||
e31.default = 1
|
||||
e31.optional = true
|
||||
|
||||
e32 = e:option(Value, "adb_msender", translate("E-Mail Sender Address"),
|
||||
translate("Sender address for adblock notification E-Mails."))
|
||||
e32.default = "no-reply@adblock"
|
||||
e32.optional = true
|
||||
|
||||
e33 = e:option(Value, "adb_mtopic", translate("E-Mail Topic"),
|
||||
translate("Topic for adblock notification E-Mails."))
|
||||
e33.default = "adblock notification"
|
||||
e33.optional = true
|
||||
|
||||
e34 = e:option(Value, "adb_mprofile", translate("E-Mail Profile"),
|
||||
translate("Mail profile used in 'msmtp' for adblock notification E-Mails."))
|
||||
e34.default = "adb_notify"
|
||||
e34.optional = true
|
||||
|
||||
e35 = e:option(Value, "adb_mcnt", translate("E-Mail Notification Count"),
|
||||
translate("Raise the minimum notification count, to get E-Mails if the overall count is less or equal to the given limit (default 0), ")
|
||||
.. translate("e.g. to receive an E-Mail notification with every adblock run set this value to 200000."))
|
||||
e35.default = 0
|
||||
e35.datatype = "min(0)"
|
||||
e35.optional = true
|
||||
|
||||
return m
|
|
@ -1,55 +0,0 @@
|
|||
-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
-- This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
local fs = require("nixio.fs")
|
||||
local util = require("luci.util")
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
local input = uci:get("adblock", "global", "adb_whitelist") or "/etc/adblock/adblock.whitelist"
|
||||
|
||||
if not fs.access(input) then
|
||||
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
if fs.stat(input).size >= 102400 then
|
||||
m = SimpleForm("error", nil,
|
||||
translate("The file size is too large for online editing in LuCI (≥ 100 KB). ")
|
||||
.. translate("Please edit this file directly in a terminal session."))
|
||||
m.reset = false
|
||||
m.submit = false
|
||||
return m
|
||||
end
|
||||
|
||||
m = SimpleForm("input", nil)
|
||||
m:append(Template("adblock/adblock_css"))
|
||||
m.submit = translate("Save")
|
||||
m.reset = false
|
||||
|
||||
s = m:section(SimpleSection, nil,
|
||||
translatef("This form allows you to modify the content of the adblock whitelist (%s). ", input)
|
||||
.. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards and regex are not."))
|
||||
|
||||
f = s:option(TextValue, "data")
|
||||
f.datatype = "string"
|
||||
f.rows = 20
|
||||
f.rmempty = true
|
||||
|
||||
function f.cfgvalue()
|
||||
return fs.readfile(input) or ""
|
||||
end
|
||||
|
||||
function f.write(self, section, data)
|
||||
return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
|
||||
end
|
||||
|
||||
function f.remove(self, section, value)
|
||||
return fs.writefile(input, "")
|
||||
end
|
||||
|
||||
function s.handle(self, state, data)
|
||||
return true
|
||||
end
|
||||
|
||||
return m
|
|
@ -1,86 +0,0 @@
|
|||
<style type="text/css">
|
||||
textarea
|
||||
{
|
||||
width: 100% !important;
|
||||
height: 450px !important;
|
||||
border: 1px solid #cccccc;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
font-family: monospace;
|
||||
resize: none;
|
||||
white-space: pre;
|
||||
overflow-wrap: normal;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
select[readonly],
|
||||
textarea[readonly]
|
||||
{
|
||||
width: 100% !important;
|
||||
height: 450px !important;
|
||||
border: 1px solid #cccccc;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
font-family: monospace;
|
||||
resize: none;
|
||||
pointer-events: auto;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.table.cbi-section-table .th,
|
||||
.table.cbi-section-table .td,
|
||||
.cbi-section-table-cell,
|
||||
.cbi-section-table-row,
|
||||
.tr[data-title]::before
|
||||
{
|
||||
text-align: left !important;
|
||||
vertical-align: top;
|
||||
margin-left: 0px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.table.cbi-section-table .th
|
||||
{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-select,
|
||||
.table.cbi-section-table select
|
||||
{
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.item,
|
||||
.add-item
|
||||
{
|
||||
white-space: nowrap;
|
||||
width: 8.2em;
|
||||
}
|
||||
|
||||
.cbi-input-checkbox
|
||||
{
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.cbi-button
|
||||
{
|
||||
-webkit-appearance: menulist;
|
||||
}
|
||||
|
||||
.runtime
|
||||
{
|
||||
color: #37c;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.button_running
|
||||
{
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
</style>
|
|
@ -1,47 +0,0 @@
|
|||
<%#
|
||||
Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
This is free software, licensed under the Apache License, Version 2.0
|
||||
-%>
|
||||
|
||||
<%-
|
||||
local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous"
|
||||
-%>
|
||||
|
||||
<%+adblock/adblock_css%>
|
||||
|
||||
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<% if self.title then -%>
|
||||
<h3><%=self.title%></h3>
|
||||
<%- end %>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<div class="cbi-section-node">
|
||||
<div class="table cbi-section-table">
|
||||
<div class="tr cbi-section-table-titles <%=anonclass%>">
|
||||
<%- for i, k in pairs(self.children) do -%>
|
||||
<div class="th cbi-section-table-cell">
|
||||
<%-=k.title-%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<%- local section, scope, isempty = true
|
||||
for i, k in ipairs(self:cfgsections()) do
|
||||
section = k
|
||||
local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k)
|
||||
local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname, true)
|
||||
isempty = false
|
||||
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
|
||||
-%>
|
||||
<div class="tr cbi-section-table-row" id="cbi-<%=self.config%>-<%=section%>"<%=sectiontitle%>>
|
||||
<%-
|
||||
for k, node in ipairs(self.children) do
|
||||
node:render(section, scope or {})
|
||||
end
|
||||
if not scope.cbid:match("adb_src_cat") then
|
||||
-%>
|
||||
<div class="td cbi-value-field"> </div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
<%- end -%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,36 +0,0 @@
|
|||
<%#
|
||||
Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
This is free software, licensed under the Apache License, Version 2.0
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
<%+adblock/adblock_css%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function log_update()
|
||||
{
|
||||
XHR.poll(-1, '<%=luci.dispatcher.build_url("admin", "services", "adblock", "logread")%>', null,
|
||||
function(x)
|
||||
{
|
||||
if (!x)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var view = document.getElementById("view_id");
|
||||
view.value = x.responseText;
|
||||
view.scrollTop = view.scrollHeight;
|
||||
});
|
||||
}
|
||||
window.onload = log_update();
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-map">
|
||||
<div class="cbi-section">
|
||||
<div class="cbi-section-descr"><%:The syslog output, pre-filtered for adblock related messages only.%></div>
|
||||
<textarea id="view_id" readonly="readonly" wrap="off" value=""></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
|
@ -1,64 +0,0 @@
|
|||
<%#
|
||||
Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
|
||||
This is free software, licensed under the Apache License, Version 2.0
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var stxhr = new XHR();
|
||||
|
||||
function update_status(data)
|
||||
{
|
||||
var domain = data.value || data.placeholder;
|
||||
var input = document.getElementById('query_input');
|
||||
var output = document.getElementById('query_output');
|
||||
|
||||
if (input && output)
|
||||
{
|
||||
output.innerHTML =
|
||||
'<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' +
|
||||
'<%:Waiting for command to complete...%>'
|
||||
;
|
||||
input.parentNode.style.display = 'block';
|
||||
input.style.display = 'inline';
|
||||
stxhr.post('<%=luci.dispatcher.build_url('admin/services/adblock/advanced/result/')%>' + domain, { token: '<%=token%>' },
|
||||
function(x)
|
||||
{
|
||||
if (x.responseText)
|
||||
{
|
||||
input.style.display = 'none';
|
||||
output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
|
||||
}
|
||||
else
|
||||
{
|
||||
input.style.display = 'none';
|
||||
output.innerHTML = '<span class="error"><%:Blocklist not found!%></span>';
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<form method="post" action="<%=REQUEST_URI%>" onsubmit="update_status(this.input); return false;">
|
||||
<div class="cbi-map">
|
||||
<div class="cbi-section">
|
||||
<div class="cbi-section-descr"><%:This form allows you to query active block lists for certain domains, e.g. for whitelisting.%></div>
|
||||
<div style="width:33%; float:left;">
|
||||
<input type="text" placeholder="google.com" name="input" />
|
||||
<input type="button" value="<%:Query%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.input)" />
|
||||
</div>
|
||||
<br style="clear:both" />
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-section" style="display:none">
|
||||
<h3 id="query_input"><%:Collecting data...%></h3>
|
||||
<span id="query_output"></span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<%+footer%>
|
|
@ -1,310 +0,0 @@
|
|||
<%#
|
||||
Copyright 2017-2019 Dirk Brenken (dev@brenken.org)
|
||||
This is free software, licensed under the Apache License, Version 2.0
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
<%+adblock/adblock_css%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function report_json(json)
|
||||
{
|
||||
document.getElementById("value_1").innerHTML = json.data.start_date + ", " + json.data.start_time || "-";
|
||||
document.getElementById("value_2").innerHTML = json.data.end_date + ", " + json.data.end_time || "-";
|
||||
document.getElementById("value_3").innerHTML = json.data.total || "-";
|
||||
document.getElementById("value_4").innerHTML = json.data.blocked + " (" + json.data.percent + ")" || "-";
|
||||
|
||||
var a_cnt;
|
||||
var b_cnt;
|
||||
var c_cnt;
|
||||
var a_val;
|
||||
var b_val;
|
||||
var c_val;
|
||||
var s = '<div class="tr table-titles">';
|
||||
s += '<div class="th left"><%:Count%></div>';
|
||||
s += '<div class="th left"><%:Name / IP-Address%></div>';
|
||||
s += '<div class="th left"><%:Count%></div>';
|
||||
s += '<div class="th left"><%:Domain%></div>';
|
||||
s += '<div class="th left"><%:Count%></div>';
|
||||
s += '<div class="th left"><%:Blocked Domain%></div></div>';
|
||||
|
||||
for(var i=0;i<10;i++)
|
||||
{
|
||||
if (i < json.top_clients.length)
|
||||
{
|
||||
a_cnt = json.top_clients[i].count;
|
||||
a_val = json.top_clients[i].address;
|
||||
}
|
||||
else
|
||||
{
|
||||
a_cnt = "-";
|
||||
a_val = "";
|
||||
}
|
||||
|
||||
if (i < json.top_domains.length)
|
||||
{
|
||||
b_cnt = json.top_domains[i].count;
|
||||
b_val = json.top_domains[i].address;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_cnt = "-";
|
||||
b_val = "";
|
||||
}
|
||||
|
||||
if (i < json.top_blocked.length)
|
||||
{
|
||||
c_cnt = json.top_blocked[i].count;
|
||||
c_val = json.top_blocked[i].address;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_cnt = "-";
|
||||
c_val = "";
|
||||
}
|
||||
|
||||
s += '<div class="tr left">';
|
||||
s += '<div class="td left" data-title="<%:Count%>">' + a_cnt + '</div>';
|
||||
s += '<div class="td left" data-title="<%:Name / IP-Address%>">' + a_val + '</div>';
|
||||
s += '<div class="td left" data-title="<%:Count%>">' + b_cnt + '</div>';
|
||||
s += '<div class="td left" data-title="<%:Domain%>">' + b_val + '</div>';
|
||||
s += '<div class="td left" data-title="<%:Count%>">' + c_cnt + '</div>';
|
||||
s += '<div class="td left" data-title="<%:Blocked Domain%>">' + c_val + '</div></div>';
|
||||
}
|
||||
document.getElementById("value_5").innerHTML = s;
|
||||
}
|
||||
|
||||
function report_text(text)
|
||||
{
|
||||
var s = '<div class="tr table-titles">';
|
||||
s += '<div class="th left"><%:Date%></div>';
|
||||
s += '<div class="th left"><%:Time%></div>';
|
||||
s += '<div class="th left"><%:Client%></div>';
|
||||
s += '<div class="th left"><%:Domain%></div>';
|
||||
s += '<div class="th left"><%:Answer%></div>';
|
||||
s += '<div class="th left"><%:Action%></div></div>';
|
||||
var btn1;
|
||||
var record;
|
||||
var title_arr = ["<%:Date%>", "<%:Time%>", "<%:Client%>", "<%:Domain%>", "<%:Answer%>", "<%:Action%>"];
|
||||
var array = text.split("\n");
|
||||
for (var i=0;i<array.length;i++)
|
||||
{
|
||||
record = array[i].split("\t");
|
||||
if (record[0] && record[0] != "undefined")
|
||||
{
|
||||
s += '<div class="tr left">';
|
||||
for (var j=0;j<5;j++)
|
||||
{
|
||||
s += '<div class="td left" data-title="' + title_arr[j] + '">' + record[j] + '</div>';
|
||||
if (record[4] === "NX")
|
||||
{
|
||||
btn1 = '<div class="td left" data-title="' + title_arr[5] + '"><input type="button" class="cbi-button cbi-button-edit" name="add_whitelist,' + record[3] + '" value="<%:Whitelist%>" onclick="btn_action(this)" /></div>';
|
||||
}
|
||||
else if (record[4] === "OK")
|
||||
{
|
||||
btn1 = '<div class="td left" data-title="' + title_arr[5] + '"><input type="button" class="cbi-button cbi-button-remove" name="add_blacklist,' + record[3] + '" value="<%:Blacklist%>" onclick="btn_action(this)" /></div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
btn1 = '-'
|
||||
}
|
||||
}
|
||||
s += btn1 + '</div>'
|
||||
}
|
||||
}
|
||||
document.getElementById("value_6").innerHTML = s;
|
||||
}
|
||||
|
||||
function btn_action(value)
|
||||
{
|
||||
var action = value.name.split(",");
|
||||
|
||||
if (action[0] === "do_report")
|
||||
{
|
||||
var btn1 = document.getElementById("btn1");
|
||||
var btn1_running = document.getElementById("btn1_running");
|
||||
|
||||
btn1.disabled = true;
|
||||
running(btn1_running, 1);
|
||||
|
||||
document.getElementById("filter_search").value = '';
|
||||
document.getElementById("filter_count").selectedIndex = 1;
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock")%>/action/' + action[0], null,
|
||||
function(x)
|
||||
{
|
||||
if (!x)
|
||||
{
|
||||
return;
|
||||
}
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "report_json")%>', null,
|
||||
function(x, json_info)
|
||||
{
|
||||
if (!x || !json_info || !json_info.data)
|
||||
{
|
||||
running(btn1_running, 0);
|
||||
btn1.disabled = false;
|
||||
return;
|
||||
}
|
||||
report_json(json_info);
|
||||
});
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "report_text")%>', null,
|
||||
function(x)
|
||||
{
|
||||
if (!x || !x.responseText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
report_text(x.responseText);
|
||||
running(btn1_running, 0);
|
||||
btn1.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (action[0] === "do_filter")
|
||||
{
|
||||
var btn2 = document.getElementById("btn2");
|
||||
var btn2_running = document.getElementById("btn2_running");
|
||||
var search = document.getElementById("filter_search").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()+=\[\]{};'"\\|,<>\/?]/g,'') || "\"+\"";
|
||||
var count = document.getElementById("filter_count").value;
|
||||
|
||||
btn2.disabled = true;
|
||||
running(btn2_running, 1);
|
||||
if (search != "\"+\"")
|
||||
{
|
||||
document.getElementById("filter_search").value = search;
|
||||
}
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock")%>/action/' + action[0] + "/" + "-" + "/" + search + "/" + count + "/" + "true" + "/" + "false", null,
|
||||
function(x)
|
||||
{
|
||||
if (!x)
|
||||
{
|
||||
return;
|
||||
}
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "report_text")%>', null,
|
||||
function(x)
|
||||
{
|
||||
if (!x || !x.responseText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
report_text(x.responseText);
|
||||
running(btn2_running, 0);
|
||||
btn2.disabled = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (action[0] === "add_blacklist" || action[0] === "add_whitelist")
|
||||
{
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock")%>/action/' + action[0] + "/" + action[1], null,
|
||||
function(x)
|
||||
{
|
||||
if (!x)
|
||||
{
|
||||
return;
|
||||
}
|
||||
btn3 = document.getElementsByName(value.name);
|
||||
for (var i=0; i<btn3.length; i++)
|
||||
{
|
||||
btn3[i].disabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function running(element, state)
|
||||
{
|
||||
if (state === 1)
|
||||
{
|
||||
var running_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" />';
|
||||
element.innerHTML = running_html;
|
||||
}
|
||||
else
|
||||
{
|
||||
element.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "report_json")%>', null,
|
||||
function(x, json_info)
|
||||
{
|
||||
if (!x || !json_info || !json_info.data)
|
||||
{
|
||||
running(btn1_running, 0);
|
||||
btn1.disabled = false;
|
||||
return;
|
||||
}
|
||||
report_json(json_info);
|
||||
});
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "report_text")%>', null,
|
||||
function(x)
|
||||
{
|
||||
if (!x || !x.responseText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
report_text(x.responseText);
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-section">
|
||||
<div class="cbi-value" id="status_1">
|
||||
<label class="cbi-value-title" for="status_1"><%:Start Date%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_1">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_2">
|
||||
<label class="cbi-value-title" for="status_2"><%:End Date%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_2">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_3">
|
||||
<label class="cbi-value-title" for="status_3"><%:Total DNS Queries%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_3">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_4">
|
||||
<label class="cbi-value-title" for="status_4"><%:Blocked DNS Queries%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_4">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div id="button">
|
||||
<input type="button" class="cbi-button cbi-button-action important" id="btn1" name="do_report" value="<%:Refresh Report%>" onclick="btn_action(this)" />
|
||||
<span id="btn1_running" class="btn1_running"></span>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="cbi-section">
|
||||
<h3><%:Top 10 Reporting%></h3>
|
||||
<div class="table" id="value_5"></div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="cbi-section">
|
||||
<div class="cbi-section-descr"><%:Filter the DNS Query result set for a particular domain, client or time frame.%></div>
|
||||
<div style="float:left;">
|
||||
<input type="text" placeholder="<%:Domain/Client/Date/Time%>" id="filter_search" name="filter_search" />
|
||||
<select name="filter_count" id="filter_count">
|
||||
<option value="25">25</option>
|
||||
<option value="50" selected="selected">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="250">250</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
<input type="button" class="cbi-button cbi-button-action" id="btn2" name="do_filter" value="<%:Filter%>" onclick="btn_action(this)" />
|
||||
<span id="btn2_running" class="btn2_running"></span>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<h3><%:Latest DNS Queries%></h3>
|
||||
<div class="table" id="value_6"></div>
|
||||
</div>
|
||||
<%+footer%>
|
|
@ -1,213 +0,0 @@
|
|||
<%#
|
||||
Copyright 2017-2019 Dirk Brenken (dev@brenken.org)
|
||||
This is free software, licensed under the Apache License, Version 2.0
|
||||
-%>
|
||||
|
||||
<%+adblock/adblock_css%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function format(number)
|
||||
{
|
||||
var string = number.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.');
|
||||
return string;
|
||||
}
|
||||
|
||||
function status_update(json)
|
||||
{
|
||||
var btn1 = document.getElementById("btn1");
|
||||
var btn1_running = document.getElementById("btn1_running");
|
||||
var btn2 = document.getElementById("btn2");
|
||||
var btn2_running = document.getElementById("btn2_running");
|
||||
var input = json.data.adblock_status || "-";
|
||||
|
||||
document.getElementById("value_1").innerHTML = input;
|
||||
if (input === "enabled")
|
||||
{
|
||||
btn1.value = "<%:Suspend%>";
|
||||
btn1.name = "do_suspend";
|
||||
btn2.value = "<%:Refresh%>";
|
||||
btn2.name = "do_refresh";
|
||||
btn1.disabled = false;
|
||||
running(btn1_running, 0);
|
||||
btn2.disabled = false;
|
||||
running(btn2_running, 0);
|
||||
}
|
||||
else if (input === "paused")
|
||||
{
|
||||
btn1.value = "<%:Resume%>";
|
||||
btn1.name = "do_resume";
|
||||
btn2.value = "<%:Refresh%>";
|
||||
btn2.name = "do_refresh";
|
||||
btn1.disabled = false;
|
||||
running(btn1_running, 0);
|
||||
btn2.disabled = false;
|
||||
running(btn2_running, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
btn1.value = "<%:Suspend%>";
|
||||
btn1.name = "do_suspend";
|
||||
btn2.value = "<%:Refresh%>";
|
||||
btn2.name = "do_refresh";
|
||||
btn1.disabled = true;
|
||||
btn2.disabled = true;
|
||||
}
|
||||
|
||||
document.getElementById("value_2").innerHTML = json.data.adblock_version || "-";
|
||||
document.getElementById("value_3").innerHTML = json.data.fetch_utility || "-";
|
||||
document.getElementById("value_4").innerHTML = json.data.dns_backend || "-";
|
||||
document.getElementById("value_5").innerHTML = json.data.dns_variant || "-";
|
||||
document.getElementById("value_6").innerHTML = json.data.backup_dir || "-";
|
||||
document.getElementById("value_7").innerHTML = format(json.data.overall_domains) || "-";
|
||||
document.getElementById("value_8").innerHTML = json.data.last_rundate || "-";
|
||||
}
|
||||
|
||||
function btn_action(action)
|
||||
{
|
||||
var btn1 = document.getElementById("btn1");
|
||||
var btn1_running = document.getElementById("btn1_running");
|
||||
var btn2 = document.getElementById("btn2");
|
||||
var btn2_running = document.getElementById("btn2_running");
|
||||
|
||||
btn1.disabled = true;
|
||||
btn2.disabled = true;
|
||||
|
||||
if (action.name === "do_refresh")
|
||||
{
|
||||
running(btn2_running, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
running(btn1_running, 1);
|
||||
}
|
||||
|
||||
new XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock")%>/action/' + action.name, null,
|
||||
function(x)
|
||||
{
|
||||
if (!x)
|
||||
{
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function running(element, state)
|
||||
{
|
||||
if (state === 1)
|
||||
{
|
||||
var running_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" />';
|
||||
element.innerHTML = running_html;
|
||||
}
|
||||
else
|
||||
{
|
||||
element.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
||||
function reset_view()
|
||||
{
|
||||
document.getElementById("btn1").value = "<%:Suspend%>";
|
||||
document.getElementById("btn1").name = "do_suspend";
|
||||
document.getElementById("btn2").value = "<%:Refresh%>";
|
||||
document.getElementById("btn2").name = "do_refresh";
|
||||
document.getElementById("btn1").disabled = true;
|
||||
document.getElementById("btn2").disabled = true;
|
||||
document.getElementById("value_1").innerHTML = "-";
|
||||
document.getElementById("value_2").innerHTML = "-";
|
||||
document.getElementById("value_3").innerHTML = "-";
|
||||
document.getElementById("value_4").innerHTML = "-";
|
||||
document.getElementById("value_5").innerHTML = "-";
|
||||
document.getElementById("value_6").innerHTML = "-";
|
||||
document.getElementById("value_7").innerHTML = "-";
|
||||
document.getElementById("value_8").innerHTML = "-";
|
||||
}
|
||||
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "adblock", "status_update")%>', null,
|
||||
function(x, json_info)
|
||||
{
|
||||
if (!x || !json_info || !json_info.data)
|
||||
{
|
||||
reset_view();
|
||||
return;
|
||||
}
|
||||
status_update(json_info);
|
||||
});
|
||||
|
||||
XHR.poll(-1, '<%=luci.dispatcher.build_url("admin", "services", "adblock", "status_update")%>', null,
|
||||
function(x, json_info)
|
||||
{
|
||||
if (!x || !json_info || !json_info.data)
|
||||
{
|
||||
reset_view();
|
||||
return;
|
||||
}
|
||||
status_update(json_info);
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<h3><%:Runtime Information%></h3>
|
||||
<div class="cbi-value" id="status_1">
|
||||
<label class="cbi-value-title" for="status_1"><%:Adblock Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_1">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_2">
|
||||
<label class="cbi-value-title" for="status_2"><%:Adblock Version%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_2">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_3">
|
||||
<label class="cbi-value-title" for="status_3"><%:Download Utility (SSL Library)%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_3">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_4">
|
||||
<label class="cbi-value-title" for="status_4"><%:DNS Backend, DNS Directory%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_4">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_5">
|
||||
<label class="cbi-value-title" for="status_5"><%:DNS Variant, DNS File Reset%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_5">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_6">
|
||||
<label class="cbi-value-title" for="status_6"><%:Backup Directory%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_6">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_7">
|
||||
<label class="cbi-value-title" for="status_7"><%:Overall Domains%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_7">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="status_8">
|
||||
<label class="cbi-value-title" for="status_8"><%:Last Run%></label>
|
||||
<div class="cbi-value-field">
|
||||
<span class="runtime" id="value_8">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="cbi-value" id="button_1">
|
||||
<label class="cbi-value-title" for="button_1"><%:Suspend / Resume Adblock%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-reset" id="btn1" type="button" value="" onclick="btn_action(this)" />
|
||||
<span id="btn1_running" class="btn_running"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p />
|
||||
<div class="cbi-value" id="button_2">
|
||||
<label class="cbi-value-title" for="button_2"><%:Refresh Blocklist Sources%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="cbi-button cbi-button-apply" id="btn2" type="button" value="" onclick="btn_action(this)" />
|
||||
<span id="btn2_running" class="btn_running"></span>
|
||||
</div>
|
||||
</div>
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@adblock[-1]
|
||||
add ucitrack adblock
|
||||
set ucitrack.@adblock[-1].init=adblock
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"admin/services/adblock": {
|
||||
"title": "Adblock",
|
||||
"order": "60",
|
||||
"action": {
|
||||
"type": "alias",
|
||||
"path": "admin/services/adblock/overview"
|
||||
},
|
||||
"depends": {
|
||||
"fs": {
|
||||
"/usr/bin/adblock.sh": "executable",
|
||||
"/etc/init.d/adblock": "executable"
|
||||
},
|
||||
"uci": { "adblock": true }
|
||||
}
|
||||
},
|
||||
"admin/services/adblock/overview": {
|
||||
"title": "Overview",
|
||||
"order": 10,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adblock/overview"
|
||||
}
|
||||
},
|
||||
"admin/services/adblock/dnsreport": {
|
||||
"title": "DNS Report",
|
||||
"order": 20,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adblock/dnsreport"
|
||||
}
|
||||
},
|
||||
"admin/services/adblock/blacklist": {
|
||||
"title": "Edit Blacklist",
|
||||
"order": 30,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adblock/blacklist"
|
||||
}
|
||||
},
|
||||
"admin/services/adblock/whitelist": {
|
||||
"title": "Edit Whitelist",
|
||||
"order": 40,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adblock/whitelist"
|
||||
}
|
||||
},
|
||||
"admin/services/adblock/logread": {
|
||||
"title": "Log View",
|
||||
"order": 50,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adblock/logread"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"luci-app-adblock": {
|
||||
"description": "Grant access to LuCI app adblock",
|
||||
"write": {
|
||||
"uci": ["adblock"],
|
||||
"file": {
|
||||
"/etc/adblock/*": ["read"],
|
||||
"/etc/adblock/adblock.blacklist": ["write"],
|
||||
"/etc/adblock/adblock.whitelist": ["write"]
|
||||
}
|
||||
},
|
||||
"read": {
|
||||
"cgi-io": [ "exec" ],
|
||||
"file": {
|
||||
"/var/run/adblock.pid": ["read"],
|
||||
"/tmp/adb_runtime.json": ["read"],
|
||||
"/etc/crontabs/root": ["read"],
|
||||
"/sbin/logread -e adblock-": [ "exec" ],
|
||||
"/usr/sbin/logread -e adblock-": [ "exec" ],
|
||||
"/etc/init.d/adblock list" : [ "exec" ],
|
||||
"/etc/init.d/adblock start" : [ "exec" ],
|
||||
"/etc/init.d/adblock suspend" : [ "exec" ],
|
||||
"/etc/init.d/adblock resume" : [ "exec" ],
|
||||
"/etc/init.d/adblock report * [0-9]* [a-z]* json" : [ "exec" ],
|
||||
"/etc/init.d/adblock timer * [0-9]* [0-9*]* [1-7,-*]*" : [ "exec" ],
|
||||
"/etc/init.d/adblock query *" : [ "exec" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue