diff options
author | MaZderMind <git@mazdermind.de> | 2015-09-05 20:48:01 +0200 |
---|---|---|
committer | MaZderMind <git@mazdermind.de> | 2015-09-05 20:48:01 +0200 |
commit | 65356fd083f31cc6956516a7e8fc04896c9f5ffc (patch) | |
tree | e3a645f6459dd4a3fae8497867200062025f762b /voctogui/lib | |
parent | 5e449400a6e7747a2135aa81dedc71c46a1e3664 (diff) |
implement config fetching and switch to async mode
Diffstat (limited to 'voctogui/lib')
-rw-r--r-- | voctogui/lib/config.py | 11 | ||||
-rw-r--r-- | voctogui/lib/connection.py | 111 |
2 files changed, 97 insertions, 25 deletions
diff --git a/voctogui/lib/config.py b/voctogui/lib/config.py index b18acfb..27dd9c7 100644 --- a/voctogui/lib/config.py +++ b/voctogui/lib/config.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 import logging +import json import os.path from configparser import SafeConfigParser from lib.args import Args @@ -10,13 +11,17 @@ __all__ = ['Config'] def getlist(self, section, option): return [x.strip() for x in self.get(section, option).split(',')] -def fetchRemoteConfig(self): +def fetchServerConfig(self): log = logging.getLogger('Config') log.info("reading server-config %s", Connection) - Connection.ask('config') + + server_config = Connection.fetchServerConfig() + + log.info("merging server-config %s", server_config) + self.read_dict(server_config) SafeConfigParser.getlist = getlist -SafeConfigParser.fetchRemoteConfig = fetchRemoteConfig +SafeConfigParser.fetchServerConfig = fetchServerConfig files = [ os.path.join(os.path.dirname(os.path.realpath(__file__)), '../default-config.ini'), diff --git a/voctogui/lib/connection.py b/voctogui/lib/connection.py index ac7243d..433693d 100644 --- a/voctogui/lib/connection.py +++ b/voctogui/lib/connection.py @@ -1,46 +1,113 @@ #!/usr/bin/python3 import logging import socket +import json +import sys +from queue import Queue +from gi.repository import GObject log = logging.getLogger('Connection') -sock = None +conn = None port = 9999 +command_queue = Queue() def establish(host): + global conn, port, log + log.info('establishing Connection to %s', host) - sock = socket.create_connection( (host, port) ) + conn = socket.create_connection( (host, port) ) log.debug('Connection successful \o/') - # TODO: register IO callback here +def fetchServerConfig(): + global conn, log -def send(command): - print("would send command talk to server now and read back the response") - filelike = sock.makefile('rw') - filelike.write(command + "\n") - filelike.flush() + log.info('reading server-config') + fd = conn.makefile('rw') + fd.write("get_config\n") + fd.flush() + + while True: + line = fd.readline() + words = line.split(' ') + + signal = words[0] + args = words[1:] + + if signal != 'server_config': + continue + + server_config_json = " ".join(args) + server_config = json.loads(server_config_json) + return server_config + + +def enterNonblockingMode(): + global conn, log + + log.debug('entering nonblocking-mode') + conn.setblocking(False) + GObject.io_add_watch(conn, GObject.IO_IN, on_data, ['']) + GObject.idle_add(on_loop) +def on_data(conn, _, leftovers, *args): + global log -def on_data(args*): - filelike = sock.makefile() - line = '' + '''Asynchronous connection handler. Pushes data from socket + into command queue linewise''' try: - line = filelike.readline() - except Exception as e: - log.warn("Can't read from socket: %s", e) + while True: + try: + leftovers.append(conn.recv(4096).decode(errors='replace')) + if len(leftovers[-1]) == 0: + log.info("socket was closed") - if len(line) == 0: - close_connection() - return False + # FIXME try to reconnect + sys.exit(1) - line = line.strip() + except UnicodeDecodeError as e: + continue + except BlockingIOError as e: + pass - process_line(line) + data = "".join(leftovers) + leftovers.clear() + lines = data.split('\n') + for line in lines[:-1]: + log.debug("got line: %r", line) -def process_line(line): - msg_type = line.split()[0] + line = line.strip() + command_queue.put((line, conn)) + log.debug("remaining %r", lines[-1]) + leftovers.append(lines[-1]) + return True -def close_connection(): +def on_loop(): + global command_queue + + '''Command handler. Processes commands in the command queue whenever + nothing else is happening (registered as GObject idle callback)''' + if command_queue.empty(): + return True + + line, requestor = command_queue.get() + + words = line.split() + if len(words) < 1: + return True + + signal = words[0] + args = words[1:] + + log.info('received signal %s, dispatching', signal) + +def send(command): + global conn, log + conn.send(command) + +def on(signal, cb): pass +def one(signal, cb): + pass |