aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaZderMind <git@mazdermind.de>2015-09-05 20:48:01 +0200
committerMaZderMind <git@mazdermind.de>2015-09-05 20:48:01 +0200
commit65356fd083f31cc6956516a7e8fc04896c9f5ffc (patch)
treee3a645f6459dd4a3fae8497867200062025f762b
parent5e449400a6e7747a2135aa81dedc71c46a1e3664 (diff)
implement config fetching and switch to async mode
-rw-r--r--voctogui/lib/config.py11
-rw-r--r--voctogui/lib/connection.py111
-rwxr-xr-xvoctogui/voctogui.py5
3 files changed, 100 insertions, 27 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
diff --git a/voctogui/voctogui.py b/voctogui/voctogui.py
index 932b8f9..1ca6579 100755
--- a/voctogui/voctogui.py
+++ b/voctogui/voctogui.py
@@ -107,8 +107,9 @@ def main():
Connection.establish(
Config.get('server', 'host'))
- # fetch serverconfig from server
- Config.fetchRemoteConfig()
+ # fetch config from server
+ Config.fetchServerConfig()
+ Connection.enterNonblockingMode()
# init main-class and main-loop
logging.debug('initializing Voctogui')