ruantiblock-mod-lua: added lua-idn. luci-app-ruantiblock: updated log.

This commit is contained in:
gSpot
2025-09-04 18:29:31 +03:00
parent 1c27840aca
commit 493cc103b8
13 changed files with 547 additions and 204 deletions
+3 -6
View File
@@ -10,9 +10,9 @@ LUCI_APP=1
HTTPS_DNS_PROXY=1
OWRT_VERSION="current"
RUAB_VERSION="2.1.6-r3"
RUAB_MOD_LUA_VERSION="2.1.6-r1"
RUAB_LUCI_APP_VERSION="2.1.6-r3"
RUAB_VERSION="2.1.7-r1"
RUAB_MOD_LUA_VERSION="2.1.7-r1"
RUAB_LUCI_APP_VERSION="2.1.7-r1"
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
PKG_DIR="/tmp"
@@ -29,7 +29,6 @@ URL_LUCI_APP_PKG="${BASE_URL}/${OWRT_VERSION}/luci-app-ruantiblock_${RUAB_LUCI_A
URL_LUCI_APP_RU_PKG="${BASE_URL}/${OWRT_VERSION}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
### tor
URL_TORRC="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_openwrt/master/tor/etc/tor/torrc"
URL_LUA_IDN="https://raw.githubusercontent.com/haste/lua-idn/master/idn.lua"
### Local files
@@ -55,7 +54,6 @@ FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
### tor
FILE_TORRC="${PREFIX}/etc/tor/torrc"
FILE_LUA_IDN="${PREFIX}/usr/lib/lua/idn.lua"
AWK_CMD="awk"
WGET_CMD="$(which wget)"
@@ -228,7 +226,6 @@ InstallLuaModule() {
InstallPackages "lua" "luasocket" "luasec" "luabitop"
RemoveFile "$FILE_MOD_LUA_PKG" > /dev/null
DlFile "$URL_MOD_LUA_PKG" "$FILE_MOD_LUA_PKG" && $OPKG_CMD install "$FILE_MOD_LUA_PKG"
FileExists "$FILE_LUA_IDN" || DlFile "$URL_LUA_IDN" "$FILE_LUA_IDN"
$UCI_CMD set ruantiblock.config.bllist_module="/usr/libexec/ruantiblock/ruab_parser.lua"
$UCI_CMD commit ruantiblock
}
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ruantiblock
PKG_VERSION:=2.1.6
PKG_RELEASE:=3
PKG_VERSION:=2.1.7
PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for ruantiblock
LUCI_DEPENDS:=+ruantiblock
LUCI_PKGARCH:=all
@@ -107,6 +107,7 @@ log-emerg td {
}
.log-info {
background-color: var(--app-log-info) !important;
/*color: var(--app-log-dark-font-color) !important;*/
}
.log-debug {
background-color: var(--app-log-debug) !important;
@@ -256,7 +257,9 @@ return baseclass.extend({
timeFilterReValue : false,
hostFilterValue : [],
hostFilterValue : null,
hostFilterReValue : false,
facilityFilterValue : [],
@@ -274,18 +277,14 @@ return baseclass.extend({
logTimestampFlag : false,
logHostsFlag : false,
logHostFlag : false,
logFacilitiesFlag : false,
logLevelsFlag : false,
logHosts : {},
logLevelsStat : {},
logHostsDropdown : null,
logFacilitiesDropdown: null,
logLevelsDropdown : null,
@@ -315,6 +314,44 @@ return baseclass.extend({
return (/^[0-9]+$/.test(value)) ? value : 0
},
makeRegExpButton(filterEl, checked) {
const btnOnClass = 'cbi-button-positive btn important',
btnOnStyle = 'text-decoration:none',
btnOffClass = 'cbi-button-neutral btn',
btnOffStyle = 'text-decoration:line-through';
let btn = E('button', {
'class': checked ? btnOnClass : btnOffClass,
'style': checked ? btnOnStyle : btnOffStyle,
'title': _('Apply pattern as regular expression'),
'click': ev => {
ev.target.toggle();
filterEl.focus();
ev.preventDefault();
},
}, 'RE');
btn._state = checked;
btn._on = function() {
this._state = true;
this.className = btnOnClass;
this.style = btnOnStyle;
};
btn._off = function() {
this._state = false;
this.className = btnOffClass;
this.style = btnOffStyle;
};
btn.checked = function() {
return this._state;
};
btn.toggle = function() {
this._state ? this._off() : this._on();
};
btn.set = function(flag) {
flag ? this._on() : this._off();
};
return btn;
},
makeLogConvertTimestampSection() {
if(!this.enableConvertTimestamp) {
return '';
@@ -330,7 +367,7 @@ return baseclass.extend({
E('label', {}),
]),
E('div', { 'class': 'cbi-value-description' },
_('Convert timestamps to a human readable date')
_('Convert timestamps to a human readable date.')
),
]),
]);
@@ -342,70 +379,52 @@ return baseclass.extend({
'class': 'cbi-value-title',
'for' : 'timeFilter',
}, _('Timestamp filter')),
E('div', { 'class': 'cbi-value-field' },
E('div', { 'class': 'cbi-value-field' }, [
E('span', { 'class': 'control-group' }, [
this.timeFilter,
E('button', {
'class': 'cbi-button btn',
'click': L.bind(ev => {
'class': 'cbi-button-neutral btn',
'click': ev => {
ev.target.blur();
ev.preventDefault();
this.timeFilter.value = null;
this.timeFilter.focus();
}, this),
},
}, '⌫'),
])
),
]);
},
makeLogtimeFilterReSection() {
return E('div', { 'class': 'cbi-value' }, [
E('label', {
'class': 'cbi-value-title',
'for' : 'timeFilterRe',
}, _('Filter is regexp')),
E('div', { 'class': 'cbi-value-field' }, [
E('div', { 'class': 'cbi-checkbox' }, [
this.timeFilterRe,
E('label', {}),
this.timeFilterReBtn,
]),
E('div', { 'class': 'cbi-value-description' },
_('Apply timestamp filter as regular expression')
_('<code>!pattern</code> - entries that do not match the pattern.')
),
]),
]);
},
makeLogHostsDropdownItem(host) {
return E(
'span',
{ 'class': 'zonebadge log-host-dropdown-item' },
E('strong', host)
);
},
makeLogHostsDropdownSection() {
this.logHostsDropdown = new ui.Dropdown(
null,
this.logHosts,
{
id : 'logHostsDropdown',
multiple : true,
select_placeholder: _('All'),
}
);
return E(
'div', { 'class': 'cbi-value' }, [
E('label', {
'class': 'cbi-value-title',
'for' : 'logHostsDropdown',
}, _('Hosts')),
E('div', { 'class': 'cbi-value-field' },
this.logHostsDropdown.render()
makeLogHostFilterSection() {
return E('div', { 'class': 'cbi-value' }, [
E('label', {
'class': 'cbi-value-title',
'for' : 'hostFilter',
}, _('Host filter')),
E('div', { 'class': 'cbi-value-field' }, [
E('span', { 'class': 'control-group' }, [
this.hostFilter,
E('button', {
'class': 'cbi-button-neutral btn',
'click': ev => {
ev.target.blur();
ev.preventDefault();
this.hostFilter.value = null;
this.hostFilter.focus();
},
}, '&#9003;'),
this.hostFilterReBtn,
]),
E('div', { 'class': 'cbi-value-description' },
_('<code>!pattern</code> - entries that do not match the pattern.')
),
]
);
]),
]);
},
makeLogFacilitiesDropdownSection() {
@@ -456,13 +475,13 @@ return baseclass.extend({
);
},
setRegexpValidator(elem, flag) {
setRegexpValidator(elem, flagEl) {
ui.addValidator(
elem,
'string',
true,
v => {
if(!flag.checked) {
if(!flagEl.checked()) {
return true;
};
try {
@@ -485,10 +504,11 @@ return baseclass.extend({
this.convertTimestampValue = this.convertTimestamp.checked;
};
this.timeFilterValue = this.timeFilter.value;
this.timeFilterReValue = this.timeFilterRe.checked;
this.timeFilterReValue = this.timeFilterReBtn.checked()
};
if(this.logHostsFlag) {
this.hostFilterValue = this.logHostsDropdown.getValue();
if(this.logHostFlag) {
this.hostFilterValue = this.hostFilter.value;
this.hostFilterReValue = this.hostFilterReBtn.checked()
};
if(this.logFacilitiesFlag) {
this.facilityFilterValue = this.logFacilitiesDropdown.getValue();
@@ -497,7 +517,8 @@ return baseclass.extend({
this.levelFilterValue = this.logLevelsDropdown.getValue();
};
this.msgFilterValue = this.msgFilter.value;
this.msgFilterReValue = this.msgFilterRe.checked;
this.msgFilterReValue = this.msgFilterReBtn.checked()
this.logSortingValue = this.logSorting.value;
this.autoRefreshValue = this.autoRefresh.checked;
if(this.autorefreshOn) {
@@ -517,11 +538,12 @@ return baseclass.extend({
if(this.enableConvertTimestamp) {
this.convertTimestamp.checked = this.convertTimestampValue;
};
this.timeFilter.value = this.timeFilterValue;
this.timeFilterRe.checked = this.timeFilterReValue;
this.timeFilter.value = this.timeFilterValue;
this.timeFilterReBtn.set(this.timeFilterReValue);
};
if(this.logHostsFlag) {
this.logHostsDropdown.setValue(this.hostFilterValue);
if(this.logHostFlag) {
this.hostFilter.value = this.hostFilterValue;
this.hostFilterReBtn.set(this.hostFilterReValue);
};
if(this.logFacilitiesFlag) {
this.logFacilitiesDropdown.setValue(this.facilityFilterValue);
@@ -529,8 +551,9 @@ return baseclass.extend({
if(this.logLevelsFlag) {
this.logLevelsDropdown.setValue(this.levelFilterValue);
};
this.msgFilter.value = this.msgFilterValue;
this.msgFilterRe.checked = this.msgFilterReValue;
this.msgFilter.value = this.msgFilterValue;
this.msgFilterReBtn.set(this.msgFilterReValue);
this.logSorting.value = this.logSortingValue;
this.autoRefresh.checked = this.autoRefreshValue;
},
@@ -586,35 +609,63 @@ return baseclass.extend({
},
setStringFilter(entriesArray, fieldNum, pattern) {
let fArr = [];
let not = pattern.startsWith('!');
pattern = pattern.replace(/^!/, '');
let isHFunc = (typeof(this.filterHighlightFunc) == 'function');
let fArr = [];
if(!pattern) {
return entriesArray;
};
entriesArray.forEach((e, i) => {
if(e[fieldNum] !== null && e[fieldNum].includes(pattern)) {
if(typeof(this.filterHighlightFunc) == 'function') {
e[fieldNum] = e[fieldNum].replace(pattern, this.filterHighlightFunc);
if(e[fieldNum] == null) {
return;
};
if(not) {
if(!(e[fieldNum].includes(pattern))) {
fArr.push(e);
};
} else {
if(e[fieldNum].includes(pattern)) {
if(isHFunc) {
e[fieldNum] = e[fieldNum].replace(pattern, this.filterHighlightFunc);
};
fArr.push(e);
};
fArr.push(e);
};
});
return fArr;
},
setRegexpFilter(entriesArray, fieldNum, pattern, formElem) {
let fArr = [];
setRegexpFilter(entriesArray, fieldNum, pattern) {
let not = pattern.startsWith('!');
pattern = pattern.replace(/^!/, '');
let isHFunc = (typeof(this.filterHighlightFunc) == 'function');
let fArr = [];
if(!pattern) {
return entriesArray;
};
try {
let regExp = new RegExp(pattern, 'giu');
entriesArray.forEach((e, i) => {
if(e[fieldNum] !== null && regExp.test(e[fieldNum])) {
if(this.filterHighlightFunc) {
e[fieldNum] = e[fieldNum].replace(regExp, this.filterHighlightFunc);
if(e[fieldNum] == null) {
return;
};
if(not) {
if(!(regExp.test(e[fieldNum]))) {
fArr.push(e);
};
} else {
if(regExp.test(e[fieldNum])) {
if(isHFunc) {
e[fieldNum] = e[fieldNum].replace(regExp, this.filterHighlightFunc);
};
fArr.push(e);
};
fArr.push(e);
};
regExp.lastIndex = 0;
});
} catch(err) {
if(err.name == 'SyntaxError') {
ui.addNotification(null,
E('p', {}, _('Invalid regular expression') + ': ' + err.message));
return entriesArray;
} else {
throw err;
@@ -629,20 +680,18 @@ return baseclass.extend({
return entriesArray;
};
return (this.timeFilterReValue) ?
this.setRegexpFilter(entriesArray, 1, fPattern, this.timeFilter) :
this.setRegexpFilter(entriesArray, 1, fPattern) :
this.setStringFilter(entriesArray, 1, fPattern);
},
setHostFilter(entriesArray) {
let logHostsKeys = Object.keys(this.logHosts);
if(logHostsKeys.length > 0 && this.logHostsDropdown) {
this.logHostsDropdown.addChoices(logHostsKeys, this.logHosts);
if(this.hostFilterValue.length == 0) {
return entriesArray;
};
return entriesArray.filter(e => this.hostFilterValue.includes(e[2]));
let fPattern = this.hostFilterValue;
if(!fPattern) {
return entriesArray;
};
return entriesArray;
return (this.hostFilterReValue) ?
this.setRegexpFilter(entriesArray, 2, fPattern) :
this.setStringFilter(entriesArray, 2, fPattern);
},
setFacilityFilter(entriesArray) {
@@ -673,7 +722,7 @@ return baseclass.extend({
return entriesArray;
};
return (this.msgFilterReValue) ?
this.setRegexpFilter(entriesArray, 5, fPattern, this.msgFilter) :
this.setRegexpFilter(entriesArray, 5, fPattern) :
this.setStringFilter(entriesArray, 5, fPattern);
},
@@ -803,19 +852,15 @@ return baseclass.extend({
if(this.logTimestampFlag && !this.logTimeFilterElem) {
this.logTimeFilterElem = this.makeLogTimeFilterSection();
};
if(this.logTimestampFlag && !this.logtimeFilterReElem) {
this.logtimeFilterReElem = this.makeLogtimeFilterReSection();
if(this.logHostFlag && !this.logHostFilterElem) {
this.logHostFilterElem = this.makeLogHostFilterSection();
};
if(this.logFacilitiesFlag && !this.logFacilitiesDropdown) {
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
};
if(this.logLevelsFlag && !this.logLevelsDropdown) {
this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection();
};
if(this.logHostsFlag && !this.logHostsDropdown) {
this.logHostsDropdownElem = this.makeLogHostsDropdownSection();
};
};
if(!autorefresh) {
@@ -845,21 +890,20 @@ return baseclass.extend({
E('span', { 'class': 'control-group' }, [
this.tailInput,
E('button', {
'class': 'cbi-button btn',
'click': L.bind(ev => {
'class': 'cbi-button-neutral btn',
'click': ev => {
ev.target.blur();
ev.preventDefault();
this.tailInput.value = 0;
this.tailInput.focus();
}, this),
},
}, '&#9003;'),
])
),
]),
this.logConvertTimestampElem,
this.logTimeFilterElem,
this.logtimeFilterReElem,
this.logHostsDropdownElem,
this.logHostFilterElem,
this.logFacilitiesDropdownElem,
this.logLevelsDropdownElem,
E('div', { 'class': 'cbi-value' }, [
@@ -867,33 +911,22 @@ return baseclass.extend({
'class': 'cbi-value-title',
'for' : 'msgFilter',
}, _('Message filter')),
E('div', { 'class': 'cbi-value-field' },
E('div', { 'class': 'cbi-value-field' }, [
E('span', { 'class': 'control-group' }, [
this.msgFilter,
E('button', {
'class': 'cbi-button btn',
'click': L.bind(ev => {
'class': 'cbi-button-neutral btn',
'click': ev => {
ev.target.blur();
ev.preventDefault();
this.msgFilter.value = null;
this.msgFilter.focus();
}, this),
},
}, '&#9003;'),
])
)
]),
E('div', { 'class': 'cbi-value' }, [
E('label', {
'class': 'cbi-value-title',
'for' : 'msgFilterRe',
}, _('Filter is regexp')),
E('div', { 'class': 'cbi-value-field' }, [
E('div', { 'class': 'cbi-checkbox' }, [
this.msgFilterRe,
E('label', {}),
this.msgFilterReBtn,
]),
E('div', { 'class': 'cbi-value-description' },
_('Apply message filter as regular expression')
_('<code>!pattern</code> - entries that do not match the pattern.')
),
]),
]),
@@ -1057,10 +1090,10 @@ return baseclass.extend({
ui.addValidator(this.tailInput, 'uinteger', true);
this.convertTimestamp = E('input', {
'id' : 'convertTimestamp',
'name' : 'convertTimestamp',
'type' : 'checkbox',
'form' : 'logFilterForm',
'id' : 'convertTimestamp',
'name': 'convertTimestamp',
'type': 'checkbox',
'form': 'logFilterForm',
});
this.convertTimestamp.checked = this.convertTimestampValue;
@@ -1073,27 +1106,30 @@ return baseclass.extend({
'placeholder': _('Type a search pattern...'),
});
this.timeFilterRe = E('input', {
'id' : 'timeFilterRe',
'name' : 'timeFilterRe',
'type' : 'checkbox',
'form' : 'logFilterForm',
'change': ev => this.timeFilter.focus(),
this.timeFilterReBtn = this.makeRegExpButton(this.timeFilter, this.timeFilterReValue);
this.setRegexpValidator(this.timeFilter, this.timeFilterReBtn);
this.hostFilter = E('input', {
'id' : 'hostFilter',
'name' : 'hostFilter',
'type' : 'text',
'form' : 'logFilterForm',
'class' : 'cbi-input-text',
'placeholder': _('Type a search pattern...'),
});
this.setRegexpValidator(this.timeFilter, this.timeFilterRe);
this.hostFilterReBtn = this.makeRegExpButton(this.hostFilter, this.hostFilterReValue);
this.setRegexpValidator(this.hostFilter, this.hostFilterReBtn);
this.logConvertTimestampElem = '';
this.logTimeFilterElem = '';
this.logtimeFilterReElem = '';
this.logHostsDropdownElem = '';
this.logHostFilterElem = '';
this.logFacilitiesDropdownElem = '';
this.logLevelsDropdownElem = '';
if(this.logTimestampFlag) {
this.logConvertTimestampElem = this.makeLogConvertTimestampSection();
this.logTimeFilterElem = this.makeLogTimeFilterSection();
this.logtimeFilterReElem = this.makeLogtimeFilterReSection();
};
if(this.logLevelsFlag) {
this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection();
@@ -1101,8 +1137,8 @@ return baseclass.extend({
if(this.logFacilitiesFlag) {
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
};
if(this.logHostsFlag) {
this.logHostsDropdownElem = this.makeLogHostsDropdownSection();
if(this.logHostFlag) {
this.logHostFilterElem = this.makeLogHostFilterSection();
};
this.msgFilter = E('input', {
@@ -1114,15 +1150,8 @@ return baseclass.extend({
'placeholder': _('Type a search pattern...'),
});
this.msgFilterRe = E('input', {
'id' : 'msgFilterRe',
'name' : 'msgFilterRe',
'type' : 'checkbox',
'form' : 'logFilterForm',
'change': ev => this.msgFilter.focus(),
});
this.setRegexpValidator(this.msgFilter, this.msgFilterRe);
this.msgFilterReBtn = this.makeRegExpButton(this.msgFilter, this.msgFilterReValue);
this.setRegexpValidator(this.msgFilter, this.msgFilterReBtn);
this.logSorting = E('select', {
'id' : 'logSorting',
@@ -54,9 +54,6 @@ return baseclass.extend({
// syslog-ng
syslog_ngHandler(strArray, lineNum) {
if(!(strArray[2] in this.logHosts)) {
this.logHosts[strArray[2]] = this.makeLogHostsDropdownItem(strArray[2]);
};
return [
lineNum, // # (Number)
strArray[1], // Timestamp (String)
@@ -130,8 +127,7 @@ return baseclass.extend({
this.logTimestampFlag = true;
this.logFacilitiesFlag = true;
this.logLevelsFlag = true;
this.logHostsFlag = false;
this.logHosts = {};
this.logHostFlag = false;
this.entriesHandler = this.logdHandler;
this.logCols = [
'#',
@@ -148,7 +144,7 @@ return baseclass.extend({
this.logTimestampFlag = true;
this.logFacilitiesFlag = false;
this.logLevelsFlag = false;
this.logHostsFlag = true;
this.logHostFlag = true;
this.logFacilities = {};
this.logLevels = {};
this.entriesHandler = this.syslog_ngHandler;
+12 -21
View File
@@ -13,18 +13,21 @@ msgstr ""
"Language: ru\n"
"X-Generator: Poedit 2.0.6\n"
msgid "<code>!pattern</code> - entries that do not match the pattern."
msgstr "<code>!шаблон</code> - записи не совпадающие с шаблоном."
msgid "2nd level domains that are excluded from optimization"
msgstr "Домены 2-го уровня не подлежащие оптимизации"
msgid "Add user entries to the blacklist when updating"
msgstr "Добавлять записи пользователя в блэклист при обновлении"
msgid "Alert"
msgstr "Тревога"
msgid "All"
msgstr "Все"
msgid "All entries"
msgstr "Все записи"
msgid "All entries except matching patterns"
msgstr "Все записи, кроме соответствующих шаблонам"
@@ -43,6 +46,9 @@ msgstr "Произошла ошибка при попытке получить
msgid "Apply"
msgstr "Применить"
msgid "Apply pattern as regular expression"
msgstr "Применять фильтр как регулярное выражение"
msgid "Apply proxy rules to router application traffic"
msgstr "Применять правила прокси к трафику приложений роутера"
@@ -95,9 +101,6 @@ msgstr "Содержимое сохранено."
msgid "Convert cyrillic domains to punycode"
msgstr "Конвертировать кириллические домены в punycode"
msgid "Critical"
msgstr "Критическая ситуация"
msgid "Current schedule"
msgstr "Текущее расписание"
@@ -110,9 +113,6 @@ msgstr "DNS сервер для FQDN записей списка исключе
msgid "Day"
msgstr "День"
msgid "Debug"
msgstr "Отладка"
msgid "Description"
msgstr "Описание"
@@ -143,9 +143,6 @@ msgstr "Изменить"
msgid "Edit entries"
msgstr "Изменить записи"
msgid "Emergency"
msgstr "Чрезвычайная ситуация"
msgid "Enable"
msgstr "Включить"
@@ -245,9 +242,6 @@ msgstr "Режим ограничения IP адресов"
msgid "IP subnet patterns (/24) that are excluded from optimization"
msgstr "Шаблоны IP подсетей (/24) не подлежащих оптимизации"
msgid "Info"
msgstr "Информация"
msgid "Instance"
msgstr "Экземпляр"
@@ -305,6 +299,9 @@ msgstr "Минута"
msgid "Module settings"
msgstr "Настройки модуля"
msgid "More entries"
msgstr "Больше записей"
msgid "Name"
msgstr "Имя"
@@ -323,9 +320,6 @@ msgstr "Нет данных"
msgid "No entries available..."
msgstr "Нет доступных записей..."
msgid "Notice"
msgstr "Сообщение"
msgid "Number of entries"
msgstr "Кол-во записей"
@@ -598,9 +592,6 @@ msgstr "Режим VPN"
msgid "VPN routing error! Need restart"
msgstr "Ошибка маршрутизации VPN! Необходим перезапуск"
msgid "Warning"
msgstr "Внимание"
msgid "all"
msgstr "все"
@@ -1,16 +1,19 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "<code>!pattern</code> - entries that do not match the pattern."
msgstr ""
msgid "2nd level domains that are excluded from optimization"
msgstr ""
msgid "Add user entries to the blacklist when updating"
msgstr ""
msgid "Alert"
msgid "All"
msgstr ""
msgid "All"
msgid "All entries"
msgstr ""
msgid "All entries except matching patterns"
@@ -28,6 +31,9 @@ msgstr ""
msgid "Apply"
msgstr ""
msgid "Apply pattern as regular expression"
msgstr ""
msgid "Apply proxy rules to router application traffic"
msgstr ""
@@ -80,9 +86,6 @@ msgstr ""
msgid "Convert cyrillic domains to punycode"
msgstr ""
msgid "Critical"
msgstr ""
msgid "Current schedule"
msgstr ""
@@ -95,9 +98,6 @@ msgstr ""
msgid "Day"
msgstr ""
msgid "Debug"
msgstr ""
msgid "Description"
msgstr ""
@@ -128,8 +128,6 @@ msgstr ""
msgid "Edit entries"
msgstr ""
msgid "Emergency"
msgstr ""
msgid "Enable"
msgstr ""
@@ -226,9 +224,6 @@ msgstr ""
msgid "IP subnet patterns (/24) that are excluded from optimization"
msgstr ""
msgid "Info"
msgstr ""
msgid "Instance"
msgstr ""
@@ -286,6 +281,9 @@ msgstr ""
msgid "Module settings"
msgstr ""
msgid "More entries"
msgstr ""
msgid "Name"
msgstr ""
@@ -304,9 +302,6 @@ msgstr ""
msgid "No entries available..."
msgstr ""
msgid "Notice"
msgstr ""
msgid "Number of entries"
msgstr ""
@@ -553,9 +548,6 @@ msgstr ""
msgid "VPN routing error! Need restart"
msgstr ""
msgid "Warning"
msgstr ""
msgid "all"
msgstr "все"
+2 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-lua
PKG_VERSION:=2.1.6
PKG_VERSION:=2.1.7
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
@@ -35,6 +35,7 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) ./files/usr/libexec/ruantiblock/ruab_parser.lua $(1)/usr/libexec/ruantiblock/ruab_parser.lua
$(INSTALL_DIR) $(1)/usr/lib/lua
$(INSTALL_DATA) ./files/usr/lib/lua/iptool.lua $(1)/usr/lib/lua/iptool.lua
$(INSTALL_DATA) ./files/usr/lib/lua/idn.lua $(1)/usr/lib/lua/idn.lua
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
@@ -0,0 +1,337 @@
--[[
GitHub: https://github.com/haste/lua-idn/
MIT License
Copyright (c) 2011 Trond A Ekseth <troeks@gmail.com>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
--]]
local bit = require'bit'
local base = 36
local tmin = 1
local tmax = 26
local skew = 38
local damp = 700
local initial_bias = 72
local initial_n = 0x80
local delimiter = 0x2D
-- Bias adaptation function
local adapt = function(delta, numpoints, firsttime)
if(firsttime) then
delta = math.floor(delta / damp)
else
delta = bit.rshift(delta, 1)
end
delta = delta + math.floor(delta / numpoints)
local k = 0
while(delta > math.floor(((base - tmin) * tmax) / 2)) do
delta = math.floor(delta / (base - tmin))
k = k + base
end
return math.floor(k + (base - tmin + 1) * delta / (delta + skew))
end
-- tests whether cp is a basic code point:
local basic = function(cp)
return cp < 0x80
end
local offset = {0, 0x3000, 0xE0000, 0x3C00000}
local utf8code = function(U, ...)
local numBytes = select('#', ...)
for i=1, numBytes do
local b = select(i, ...)
U = bit.lshift(U, 6) + bit.band(b, 63)
end
return U - offset[numBytes + 1]
end
local toUCS4 = function(str)
local out = {}
for c in str:gmatch'([%z\1-\127\194-\244][\128-\191]*)' do
table.insert(out, utf8code(string.byte(c, 1, -1)))
end
return out
end
local toUnicode = function(n)
if(n < 128) then
return string.char(n)
elseif(n < 2048) then
return string.char(192 + ((n - (n % 64)) / 64), 128 + (n % 64))
else
return string.char(224 + ((n - (n % 4096)) / 4096), 128 + (((n % 4096) - (n % 64)) / 64), 128 + (n % 64))
end
end
local punycode_encode
do
-- returns the basic code point whose value
-- (when used for representing integers) is d, which needs to be in
-- the range 0 to base-1.
local encode_digit = function(d)
return d + 22 + 75 * (d < 26 and 1 or 0)
-- 0..25 map to ASCII a..z
-- 26..35 map to ASCII 0..9
end
function punycode_encode(input)
if(type(input) == 'string') then
input = toUCS4(input)
end
local output = {}
-- Initialize the state
local n = initial_n
local delta = 0
local bias = initial_bias
-- Handle the basic code poinst
for j = 1, #input do
local c = input[j]
if(basic(c)) then
table.insert(output, string.char(c))
end
end
local h = #output
local b = h
-- h is the number of code points that have been handled, b is the
-- number of basic code points.
if(b > 0) then
table.insert(output, string.char(delimiter))
end
-- Main encoding loop
while(h < #input) do
-- All non-basic code points < n have been
-- handled already. Find the next larger one
local m = math.huge
for j = 1, #input do
local c = input[j]
if(c >= n and c < m) then
m = c
end
end
delta = delta + (m - n) * (h + 1)
n = m
for j = 1, #input do
local cp = input[j]
if(cp < n) then
delta = delta + 1
end
if(cp == n) then
local q = delta
local k = base
while(true) do
local t
if(k <= bias) then
t = tmin
else
if(k >= bias + tmax) then
t = tmax
else
t = k - bias
end
end
if(q < t) then break end
table.insert(output, string.char(encode_digit(t + (q - t) % (base - t))))
q = math.floor((q - t) / (base - t))
k = k + base
end
table.insert(output, string.char(encode_digit(q)))
bias = adapt(delta, h + 1, h == b)
delta = 0
h = h +1
end
end
delta = delta + 1
n = n + 1
end
return table.concat(output)
end
end
local punycode_decode
do
local decode_digit = function(d)
if(d - 48 < 10) then
return d - 22
elseif(d - 65 < 26) then
return d - 65
elseif(d - 97 < 26) then
return d - 97
else
return base
end
end
function punycode_decode(input)
if(type(input) == 'string') then
input = toUCS4(input)
end
local output = {}
-- Initialize the state
local n = initial_n
local i = 0
local out = 1
local bias = initial_bias
local b = 1
for j = 1, #input do
if(input[j] == delimiter) then
b = j
end
end
for j = 1, #input do
local c = input[j]
if(not basic(c)) then return nil, 'Invalid input' end
end
for j = 1, b - 1 do
local c = input[j]
output[out] = toUnicode(c)
out = out + 1
end
local index = 1
if(b > 1) then
index = b + 1
end
local inputLength = #input
while(index <= inputLength) do
local oldi = i
local w = 1
local k = base
while(true) do
if(index > inputLength) then return nil, 'Bad input' end
local digit = decode_digit(input[index])
if(digit >= base) then return nil, 'Bad input' end
index = index + 1
i = i + (digit * w)
local t
if(k <= bias) then
t = tmin
elseif(k >= bias + tmax) then
t = tmax
else
t = k - bias
end
if(digit < t) then
break
end
w = w * (base - t)
k = k + base
end
bias = adapt(i - oldi, out, oldi == 0)
n = n + math.floor(i / (out))
i = (i % out) + 1
table.insert(output, i, toUnicode(n))
out = out + 1
end
return table.concat(output)
end
end
local idn_encode
do
function idn_encode(domain)
local labels = {}
for label in domain:gmatch('([^.]+)%.?') do
-- Domain names can only consist of a-z, A-Z, 0-9, - and aren't allowed
-- to start or end with a hyphen
local first, last = label:sub(1, 1), label:sub(-1)
if(first == '-' or last == '-') then
return nil, 'Invalid DNS label'
end
if(label:match('^[a-zA-Z0-9-]+$')) then
table.insert(labels, label)
elseif(label:sub(1,1) ~= '-' and label:sub(2,2) ~= '-') then
local plabel = punycode_encode(label)
table.insert(labels, string.format('xn--%s', plabel))
end
end
return table.concat(labels, '.')
end
end
local idn_decode
do
function idn_decode(domain)
local labels = {}
for label in domain:gmatch('([^.]+)%.?') do
if(label:sub(1, 4) == 'xn--') then
table.insert(labels, punycode_decode(label:sub(5)))
elseif(label:match('^[a-zA-Z0-9-]+$')) then
table.insert(labels, label)
end
end
return table.concat(labels, '.')
end
end
return {
encode = idn_encode,
decode = idn_decode,
punycode = {
encode = punycode_encode,
decode = punycode_decode,
},
}
@@ -309,7 +309,7 @@ function BlackListParser:convert_encoding(input)
if self.ICONV_TYPE == "lua" and self.iconv_handler then
output = self.iconv_handler:iconv(input)
elseif self.ICONV_TYPE == "standalone" and self.ICONV_CMD then
local iconv_handler = assert(io.popen('printf \'' .. input .. '\' | ' .. self.ICONV_CMD .. ' -f "' .. self.site_encoding .. '" -t "' .. self.encoding .. '"', 'r'))
local iconv_handler = assert(io.popen('printf \'%s\' \'' .. input .. '\' | ' .. self.ICONV_CMD .. ' -f "' .. self.site_encoding .. '" -t "' .. self.encoding .. '"', 'r'))
output = iconv_handler:read("*a")
iconv_handler:close()
end
+1 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-py
PKG_VERSION:=2.1.6
PKG_VERSION:=2.1.7
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock
PKG_VERSION:=2.1.6
PKG_RELEASE:=3
PKG_VERSION:=2.1.7
PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
include $(INCLUDE_DIR)/package.mk
+1 -1
View File
@@ -27,7 +27,7 @@ config main 'config'
option bllist_sd_limit '16'
option bllist_fqdn_filter '1'
option bllist_fqdn_filter_type '0'
option bllist_enable_idn '0'
option bllist_enable_idn '1'
option bllist_alt_nslookup '0'
option bllist_alt_dns_addr '8.8.8.8'
@@ -140,7 +140,7 @@ BLLIST_FQDN_EXCLUDED_FILE="/etc/ruantiblock/fqdn_excluded"
### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл)
BLLIST_STRIP_WWW=1
### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл)
BLLIST_ENABLE_IDN=0
BLLIST_ENABLE_IDN=1
### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - выкл, 1 - вкл)
BLLIST_ALT_NSLOOKUP=0
### Альтернативный DNS-сервер