mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-10 21:46:53 +03:00
feat: Add diagnostics tab
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
'require form';
|
'require form';
|
||||||
'require ui';
|
'require ui';
|
||||||
'require network';
|
'require network';
|
||||||
|
'require fs';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
async render() {
|
async render() {
|
||||||
@@ -626,6 +627,151 @@ return view.extend({
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Добавьте новую вкладку Diagnostics (оставьте весь существующий код и добавьте это перед return m.render())
|
||||||
|
|
||||||
|
// Добавляем вкладку диагностики
|
||||||
|
o = s.tab('diagnostics', _('Diagnostics'));
|
||||||
|
|
||||||
|
// Функция форматирования вывода для модального окна
|
||||||
|
function formatDiagnosticOutput(output) {
|
||||||
|
if (!output) return '';
|
||||||
|
|
||||||
|
return output
|
||||||
|
.replace(/\x1B\[[0-9;]*[mK]/g, '')
|
||||||
|
.replace(/\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\] /g, '')
|
||||||
|
.replace(/\n{3,}/g, '\n\n')
|
||||||
|
.replace(/===\s+(.*?)\s+===/g, (_, title) => `\n${title}\n${'─'.repeat(title.length)}`)
|
||||||
|
.replace(/^Checking\s+(.+)\.{3}/gm, '► Checking $1...')
|
||||||
|
.replace(/:\s+(available|not found)$/gm, (_, status) =>
|
||||||
|
`: ${status === 'available' ? '✓' : '✗'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check All - полная диагностика
|
||||||
|
o = s.taboption('diagnostics', form.Button, '_check_all');
|
||||||
|
o.title = _('Main Check');
|
||||||
|
o.description = _('Run a comprehensive diagnostic check of all components');
|
||||||
|
o.inputtitle = _('Run Check');
|
||||||
|
o.inputstyle = 'apply';
|
||||||
|
o.onclick = function () {
|
||||||
|
return fs.exec('/etc/init.d/podkop', ['check_three'])
|
||||||
|
.then(function (res) {
|
||||||
|
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
||||||
|
|
||||||
|
const modalElement = ui.showModal(_('Full Diagnostic Results'), [
|
||||||
|
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 () {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = '```txt\n' + formattedOutput + '\n```';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
ui.addNotification(null, E('p', {}, _('Results copied to clipboard')));
|
||||||
|
} 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'))
|
||||||
|
])
|
||||||
|
], 'large');
|
||||||
|
|
||||||
|
if (modalElement && modalElement.parentElement) {
|
||||||
|
modalElement.parentElement.style.width = '90%';
|
||||||
|
modalElement.parentElement.style.maxWidth = '1200px';
|
||||||
|
modalElement.parentElement.style.margin = '2rem auto';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check Logs - проверка логов
|
||||||
|
o = s.taboption('diagnostics', form.Button, '_check_logs');
|
||||||
|
o.title = _('System Logs');
|
||||||
|
o.description = _('View recent system logs related to Podkop');
|
||||||
|
o.inputtitle = _('View Logs');
|
||||||
|
o.inputstyle = 'apply';
|
||||||
|
o.onclick = function () {
|
||||||
|
return fs.exec('/etc/init.d/podkop', ['check_logs'])
|
||||||
|
.then(function (res) {
|
||||||
|
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
||||||
|
|
||||||
|
const modalElement = ui.showModal(_('System Logs'), [
|
||||||
|
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 () {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = '```txt\n' + formattedOutput + '\n```';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
ui.addNotification(null, E('p', {}, _('Logs copied to clipboard')));
|
||||||
|
} 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'))
|
||||||
|
])
|
||||||
|
], 'large');
|
||||||
|
|
||||||
|
if (modalElement && modalElement.parentElement) {
|
||||||
|
modalElement.parentElement.style.width = '90%';
|
||||||
|
modalElement.parentElement.style.maxWidth = '1200px';
|
||||||
|
modalElement.parentElement.style.margin = '2rem auto';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return m.render();
|
return m.render();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -7,7 +7,7 @@ script=$(readlink "$initscript")
|
|||||||
NAME="$(basename ${script:-$initscript})"
|
NAME="$(basename ${script:-$initscript})"
|
||||||
config_load "$NAME"
|
config_load "$NAME"
|
||||||
|
|
||||||
EXTRA_COMMANDS="list_update add_route_interface check_proxy check_nft check_github check_logs check_all"
|
EXTRA_COMMANDS="list_update add_route_interface check_proxy check_nft check_github check_logs check_all check_three"
|
||||||
EXTRA_HELP=" list_update Updating domain and subnet lists
|
EXTRA_HELP=" list_update Updating domain and subnet lists
|
||||||
add_route_interface Adding route for interface
|
add_route_interface Adding route for interface
|
||||||
sing_box_config_vless For test vless string
|
sing_box_config_vless For test vless string
|
||||||
@@ -15,7 +15,8 @@ EXTRA_HELP=" list_update Updating domain and subnet lists
|
|||||||
check_nft Show PodkopTable nftables rules
|
check_nft Show PodkopTable nftables rules
|
||||||
check_github Check GitHub connectivity and lists availability
|
check_github Check GitHub connectivity and lists availability
|
||||||
check_logs Show podkop logs from system journal
|
check_logs Show podkop logs from system journal
|
||||||
check_all Run all checks"
|
check_all Run all checks
|
||||||
|
check_three Run check_proxy, check_nft and check_github"
|
||||||
|
|
||||||
[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop
|
[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop
|
||||||
|
|
||||||
@@ -1125,12 +1126,20 @@ check_proxy() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
nolog "Checking sing-box proxy connection..."
|
nolog "Checking sing-box proxy connection..."
|
||||||
if ! sing-box tools fetch ifconfig.me -D /etc/sing-box; then
|
|
||||||
nolog "Failed to check proxy connection"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
for attempt in `seq 1 5`; do
|
||||||
|
response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box)
|
||||||
|
if echo "$response" | grep -q "403 Forbidden"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
nolog "Proxy check completed successfully"
|
nolog "Proxy check completed successfully"
|
||||||
|
echo "$response"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
nolog "Failed to get a non-403 response after 5 attempts"
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
check_nft() {
|
check_nft() {
|
||||||
@@ -1204,12 +1213,7 @@ check_logs() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_all() {
|
check_three() {
|
||||||
nolog "Starting full diagnostic check..."
|
|
||||||
|
|
||||||
nolog "\n=== Checking recent logs ==="
|
|
||||||
check_logs
|
|
||||||
|
|
||||||
nolog "\n=== Checking GitHub connectivity ==="
|
nolog "\n=== Checking GitHub connectivity ==="
|
||||||
check_github
|
check_github
|
||||||
|
|
||||||
@@ -1222,6 +1226,15 @@ check_all() {
|
|||||||
nolog "\nFull diagnostic check completed"
|
nolog "\nFull diagnostic check completed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_all() {
|
||||||
|
nolog "Starting full diagnostic check..."
|
||||||
|
|
||||||
|
nolog "\n=== Checking recent logs ==="
|
||||||
|
check_logs
|
||||||
|
|
||||||
|
check_three
|
||||||
|
}
|
||||||
|
|
||||||
process_domains_text() {
|
process_domains_text() {
|
||||||
local text="$1"
|
local text="$1"
|
||||||
local name="$2"
|
local name="$2"
|
||||||
|
|||||||
Reference in New Issue
Block a user