Compare commits
5 Commits
b673f416a6
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 028c16be3d | |||
| a7658c33b1 | |||
| fbb0ac86d5 | |||
| aa3564284f | |||
| 2c17960a9d |
@@ -9,7 +9,7 @@ function get_fmt(): string {
|
||||
header('Location: ?format=text');
|
||||
header('Content-Length: 14');
|
||||
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('Content-Type: text/html; charset=UTF-8');
|
||||
header('Content-Length: 162');
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
<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"/>
|
||||
<meta property="og:site_name" content="Elwig"/>
|
||||
<meta property="og:title" content="Elwig - Elektronische Winzergenossenschaftsverwaltung"/>
|
||||
<meta property="og:site_name" content="Elwig - Elektronische Winzergenossenschaftsverwaltung"/>
|
||||
<meta property="og:title" content="Über - Elwig"/>
|
||||
<meta property="og:description" content="Elwig ist eine spezialisierte, praxisnah entwickelte Softwarelösung zur Unterstützung von Winzergenossenschaften bei ihren zentralen organisatorischen und administrativen Aufgaben entlang der tatsächlichen Abläufe im genossenschaftlichen Weinbau – von der Traubenübernahme bis zur jährlichen Abrechnung."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:url" content="https://elwig.at/"/>
|
||||
@@ -32,9 +32,9 @@
|
||||
<a href="https://elwig.at/de/"><img src="/res/elwig.png" alt="Elwig Logo"/></a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="#">Start</a></li>
|
||||
<li><a href="#about">Über</a></li>
|
||||
<li><a href="#clients">Genossenschaften</a></li>
|
||||
<li><a href="/de/vorschau">Vorschau</a></li>
|
||||
<li><a href="/files/">Downloads</a></li>
|
||||
<li><a href="https://git.necronda.net/winzer/">Quellcode</a></li>
|
||||
</ul>
|
||||
@@ -93,7 +93,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Die Bedeutung dieser Unterstützung zeigt sich auch in den betreuten Mengen:
|
||||
Die vier mit Elwig arbeitende Genossen­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­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 % der in Österreich verarbeiteten Menge Wein.
|
||||
Diese Größen­ordnungen verdeutlichen die Anforderungen an ein zuverlässiges, skalierbares und praxisnahes System.
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Vorschau - Elwig - Elektronische Winzergenossenschaftsverwaltung</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/style.css?v=2025-01-12"/>
|
||||
<link rel="alternate" href="/en/preview" hreflang="en"/>
|
||||
<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"/>
|
||||
<meta property="og:site_name" content="Elwig - Elektronische Winzergenossenschaftsverwaltung"/>
|
||||
<meta property="og:title" content="Vorschau - Elwig"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:url" content="https://elwig.at/preview"/>
|
||||
<meta property="og:image" content="https://elwig.at/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-1.png"/>
|
||||
<meta property="og:image:type" content="image/png"/>
|
||||
<meta property="og:image:width" content="1136"/>
|
||||
<meta property="og:image:height" content="713"/>
|
||||
<meta property="og:locale" content="de"/>
|
||||
<meta property="og:ttl" content="60"/>
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<script src="/res/preview.js"></script>
|
||||
</head>
|
||||
<body class="header-footer" style="background-color: var(--bg-color);">
|
||||
<header>
|
||||
<nav class="index">
|
||||
<div>
|
||||
<a href="https://elwig.at/de/"><img src="/res/elwig.png" alt="Elwig Logo"/></a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="/de/#about">Über</a></li>
|
||||
<li><a href="/de/#clients">Genossenschaften</a></li>
|
||||
<li><a href="/de/vorschau">Vorschau</a></li>
|
||||
<li><a href="/files/">Downloads</a></li>
|
||||
<li><a href="https://git.necronda.net/winzer/">Quellcode</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="/en/preview" class="flag">
|
||||
<div></div>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="preview">
|
||||
|
||||
<div class="window members" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder.png" class="selected" alt="Mitglieder-Fenster, ohne ausgewähltes Mitglied"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Musterbauer.png" alt="Mitglieder-Fenster, MUSTERBAUER Matthäus ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Mustermann.png" alt="Mitglieder-Fenster, MUSTERMANN Max ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Weinbauer.png" alt="Mitglieder-Fenster, WEINBAUER Wernhardt ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Weinland-Weine.png" alt="Mitglieder-Fenster, Weinland Weine AG ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Winzer.png" alt="Mitglieder-Fenster, WINZER Waltraud ausgewählt"/>
|
||||
<canvas width="1236" height="693"></canvas>
|
||||
</div>
|
||||
|
||||
<p style="text-align: center;">Die Fenster können teilweise interaktiv erkundet werden.</p>
|
||||
|
||||
<div class="window deliveries" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen.png" class="selected" alt="Lieferungen-Fenster, ohne ausgewählte Lieferung"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-002-1.png" alt="Lieferungen-Fenster, Lieferung 20250930X002, Teillieferung 1 ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-002-2.png" alt="Lieferungen-Fenster, Lieferung 20250930X002, Teillieferung 2 ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-1.png" alt="Lieferungen-Fenster, Lieferung 20250930X001, Teillieferung 1 ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-2.png" alt="Lieferungen-Fenster, Lieferung 20250930X001, Teillieferung 2 ausgewählt"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-3.png" alt="Lieferungen-Fenster, Lieferung 20250930X001, Teillieferung 3 ausgewählt"/>
|
||||
<canvas width="1136" height="713"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="window receipt" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Übernahme.png" class="selected" alt="Übernahme-Fenster"/>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<h4>Dokumente – Mitglieder</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Mitgliederliste.pdf">Mitgliederliste</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_MUSTERBAUER_Matthäus.pdf">Stammdatenblatt MUSTERBAUER Matthäus</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_MUSTERMANN_Max.pdf">Stammdatenblatt MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_WEINBAUER_Wernhardt.pdf">Stammdatenblatt WEINBAUER Wernhardt</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_Weinland_Weine_AG.pdf">Stammdatenblatt Weinland Weine AG</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_WINZER_Waltraud.pdf">Stammdatenblatt WINZER Waltraud</a></li>
|
||||
</ul>
|
||||
<h4>Dokumente – Lieferungen</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/Lieferjournal_2025.pdf">Lieferjournal 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/20250930X001.pdf">Lieferschein 20250930X001</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/20250930X002.pdf">Lieferschein 20250930X002</a></li>
|
||||
</ul>
|
||||
<h4>Dokumente – Auszahlung</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Anlieferungsbestätigung_2025_Mustermann.pdf">Anlieferungsbestätigung 2025 – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Anlieferungsbestätigung_2025_Weinbauer.pdf">Anlieferungsbestätigung 2025 – WEINBAUER Wernhart</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Auszahlungsvariante_2025_-_1_Teilzahlung.pdf">Variantendaten 1. Teilzahlung 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-001_1_Teilzahlung.pdf">Traubengutschrift Nr. 2025/001 – 1. Teilzahlung – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-002_1_Teilzahlung.pdf">Traubengutschrift Nr. 2025/002 – 1. Teilzahlung – WEINBAUER Wernhart</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Auszahlungsvariante_2025_-_Endauszahlung.pdf">Variantendaten Endauszahlung 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-003_Endauszahlung.pdf">Traubengutschrift Nr. 2025/003 – Endauszahlung – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-004_Endauszahlung.pdf">Traubengutschrift Nr. 2025/004 – Endauszahlung – WEINBAUER Wernhart</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<a href="https://elwig.at/"><img src="/res/elwig.png" alt="Elwig"/></a>
|
||||
<p>
|
||||
<strong>Impressum</strong><br/>
|
||||
Lorenz Stechauner, Thomas Hilscher<br/>
|
||||
Österreich (Austria)<br/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Kontakt</strong><br/>
|
||||
E-Mail: <a href="mailto:contact%40necronda%2enet">contact<!--(at)-->@necronda<!--.net-->.net</a><br/>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -12,8 +12,8 @@
|
||||
<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"/>
|
||||
<meta property="og:site_name" content="Elwig"/>
|
||||
<meta property="og:title" content="Elwig - Electronic Management for Vintners' Cooperatives"/>
|
||||
<meta property="og:site_name" content="Elwig - Electronic Management for Vintners' Cooperatives"/>
|
||||
<meta property="og:title" content="About - Elwig"/>
|
||||
<meta property="og:description" content="Elwig is a specialized, practice-oriented software solution designed to support vintners' cooperatives in their core organizational and administrative tasks, aligned with real-world cooperative wine production workflows – from grape intake to annual settlement."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:url" content="https://elwig.at/"/>
|
||||
@@ -32,9 +32,9 @@
|
||||
<a href="https://elwig.at/en/"><img src="/res/elwig.png" alt="Elwig Logo"/></a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="#">Start</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#clients">Cooperatives</a></li>
|
||||
<li><a href="/en/preview">Preview</a></li>
|
||||
<li><a href="/files/">Downloads</a></li>
|
||||
<li><a href="https://git.necronda.net/winzer/">Source Code</a></li>
|
||||
</ul>
|
||||
@@ -145,7 +145,7 @@
|
||||
<div>
|
||||
<h4>WG Baden</h4>
|
||||
<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>
|
||||
<p class="link">
|
||||
<a href="http://www.wg-baden.at/">wg-baden.at</a>
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Preview - Elwig - Electronic Management for Vintners' Cooperatives</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/style.css?v=2025-01-12"/>
|
||||
<link rel="alternate" href="/de/vorschau" hreflang="de"/>
|
||||
<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"/>
|
||||
<meta property="og:site_name" content="Elwig - Electronic Management for Vintners' Cooperatives"/>
|
||||
<meta property="og:title" content="Preview - Elwig"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:url" content="https://elwig.at/preview"/>
|
||||
<meta property="og:image" content="https://elwig.at/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-1.png"/>
|
||||
<meta property="og:image:type" content="image/png"/>
|
||||
<meta property="og:image:width" content="1136"/>
|
||||
<meta property="og:image:height" content="713"/>
|
||||
<meta property="og:locale" content="en"/>
|
||||
<meta property="og:ttl" content="60"/>
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<script src="/res/preview.js"></script>
|
||||
</head>
|
||||
<body class="header-footer" style="background-color: var(--bg-color);">
|
||||
<header>
|
||||
<nav class="index">
|
||||
<div>
|
||||
<a href="https://elwig.at/en/"><img src="/res/elwig.png" alt="Elwig Logo"/></a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="/en/#about">About</a></li>
|
||||
<li><a href="/en/#clients">Cooperatives</a></li>
|
||||
<li><a href="/en/preview">Preview</a></li>
|
||||
<li><a href="/files/">Downloads</a></li>
|
||||
<li><a href="https://git.necronda.net/winzer/">Source Code</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="/de/vorschau" class="flag">
|
||||
<div></div>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="preview">
|
||||
|
||||
<div class="window members" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder.png" class="selected" alt="Member window, with no member selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Musterbauer.png" alt="Member window, with MUSTERBAUER Matthäus selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Mustermann.png" alt="Member window, with MUSTERMANN Max selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Weinbauer.png" alt="Member window, with WEINBAUER Wernhardt selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Weinland-Weine.png" alt="Member window, with Weinland Weine AG selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Mitglieder/Mitglieder-Winzer.png" alt="Member window, with WINZER Waltraud selected"/>
|
||||
<canvas width="1236" height="693"></canvas>
|
||||
</div>
|
||||
|
||||
<p style="text-align: center;">The windows may be explored interactively.</p>
|
||||
|
||||
<div class="window deliveries" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen.png" class="selected" alt="Delivery window, with no delivery selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-002-1.png" alt="Delivery window, with delivery 20250930X002, delivery part 1, selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-002-2.png" alt="Delivery window, with delivery 20250930X002, delivery part 2, selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-1.png" alt="Delivery window, with delivery 20250930X001, delivery part 1, selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-2.png" alt="Delivery window, with delivery 20250930X001, delivery part 2, selected"/>
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Lieferungen-001-3.png" alt="Delivery window, with delivery 20250930X001, delivery part 3, selected"/>
|
||||
<canvas width="1136" height="713"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="window receipt" tabindex="0">
|
||||
<img src="/res/preview/v1.0.5.2/Lieferungen/Übernahme.png" class="selected" alt="Receipt window"/>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<h4>Documents – Members</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Mitgliederliste.pdf">Member List</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_MUSTERBAUER_Matthäus.pdf">Member Data Sheet MUSTERBAUER Matthäus</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_MUSTERMANN_Max.pdf">Member Data Sheet MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_WEINBAUER_Wernhardt.pdf">Member Data Sheet WEINBAUER Wernhardt</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_Weinland_Weine_AG.pdf">Member Data Sheet Weinland Weine AG</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Mitglieder/Stammdatenblatt_WINZER_Waltraud.pdf">Member Data Sheet WINZER Waltraud</a></li>
|
||||
</ul>
|
||||
<h4>Documents – Deliveries</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/Lieferjournal_2025.pdf">Delivery Journall 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/20250930X001.pdf">Delivery Note 20250930X001</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Lieferungen/20250930X002.pdf">Delivery Note 20250930X002</a></li>
|
||||
</ul>
|
||||
<h4>Documents – Annual settlement</h4>
|
||||
<ul>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Anlieferungsbestätigung_2025_Mustermann.pdf">Delivery Confirmation 2025 – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Anlieferungsbestätigung_2025_Weinbauer.pdf">Delivery Confirmation 2025 – WEINBAUER Wernhart</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Auszahlungsvariante_2025_-_1_Teilzahlung.pdf">Payment Variant Data 1. Teilzahlung 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-001_1_Teilzahlung.pdf">Credit Note No. 2025/001 – 1. Teilzahlung – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-002_1_Teilzahlung.pdf">Credit Note No. 2025/002 – 1. Teilzahlung – WEINBAUER Wernhart</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Auszahlungsvariante_2025_-_Endauszahlung.pdf">Payment Variant Data Endauszahlung 2025</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-003_Endauszahlung.pdf">Credit Note No. 2025/003 – Endauszahlung – MUSTERMANN Max</a></li>
|
||||
<li><a href="/res/preview/v1.0.5.2/Auszahlung/Traubengutschrift_Nr_2025-004_Endauszahlung.pdf">Credit Note No. 2025/004 – Endauszahlung – WEINBAUER Wernhart</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<a href="https://elwig.at/"><img src="/res/elwig.png" alt="Elwig"/></a>
|
||||
<p>
|
||||
<strong>Imprint</strong><br/>
|
||||
Lorenz Stechauner, Thomas Hilscher<br/>
|
||||
Austria<br/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Contact</strong><br/>
|
||||
E-Mail: <a href="mailto:contact%40necronda%2enet">contact<!--(at)-->@necronda<!--.net-->.net</a><br/>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -56,7 +56,12 @@ global $getVers;
|
||||
$getProd = null;
|
||||
$getVers = null;
|
||||
$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];
|
||||
if (sizeof($info) > 2) $getVers = $info[2];
|
||||
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>
|
||||
<tbody>
|
||||
<?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>
|
||||
</table>
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
<?php
|
||||
$lang = 'de'; // prefer german
|
||||
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $pref) {
|
||||
$l = substr($pref, 0, 2);
|
||||
if ($l === 'de') {
|
||||
$lang = 'de';
|
||||
break; // force german
|
||||
} else if ($l === 'en') {
|
||||
$lang = 'en'; // use english only, if user specifically asks for it
|
||||
}
|
||||
}
|
||||
}
|
||||
header("Content-Length: 0");
|
||||
switch ($_SERVER['PATH_INFO']) {
|
||||
case '':
|
||||
case '/':
|
||||
$lang = 'de'; // prefer german
|
||||
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $pref) {
|
||||
$l = substr($pref, 0, 2);
|
||||
if ($l === 'de') {
|
||||
$lang = 'de';
|
||||
break; // force german
|
||||
} else if ($l === 'en') {
|
||||
$lang = 'en'; // use english only, if user specifically asks for it
|
||||
}
|
||||
}
|
||||
}
|
||||
header("Status: 303");
|
||||
header("Location: /$lang/");
|
||||
break;
|
||||
case '/preview':
|
||||
case '/vorschau':
|
||||
header("Status: 303");
|
||||
header("Location: /$lang/" . ($lang === 'de' ? 'vorschau' : 'preview'));
|
||||
break;
|
||||
case '/changelog':
|
||||
header("Status: 303");
|
||||
header("Location: https://git.necronda.net/winzer/elwig/src/branch/main/CHANGELOG.md#changelog");
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
|
||||
function getMembersRow(x, y, w=1236) {
|
||||
const r = 1236 / w;
|
||||
x *= r;
|
||||
y *= r;
|
||||
if (x <= 12 || x > 346) return -1;
|
||||
const row = Math.floor((y - 113) / 20.5);
|
||||
return (row >= 0 && row < 5) ? row : -1;
|
||||
}
|
||||
|
||||
function getDeliveriesRow(x, y, w=1136) {
|
||||
const r = 1136 / w;
|
||||
x *= r;
|
||||
y *= r;
|
||||
if (x <= 12 || x > 395) return -1;
|
||||
const row = Math.floor((y - 120) / 20.5);
|
||||
return (row >= 0 && row < 2) ? row : -1;
|
||||
}
|
||||
|
||||
function getDeliveryPartsRow(x, y, w=1136) {
|
||||
const r = 1136 / w;
|
||||
x *= r;
|
||||
y *= r;
|
||||
if (x <= 424 || x > 753) return [-1, -1];
|
||||
const win = document.getElementsByClassName("window")[1];
|
||||
const idx = Array.prototype.indexOf.call(win.children, win.getElementsByClassName("selected")[0]);
|
||||
const len = {1: 2, 2: 2, 3: 3, 4: 3, 5: 3}[idx] ?? 0;
|
||||
const row = Math.floor((y - 319) / 20);
|
||||
return [{0: 0, 1: 1, 2: 1, 3: 2, 4: 2, 5: 2}[idx], len === 0 ? -1 : (row >= 0 && row < len) ? row : -1];
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const windows = document.getElementsByClassName("window");
|
||||
|
||||
const w1 = windows[0];
|
||||
const canvas1 = w1.getElementsByTagName("canvas")[0];
|
||||
const ctx1 = canvas1.getContext("2d");
|
||||
w1.addEventListener("mousemove", (evt) => {
|
||||
ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
|
||||
const row = getMembersRow(evt.offsetX, evt.offsetY, evt.target.clientWidth);
|
||||
if (row === -1) return;
|
||||
ctx1.fillStyle = "#0078d740";
|
||||
ctx1.fillRect(12, 113 + 20.5 * row, 334, 20.5);
|
||||
});
|
||||
w1.addEventListener("click", (evt) => {
|
||||
const row = getMembersRow(evt.offsetX, evt.offsetY, evt.target.clientWidth);
|
||||
for (const img of w1.getElementsByTagName("img")) img.classList.remove("selected");
|
||||
w1.getElementsByTagName("img")[row + 1].classList.add("selected");
|
||||
});
|
||||
|
||||
const w2 = windows[1];
|
||||
const canvas2 = w2.getElementsByTagName("canvas")[0];
|
||||
const ctx2 = canvas2.getContext("2d");
|
||||
w2.addEventListener("mousemove", (evt) => {
|
||||
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
|
||||
const row = getDeliveriesRow(evt.offsetX, evt.offsetY, evt.target.clientWidth);
|
||||
const partRow = getDeliveryPartsRow(evt.offsetX, evt.offsetY, evt.target.clientWidth)[1];
|
||||
if (row !== -1) {
|
||||
ctx2.fillStyle = "#0078d740";
|
||||
ctx2.fillRect(12, 120 + 20.5 * row, 383, 20.5);
|
||||
} else if (partRow !== -1) {
|
||||
ctx2.fillStyle = "#0078d740";
|
||||
ctx2.fillRect(424, 319 + 20 * partRow, 329, 20);
|
||||
}
|
||||
});
|
||||
w2.addEventListener("click", (evt) => {
|
||||
const row = getDeliveriesRow(evt.offsetX, evt.offsetY, evt.target.clientWidth);
|
||||
const partRow = getDeliveryPartsRow(evt.offsetX, evt.offsetY, evt.target.clientWidth);
|
||||
if (row !== -1 || partRow[1] !== -1) {
|
||||
const idx = row !== -1 ? row * 2 + 1 : (partRow[0] - 1) * 2 + partRow[1] + 1;
|
||||
for (const img of w2.getElementsByTagName("img")) img.classList.remove("selected");
|
||||
w2.getElementsByTagName("img")[idx].classList.add("selected");
|
||||
} else {
|
||||
for (const img of w2.getElementsByTagName("img")) img.classList.remove("selected");
|
||||
w2.getElementsByTagName("img")[0].classList.add("selected");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (evt) => {
|
||||
const act = document.activeElement;
|
||||
if (!act.classList.contains("window")) return;
|
||||
let el = null;
|
||||
if (evt.key === "ArrowUp" || evt.key === "ArrowLeft") {
|
||||
el = act.getElementsByClassName("selected")[0].previousElementSibling;
|
||||
evt.stopImmediatePropagation();
|
||||
evt.preventDefault();
|
||||
} else if (evt.key === "ArrowDown" || evt.key === "ArrowRight") {
|
||||
el = act.getElementsByClassName("selected")[0].nextElementSibling;
|
||||
evt.stopImmediatePropagation();
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (el && el.tagName === "IMG") {
|
||||
for (const img of act.getElementsByTagName("img")) img.classList.remove("selected");
|
||||
el.classList.add("selected");
|
||||
}
|
||||
});
|
||||
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,125 @@
|
||||
|
||||
: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;
|
||||
}
|
||||
|
||||
.device:not(.inactive) .versions .deprecated {
|
||||
color: #C00000;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
.device:not(.inactive) .versions .deprecated {
|
||||
color: #E00000;
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ nav li a {
|
||||
}
|
||||
|
||||
nav li a:hover,
|
||||
nav li.active a{
|
||||
nav li.active a {
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
@@ -92,15 +92,15 @@ nav a.flag div {
|
||||
margin: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
nav a.flag[href='/de/'] div::before,
|
||||
nav a.flag[href='/en/']:hover div::before,
|
||||
nav a.flag[href='/en/']:focus div::before {
|
||||
nav a.flag[href^='/de/'] div::before,
|
||||
nav a.flag[href^='/en/']:hover div::before,
|
||||
nav a.flag[href^='/en/']:focus div::before {
|
||||
content: '\1F1EC\1F1E7'; /* GB */
|
||||
}
|
||||
|
||||
nav a.flag[href='/en/'] div::before,
|
||||
nav a.flag[href='/de/']:hover div::before,
|
||||
nav a.flag[href='/de/']:focus div::before {
|
||||
nav a.flag[href^='/en/'] div::before,
|
||||
nav a.flag[href^='/de/']:hover div::before,
|
||||
nav a.flag[href^='/de/']:focus div::before {
|
||||
content: '\1F1E6\1F1F9'; /* AT */
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ table .unit {
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
@media screen and (max-width: 700px) {
|
||||
nav.index li:first-child {
|
||||
display: none;
|
||||
}
|
||||
@@ -425,7 +425,7 @@ table .unit {
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px) {
|
||||
@media screen and (max-width: 600px) {
|
||||
nav.index li:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
@@ -435,7 +435,7 @@ table .unit {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
nav.index li:nth-child(3) {
|
||||
nav.index li:nth-child(4) {
|
||||
display: none;
|
||||
}
|
||||
.home {
|
||||
@@ -448,3 +448,120 @@ table .unit {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
/**** Preview ****/
|
||||
|
||||
main.preview {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 4em 0;
|
||||
gap: 4em;
|
||||
}
|
||||
|
||||
main.preview section {
|
||||
background-color: #FFFFFF;
|
||||
padding: 2em 4em;
|
||||
border-radius: 0.5em;
|
||||
box-shadow: 0 0 2em #00000060;
|
||||
border: 1px solid #C0C0C0;
|
||||
}
|
||||
|
||||
main.preview section h4:not(:first-child) {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
main.preview a {
|
||||
color: var(--main-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
main.preview a:hover,
|
||||
main.preview a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
main.preview section {
|
||||
padding: 2em 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.window {
|
||||
position: relative;
|
||||
box-shadow: 0 0 2em #00000060;
|
||||
display: flex;
|
||||
font-size: 1rem;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.window img {
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 2480px) {
|
||||
.window:nth-of-type(1) {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.window:nth-of-type(1) * {
|
||||
width: 2472px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1240px) {
|
||||
.window:nth-of-type(1) {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
.window:nth-of-type(1) * {
|
||||
width: 618px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 620px) {
|
||||
.window:nth-of-type(1) {
|
||||
font-size: 0.25rem;
|
||||
}
|
||||
.window:nth-of-type(1) * {
|
||||
width: 309px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 2280px) {
|
||||
.window:nth-of-type(2), .window:nth-of-type(3) {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.window:nth-of-type(2) *, .window:nth-of-type(3) * {
|
||||
width: 2272px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1140px) {
|
||||
.window:nth-of-type(2), .window:nth-of-type(3) {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
.window:nth-of-type(2) *, .window:nth-of-type(3) * {
|
||||
width: 568px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 570px) {
|
||||
.window:nth-of-type(2), .window:nth-of-type(3) {
|
||||
font-size: 0.25rem;
|
||||
}
|
||||
.window:nth-of-type(2) *, .window:nth-of-type(3) * {
|
||||
width: 284px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.window canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.window img:not(.selected) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,3 +1,4 @@
|
||||
# robots.txt for elwig.at
|
||||
User-Agent: *
|
||||
Sitemap: https://elwig.at/sitemap.xml
|
||||
Disallow: /res/preview/
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://elwig.at/de/vorschau</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://elwig.at/en/preview</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://elwig.at/files/</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<?php
|
||||
require "../.php/format.inc";
|
||||
require "../.php/auth.inc";
|
||||
include "../.php/devices.inc";
|
||||
require ".php/format.inc";
|
||||
require ".php/auth.inc";
|
||||
include ".php/devices.inc";
|
||||
|
||||
authenticate(['stat']);
|
||||
|
||||
$fileNames = array_filter(scandir('files/'), function($e) { return str_starts_with($e, 'Elwig-'); });
|
||||
usort($fileNames, 'version_compare');
|
||||
$latestVersion = sizeof($fileNames) > 0 ? substr(substr($fileNames[sizeof($fileNames) - 1], 6), 0, -4) : null;
|
||||
|
||||
$osVersions = [
|
||||
'Microsoft Windows NT 10.0.10240.0' => 'Windows 10 (1507)',
|
||||
'Microsoft Windows NT 10.0.10586.0' => 'Windows 10 (1511)',
|
||||
@@ -27,6 +31,11 @@ $osVersions = [
|
||||
'Microsoft Windows NT 10.0.26200.0' => 'Windows 11 (25H2)',
|
||||
];
|
||||
|
||||
$latestOsVersions = [];
|
||||
foreach ($osVersions as $id => $name) {
|
||||
$latestOsVersions[substr($name, 0, 10)] = $name;
|
||||
}
|
||||
|
||||
$DEVICES ??= [];
|
||||
|
||||
if ($_SERVER['PATH_INFO'] === '/log') {
|
||||
@@ -35,13 +44,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";
|
||||
if ($_SERVER['QUERY_STRING'] === 'full') {
|
||||
passthru(<<<EOF
|
||||
cat .log.csv \
|
||||
cat files/.log.csv \
|
||||
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
|
||||
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
|
||||
EOF);
|
||||
} else {
|
||||
passthru(<<<EOF
|
||||
cat .log.csv | grep -E '\|json\|$|\|Elwig/' | grep -v "PICARD|ENTERPRISE|GEORGIOU" \
|
||||
cat files/.log.csv | grep -E '\|json\|$|\|Elwig/' | grep -v "WGX|PICARD|ENTERPRISE|GEORGIOU|78A16E85-410A-4" \
|
||||
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
|
||||
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
|
||||
EOF);
|
||||
@@ -51,12 +60,12 @@ EOF);
|
||||
} else if ($_SERVER['PATH_INFO'] === '') {
|
||||
$format = get_fmt();
|
||||
$stat = [];
|
||||
if (($file = fopen('.log.csv', 'r'))) {
|
||||
if (($file = fopen('files/.log.csv', 'r'))) {
|
||||
while (($line = fgets($file)) !== false) {
|
||||
$line = explode('|', $line);
|
||||
if (sizeof($line) < 6) 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], "WGX") || 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]);
|
||||
$version = substr(explode(' ', $line[5], 2)[0], 6);
|
||||
$comment = preg_match("/\((.*?), *(.*?), *(.*?), *(.*?)\)/", $line[5], $m);
|
||||
@@ -154,7 +163,7 @@ EOF);
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if ($format === 'table') {
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
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";
|
||||
@@ -208,7 +217,59 @@ EOF);
|
||||
echo "</table>\n";
|
||||
echo "<p><a href='stat/log'>Log</a> <a href='stat/log?full'>Full Log</a></p>\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'>";
|
||||
$elwigVers = $latestVersion === null ? '' : ($d[0] === $latestVersion ? 'latest' : 'deprecated');
|
||||
echo "<span class='elwig $elwigVers'><img src='/favicon.ico' width='16' height='16'/> $d[0]</span>";
|
||||
if (isset($osVersions[$d[2]])) {
|
||||
$v = $osVersions[$d[2]];
|
||||
$l = $latestOsVersions[substr($v, 0, 10)] ?? null;
|
||||
$osVers = $l === null ? '' : ($l === $v ? 'latest' : 'deprecated');
|
||||
echo "<span class='os $osVers'>" . str_replace('Windows', "<img src='/res/windows.png' width='16' height='16'/> ", $v) . "</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 {
|
||||
header('Status: 404');
|
||||
header('Content-Length: 0');
|
||||