algo/app/server.py

71 lines
2.1 KiB
Python

import asyncio
from os.path import join, dirname
import aiohttp
import yaml
from aiohttp import web
routes = web.RouteTableDef()
PROJECT_ROOT = dirname(dirname(__file__))
async def handle_index(_):
with open(join(PROJECT_ROOT, 'app', 'index.html'), 'r') as f:
return web.Response(body=f.read(), content_type='text/html')
async def websocket_handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
if msg.data == 'close':
await ws.close()
else:
p = await asyncio.create_subprocess_shell(
msg.data,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
while True:
line = await p.stdout.readline()
if not line:
break
else:
await ws.send_str(line.decode('ascii').rstrip())
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' % ws.exception())
print('websocket connection closed')
return ws
@routes.view("/config")
class UsersView(web.View):
async def get(self):
with open(join(PROJECT_ROOT, 'config.cfg'), 'r') as f:
config = yaml.safe_load(f.read())
return web.json_response(config)
async def post(self):
data = await self.request.json()
with open(join(PROJECT_ROOT, 'config.cfg'), 'w') as f:
try:
config = yaml.safe_dump(data)
except Exception as e:
return web.json_response({'error': {
'code': type(e).__name__,
'message': e,
}}, status=400)
else:
f.write(config)
return web.json_response({'ok': True})
app = web.Application()
app.router.add_get('/ws', websocket_handler)
app.router.add_get('/', handle_index)
app.router.add_routes(routes)
web.run_app(app)