# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2020, The Monero Project. # Copyright (c) 2020, dsc@xmr.pm import os import asyncio import json from quart import websocket, jsonify, send_from_directory import settings from wowlet_backend.factory import app, broadcast from wowlet_backend.wsparse import WebsocketParse from wowlet_backend.utils import wowlet_data @app.route("/") async def root(): data = await wowlet_data() return jsonify(data) @app.route("/suchwow/") async def suchwow(name: str): """Download a SuchWow.xyz image""" base = os.path.join(settings.cwd, "data", "suchwow") return await send_from_directory(base, name) @app.websocket('/ws') async def ws(): data = await wowlet_data() # blast available data on connect for task_key, task_value in data.items(): if not task_value: continue await websocket.send(json.dumps({"cmd": task_key, "data": task_value}).encode()) async def rx(): while True: buffer = await websocket.receive() try: blob = json.loads(buffer) if "cmd" not in blob: continue cmd = blob.get('cmd') _data = blob.get('data') result = await WebsocketParse.parser(cmd, _data) if result: rtn = json.dumps({"cmd": cmd, "data": result}).encode() await websocket.send(rtn) except Exception as ex: continue async def tx(): async for _data in broadcast.subscribe(): payload = json.dumps(_data).encode() await websocket.send(payload) # bidirectional async rx and tx loops consumer_task = asyncio.ensure_future(rx()) producer_task = asyncio.ensure_future(tx()) try: await asyncio.gather(consumer_task, producer_task) finally: consumer_task.cancel() producer_task.cancel() @app.errorhandler(403) @app.errorhandler(404) @app.errorhandler(405) @app.errorhandler(500) def page_not_found(e): return ":)", 500