hugvey/hugvey/panopticon.py

118 lines
3.6 KiB
Python

"""
The panopticon provides a way to observe (& control) all running Hugveys trough a web interface
"""
import logging
import tornado
import tornado.websocket
import tornado.web
import tornado.ioloop
import os
from pytz.reference import Central
import asyncio
import json
from urllib.parse import urlparse
logger = logging.getLogger("panopticon")
web_dir = os.path.join(os.path.split(__file__)[0], '..', 'www')
print(web_dir)
def getWebSocketHandler(central_command):
class WebSocketHandler(tornado.websocket.WebSocketHandler):
CORS_ORIGINS = ['localhost']
connections = set()
def check_origin(self, origin):
parsed_origin = urlparse(origin)
# parsed_origin.netloc.lower() gives localhost:3333
valid = parsed_origin.hostname in self.CORS_ORIGINS
return valid
# the client connected
def open(self):
self.connections.add(self)
logger.info("New client connected")
# the client sent the message
def on_message(self, message):
logger.debug(f"recieve: {message}")
try:
msg = json.loads(message)
if msg['action'] == 'init':
self.msgInit()
if msg['action'] == 'get_status':
self.msgStatus()
if msg['action'] == 'resume':
self.msgResume(msg['hugvey'])
if msg['action'] == 'pause':
self.msgPause(msg['hugvey'])
if msg['action'] == 'restart':
self.msgRestart(msg['hugvey'])
except Exception as e:
self.send({'alert': 'Invalid request: {}'.format(e)})
def send(self, message):
j = json.dumps(message)
print(self.connections)
[con.write_message(j) for con in self.connections]
# client disconnected
def on_close(self):
self.connections.remove(self)
logger.info("Client disconnected")
def getStatusMsg(self):
msg = central_command.getStatusSummary()
msg['action'] = 'status'
return msg
def msgStatus(self):
self.send(self.getStatusMsg())
def msgInit(self):
msg = self.getStatusMsg()
self.send(msg)
def msgResume(self, hv_id):
central_command.hugveys[hv_id].eventQueue.put({'event': 'resume'})
def msgPause(self, hv_id):
central_command.hugveys[hv_id].eventQueue.put({'event': 'pause'})
def msgRestart(self, hv_id):
central_command.hugveys[hv_id].eventQueue.put({'event': 'restart'})
return WebSocketHandler
class Panopticon(object):
def __init__(self, central_command, config):
self.command = central_command
self.config = config
self.application = tornado.web.Application([
(r"/ws", getWebSocketHandler(self.command)),
(r"/local/(.*)", tornado.web.StaticFileHandler,
{"path": config['web']['files_dir']}),
(r"/(.*)", tornado.web.StaticFileHandler,
{"path": web_dir, "default_filename": 'index.html'}),
], debug=True)
self.application.listen(config['web']['port'])
# self.loop.configure(evt_loop)
def start(self):
evt_loop = asyncio.new_event_loop()
asyncio.set_event_loop(evt_loop)
self.loop = tornado.ioloop.IOLoop.current()
logger.info(f"Start Panopticon on http://localhost:{self.config['web']['port']}")
self.loop.start()
def stop(self):
self.loop.stop()