Spaces:
Build error
Build error
Create api/stats.php
Browse files- api/stats.php +79 -0
api/stats.php
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
header('Content-Type: application/json');
|
| 3 |
+
header('Access-Control-Allow-Origin: *');
|
| 4 |
+
header('Access-Control-Allow-Methods: GET, OPTIONS');
|
| 5 |
+
header('Access-Control-Allow-Headers: Content-Type');
|
| 6 |
+
|
| 7 |
+
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
| 8 |
+
http_response_code(204);
|
| 9 |
+
exit;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
|
| 13 |
+
http_response_code(405);
|
| 14 |
+
echo json_encode(['error' => 'Method not allowed']);
|
| 15 |
+
exit;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// Connect to SQLite
|
| 19 |
+
$db = new PDO('sqlite:/data/db/platform.sqlite');
|
| 20 |
+
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 21 |
+
|
| 22 |
+
// Total users
|
| 23 |
+
$totalUsers = $db->query('SELECT COUNT(*) FROM users')->fetchColumn();
|
| 24 |
+
|
| 25 |
+
// Disk usage of /data
|
| 26 |
+
$totalBytes = diskTotalSpace('/data');
|
| 27 |
+
$freeBytes = diskFreeSpace('/data');
|
| 28 |
+
$usedBytes = $totalBytes - $freeBytes;
|
| 29 |
+
|
| 30 |
+
// Per-user disk usage
|
| 31 |
+
$users = $db->query('SELECT username FROM users ORDER BY username')->fetchAll(PDO::FETCH_COLUMN);
|
| 32 |
+
$userStats = [];
|
| 33 |
+
|
| 34 |
+
foreach ($users as $username) {
|
| 35 |
+
$htdocs = "/data/sites/{$username}/htdocs";
|
| 36 |
+
$size = is_dir($htdocs) ? directorySize($htdocs) : 0;
|
| 37 |
+
$userStats[] = [
|
| 38 |
+
'username' => $username,
|
| 39 |
+
'size_bytes' => $size,
|
| 40 |
+
'size_human' => humanSize($size)
|
| 41 |
+
];
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
echo json_encode([
|
| 45 |
+
'success' => true,
|
| 46 |
+
'total_users' => (int)$totalUsers,
|
| 47 |
+
'disk' => [
|
| 48 |
+
'total_bytes' => $totalBytes,
|
| 49 |
+
'used_bytes' => $usedBytes,
|
| 50 |
+
'free_bytes' => $freeBytes,
|
| 51 |
+
'total_human' => humanSize($totalBytes),
|
| 52 |
+
'used_human' => humanSize($usedBytes),
|
| 53 |
+
'free_human' => humanSize($freeBytes),
|
| 54 |
+
'used_percent'=> $totalBytes > 0 ? round(($usedBytes / $totalBytes) * 100, 2) : 0
|
| 55 |
+
],
|
| 56 |
+
'users' => $userStats
|
| 57 |
+
]);
|
| 58 |
+
|
| 59 |
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
| 60 |
+
function directorySize(string $dir): int {
|
| 61 |
+
$size = 0;
|
| 62 |
+
$items = new RecursiveIteratorIterator(
|
| 63 |
+
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
|
| 64 |
+
);
|
| 65 |
+
foreach ($items as $item) {
|
| 66 |
+
$size += $item->getSize();
|
| 67 |
+
}
|
| 68 |
+
return $size;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
function humanSize(int $bytes): string {
|
| 72 |
+
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
| 73 |
+
$i = 0;
|
| 74 |
+
while ($bytes >= 1024 && $i < count($units) - 1) {
|
| 75 |
+
$bytes /= 1024;
|
| 76 |
+
$i++;
|
| 77 |
+
}
|
| 78 |
+
return round($bytes, 2) . ' ' . $units[$i];
|
| 79 |
+
}
|