From f5f08fc10360aa4df5f5ac710820845a34acc6ae Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Fri, 18 Jan 2019 19:39:35 +0100 Subject: [PATCH] Starting Panopticon implementation --- hugvey/central_command.py | 28 +++++++++++++++------ hugvey/panopticon.py | 52 +++++++++++++++++++++++++++++++++++++-- server_config.yml | 4 ++- tsconfig.json | 28 +++++++++++++++++++++ www/index.html | 17 +++++++++++++ 5 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 tsconfig.json create mode 100644 www/index.html diff --git a/hugvey/central_command.py b/hugvey/central_command.py index 9b357d0..f5b60f4 100644 --- a/hugvey/central_command.py +++ b/hugvey/central_command.py @@ -3,24 +3,20 @@ This server controls all hugveys and the processing of their narratives. It exposes itself for control to the panopticon server. """ - import asyncio import logging -from pandas.conftest import ip import threading +import time import yaml import zmq from zmq.asyncio import Context -from hugvey import panopticon from hugvey.communication import getTopic, zmqSend, zmqReceive +from hugvey.panopticon import Panopticon +from hugvey.story import Story from hugvey.voice.google import GoogleVoiceClient from hugvey.voice.player import Player from hugvey.voice.streamer import AudioStreamer -import uuid -from hugvey.story import Story -import time -from _ast import Await logger = logging.getLogger("command") @@ -38,6 +34,9 @@ class CentralCommand(object): def loadConfig(self, filename): + if hasattr(self, 'config'): + raise Exception("Overriding config not supported yet") + with open(filename, 'r') as fp: logger.debug('Load config from {}'.format(filename)) self.config = yaml.safe_load(fp) @@ -50,6 +49,8 @@ class CentralCommand(object): for lang in self.config['languages']: with open(lang['file'], 'r') as fp: self.languages[lang['code']] = yaml.load(fp) + + self.panopticon = Panopticon(self, self.config) def commandHugvey(self, hv_id, msg): @@ -148,14 +149,25 @@ class CentralCommand(object): else: await self.hugveys[hugvey_id].eventQueue.put(msg) pass + +# def getPanopticon(self): +# self.panopticon = def start(self): self.isRunning.set() self.loop = asyncio.get_event_loop() +# self.panopticon_loop = asyncio.new_event_loop() + self.tasks = {} # collect tasks so we can cancel in case of error self.tasks['eventListener'] = self.loop.create_task(self.eventListener()) self.tasks['commandSender'] = self.loop.create_task(self.commandSender()) -# self.tasks['commandSender'] = self.loop.create_task(self.commandSender()) + + print(threading.current_thread()) + # we want the web interface in a separate thread + self.panopticon_thread = threading.Thread(target=self.panopticon.start, name="Panopticon") + self.panopticon_thread.start() + print(threading.current_thread()) + self.loop.run_forever() def stop(self): diff --git a/hugvey/panopticon.py b/hugvey/panopticon.py index ef8b73a..b33d824 100644 --- a/hugvey/panopticon.py +++ b/hugvey/panopticon.py @@ -5,9 +5,57 @@ The panopticon provides a way to observe (& control) all running Hugveys trough import logging import tornado +import tornado.websocket +import tornado.web +import tornado.ioloop +import os +from pytz.reference import Central +import asyncio logger = logging.getLogger("panopticon") +web_dir = os.path.join(os.path.split(__file__)[0], '..','www') +print(web_dir) + +class WebSocketHandler(tornado.websocket.WebSocketHandler): + connections = set() + + # the client connected + def open(self): + self.connections.add(self) + print("New client connected") + + # the client sent the message + def on_message(self, message): + [con.write_message(message) for con in self.connections] + + # client disconnected + def on_close(self): + self.connections.remove(self) + print("Client disconnected") + + class Panopticon(object): - def __init__(self, config, command): - pass \ No newline at end of file + def __init__(self, central_command, config): + self.command = central_command + self.config = config + self.application = tornado.web.Application([ + (r"/ws", WebSocketHandler), + (r"/uploads/(.*)", 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 port {self.config['web']['port']}") + self.loop.start() + + def stop(self): + self.loop.stop() diff --git a/server_config.yml b/server_config.yml index a6967c4..63e77db 100644 --- a/server_config.yml +++ b/server_config.yml @@ -15,4 +15,6 @@ languages: file: story_de.json - code: fr-FR file: story_fr.json - \ No newline at end of file +web: + port: 8888 + files_dir: "/home/ruben/Documents/Projecten/2018/Hugvey/hugvey/local/" \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6bd2f48 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "declaration": true, + "emitDecoratorMetadata": false, + "experimentalDecorators": false, + "module": "es2015", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": false, + "noImplicitAny": false, + "noImplicitReturns": false, + "outDir": "www/js", + "removeComments": false, + "sourceMap": true, + "strictNullChecks": false, + "target": "es2015", + "watch": true, + // this enables stricter inference for data properties on `this` + "strict": true, + "plugins": [ + { + "name": "tslint-language-service" + } + ], + "rootDir": "www" + }, + "compileOnSave": true, + "buildOnSave": true +} \ No newline at end of file diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..3f40d66 --- /dev/null +++ b/www/index.html @@ -0,0 +1,17 @@ + + + Pillow Talk Control Interface + + + + +
+
+
+
+
+
+
{{message}}
+ + + \ No newline at end of file