diff options
author | stuebinm | 2022-12-05 16:37:27 +0100 |
---|---|---|
committer | stuebinm | 2022-12-05 16:37:27 +0100 |
commit | 8a10ea437cf74619865e0966f8be8f16e6cba938 (patch) | |
tree | 3f6d07986d3eb2963114739ccfab6ad0756fa443 /chaski | |
parent | 64546ed6399d49ff125ee667b9632825eb3ccba5 (diff) |
update to nixos22.11
Diffstat (limited to 'chaski')
-rw-r--r-- | chaski/configuration.nix | 6 | ||||
-rw-r--r-- | chaski/ilztal.live/geolocation/index.html | 179 | ||||
-rw-r--r-- | chaski/ilztal.live/geolocation/mapview.html | 94 | ||||
-rw-r--r-- | chaski/ilztal.live/geolocation/view.html | 77 | ||||
-rw-r--r-- | chaski/services/geolocation.nix | 6 | ||||
-rw-r--r-- | chaski/services/tracktrain.nix | 16 | ||||
-rw-r--r-- | chaski/services/woitb/index.html | 124 | ||||
-rw-r--r-- | chaski/services/woitb/info.html | 180 |
8 files changed, 10 insertions, 672 deletions
diff --git a/chaski/configuration.nix b/chaski/configuration.nix index e8095c0..3618572 100644 --- a/chaski/configuration.nix +++ b/chaski/configuration.nix @@ -8,16 +8,12 @@ imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix - # ./services/uplcg.nix - ./services/geolocation.nix + ./services/uplcg.nix ./services/tracktrain.nix ]; networking.firewall.allowedTCPPorts = [ 80 443 ]; - services.nginx.package = - (pkgs.nginxStable.override { openssl = pkgs.openssl_1_1; }); - services.nginx.enable = true; services.nginx.appendHttpConfig = '' access_log off; diff --git a/chaski/ilztal.live/geolocation/index.html b/chaski/ilztal.live/geolocation/index.html deleted file mode 100644 index 052a9fa..0000000 --- a/chaski/ilztal.live/geolocation/index.html +++ /dev/null @@ -1,179 +0,0 @@ -<!doctype html> -<html class="no-js" lang=""> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="ie=edge"> - <title>geolocation tracker test</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="apple-touch-icon" href="/apple-touch-icon.png"> - <!-- Place favicon.ico in the root directory --> - - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade"> - You are using an <strong>outdated</strong> browser. Please - <a href="http://browsehappy.com/">upgrade your browser</a> to improve - your experience. - </p> - <![endif]--> - - <button id = "initialise">Start Tracking</button><br/> - <p id = "status"></p> - <a id = "map-link" target="_blank"></a> - - <p> - Latitude: <span id="latitude"></span><br> - Longitude: <span id="longitude"></span><br> - Altitude: <span id="altitude"></span><br> - Accuracy: <span id="accuracy"></span><br> - Speed: <span id="speed"></span><br> - Angle: <span id="angle"></span><br> - </p> - - <input id="note" placeholder="enter note here"> - <button id="submit-note">Submit</button> - - <p> - <button id="download">Download Log</button> - <button id="reset">Reset History</button> - </p> - <p id="error"></p> - </body> - <script> - - /* TODO: - / - how to push things to rocket? (probably just http post for now …) - / - how to rate-limit new positions (either count dates, or option in geolocation?) - / - how to get closest point on path? - */ - - let lat = document.getElementById("latitude"); - let long = document.getElementById("longitude"); - let speed = document.getElementById("speed"); - let acc = document.getElementById("accuracy"); - let angle = document.getElementById("angle"); - let alt = document.getElementById("altitude"); - - let status = document.querySelector('#status'); - let mapLink = document.querySelector('#map-link'); - - function resetDisplay () { - lat.innerText = "-"; - long.innerText = "-"; - speed.innerText = "-"; - acc.innerText = "-"; - angle.innerText = "-"; - alt.innerText = "-"; - } - - function init() { - - mapLink.href = ''; - mapLink.textContent = ''; - - resetDisplay(); - - if(!navigator.geolocation) { - status.textContent = 'Error: Geolocation API is not supported!'; - } else { - status.textContent = 'Initialising …'; - trackPosition(); - } - - } - var errcount = 1; - var geolog = []; - - function trackPosition() { - function success(position) { - const latitude = position.coords.latitude; - const longitude = position.coords.longitude; - errcount = 0; - - status.textContent = ''; - mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`; - mapLink.textContent = `Latitude: ${latitude} °, Longitude: ${longitude} °`; - - lat.innerText = position.coords.latitude; - long.innerText = position.coords.longitude; - alt.innerText = position.coords.altitude; - acc.innerText = position.coords.accuracy; - speed.innerText = position.coords.speed; - angle.innerText = position.coords.heading; - - document.getElementById("error").innerText = JSON.stringify(position.coords); - - let datapoint = { - timestamp: new Date().toISOString(), - data: { - latitude: position.coords.latitude, - longitude: position.coords.longitude, - altitude: position.coords.altitude, - accuracy: position.coords.accuracy, - altitudeAccuracy: position.coords.altitudeAccuracy, - heading: position.coords.heading, - speed: position.coords.speed - } - }; - - geolog.push(datapoint); - fetch( - "https://ilztal.live/geoloc/push", - { method: "POST", body: JSON.stringify(datapoint)} - ).then(() => console.log("pushed position")) - .catch(e => console.log("some error: ", e)) - } - - function error() { - status.textContent = "("+errcount+") Error: Getting Location failed, retrying …"; - resetDisplay(); - errcount += 1; - setTimeout(trackPosition, 3000); - } - - navigator.geolocation.watchPosition(success, error); - } - - function downloadHistory () { - let json = JSON.stringify(geolog); - let a = document.createElement("a"); - console.log("attempting download!", geolog); - a.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(json)); - a.setAttribute("download","history.json"); - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - } - - document.getElementById("initialise").addEventListener('click', init); - - document.getElementById("submit-note").onclick = (a) => { - let input = document.getElementById("note"); - let text = input.value; - console.log("submitting note:", text); - geolog.push(text); - fetch("https://ilztal.live/geoloc/push", - {method:"POST", body: JSON.stringify({ - //ty: "note", - timestamp: new Date().toISOString(), - data: text - })} - ).then(() => input.value = "") - .catch(e => { - document.getElementById("error").innerText = "error:" + e; - console.log("error occurred"); - }); - }; - - document.getElementById("download").onclick = (a) => downloadHistory(); - - document.getElementById("reset").onclick = (a) => geolog = []; - - </script> - - - </body> -</html> diff --git a/chaski/ilztal.live/geolocation/mapview.html b/chaski/ilztal.live/geolocation/mapview.html deleted file mode 100644 index bb62f62..0000000 --- a/chaski/ilztal.live/geolocation/mapview.html +++ /dev/null @@ -1,94 +0,0 @@ -<!doctype html> -<html class="no-js" lang=""> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="ie=edge"> - <title>Position view</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="apple-touch-icon" href="/apple-touch-icon.png"> - <!-- Place favicon.ico in the root directory --> - - <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" - integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" - crossorigin=""/> - <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" - integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" - crossorigin=""></script> - - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade"> - You are using an <strong>outdated</strong> browser. Please - <a href="http://browsehappy.com/">upgrade your browser</a> to improve - your experience. - </p> - <![endif]--> - - <div align="justify"> - <div id="MapID2" style="height:100vh; margin-left: auto; margin-right:auto; width:80%"></div> - </div> - <script> - var mymap = L.map('MapID2'); - L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmVsaXg4MTgyOTMiLCJhIjoiY2p6a2h6cjdyMGpicjNvbzlzZ3UwNmloMCJ9.a4t1KM9Gid-q29ultM7HgA', { - attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', - maxZoom: 18, - id: 'mapbox/streets-v11', - accessToken: 'pk.eyJ1IjoiZmVsaXg4MTgyOTMiLCJhIjoiY2p6a2h6cjdyMGpicjNvbzlzZ3UwNmloMCJ9.a4t1KM9Gid-q29ultM7HgA' - }).addTo(mymap); - var marker = L.marker([0,0]).addTo(mymap); - marker.bindPopup("Hello Train!"); - - mymap.setView([0,0], 16); - function updateMap(pos) { - if (pos === null) { - console.log("no data yet?"); - return; - } - mymap.setView(pos); - mymap.scrollWheelZoom.disable(); - marker.setLatLng(pos); - } - updateMap([48.13716,11.57540]); - - function fetchUpdate () { - fetch("https://ilztal.live/geoloc/history") - .then((data) => { - let text = data.text().then(text => { - let hist = JSON.parse(text); - console.log(hist) - - let latlngs = hist.filter(e => e.data.latitude !== undefined).map((e) => [e.data.latitude, e.data.longitude]); - - console.log(latlngs); - let polyline = L.polyline(latlngs, {color: "red"}).addTo(mymap); - - mymap.fitBounds(polyline.getBounds()) - - for (idx in hist) { - if (hist[idx].data.latitude === undefined) { - console.log(hist[idx].data, idx, 1+parseInt(idx)) - let nidx = 1+parseInt(idx); - if (hist[nidx] !== undefined && hist[nidx].data.latitude !== undefined) { - let marker = L.marker([hist[nidx].data.latitude, hist[nidx].data.longitude]) - .addTo(mymap); - marker.bindPopup(hist[idx].data); - } - } - } - }); - - }) - .catch((e) => { - console.log("some error!", e); - setTimeout(fetchUpdate, 3000); - }) - } - - fetchUpdate() - </script> - - </body> -</html> diff --git a/chaski/ilztal.live/geolocation/view.html b/chaski/ilztal.live/geolocation/view.html deleted file mode 100644 index 58b4c76..0000000 --- a/chaski/ilztal.live/geolocation/view.html +++ /dev/null @@ -1,77 +0,0 @@ -<!doctype html> -<html class="no-js" lang=""> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="ie=edge"> - <title>Position view</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="apple-touch-icon" href="/apple-touch-icon.png"> - <!-- Place favicon.ico in the root directory --> - - <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" - integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" - crossorigin=""/> - <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" - integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" - crossorigin=""></script> - - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade"> - You are using an <strong>outdated</strong> browser. Please - <a href="http://browsehappy.com/">upgrade your browser</a> to improve - your experience. - </p> - <![endif]--> - - <div align="justify"> - <div id="MapID2" style="height:60vh; margin-left: auto; margin-right:auto; width:80%"></div> - </div> - <script> - var mymap = L.map('MapID2'); - L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZmVsaXg4MTgyOTMiLCJhIjoiY2p6a2h6cjdyMGpicjNvbzlzZ3UwNmloMCJ9.a4t1KM9Gid-q29ultM7HgA', { - attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', - maxZoom: 18, - id: 'mapbox/streets-v11', - accessToken: 'pk.eyJ1IjoiZmVsaXg4MTgyOTMiLCJhIjoiY2p6a2h6cjdyMGpicjNvbzlzZ3UwNmloMCJ9.a4t1KM9Gid-q29ultM7HgA' - }).addTo(mymap); - var marker = L.marker([0,0]).addTo(mymap); - marker.bindPopup("Hello Train!"); - - mymap.setView([0,0], 16); - function updateMap(pos) { - if (pos === null) { - console.log("no data yet?"); - return; - } - mymap.setView(pos); - mymap.scrollWheelZoom.disable(); - marker.setLatLng(pos); - } - updateMap([48.13716,11.57540]); - - function fetchUpdate () { - fetch("https://ilztal.live/geoloc/current") - .then((data) => { - let text = data.text().then(text => { - let pos = JSON.parse(text); - console.log(pos) - updateMap(pos.pos); - }); - - setTimeout(fetchUpdate, 3000); - }) - .catch((e) => { - console.log("some error!", e); - setTimeout(fetchUpdate, 3000); - }) - } - - fetchUpdate() - </script> - - </body> -</html> diff --git a/chaski/services/geolocation.nix b/chaski/services/geolocation.nix deleted file mode 100644 index 9fe0973..0000000 --- a/chaski/services/geolocation.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - services.nginx.virtualHosts."ilztal.live".locations."/geolocation".root = - ../ilztal.live; -} diff --git a/chaski/services/tracktrain.nix b/chaski/services/tracktrain.nix index 5887f73..34391b0 100644 --- a/chaski/services/tracktrain.nix +++ b/chaski/services/tracktrain.nix @@ -60,15 +60,17 @@ in services.grafana = { enable = true; - domain = "tracktrain.ilztalbahn.eu"; - rootUrl = "%(protocol)s://%(domain)s:/metrics/"; - port = 2342; - addr = "0.0.0.0"; - extraOptions.serve_from_sub_path = "true"; + settings.server = { + serve_from_sub_path = true; + domain = "tracktrain.ilztalbahn.eu"; + root_url = "%(protocol)s://%(domain)s:/metrics/"; + http_port = 2342; + http_addr = "0.0.0.0"; + }; provision = { enable = true; - datasources = [ { + datasources.settings.datasources = [ { url = "http://localhost:9001"; type = "prometheus"; name = "prometheus"; @@ -98,7 +100,7 @@ in path = [ pkgs.wget ]; script = '' cd /tmp - wget "https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip" + # wget "https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip" ${stripLib (((import inputs.tracktrain {nixpkgs = pkgs;})) # have to remove version constraints because some aren't in 22.05 .overrideAttrs (old: { patchPhase = '' diff --git a/chaski/services/woitb/index.html b/chaski/services/woitb/index.html deleted file mode 100644 index 8d08826..0000000 --- a/chaski/services/woitb/index.html +++ /dev/null @@ -1,124 +0,0 @@ -<!DOCTYPE html> -<html lang="de"><head> -<meta http-equiv="content-type" content="text/html; charset=UTF-8"> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="ie=edge"> - <title>Wo ist die Ilztalbahn?</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="apple-touch-icon" href="https://ilztal.live/apple-touch-icon.png"> - <!-- Place favicon.ico in the root directory --> - <style> - - body { - background-color: olivedrab; - color: white; - font-family: "Sans Serif"; - max-width: 60em; - margin-left: auto; - margin-right: auto; - margin-top: 4em; - } - - body > p, #sonst p { - text-align: center; - margin-bottom: 4rem; - } - - section > p { - text-align: center; - } - - a { - text-decoration: none; - } - - h1, h2, h3 { - font-weight: lighter - } - - h1 { - font-size: 40pt; - text-align: center; - } - - @media only screen and (max-width: 1000px) { - h1 { - font-size: 30pt; - } - body { - margin: 1em; - } - } - - h2 { - font-size: 23pt; - } - - tr { - background-color: white; - color: black; - } - - td { - margin-left: 0; - padding: 0.5em; - } - - #wo { - color: black; - background-color: white; - padding: 1em; - max-width: 40em; - margin: auto; - font-weight: bold; - } - - #wo div h2 { - margin-left: 2rem; - } - - #wo div p { - margin-left: 3rem; - } - - #fahrplan { - margin: auto; - max-width: 40em; - } - - #fahrplan table tr td:last-child { - min-width: 70%; - } - - #fahrplan table { - width: 100%; - } - - </style> - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade"> - You are using an <strong>outdated</strong> browser. Please - <a href="http://browsehappy.com/">upgrade your browser</a> to improve - your experience. - </p> - <![endif]--> - - <h1>Wo ist die <a href="https://ilztalbahn.eu/">Ilztalbahn</a> gerade?</h1> - - <p>(es gibt eh nur eine)</p> - - <div id="root"><main id=""><h2 id="">Gerade nicht unterwegs</h2><div id="wo"><h2 id="">Nächste Fahrt 2022</h2><p id="">Fahrplan ist noch nicht bekannt.</p></div></main></div> - - <section> - <p>Andere Abfahrten ab Passau <a href="https://marudor.de/NPA">via marudor.de</a> | <a href="https://iris.noncd.db.de/wbt/js/index.html?bhf=NPA&Zeilen=20">via Iris der DB</a></p> - - <p style="margin-top:3em">(Diese Seite also known as "oh, die Ilztalbahn <a href="https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip">hat ja Open Data</a> 😍" – <a href="https://ilztal.live/info.html">Weitere Infos</a>)</p> - </section> - - - -</body></html> diff --git a/chaski/services/woitb/info.html b/chaski/services/woitb/info.html deleted file mode 100644 index e68d728..0000000 --- a/chaski/services/woitb/info.html +++ /dev/null @@ -1,180 +0,0 @@ -<!doctype html> -<html lang="de"> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="ie=edge"> - <title>Wo ist die Ilztalbahn?</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="apple-touch-icon" href="/apple-touch-icon.png"> - <!-- Place favicon.ico in the root directory --> - <style> - - body { - background-color: olivedrab; - color: white; - font-family: "Sans Serif"; - max-width: 60em; - margin-left: auto; - margin-right: auto; - margin-top: 4em; - } - - body > p, #sonst p { - text-align: center; - margin-bottom: 4rem; - } - - section > p { - text-align: center; - } - - a { - text-decoration: none; - } - - h1, h2, h3 { - font-weight: lighter - } - - h1 { - font-size: 40pt; - text-align: center; - } - - @media only screen and (max-width: 1000px) { - h1 { - font-size: 30pt; - } - body { - margin: 1em; - } - } - - h2 { - font-size: 23pt; - } - - tr { - background-color: white; - color: black; - } - - td { - margin-left: 0; - padding: 0.5em; - } - - #wo { - color: black; - background-color: white; - padding: 1em; - max-width: 40em; - margin: auto; - font-weight: bold; - } - - #wo div h2 { - margin-left: 2rem; - } - - #wo div p { - margin-left: 3rem; - } - - #fahrplan { - margin: auto; - max-width: 40em; - } - - #fahrplan table tr td:last-child { - min-width: 70%; - } - - #fahrplan table { - width: 100%; - } - - </style> - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade"> - You are using an <strong>outdated</strong> browser. Please - <a href="http://browsehappy.com/">upgrade your browser</a> to improve - your experience. - </p> - <![endif]--> - - <h1><a href="index.html">Wo ist die Ilztalbahn</a> – Über</h1> - - <main> - <h2>Was ist das hier?</h2> - <p> - Diese Webseite zeigt den Fahrplan der <a href="https://ilztalbahn.eu">Ilztalbahn</a> an, - und macht sonst nicht viel. Bitte beachtet, dass diese Seite nicht von der Ilztalbahn GmbH, - dem Förderverein o.ä. betrieben wird, sondern nur ein privates Projekt einer einzelnen Person - ohne jede Verfügbarkeitsgarantie ist. - </p> - - <h2>Wie funktioniert das?</h2> - <p> - Die Ilztalbahn bietet ihren Fahrplan im offenen Standard <a href="https://gtfs.org/">GTFS</a> - an. Weil GTFS an einigen Stellen ein manchmal schwer zu benutzender Standard ist (und nicht - jeder Besuch dieser Webseite einen Aufruf des GTFS der Ilztalbahn triggern muss), hängt noch - ein kleiner Server dazwischen der die relevanten Teile in JSON übersetzt. - </p> - <p> - Der Fahrplan ist jeweils für einen ganzen Sommer gültig, und wird auch währenddessen - (soweit ich sehen kann) nicht verändert oder aktualisiert — es gibt also keinerlei Garantie, - dass die Daten hier korrekt sind! - </p> - - <h2>Gibt es das auch als App?</h2> - <p> - Aktuell nicht. Wenn ihr die Webseite im Browser offen lasst, sollte sie sich aber auch offline - noch automatisch aktualisieren. - </p> - - <h2>Werden Verspätungen/etc. angezeigt?</h2> - <p> - Leider nein. Es gibt für einige Fahrten der Ilztalbahn zwar Echtzeitdaten von der DB, diese - sind aber nicht im Datensatz der Ilztalbahn enthalten. Vielleicht kommen die hier noch - irgendwann mit rein, solange könnt ihr sie (falls es sie gibt) bei - <a href="https://marudor.de/Passau%20Hbf">marudor.de</a> anschauen. - </p> - - <h2>Gibts hier Quellcode zu?</h2> - <p> - Ja klar, hier: <a href="https://stuebinm.eu/git/woitb">git-Repository</a> - </p> - - <h2>Datenschutz?</h2> - <p> - Diese Seite läuft aktuell auf einer kleinen vps bei <a href="https://hetzner.de">Hetzner</a>, - geloggt werden aktuell nur Zugriffe, aber keine IP-Adressen. - </p> - - <h2>Wer macht das hier?</h2> - <p> - Auch nur so ein Mensch im Internet. Falls ihr wollt könnt ihr - <a href="https://pleroma.stuebinm.eu/stuebinm">auf meinem Pleroma</a> vorbeischauen. - </p> - - <h2>Ich hab ne Idee für ein Feature!</h2> - <p> - Schreibt mich über Pleroma an, vielleicht habe ich Zeit und Lust es einzubauen. - </p> - - <h2>Ich hab ein Feature dazuimplementiert!</h2> - <p> - Cool! Schick mir gerne nen Patch! (Mail ist im Repository) - </p> - </main> - <section> - <p style="margin-top:3em;">(Diese Seite also known as "oh, die Ilztalbahn <a href="https://ilztalbahn.eu/wp-content/uploads/2020/07/gtfs.zip">hat ja Open Data</a> 😍" – <a href="info.html">Weitere Infos</a>)</p> - </section> - - </body> -</html> |