summaryrefslogtreecommitdiff
path: root/voctocore/lib/controlserver.py
blob: fffeda8506916878b3ae83d66c41b2c795af5c3e (plain)
  1. import socket, threading, queue, logging
  2. from gi.repository import GObject
  3. def controlServerEntrypoint(f):
  4. # mark the method as something that requires view's class
  5. f.is_control_server_entrypoint = True
  6. return f
  7. class ControlServer():
  8. log = logging.getLogger('ControlServer')
  9. def __init__(self, videomix):
  10. '''Initialize server and start listening.'''
  11. self.videomix = videomix
  12. sock = socket.socket()
  13. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  14. sock.bind(('0.0.0.0', 23000))
  15. sock.listen(1)
  16. # register socket for callback inside the GTK-Mainloop
  17. GObject.io_add_watch(sock, GObject.IO_IN, self.listener)
  18. def listener(self, sock, *args):
  19. '''Asynchronous connection listener. Starts a handler for each connection.'''
  20. conn, addr = sock.accept()
  21. self.log.info("Connection from %s", addr)
  22. # register data-received handler inside the GTK-Mainloop
  23. GObject.io_add_watch(conn, GObject.IO_IN, self.handler)
  24. return True
  25. def handler(self, conn, *args):
  26. '''Asynchronous connection handler. Processes each line from the socket.'''
  27. line = conn.recv(4096)
  28. if not len(line):
  29. self.log.debug("Connection closed.")
  30. return False
  31. r = self.processLine(line.decode('utf-8'))
  32. if isinstance(r, str):
  33. conn.send((r+'\n').encode('utf-8'))
  34. return False
  35. conn.send('OK\n'.encode('utf-8'))
  36. return True
  37. def processLine(self, line):
  38. command, argstring = (line.strip()+' ').split(' ', 1)
  39. args = argstring.strip().split()
  40. self.log.info(command % args)
  41. if not hasattr(self.videomix, command):
  42. return 'unknown command {}'.format(command)
  43. f = getattr(self.videomix, command)
  44. if not hasattr(f, 'is_control_server_entrypoint'):
  45. return 'method {} not callable from controlserver'.format(command)
  46. try:
  47. return f(*args)
  48. except Exception as e:
  49. return str(e)