diff options
-rwxr-xr-x | bin/nvm | 30 | ||||
-rw-r--r-- | static/v0/js/geolocation.js | 67 | ||||
-rw-r--r-- | templates/landing_page.html | 36 |
3 files changed, 133 insertions, 0 deletions
@@ -22,6 +22,11 @@ headers = { "Content-Type": "text/html; charset=utf-8", } +ajax_headers = { + "Access-Control-Allow-Origin": "*", + "Content-Type": "application/json; charset=utf-8", +} + db_rest_api = os.getenv("NVM_DB_REST_API", "https://v5.db.transport.rest") env = Environment(loader=FileSystemLoader("templates"), autoescape=select_autoescape()) @@ -122,6 +127,29 @@ async def show_departure_board(request): ) +async def show_landing_page(request): + landing_page = env.get_template("landing_page.html") + return web.Response( + body=landing_page.render(title="Noot"), + headers=headers, + ) + + +async def ajax_geolocation(request): + request_data = await request.json() + lat = request_data["lat"] + lon = request_data["lon"] + async with aiohttp.ClientSession() as session: + async with session.get( + f"{db_rest_api}/stops/nearby?latitude={lat}&longitude={lon}&linesOfStops=true" + ) as response: + departures = await response.json() + return web.Response( + body=json.dumps(departures), + headers=ajax_headers, + ) + + if __name__ == "__main__": parser = argparse.ArgumentParser(description="eva to efa gateway") @@ -130,6 +158,8 @@ if __name__ == "__main__": args = parser.parse_args() app = web.Application() + app.router.add_get(args.prefix, show_landing_page) app.router.add_get(f"{args.prefix}board/{{eva}}", show_departure_board) + app.router.add_post(f"{args.prefix}geolocation", ajax_geolocation) app.router.add_static(f"{args.prefix}static", "static") web.run_app(app, host="localhost", port=args.port) diff --git a/static/v0/js/geolocation.js b/static/v0/js/geolocation.js new file mode 100644 index 0000000..7efffe0 --- /dev/null +++ b/static/v0/js/geolocation.js @@ -0,0 +1,67 @@ +document.addEventListener("DOMContentLoaded", function() { + const geoLocationButton = document.getElementById('geolocationsearch'); + + const processResult = function(results) { + console.log(results); + const list = document.createElement("ul"); + for (var result in results) { + result = results[result]; + var listentry = document.createElement("li"); + var link = document.createElement("a"); + link.text = result.name + link.href = "/board/" + result.id; + listentry.appendChild(link) + list.appendChild(listentry) + } + geoLocationButton.replaceWith(list); + }; + + const processLocation = function(loc) { + fetch('/geolocation', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + lon: loc.coords.longitude, + lat: loc.coords.latitude + }) + }).then(response => response.json()).then(processResult); + }; + + const processError = function(error) { + if (error.code == error.PERMISSION_DENIED) { + showError('Standortanfrage nicht möglich.', 'Vermutlich fehlen die Rechte im Browser oder der Android Location Service ist deaktiviert.', 'geolocation.error.PERMISSION_DENIED'); + } else if (error.code == error.POSITION_UNAVAILABLE) { + showError('Standort konnte nicht ermittelt werden', 'Service nicht verfügbar', 'geolocation.error.POSITION_UNAVAILABLE'); + } else if (error.code == error.TIMEOUT) { + showError('Standort konnte nicht ermittelt werden', 'Timeout', 'geolocation.error.TIMEOUT'); + } else { + showError('Standort konnte nicht ermittelt werden', 'unbekannter Fehler', 'unknown geolocation.error code'); + } + }; + + const getGeoLocation = function() { + geoLocationButton.textContent = "Suche Haltestellen ..."; + geoLocationButton.disabled = true; + navigator.geolocation.getCurrentPosition(processLocation, processError); + } + + if (geoLocationButton) { + if (navigator.geolocation) { + if (navigator.permissions) { + navigator.permissions.query({ name:'geolocation' }).then(function(value) { + if (value.state === 'prompt') { + geoLocationButton.addEventListener('click', getGeoLocation); + } else { + getGeoLocation(); + } + }); + } else { + geoLocationButton.addEventListener('click', getGeoLocation); + } + } else { + geoLocationButton.css('visibility', 'hidden'); + } + } +}); diff --git a/templates/landing_page.html b/templates/landing_page.html new file mode 100644 index 0000000..a059b55 --- /dev/null +++ b/templates/landing_page.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html lang="de"> +<head> + <title>{{ title }}</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="keywords" content="Abfahrtsmonitor, Bahnhofstafel, Abfahrten, Abfahrtstafel, Nahverkehr, Haltestellen"> + <meta name="description" content="Inoffizieller Abfahrtsmonitor für Nahverkehr"> + <meta name="theme-color" content="#00838f"> + <link rel="icon" type="image/png" href="/static/icons/icon-16x16.png" sizes="16x16"> + <link rel="icon" type="image/png" href="/static/icons/icon-32x32.png" sizes="32x32"> + <link rel="icon" type="image/png" href="/static/icons/icon-96x96.png" sizes="96x96"> + <link rel="apple-touch-icon" href="/static/icons/icon-120x120.png"> + <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-180x180.png"> + <link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152x152.png"> + <link rel="apple-touch-icon" sizes="167x167" href="/static/icons/icon-167x167.png"> + <link href="/static/v0/css/wip.css" id="theme" rel="stylesheet"> + <script src="/static/v0/js/geolocation.js"></script> +</head> +<body> +<div class="container"> + <div class="content"> + <div class="geolocation"> + <button id="geolocationsearch">Haltestellen in der Umgebung suchen</button> + </div> + <!--<form action="/to_board" method="POST"> + <input id="name" name="name" required type="text"> + <label for="name">Manuelle Eingabe</label> + <button class="btn waves-effect waves-light btn-flat" type="submit" name="action" value="departures"> + Suchen + </button> + </form>--> + </div> +</div> +</body> +</html> |