feat: add version information tab to diagnostics

This commit is contained in:
Ivan K
2025-02-18 13:59:04 +03:00
parent 66b179f282
commit cd43449585
4 changed files with 166 additions and 25 deletions

View File

@@ -153,7 +153,7 @@ return view.extend({
if (removedServices.length > 0) {
newValues = newValues.filter(v => allowedWithRussiaInside.includes(v));
const warningMsg = _('Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s have been removed from selection.').format(
const warningMsg = _('Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s already in Russia inside and have been removed from selection.').format(
removedServices.join(', ')
);
@@ -469,7 +469,6 @@ return view.extend({
o.ucisection = 'main';
// Additional Settings Tab
o = s.tab('additional', _('Additional Settings'));
o = s.taboption('additional', form.Flag, 'yacd', _('Yacd enable'), _('http://openwrt.lan:9090/ui'));
@@ -497,6 +496,7 @@ return view.extend({
o.rmempty = false;
o.ucisection = 'main';
// Diagnostics tab
o = s.tab('diagnostics', _('Diagnostics'));
function formatDiagnosticOutput(output) {
@@ -512,6 +512,76 @@ return view.extend({
`: ${status === 'available' ? '✓' : '✗'}`);
}
// Version Information Section
o = s.taboption('diagnostics', form.Button, '_show_versions');
o.title = _('Version Information');
o.description = _('Show version information for all components');
o.inputtitle = _('Show Versions');
o.inputstyle = 'apply';
o.onclick = function () {
Promise.all([
fs.exec('/etc/init.d/podkop', ['show_version']),
fs.exec('/etc/init.d/podkop', ['show_luci_version']),
fs.exec('/etc/init.d/podkop', ['show_sing_box_version']),
fs.exec('/etc/init.d/podkop', ['show_system_info'])
]).then(function ([podkop, luci, singbox, system]) {
const versions = [
'=== Podkop Version ===\n' + (podkop.stdout || _('No output')) + '\n',
'=== LuCI App ===\n' + (luci.stdout || _('No output')) + '\n',
'=== sing-box ===\n' + (singbox.stdout || _('No output')) + '\n',
system.stdout || _('No output')
].join('\n');
const formattedOutput = formatDiagnosticOutput(versions);
ui.showModal(_('Version Information'), [
E('div', {
style:
'max-height: 70vh;' +
'overflow-y: auto;' +
'margin: 1em 0;' +
'padding: 1.5em;' +
'background: #f8f9fa;' +
'border: 1px solid #e9ecef;' +
'border-radius: 4px;' +
'font-family: monospace;' +
'white-space: pre-wrap;' +
'word-wrap: break-word;' +
'line-height: 1.5;' +
'font-size: 14px;'
}, [
E('pre', { style: 'margin: 0;' }, formattedOutput)
]),
E('div', {
style: 'display: flex; justify-content: space-between; margin-top: 1em;'
}, [
E('button', {
'class': 'btn',
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = '```txt\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Close'))
])
]);
});
};
// Connection Checks Section
o = s.taboption('diagnostics', form.Button, '_check_nft');
o.title = _('NFT Rules');
@@ -545,13 +615,17 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```txt\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
@@ -567,8 +641,6 @@ return view.extend({
});
};
// Logs Section
o = s.taboption('diagnostics', form.Button, '_check_sing_box_logs');
o.title = _('Sing-Box Logs');
@@ -602,15 +674,19 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```logs\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
ui.addNotification(null, E('p', {}, _('Failed to copy logs: ') + err.message));
}
document.body.removeChild(textarea);
}
@@ -656,15 +732,19 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```logs\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
ui.addNotification(null, E('p', {}, _('Failed to copy logs: ') + err.message));
}
document.body.removeChild(textarea);
}
@@ -711,13 +791,17 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```txt\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
@@ -765,13 +849,17 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```txt\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
@@ -819,13 +907,17 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = '```json\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
@@ -873,13 +965,17 @@ return view.extend({
}, [
E('button', {
'class': 'btn',
'click': function () {
'click': function (ev) {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
textarea.value = '```json\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ev.target.textContent = _('Copied!');
setTimeout(() => {
ev.target.textContent = _('Copy to Clipboard');
}, 1000);
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}

View File

@@ -468,8 +468,8 @@ msgid "Warning: %s cannot be used together with %s. Previous selections have bee
msgstr "Предупреждение: %s нельзя использовать вместе с %s. Предыдущие варианты были удалены."
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
msgid "Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s have been removed from selection."
msgstr "Внимание: Russia inside может использоваться только с Meta, Twitter, Discord и Telegram. %s были удалены из выбора."
msgid "Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s already in Russia inside and have been removed from selection."
msgstr "Внимание: Russia inside может использоваться только с Meta, Twitter, Discord и Telegram. %s уже в Russia inside и были удалены из выбора."
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
msgid "Regional options cannot be used together"
@@ -477,4 +477,16 @@ msgstr "Нельзя использовать несколько региона
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
msgid "Russia inside restrictions"
msgstr "Ограничения Russia inside"
msgstr "Ограничения Russia inside"
msgid "Version Information"
msgstr "Информация о версиях"
msgid "Show version information for all components"
msgstr "Показать информацию о версиях всех компонентов"
msgid "Show Versions"
msgstr "Показать версии"
msgid "Copied!"
msgstr "Скопировано!"

View File

@@ -468,7 +468,7 @@ msgid "Warning: %s cannot be used together with %s. Previous selections have bee
msgstr ""
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
msgid "Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s have been removed from selection."
msgid "Warning: Russia inside can only be used with Meta, Twitter, Discord, and Telegram. %s already in Russia inside and have been removed from selection."
msgstr ""
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
@@ -477,4 +477,16 @@ msgstr ""
#: applications/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js:XXX
msgid "Russia inside restrictions"
msgstr ""
msgid "Version Information"
msgstr ""
msgid "Show version information for all components"
msgstr ""
msgid "Show Versions"
msgstr ""
msgid "Copied!"
msgstr ""

View File

@@ -7,7 +7,7 @@ script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})"
config_load "$NAME"
EXTRA_COMMANDS="main list_update check_proxy check_nft check_github check_logs check_sing_box_connections check_sing_box_logs check_dnsmasq show_config show_version show_sing_box_config"
EXTRA_COMMANDS="main list_update check_proxy check_nft check_github check_logs check_sing_box_connections check_sing_box_logs check_dnsmasq show_config show_version show_sing_box_config show_luci_version show_sing_box_version show_system_info"
EXTRA_HELP=" list_update Updating domain and subnet lists
check_proxy Check if sing-box proxy works correctly
check_nft Show PodkopTable nftables rules
@@ -18,7 +18,10 @@ EXTRA_HELP=" list_update Updating domain and subnet lists
check_dnsmasq Show current DNSMasq configuration
show_config Show current configuration with masked sensitive data
show_version Show current version
show_sing_box_config Show current sing-box configuration"
show_sing_box_config Show current sing-box configuration
show_luci_version Show LuCI app version
show_sing_box_version Show sing-box version
show_system_info Show OpenWrt version and device model"
[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop
@@ -1608,4 +1611,22 @@ show_config() {
show_version() {
local version=$(opkg info podkop | grep -m 1 "Version:" | cut -d' ' -f2)
echo "$version"
}
show_luci_version() {
local version=$(opkg info luci-app-podkop | grep -m 1 "Version:" | cut -d' ' -f2)
echo "$version"
}
show_sing_box_version() {
local version=$(opkg info sing-box | grep -m 1 "Version:" | cut -d' ' -f2)
echo "$version"
}
show_system_info() {
echo "=== OpenWrt Version ==="
grep OPENWRT_RELEASE /etc/os-release | cut -d'"' -f2
echo
echo "=== Device Model ==="
cat /tmp/sysinfo/model
}