PHP app layer: consolidate common functions, fix critical bugs, standardize patterns

Consolidations (config.php gains 5 shared utilities):
- vv_format_uptime() replaces 4 inline uptime-formatting blocks
- vv_parse_conf_scalar() replaces vv_arr_scalar/vv_wd_scalar/vv_fb_scalar/vv_media_conf_scalar
- vv_known_hosts() replaces vv_arr_known_hosts/vv_fb_known_hosts + inline parser in watchdog
- vv_parse_kv_db() replaces inline key=value parsing in snapshot and monitor
- vv_local_ip() replaces duplicate in docker_folders.php and inline in docker.php
All module-level function names kept as thin aliases so call sites unchanged.

Critical bug fixes:
- api/system.php: added require_once config.php and POST-only guard (no auth on shutdown)
- api/movescript.php + reorderarray.php: use vv_write_conf_raw (atomic) + vv_push_master_conf
- api/snapshot.php: share /tmp/vv_cpu_stat.json with vv_cpu_per_core() instead of own state file

Correctness:
- vv_cpu_per_core() and vv_network_stats(): atomic tmp+rename for state files (concurrent poll safety)
- ext_ip curl cache moved from /tmp/vv_ext_ip.cache to vv_cache_read/write (canonical cache dir)
- monitor_remote.php + board.php + snapshot.php: all use vv_cache_read/write instead of ad-hoc /tmp files

HTTP method guards added to write-only APIs that were missing them:
- api/scheduler.php, conf_toggle.php, flag_toggle.php
This commit is contained in:
Gmer4Lfe
2026-06-04 16:44:16 -04:00
parent 6aaf04e25b
commit ce0b3fb74b
16 changed files with 127 additions and 123 deletions
+15 -40
View File
@@ -3,61 +3,36 @@ header('Content-Type: application/json');
require_once dirname(__DIR__) . '/include/monitor.php';
require_once dirname(__DIR__) . '/include/media.php';
// CPU% — delta from own state file so it doesn't conflict with monitor.php
$cpuPct = 0;
$cpuLine = '';
foreach (file('/proc/stat') ?: [] as $line) {
if (strncmp($line, 'cpu ', 4) === 0) { $cpuLine = $line; break; }
}
if (preg_match('/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/', $cpuLine, $m)) {
$c = [(int)$m[1],(int)$m[2],(int)$m[3],(int)$m[4],(int)$m[5],(int)$m[6],(int)$m[7]];
$sf = '/tmp/vv_snap_cpu.json';
$p = file_exists($sf) ? (json_decode(file_get_contents($sf), true) ?: null) : null;
file_put_contents($sf, json_encode($c));
if ($p && is_array($p)) {
$dt = array_sum($c) - array_sum($p);
$di = ($c[3] + $c[4]) - ($p[3] + $p[4]);
$cpuPct = $dt > 0 ? max(0, min(100, (int)round((1 - $di / $dt) * 100))) : 0;
}
}
// CPU% — shares /tmp/vv_cpu_stat.json with vv_cpu_per_core() so both read the same baseline
$cpuPct = vv_cpu_per_core()['overall'] ?? 0;
// RAM%
$mem = [];
foreach (file('/proc/meminfo') ?: [] as $line) {
if (preg_match('/^(MemTotal|MemAvailable):\s+(\d+)/', $line, $m)) $mem[$m[1]] = (int)$m[2];
}
$ramTotalMb = (int)(($mem['MemTotal'] ?? 0) / 1024);
$ramUsedMb = (int)((($mem['MemTotal'] ?? 0) - ($mem['MemAvailable'] ?? 0)) / 1024);
$res = vv_system_resources();
$ramTotalMb = $res['ram_total_mb'];
$ramUsedMb = $ramTotalMb - $res['ram_free_mb'];
$ramPct = $ramTotalMb > 0 ? (int)round($ramUsedMb / $ramTotalMb * 100) : 0;
// Fallback state (fast file read, no exec)
$fallbackState = 'UNKNOWN';
foreach (@file('/tmp/fallback_state.db') ?: [] as $line) {
if (preg_match('/^state=(.+)/', trim($line), $m)) { $fallbackState = trim($m[1]); break; }
}
$fbRaw = @file_get_contents('/tmp/fallback_state.db') ?: '';
$fbData = vv_parse_kv_db($fbRaw);
$fallbackState = $fbData['state'] ?? 'UNKNOWN';
// Partner
$partner = vv_partner_state();
$peers = array_values(array_filter($partner['hosts'], fn($h) => !$h['is_me']));
// Media sessions — cached 30s so the HTTP calls don't hold up every snapshot poll
$streamCount = 0;
$transcodeCount = 0;
$mediaCacheFile = '/tmp/vv_snap_media.json';
$cacheMaxAge = 30;
$cacheValid = file_exists($mediaCacheFile) && (time() - filemtime($mediaCacheFile)) < $cacheMaxAge;
if ($cacheValid) {
$cached = json_decode(file_get_contents($mediaCacheFile), true) ?: [];
} else {
$media = vv_media_sessions();
$cached = [
$mediaCache = vv_cache_read('snap_media', 30);
if (!$mediaCache) {
$media = vv_media_sessions();
$mediaCache = [
'stream_count' => count($media['sessions']),
'transcode_count' => count(array_filter($media['sessions'], fn($s) => !empty($s['is_tc']))),
];
file_put_contents($mediaCacheFile, json_encode($cached));
vv_cache_write('snap_media', $mediaCache);
}
$streamCount = (int)($cached['stream_count'] ?? 0);
$transcodeCount = (int)($cached['transcode_count'] ?? 0);
$streamCount = (int)($mediaCache['stream_count'] ?? 0);
$transcodeCount = (int)($mediaCache['transcode_count'] ?? 0);
echo json_encode([
'cpu_pct' => $cpuPct,