move route code out of server into own blueprints and cleanup the codebase
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
from typing import TYPE_CHECKING
|
||||
import asyncio, json, os
|
||||
|
||||
from quart import (
|
||||
Blueprint,
|
||||
render_template,
|
||||
send_from_directory,
|
||||
request,
|
||||
websocket,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from server.Server import Server
|
||||
|
||||
def create_dashboard_blueprint(server:'Server') -> Blueprint:
|
||||
blueprint = Blueprint('dashboard', __name__)
|
||||
|
||||
@blueprint.get('/dashboard')
|
||||
async def dashboard_view():
|
||||
initial_game_id = request.args.get('game_id', '')
|
||||
initial_summary = await server._get_dashboard_summary()
|
||||
initial_games = await server._get_dashboard_games(limit=100)
|
||||
return await render_template(
|
||||
'dashboard.html',
|
||||
initial_game_id=initial_game_id,
|
||||
initial_summary=initial_summary,
|
||||
initial_games=initial_games,
|
||||
)
|
||||
|
||||
@blueprint.get('/dashboard/customizations/<path:asset_path>')
|
||||
async def dashboard_customizations_asset(asset_path:str):
|
||||
customization_root = os.path.join(
|
||||
server.data_path,
|
||||
'server',
|
||||
'static',
|
||||
'customizations',
|
||||
)
|
||||
return await send_from_directory(customization_root, asset_path)
|
||||
|
||||
@blueprint.websocket('/dashboard/ws/games')
|
||||
async def dashboard_games_ws():
|
||||
ws_hub = server.dashboard_ws_hub
|
||||
websocket_task = asyncio.current_task()
|
||||
if websocket_task is not None:
|
||||
await server._register_dashboard_ws_task(websocket_task)
|
||||
|
||||
subscriber_queue:asyncio.Queue[str] = asyncio.Queue(maxsize=20)
|
||||
await server._register_dashboard_game_subscriber(subscriber_queue)
|
||||
try:
|
||||
initial_payload = await server._build_dashboard_games_event()
|
||||
await asyncio.wait_for(
|
||||
websocket.send(json.dumps(initial_payload)), timeout=1.5
|
||||
)
|
||||
while True:
|
||||
queue_task = asyncio.create_task(subscriber_queue.get())
|
||||
receive_task = asyncio.create_task(websocket.receive())
|
||||
try:
|
||||
done, _ = await asyncio.wait(
|
||||
{queue_task, receive_task},
|
||||
timeout=1.0,
|
||||
return_when=asyncio.FIRST_COMPLETED,
|
||||
)
|
||||
|
||||
if len(done) == 0:
|
||||
if ws_hub.shutdown_event.is_set():
|
||||
await asyncio.wait_for(
|
||||
websocket.send(ws_hub.shutdown_message),
|
||||
timeout=1.5,
|
||||
)
|
||||
break
|
||||
continue
|
||||
|
||||
if receive_task in done:
|
||||
try:
|
||||
request_payload_raw = receive_task.result()
|
||||
except Exception:
|
||||
break
|
||||
|
||||
response_event = await server._handle_dashboard_ws_request(request_payload_raw)
|
||||
if response_event is not None:
|
||||
await asyncio.wait_for(
|
||||
websocket.send(json.dumps(response_event)),
|
||||
timeout=1.5,
|
||||
)
|
||||
|
||||
if queue_task in done:
|
||||
event_payload = queue_task.result()
|
||||
if event_payload == ws_hub.shutdown_message:
|
||||
await asyncio.wait_for(
|
||||
websocket.send(event_payload), timeout=1.5
|
||||
)
|
||||
break
|
||||
await asyncio.wait_for(
|
||||
websocket.send(event_payload), timeout=1.5
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
if ws_hub.shutdown_event.is_set():
|
||||
await asyncio.wait_for(
|
||||
websocket.send(ws_hub.shutdown_message),
|
||||
timeout=1.5,
|
||||
)
|
||||
break
|
||||
finally:
|
||||
for pending_task in (queue_task, receive_task):
|
||||
if not pending_task.done():
|
||||
pending_task.cancel()
|
||||
await asyncio.gather(
|
||||
queue_task, receive_task, return_exceptions=True
|
||||
)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
await server._unregister_dashboard_game_subscriber(subscriber_queue)
|
||||
if websocket_task is not None:
|
||||
await server._unregister_dashboard_ws_task(websocket_task)
|
||||
|
||||
return blueprint
|
||||
Reference in New Issue
Block a user