118 lines
3.6 KiB
Python
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()
|