summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2021-05-29 22:45:38 +0200
committerDaniel Friesel <derf@finalrewind.org>2021-05-29 22:45:38 +0200
commit886b9e56dc515c6536129711494f91262d402214 (patch)
treeb8f96e798a5a5cec39da734ed6d28103963a89a2
initial commit
-rwxr-xr-xbin/nvm71
-rw-r--r--static/v0/css/wip.css78
-rw-r--r--templates/departure_list.html34
3 files changed, 183 insertions, 0 deletions
diff --git a/bin/nvm b/bin/nvm
new file mode 100755
index 0000000..8e506dd
--- /dev/null
+++ b/bin/nvm
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+# vim:tabstop=4 softtabstop=4 shiftwidth=4 textwidth=160 smarttab expandtab colorcolumn=160
+#
+# Copyright (C) 2021 Daniel Friesel
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+import argparse
+
+import aiohttp
+from aiohttp import web
+from datetime import datetime
+import dateutil.parser
+
+from jinja2 import Environment, FileSystemLoader, select_autoescape
+
+import json
+import os
+
+headers = {
+ "Access-Control-Allow-Origin": "*",
+ "Content-Type": "text/html; 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())
+
+class Departure:
+ def __init__(self, obj):
+ self.__dict__.update(obj)
+ if "line" in obj:
+ self.line = Line(self.line)
+ self.when = dateutil.parser.parse(self.when)
+ self.plannedWhen = dateutil.parser.parse(self.plannedWhen)
+
+class Line:
+ def __init__(self, obj):
+ self.__dict__.update(obj)
+
+async def show_departure_board(request):
+ try:
+ eva = int(request.match_info.get("eva"))
+ except ValueError:
+ return web.HTTPBadRequest(text="EVA must be a number at the moment")
+
+ async with aiohttp.ClientSession() as session:
+ async with session.get(
+ f"{db_rest_api}/stops/{eva}/departures?results=60&duration=120&stopovers=true"
+ ) as response:
+ departures = await response.text()
+ departures = json.loads(departures)
+
+ if type(departures) is dict and departures.get("error", False):
+ return web.HTTPNotFound(body=json.dumps(departures), headers=headers)
+
+ departures = list(map(Departure, departures))
+ departure_board = env.get_template("departure_list.html")
+ return web.Response(body=departure_board.render(title="Noot", departures=departures), headers=headers)
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(description="eva to efa gateway")
+ parser.add_argument("--port", type=int, metavar="PORT", default=8080)
+ parser.add_argument("--prefix", type=str, metavar="PATH", default="/")
+ args = parser.parse_args()
+
+ app = web.Application()
+ app.router.add_get(f"{args.prefix}board/{{eva}}", show_departure_board)
+ app.router.add_static(f"{args.prefix}static", "static")
+ web.run_app(app, host="localhost", port=args.port)
diff --git a/static/v0/css/wip.css b/static/v0/css/wip.css
new file mode 100644
index 0000000..e3efc2a
--- /dev/null
+++ b/static/v0/css/wip.css
@@ -0,0 +1,78 @@
+body {
+ margin: 0;
+ color: black;
+ background-color: white;
+}
+
+html {
+ font-family: Sans-Serif;
+}
+
+.container {
+ max-width: 60em;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+ul.departures {
+ position:relative;
+ width:100%;
+
+ border-width:1px 2px;
+ margin-bottom: 5em;
+
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+
+ul.departures > li {
+ display: block;
+ height: 3em;
+ width: 100%;
+ position: relative;
+ cursor: pointer;
+ border-bottom: 1px solid grey;
+ background-color: white;
+}
+
+ul.departures li .line {
+ position: absolute;
+ bottom: 5px;
+ left: 2px;
+ max-width: 6em;
+ max-height: 3ex;
+ overflow: hidden;
+ font-size: 150%;
+}
+
+ul.departures li .dest {
+ position: absolute;
+ top: 0.5ex;
+ left: 4em;
+ bottom: 0px;
+ width: 70%;
+ overflow: hidden;
+ background-color: transparent;
+ font-size: 200%;
+ color: black;
+}
+
+ul.departures li .time {
+ position: absolute;
+ right: 5px;
+ top: 4px;
+ background-color: transparent;
+ font-size: 100%;
+ padding-left: 0.2em;
+ color: black;
+}
+
+@media only screen and (max-width: 600px) {
+ ul.departures > li {
+ font-size: 85%;
+ }
+}
+
+@media only screen and (min-width: 600px) {
+}
diff --git a/templates/departure_list.html b/templates/departure_list.html
new file mode 100644
index 0000000..464951b
--- /dev/null
+++ b/templates/departure_list.html
@@ -0,0 +1,34 @@
+<!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">
+</head>
+<body>
+<div class="container">
+ <div class="content">
+ <ul class="departures">
+ {% for departure in departures %}
+ <li onclick="location.href='https://dbf.finalrewind.org/map/{{ departure.tripId }}/0';">
+ <span class="line {{ departure.line.mode }}">{{ departure.line.name }}</span>
+ <span class="dest" aria-label="nach {{ departure.direction }}">{{ departure.direction }}</span>
+ <span class="time" aria-label="um {{ departure.when.strftime('%H:%M') }}">{{ departure.when.strftime('%H:%M') }}</span>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+</div>
+</body>
+</html>