aboutsummaryrefslogtreecommitdiff
path: root/host/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'host/server.py')
-rwxr-xr-xhost/server.py89
1 files changed, 52 insertions, 37 deletions
diff --git a/host/server.py b/host/server.py
index 3ce1bdc..f83e2cd 100755
--- a/host/server.py
+++ b/host/server.py
@@ -1,12 +1,14 @@
#!/usr/bin/env python
import socket
-from time import strftime
+import time
import itertools
import sys
from contextlib import suppress
+import asyncio
+import threading
-from config import *
+import config
import matelight
import bdf
@@ -14,48 +16,48 @@ import crap
def log(*args):
- print(strftime('\x1B[93m[%m-%d %H:%M:%S]\x1B[0m'), ' '.join(str(arg) for arg in args), '\x1B[0m')
+ print(time.strftime('\x1B[93m[%m-%d %H:%M:%S]\x1B[0m'), ' '.join(str(arg) for arg in args), '\x1B[0m')
sys.stdout.flush()
class TextRenderer:
- def __init__(self, text):
+ def __init__(self, text, title='default', font=bdf.unifont):
self.text = text
- self.width, _ = unifont.compute_text_bounds(text)
+ self.font = font
+ (self.width, _), _testrender = font.compute_text_bounds(text), font.render_text(text, 0)
+ self.title = title
def __iter__(self):
- for i in range(-DISPLAY_WIDTH, self.width):
- yield render_text(self.text, i)
+ for i in range(-config.display_width, self.width):
+ yield self.title, self.font.render_text(self.text, i)
+ time.sleep(0.05)
class MatelightTCPServer:
- def __init__(self, port, ip):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.sock.setblocking(blocking)
- self.sock.bind((ip, port))
- self.conns = set()
+ def __init__(self, ip, port, loop):
+ coro = asyncio.start_server(self.handle_conn, ip, port, loop=loop)
+ server = loop.run_until_complete(coro)
self.renderqueue = []
+ self.close = server.close
def __iter__(self):
q, self.renderqueue = self.renderqueue, []
- for frame in itertools.chain(*q):
- yield frame
+ for title, frame in itertools.chain(*q):
+ yield title, frame
- def handle_connections(self):
- for conn in self.conns:
+ async def handle_conn(self, reader, writer):
+ line = (await reader.read(1024)).decode('UTF-8').strip()
+ if len(line) > 140: # Unicode string length, *not* byte length of encoded UTF-8
+ writer.write(b'TOO MUCH INFORMATION!\n')
+ else:
+ addr,*rest = writer.get_extra_info('peername')
+ log('\x1B[95mText from\x1B[0m {}: {}\x1B[0m'.format(addr, line))
try:
- line = conn.recv(1024).decode('UTF-8').strip()
- if len(data) > 140: # Unicode string length, *not* byte length of encoded UTF-8
- conn.sendall(b'TOO MUCH INFORMATION!\n')
- else:
- log('\x1B[95mText from\x1B[0m {}: {}\x1B[0m'.format(addr, data))
- renderqueue.append(TextRenderer(data))
- conn.sendall(b'KTHXBYE!\n')
- except socket.error, e:
- if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
- continue
- with suppress(socket.error):
- conn.close()
- self.conns.remove(conn)
+ self.renderqueue.append(TextRenderer(line, title='tcp:'+addr))
+ except:
+ writer.write(b'STAHPTROLLINK?\n')
+ else:
+ writer.write(b'KTHXBYE!\n')
+ await writer.drain()
+ writer.close()
def _fallbackiter(it, fallback):
for fel in fallback:
@@ -63,19 +65,32 @@ def _fallbackiter(it, fallback):
yield el
yield fel
+def defaulttexts(filename='default.lines'):
+ with open(filename) as f:
+ return itertools.chain.from_iterable(( TextRenderer(l[:-1].replace('\\x1B', '\x1B')) for l in f.readlines() ))
+
if __name__ == '__main__':
- tcp_server = MatelightTCPServer(config.tcp_addr, config.tcp_port)
+ try:
+ ml = matelight.Matelight(config.ml_usb_serial_match)
+ except ValueError as e:
+ print(e, 'Starting in headless mode.', file=sys.stderr)
+ ml = None
+
+ loop = asyncio.get_event_loop()
+
+ tcp_server = MatelightTCPServer(config.tcp_addr, config.tcp_port, loop)
udp_server = crap.CRAPServer(config.udp_addr, config.udp_port)
forwarder = crap.CRAPClient(config.crap_fw_addr, config.crap_fw_port) if config.crap_fw_addr is not None else None
- def defaulttexts(filename='default.lines'):
- with open(filename) as f:
- return itertools.chain.from_iterable(( TextRenderer(l[:-1].replace('\\x1B', '\x1B')) for l in f.readlines() ))
+ async_thr = threading.Thread(target=loop.run_forever)
+ async_thr.daemon = True
+ async_thr.start()
with suppress(KeyboardInterrupt):
- for renderer in _fallbackiter(tcp_server, defaulttexts()):
- for frame in _fallbackiter(udp_server, renderer):
- matelight.sendframe(frame)
+ while True:
+ for title, frame in _fallbackiter(udp_server, _fallbackiter(tcp_server, defaulttexts())):
+ if ml:
+ ml.sendframe(frame)
if forwarder:
forwarder.sendframe(frame)