# -*- encoding: utf-8 -*- """ The REST endpoints. """ from aiohttp import web import datetime import logging import typing as T from aiohttp_session import get_session, Session from bot_z.async_operator import AsyncOperator from api.async_bot import login, logout, checkin, checkout, status from api import BASE_URI alog = logging.getLogger("api") routes = web.RouteTableDef() OPERATORS = {} # type: T.Dict[T.Text, AsyncOperator] async def get_set_operator( request: web.Request, user: T.Text, password: T.Text ) -> T.Tuple[AsyncOperator, Session]: session = await get_session(request) if "async_operator" in session: op = OPERATORS[session["async_operator"]] else: op = AsyncOperator(BASE_URI, name=user) session["async_operator"] = user OPERATORS[user] = op return op, session @routes.post("/login") async def login_handler(request: web.Request) -> web.Response: data = await request.post() user = data.get("username") password = data.get("password") if not user or not password: return web.json_response({"error": "Missing username or password"}, status=404) op, session = await get_set_operator(request, user, password) alog.debug("login - user: %s, password: %s", user, password) res = await login(op, user, password) alog.debug("login result: %s", res) if not res: session.invalidate() alog.info("Login failed; session invalidated.") return web.json_response({"logged_in": res}, status=200) @routes.post("/logout") async def logout_handler(request: web.Request) -> web.Response: alog.debug("logout") session = await get_session(request) op = OPERATORS.get(session.get("async_operator")) if not op: return web.json_response({"error": "No session"}, status=404) res = await logout(op) alog.debug("logout result: %s", res) # FIX: assess if better to invalidate session and dump the browser instance. return web.json_response({"logged_in": res}, status=200) @routes.post("/checkin") async def checkin_handler(request: web.Request) -> web.Response: alog.debug("checkin") session = await get_session(request) op = OPERATORS.get(session.get("async_operator")) if not op: return web.json_response({"error": "No session"}, status=404) res = await checkin(op) alog.debug("checkin result: %s", res) return web.json_response({"checked_in": res}, status=200) @routes.post("/checkout") async def checkout_handler(request: web.Request) -> web.Response: alog.debug("checkout") session = await get_session(request) op = OPERATORS.get(session.get("async_operator")) if not op: return web.json_response({"error": "No session"}, status=404) res = await checkout(op) alog.debug("checkout result: %s", res) return web.json_response({"checked_in": res}, status=200) @routes.get("/movements") async def movements_handle(request: web.Request) -> web.Response: alog.debug("movements") session = await get_session(request) op = OPERATORS.get(session.get("async_operator")) if not op: return web.json_response({"error": "No session"}, status=404) res = await status(op) alog.debug("movements result: %s", res) if not res: return web.json_response({"error": "No movements found"}, status=404) resp_data = dict((i[1], i[0]) for i in res) # type: ignore return web.json_response(resp_data, status=200)