Compare commits

...

2 Commits

Author SHA1 Message Date
lorenz.stechauner aa3564284f index: Fix small issues 2026-04-21 22:53:29 +02:00
lorenz.stechauner 2c17960a9d stat: move from /files/stat to /stat 2026-04-21 22:53:12 +02:00
7 changed files with 183 additions and 13 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ function get_fmt(): string {
header('Location: ?format=text'); header('Location: ?format=text');
header('Content-Length: 14'); header('Content-Length: 14');
exit("303 See Other\n"); exit("303 See Other\n");
} else if ($fmt !== 'json' && $fmt !== 'html' && $fmt !== 'text') { } else if ($fmt !== 'json' && $fmt !== 'html' && $fmt !== 'text' && $fmt !== 'table') {
header('Status: 300'); header('Status: 300');
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
header('Content-Length: 162'); header('Content-Length: 162');
+1 -1
View File
@@ -93,7 +93,7 @@
</p> </p>
<p> <p>
Die Bedeutung dieser Unterstützung zeigt sich auch in den betreuten Mengen: Die Bedeutung dieser Unterstützung zeigt sich auch in den betreuten Mengen:
Die vier mit Elwig arbeitende Genossen&shy;schaften haben in den letzten Jahren gemeinsam rund 10 Millionen kg Trauben im Jahr 2023, etwa 8 Millionen kg im Jahr 2024 und rund 11 Millionen kg im Jahr 2025 verarbeitet. Die vier mit Elwig arbeitenden Genossen&shy;schaften haben in den letzten Jahren gemeinsam rund 10 Millionen kg Trauben im Jahr 2023, etwa 8 Millionen kg im Jahr 2024 und rund 11 Millionen kg im Jahr 2025 verarbeitet.
Das sind ca. 3,5&nbsp;% der in Österreich verarbeiteten Menge Wein. Das sind ca. 3,5&nbsp;% der in Österreich verarbeiteten Menge Wein.
Diese Größen&shy;ordnungen verdeutlichen die Anforderungen an ein zuverlässiges, skalierbares und praxisnahes System. Diese Größen&shy;ordnungen verdeutlichen die Anforderungen an ein zuverlässiges, skalierbares und praxisnahes System.
</p> </p>
+1 -1
View File
@@ -145,7 +145,7 @@
<div> <div>
<h4>WG Baden</h4> <h4>WG Baden</h4>
<h5><span>Winzergenossenschaft</span> <span>Baden - Bad Vöslau</span><br/><span>reg. Gen.m.b.H.</span></h5> <h5><span>Winzergenossenschaft</span> <span>Baden - Bad Vöslau</span><br/><span>reg. Gen.m.b.H.</span></h5>
<h6>Zweigstellen:</h6> <h6>Branches:</h6>
<div class="branches">Baden</div> <div class="branches">Baden</div>
<p class="link"> <p class="link">
<a href="http://www.wg-baden.at/">wg-baden.at</a> <a href="http://www.wg-baden.at/">wg-baden.at</a>
+7 -2
View File
@@ -56,7 +56,12 @@ global $getVers;
$getProd = null; $getProd = null;
$getVers = null; $getVers = null;
$info = explode('/', $_SERVER['PATH_INFO']); $info = explode('/', $_SERVER['PATH_INFO']);
if (sizeof($info) > 1 && ($info[1] === 'elwig' || $info[1] === 'winziprint')) { if (sizeof($info) > 0 && $info[1] === 'stat') {
header('Status: 303');
header('Content-Length: 0');
header('Location: /stat');
exit();
} else if (sizeof($info) > 1 && ($info[1] === 'elwig' || $info[1] === 'winziprint')) {
$getProd = $info[1]; $getProd = $info[1];
if (sizeof($info) > 2) $getVers = $info[2]; if (sizeof($info) > 2) $getVers = $info[2];
if (sizeof($info) > 3) { if (sizeof($info) > 3) {
@@ -180,7 +185,7 @@ if ($format === 'json') {
<thead><tr><th class="center">Name</th><th class="center">Größe</th><th class="center">Änderungsdatum</th></tr></thead> <thead><tr><th class="center">Name</th><th class="center">Größe</th><th class="center">Änderungsdatum</th></tr></thead>
<tbody> <tbody>
<?php foreach (array_reverse($entities) as $name => [$prod, $vers, $url, $size, $mtime, $ctime, $mod, $cre]) { <?php foreach (array_reverse($entities) as $name => [$prod, $vers, $url, $size, $mtime, $ctime, $mod, $cre]) {
echo " <tr><td><a href=\"/files/$name\">$name</a></td><td>" . number_format($size / 1024 / 1024, 1) . " MB</td><td>" . date('d.m.Y, H:i', $mtime) . "</td></tr>\n"; echo " <tr><td><a href=\"/files/$name\">$name</a></td><td style='text-align: right;'>" . number_format($size / 1024 / 1024, 1) . " MB</td><td>" . date('d.m.Y, H:i', $mtime) . "</td></tr>\n";
} ?> } ?>
</tbody> </tbody>
</table> </table>
+118
View File
@@ -0,0 +1,118 @@
:root {
font-family: 'Arial', sans-serif;
}
.client {
background-color: #F8F8F8;
border: 1px solid #C0C0C0;
border-radius: 4px;
padding: 0.5em;
margin: 2em 0;
}
.client > div {
display: flex;
justify-content: center;
gap: 2em;
flex-wrap: wrap;
margin-top: 1.5em;
}
.client > span {
font-size: 0.75em;
color: #808080;
position: absolute;
}
.device {
background-color: #F0F0F0;
border: 1px solid #C0C0C0;
border-radius: 4px;
padding: 1em 1.5em;
flex: 0 1 260px;
}
.device.online {
background-color: #E0FFE0;
border-color: #80C080;
}
.device.inactive {
background-color: #E0E0E0;
border-color: #B0B0B0;
color: #808080 !important;
}
.device .name {
text-align: center;
font-size: 1.5em;
font-weight: bold;
}
.device.online .name {
color: #008000;
}
.device .id {
text-align: center;
font-size: 0.75em;
color: #808080;
}
.device .date {
text-align: center;
font-size: 1em;
font-weight: bold;
margin-top: 1em;
}
.device.online .date {
color: #008000;
}
.device .address {
text-align: center;
font-size: 0.75em;
color: #808080;
}
.device .versions {
display: flex;
justify-content: space-between;
}
img {
width: 1em;
height: 1em;
transform: translateY(0.125em);
}
@media (prefers-color-scheme: dark) {
body {
background-color: #000000;
color: #F0F0F0;
}
.client {
background-color: #080808;
border-color: #202020;
}
.device {
background-color: #101010;
border-color: #202020;
}
.device.online {
background-color: #002000;
border-color: #004000;
}
.device.inactive {
background-color: #181818;
border-color: #303030;
}
.device.online .name {
color: #00A000;
}
.device.online .date {
color: #00A000;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

+55 -8
View File
@@ -1,7 +1,7 @@
<?php <?php
require "../.php/format.inc"; require ".php/format.inc";
require "../.php/auth.inc"; require ".php/auth.inc";
include "../.php/devices.inc"; include ".php/devices.inc";
authenticate(['stat']); authenticate(['stat']);
@@ -35,13 +35,13 @@ if ($_SERVER['PATH_INFO'] === '/log') {
echo "<tr><th>Timestamp</th><th>IP Address</th><th>Method</th><th>URI</th><th>Format</th><th>User Agent</th></tr>\n"; echo "<tr><th>Timestamp</th><th>IP Address</th><th>Method</th><th>URI</th><th>Format</th><th>User Agent</th></tr>\n";
if ($_SERVER['QUERY_STRING'] === 'full') { if ($_SERVER['QUERY_STRING'] === 'full') {
passthru(<<<EOF passthru(<<<EOF
cat .log.csv \ cat files/.log.csv \
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \ | awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g' | sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
EOF); EOF);
} else { } else {
passthru(<<<EOF passthru(<<<EOF
cat .log.csv | grep -E '\|json\|$|\|Elwig/' | grep -v "PICARD|ENTERPRISE|GEORGIOU" \ cat files/.log.csv | grep -E '\|json\|$|\|Elwig/' | grep -v "PICARD|ENTERPRISE|GEORGIOU|78A16E85-410A-4" \
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \ | awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g' | sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
EOF); EOF);
@@ -51,12 +51,12 @@ EOF);
} else if ($_SERVER['PATH_INFO'] === '') { } else if ($_SERVER['PATH_INFO'] === '') {
$format = get_fmt(); $format = get_fmt();
$stat = []; $stat = [];
if (($file = fopen('.log.csv', 'r'))) { if (($file = fopen('files/.log.csv', 'r'))) {
while (($line = fgets($file)) !== false) { while (($line = fgets($file)) !== false) {
$line = explode('|', $line); $line = explode('|', $line);
if (sizeof($line) < 6) continue; if (sizeof($line) < 6) continue;
if (!str_starts_with($line[5], 'Elwig/')) continue; if (!str_starts_with($line[5], 'Elwig/')) continue;
if (str_contains($line[5], "PICARD") || str_contains($line[5], "ENTERPRISE") || str_contains($line[5], "GEORGIOU")) continue; if (str_contains($line[5], "PICARD") || str_contains($line[5], "ENTERPRISE") || str_contains($line[5], "GEORGIOU") || str_contains($line[5], "78A16E85-410A-4")) continue;
$timestamp = intval($line[0]); $timestamp = intval($line[0]);
$version = substr(explode(' ', $line[5], 2)[0], 6); $version = substr(explode(' ', $line[5], 2)[0], 6);
$comment = preg_match("/\((.*?), *(.*?), *(.*?), *(.*?)\)/", $line[5], $m); $comment = preg_match("/\((.*?), *(.*?), *(.*?), *(.*?)\)/", $line[5], $m);
@@ -154,7 +154,7 @@ EOF);
echo "\n"; echo "\n";
} }
} }
} else { } else if ($format === 'table') {
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
echo "<!DOCTYPE html>\n<html lang='en'>\n"; echo "<!DOCTYPE html>\n<html lang='en'>\n";
echo "<head><title>Activity Statistics - Elwig</title><style>table{border-collapse:collapse;}th,td{border:1px solid black;padding:0.25em 0.5em;}</style></head>\n"; echo "<head><title>Activity Statistics - Elwig</title><style>table{border-collapse:collapse;}th,td{border:1px solid black;padding:0.25em 0.5em;}</style></head>\n";
@@ -208,7 +208,54 @@ EOF);
echo "</table>\n"; echo "</table>\n";
echo "<p><a href='stat/log'>Log</a> <a href='stat/log?full'>Full Log</a></p>\n"; echo "<p><a href='stat/log'>Log</a> <a href='stat/log?full'>Full Log</a></p>\n";
echo "</body>\n</html>\n"; echo "</body>\n</html>\n";
} else {
header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8"/>
<title>Statistiken - Elwig</title>
<link rel="icon" href="/favicon.ico" sizes="16x16 20x20 24x24 30x30 32x32 36x36 40x40 48x48 60x60 64x64 72x72 80x80 96x96 128x128 256x256"/>
<link rel="stylesheet" href="/res/stat.css"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<meta name="theme-color" content="#A040C0"/>
<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
</head>
<body>
<?php
foreach ($stat as $token => $devices) {
echo "<div class='client'><span>$token</span><div>\n";
foreach ($devices as $device => $data) {
$timestamp = array_key_last($data);
$addr = array_reverse(array_unique(array_map(function ($d) {
return $d[3];
}, array_values($data))));
$d = $data[$timestamp];
$name = $DEVICES[$token][$device] ?? $device;
$active = $timestamp + 36 * 60 * 60 > time() ? 'online' : ($timestamp + 28 * 24 * 60 * 60 > time() ? 'offline' : 'inactive');
echo "<div class='device $active'>";
echo "<div class='versions'><span><img src='/favicon.ico' width='16' height='16'/> $d[0]</span>";
if (isset($osVersions[$d[2]])) {
echo "<span class='os'>" . str_replace('Windows', "<img src='/res/windows.png' width='16' height='16'/> ", $osVersions[$d[2]]) . "</span>";
} else {
echo "<span class='os'>$d[2]</span>";
} }
echo "</div>";
echo "<div class='date'>" . date('d.m.Y', $timestamp) . "</div>";
echo "<div class='name'>$name</div>";
echo "<div class='id'>$device</div>";
echo "<div class='address'>" . implode("<br>", array_slice($addr, 0, 1)) . "</div>";
echo "</div>\n";
}
echo "</div></div>\n";
}
}
echo "</body>\n</html>\n";
} else { } else {
header('Status: 404'); header('Status: 404');
header('Content-Length: 0'); header('Content-Length: 0');