From 3fb255694655c98b6edf79bb37ec067de65cf0f7 Mon Sep 17 00:00:00 2001 From: rubn Date: Sun, 15 Feb 2026 12:48:21 +0100 Subject: [PATCH] :construction: autorefresh --- gui/bastille_manager_gui.php | 143 ++++++++++++++++++++++++---- gui/css/bastille-header-refresh.css | 58 +++++++++++ 2 files changed, 183 insertions(+), 18 deletions(-) create mode 100644 gui/css/bastille-header-refresh.css diff --git a/gui/bastille_manager_gui.php b/gui/bastille_manager_gui.php index 7d1b0e4..bbdff46 100644 --- a/gui/bastille_manager_gui.php +++ b/gui/bastille_manager_gui.php @@ -39,6 +39,36 @@ require_once 'auth.inc'; require_once 'guiconfig.inc'; require_once 'bastille_manager-lib.inc'; +// --- START AUTO-REFRESH LOGIC --- +if (isset($_GET['action']) && $_GET['action'] === 'refresh_table') { + error_reporting(0); + ini_set('display_errors', 0); + ob_start(); + + // Force cache invalidation + $cache_file = '/tmp/bastille_jail_info_cache.json'; + if (file_exists($cache_file)) { + if (!@unlink($cache_file)) { + // Try system level delete if PHP fails (permissions) + mwexec("/bin/rm -f " . escapeshellarg($cache_file)); + } + } + + // Fetch fresh data + $jls_list = []; + if (function_exists('get_jail_infos')) { + $jls_list = get_jail_infos(); + } + + // Return JSON + ob_clean(); + header('Content-Type: application/json'); + header('Cache-Control: no-cache'); + echo json_encode(['success' => true, 'jails' => $jls_list ?: []]); + exit; +} +// --- END AUTO-REFRESH LOGIC --- + function mwexec_parallel($commands) { $processes = []; $results = []; @@ -53,7 +83,6 @@ function mwexec_parallel($commands) { $process = proc_open($command, $descriptors, $pipes); if (is_resource($process)) { - stream_set_blocking($pipes[1], false); stream_set_blocking($pipes[2], false); @@ -71,7 +100,6 @@ function mwexec_parallel($commands) { foreach ($processes as $key => $proc) { $elapsed = time() - $start_time; if ($elapsed < $timeout) { - $stdout = stream_get_contents($proc['pipes'][1]); $stderr = stream_get_contents($proc['pipes'][2]); @@ -102,8 +130,8 @@ function mwexec_parallel($commands) { } function mwexec_background($command) { - $command = $command . ' > /dev/null 2>&1 &'; - exec($command); + $command = $command . ' > /dev/null 2>&1 &'; + exec($command); } $sphere_scriptname = basename(__FILE__); @@ -184,19 +212,16 @@ if($_POST): if(isset($_POST['start_selected_jail']) && $_POST['start_selected_jail']): $checkbox_member_array = isset($_POST[$checkbox_member_name]) ? $_POST[$checkbox_member_name] : []; $commands = []; - $jail_names = []; foreach($checkbox_member_array as $checkbox_member_record): if(false !== ($index = array_search_ex($checkbox_member_record, $sphere_array, 'jailname'))): if(!isset($sphere_array[$index]['protected'])): $commands[] = "/usr/local/bin/bastille start {$checkbox_member_record}"; - $jail_names[] = $checkbox_member_record; endif; endif; endforeach; if (!empty($commands)): - $results = mwexec_parallel($commands); $success_count = 0; @@ -345,7 +370,7 @@ if($_POST): endif; endif; -$pgtitle = [gtext("Extensions"), gtext('Bastille')]; +$pgtitle = [gtext("Extensions"), gtext('Bastille'), gtext('Manager')]; include 'fbegin.inc'; ?> render(); - - + + +
+ Last update: just now + +
+ @@ -533,6 +638,7 @@ $document->render(); endif; endif; ?> + @@ -562,8 +668,9 @@ $document->render();
<?=$gt_record_conf?>
\ No newline at end of file diff --git a/gui/css/bastille-header-refresh.css b/gui/css/bastille-header-refresh.css new file mode 100644 index 0000000..91a947f --- /dev/null +++ b/gui/css/bastille-header-refresh.css @@ -0,0 +1,58 @@ +/* bastille_manager.css + Estilo NATIVO (Minimalista) +*/ + +#refresh-controls { + /* Fondo transparente y sin bordes para integrarse con el tema */ + background: transparent; + border: none; + padding: 10px 0; + margin-bottom: 5px; + + /* Alineación a la derecha */ + display: flex; + justify-content: flex-end; + align-items: center; + gap: 15px; + + /* Fuente estándar del sistema */ + font-size: 13px; + color: inherit; +} + +#refresh-status { + /* Color de texto por defecto del tema (negro/gris) */ + color: inherit; + margin-right: 5px; + + /* Coloca el texto a la izquierda de los botones */ + order: -1; +} + +/* Pequeño spinner azul discreto solo cuando actualiza */ +#refresh-status.updating .refresh-spinner { + display: inline-block; + width: 10px; + height: 10px; + border: 2px solid #ccc; + border-top-color: #007bff; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 5px; +} + +/* Animación del spinner */ +@keyframes spin { + to { transform: rotate(360deg); } +} + +/* Asegurar que los iconos de la tabla estén centrados verticalmente */ +.area_data_selection tbody td img { + vertical-align: middle; +} + +/* Centrado perfecto para los checkboxes */ +.lcelc { + text-align: center; + vertical-align: middle; +} \ No newline at end of file