#!/usr/bin/env python3 # vim:tabstop=4 softtabstop=4 shiftwidth=4 textwidth=160 smarttab expandtab colorcolumn=160 import argparse import aiohttp from aiohttp import web from datetime import datetime import json headers = { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json; charset=utf-8", } occupancy_map = {"MANY_SEATS": 1, "FEW_SEATS": 2, "STANDING_ONLY": 3} cache = dict() eva_to_name = dict() def get_occupancy(occupancy): try: return occupancy_map[occupancy] except KeyError: return None def build_response(content, eva, now): train_data = dict() for train in content["raw"]: if train["train_no"]: train_data[train["train_no"]] = { "occupancy": get_occupancy(train["occupancy"]) } reply = {"train": train_data} cache[eva] = (now, reply) return web.Response(body=json.dumps(reply), headers=headers) async def handle_eva(request): try: eva = int(request.match_info.get("eva")) except ValueError: return web.HTTPBadRequest(text="EVA must be a number") try: station, optid = eva_to_name[eva] except KeyError: return web.HTTPNotFound(text="Unknown EVA") now = datetime.now().timestamp() if eva in cache and now - cache[eva][0] < 300: return web.Response(body=json.dumps(cache[eva][1]), headers=headers) async with aiohttp.ClientSession() as session: async with session.get( f"https://vrrf.finalrewind.org/{station}.json?line=RE,RB,S&backend=efa.VRR2" ) as response: content = await response.text() content = json.loads(content) if not content["error"]: return build_response(content, eva, now) async with aiohttp.ClientSession() as session: async with session.get( f"https://vrrf.finalrewind.org/{optid}.json?line=RE,RB,S&backend=efa.VRR2&proximity_search=1" ) as response: content = await response.text() content = json.loads(content) return build_response(content, eva, now) if __name__ == "__main__": parser = argparse.ArgumentParser(description="eva to efa gateway") parser.add_argument( "--eva-csv", type=str, metavar="FILE", default="haltestellenMitEva.csv" ) parser.add_argument("--port", type=int, metavar="PORT", default=8080) parser.add_argument("--prefix", type=str, metavar="PATH", default="/") args = parser.parse_args() with open("share/vrr.json", "r") as f: for eva, (name, optid) in json.load(f).items(): eva_to_name[int(eva)] = name, optid app = web.Application() app.add_routes([web.get(f"{args.prefix}{{eva}}.json", handle_eva)]) web.run_app(app, host="localhost", port=args.port)