summaryrefslogtreecommitdiff
path: root/voctogui/lib/connection.py
blob: b56a490a01cb067b6947ce266d7a45cc823879bb (plain)
  1. #!/usr/bin/python3
  2. import logging
  3. import socket
  4. import json
  5. import sys
  6. from queue import Queue
  7. from gi.repository import GObject
  8. log = logging.getLogger('Connection')
  9. conn = None
  10. port = 9999
  11. command_queue = Queue()
  12. def establish(host):
  13. global conn, port, log
  14. log.info('establishing Connection to %s', host)
  15. conn = socket.create_connection( (host, port) )
  16. log.debug('Connection successful \o/')
  17. def fetchServerConfig():
  18. global conn, log
  19. log.info('reading server-config')
  20. fd = conn.makefile('rw')
  21. fd.write("get_config\n")
  22. fd.flush()
  23. while True:
  24. line = fd.readline()
  25. words = line.split(' ')
  26. signal = words[0]
  27. args = words[1:]
  28. if signal != 'server_config':
  29. continue
  30. server_config_json = " ".join(args)
  31. server_config = json.loads(server_config_json)
  32. return server_config
  33. def enterNonblockingMode():
  34. global conn, log
  35. log.debug('entering nonblocking-mode')
  36. conn.setblocking(False)
  37. GObject.io_add_watch(conn, GObject.IO_IN, on_data, [''])
  38. GObject.idle_add(on_loop)
  39. def on_data(conn, _, leftovers, *args):
  40. global log
  41. '''Asynchronous connection handler. Pushes data from socket
  42. into command queue linewise'''
  43. try:
  44. while True:
  45. try:
  46. leftovers.append(conn.recv(4096).decode(errors='replace'))
  47. if len(leftovers[-1]) == 0:
  48. log.info("socket was closed")
  49. # FIXME try to reconnect
  50. sys.exit(1)
  51. except UnicodeDecodeError as e:
  52. continue
  53. except BlockingIOError as e:
  54. pass
  55. data = "".join(leftovers)
  56. leftovers.clear()
  57. lines = data.split('\n')
  58. for line in lines[:-1]:
  59. log.debug("got line: %r", line)
  60. line = line.strip()
  61. command_queue.put((line, conn))
  62. log.debug("remaining %r", lines[-1])
  63. leftovers.append(lines[-1])
  64. return True
  65. def on_loop():
  66. global command_queue
  67. '''Command handler. Processes commands in the command queue whenever
  68. nothing else is happening (registered as GObject idle callback)'''
  69. if command_queue.empty():
  70. return True
  71. line, requestor = command_queue.get()
  72. words = line.split()
  73. if len(words) < 1:
  74. return True
  75. signal = words[0]
  76. args = words[1:]
  77. log.info('received signal %s, dispatching', signal)
  78. def send(command):
  79. global conn, log
  80. if isinstance(command, str):
  81. command = command.encode('ascii')
  82. conn.send(command)
  83. def on(signal, cb):
  84. pass
  85. def one(signal, cb):
  86. pass