summaryrefslogtreecommitdiff
path: root/voctogui/lib/connection.py
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 /voctogui/lib/connection.py
parent5e449400a6e7747a2135aa81dedc71c46a1e3664 (diff)
implement config fetching and switch to async mode
Diffstat (limited to 'voctogui/lib/connection.py')
-rw-r--r--voctogui/lib/connection.py111
1 files changed, 89 insertions, 22 deletions
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