diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/muxconfig.py | 47 | ||||
-rwxr-xr-x | gui/odr-dabmux-gui.py | 47 | ||||
-rw-r--r-- | gui/static/stats.js | 17 | ||||
-rw-r--r-- | gui/views/configeditor.tpl | 29 | ||||
-rw-r--r-- | gui/views/stats.tpl | 20 |
5 files changed, 149 insertions, 11 deletions
diff --git a/gui/muxconfig.py b/gui/muxconfig.py index 64321a2..4b307fd 100644 --- a/gui/muxconfig.py +++ b/gui/muxconfig.py @@ -20,7 +20,7 @@ # # You should have received a copy of the GNU General Public License # along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. -import socket +import zmq import json class General(object): @@ -95,23 +95,45 @@ class ConfigurationHandler(object): # local copy of the configuration self._server_version = None self._config = None + self._statistics = None + + self._ctx = zmq.Context() + self.sock = zmq.Socket(self._ctx, zmq.REQ) + self.sock.connect("tcp://{}:{}".format(self._host, self._port)) def load(self): """Load the configuration from the multiplexer and save it locally""" - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.send(b'info') + server_info = self.sock.recv() + + self.sock.send(b'getptree') + config_info = self.sock.recv() + + print("Config '%r'" % config_info) + + self._server_version = json.loads(server_info)['service'] + self._config = json.loads(config_info) - s.connect((self._host, self._port)) - s.sendall(b'getptree\n') - server_info = s.recv(32768) - config_info = s.recv(32768) - s.close() + def update_stats(self): + """Load the statistics from the multiplexer and + save them locally""" - self._server_version = json.loads(server_info.decode())['service'] - self._config = json.loads(config_info.decode()) + self.sock.send(b'info') + server_info = self.sock.recv() + + self.sock.send(b'values') + stats_info = self.sock.recv() + + self._statistics = json.loads(stats_info)['values'] def get_full_configuration(self): - return self._config + return json.dumps(self._config, indent=4) + + def set_full_configuration(self, config_json): + self.sock.send(b'setptree', flags=zmq.SNDMORE) + self.sock.send(config_json) + return self.sock.recv() == "OK" def get_mux_version(self): return self._server_version @@ -130,3 +152,8 @@ class ConfigurationHandler(object): def get_general_options(self): return General(self._config) + + def get_stats_dict(self): + """Return a dictionary with all stats""" + self.update_stats() + return self._statistics diff --git a/gui/odr-dabmux-gui.py b/gui/odr-dabmux-gui.py index 84331b5..caa4ea7 100755 --- a/gui/odr-dabmux-gui.py +++ b/gui/odr-dabmux-gui.py @@ -28,13 +28,46 @@ # along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. from muxconfig import * -from bottle import route, run, template, static_file +from bottle import route, run, template, static_file, request import json conf = ConfigurationHandler('localhost') @route('/config') def config(): + """Show the JSON ptree in a textbox for editing""" + + conf.load() + + return template('configeditor', + version = conf.get_mux_version(), + config = conf.get_full_configuration(), + message = "") + +@route('/config', method="POST") +def config_json_post(): + """Update the ODR-DabMux configuration with the JSON ptree + given as POST data""" + + new_config = request.forms.get('config') + print("New config %s" % new_config) + + success = conf.set_full_configuration(new_config) + + if success: + successmessage = "Success" + else: + successmessage = "Failure" + + conf.load() + + return template('configeditor', + version = conf.get_mux_version(), + config = conf.get_full_configuration(), + message = successmessage) + +@route('/config.json', method="GET") +def config_json_get(): """Return a application/json containing the full ptree of the mux""" @@ -43,6 +76,7 @@ def config(): return {'version': conf.get_mux_version(), 'config': conf.get_full_configuration()} + @route('/') def index(): conf.load() @@ -62,6 +96,17 @@ def index(): version = conf.get_mux_version(), services = conf.get_services()) +@route('/stats') +def index(): + conf.load() + + return template('stats', + version = conf.get_mux_version()) + +@route('/stats.json') +def stats_json(): + return conf.get_stats_dict() + @route('/static/<filename:path>') def send_static(filename): diff --git a/gui/static/stats.js b/gui/static/stats.js new file mode 100644 index 0000000..7b07099 --- /dev/null +++ b/gui/static/stats.js @@ -0,0 +1,17 @@ +var updatefunc = function(event) { + $('#statdata p').remove(); + $.getJSON('/stats.json', function(result) { + $.each(result, function(name) { + // TODO: use a hidden template inside the DOM instead + // of building the HTML here + $("<p></p>") + .append(result[name]['inputstat']['num_underruns']) + .appendTo('#statdata'); + }); + }); +} + +// Handle clicks on the to change visiblity of panes +setInterval(updatefunc, 1000); + + diff --git a/gui/views/configeditor.tpl b/gui/views/configeditor.tpl new file mode 100644 index 0000000..9d1d193 --- /dev/null +++ b/gui/views/configeditor.tpl @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>ODR-DabMux Configuration Editor</title> + <link rel="stylesheet" href="static/style.css" type="text/css" media="screen" charset="utf-8"/> + <script type="text/javascript" src="static/jquery-1.7.1.min.js"></script> +</head> +<body> + <h1>Configuration for {{version}}</h1> + + <p><a href="/config">Reload</a></p> + + % if message: + <p>{{message}}</p> + % end + + <form action="/config" method="post"> + <p> + <textarea name="config" cols="60" rows="50">{{config}}</textarea> + </p> + + <p> + <input type="submit" value="Update ODR-DabMux configuration"></input> + </p> + </form> + +</body> +</html> + diff --git a/gui/views/stats.tpl b/gui/views/stats.tpl new file mode 100644 index 0000000..30d82c5 --- /dev/null +++ b/gui/views/stats.tpl @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>ODR-DabMux Statistics</title> + <link rel="stylesheet" href="static/style.css" type="text/css" media="screen" charset="utf-8"/> + <script type="text/javascript" src="static/jquery-1.7.1.min.js"></script> +</head> +<body> + <h1>Subchannel stats for {{version}}</h1> + + <a id="update">Update</a> + + <div id="subchannels"> + <p>Subchannels</p> + <div id="statdata"></div> + </div> + <script type="text/javascript" src="static/stats.js"></script> +</body> +</html> + |