import aiohttp.web import traceback from model import Model routes = aiohttp.web.RouteTableDef() routes.static('/static', 'static') admintoken = "ae33fd8cc4fdcb1ff50ba42ff48046a7" CLIENT_REGEX = r'/{client:[a-zA-Z0-9]{16}}' def get_client(request: aiohttp.web.Request): client = request.match_info.get("client", None) model = request.app['model'] if not client: print('[get_client] client is not set, wtf') raise aiohttp.web.HTTPBadRequest() if not model.exists_client(client): print(f'[get_client] model does not know {client=}') raise aiohttp.web.HTTPBadRequest() return client @routes.get(CLIENT_REGEX) async def handler(request: aiohttp.web.Request): # this handler prevents people missing trailing slashes client = get_client(request) raise aiohttp.web.HTTPFound(f"/{client}/") @routes.get(CLIENT_REGEX + '/') async def handler(request: aiohttp.web.Request): client = get_client(request) print(f"{client=} accessed") return aiohttp.web.FileResponse('ui.html') @routes.post(CLIENT_REGEX + '/api/{method}') async def handler(request: aiohttp.web.Request): client = get_client(request) method = request.match_info.get('method', None) model = request.app['model'] data = await request.json() print(f'{client=} {data=}') try: assert method in model.ApiMethod.dict await model.ApiMethod.dict[method](model, client, **data) return aiohttp.web.Response(status=200) except Exception as e: del e # unused? traceback.print_exc() return aiohttp.web.Response(status=400) @routes.get(CLIENT_REGEX + '/ws') async def _(request: aiohttp.web.Request): client = get_client(request) model = request.app['model'] ws = aiohttp.web.WebSocketResponse(heartbeat=10) await ws.prepare(request) print(f'[WS] client {client} connected, {ws=}') await model.subscribe(client, ws) async for msg in ws: print(f'[WS] incoming message from client {client}, {ws=}, {msg=}') print(f'[WS] client {client} disconnected, {ws=}') model.unsubscribe(ws) return ws @routes.get(f"/api/{admintoken}") async def handler(request: aiohttp.web.Request): model = request.app['model'] return aiohttp.web.json_response(model.sessions) @routes.get('/') async def handler(request): del request # unused return aiohttp.web.FileResponse('index.html') @routes.get('/newclient') async def handler(request): model = request.app['model'] client = model.create_client() raise aiohttp.web.HTTPFound(f"/{client}/") if __name__ == '__main__': app = aiohttp.web.Application() app.add_routes(routes) app['model'] = Model() aiohttp.web.run_app(app, port=42042) app['model'].save()