Re-add spam filtering, improve length marquee limiting

This commit is contained in:
jaseg 2016-01-04 21:14:55 +01:00
parent dfca7a95a3
commit cae13443bc
4 changed files with 87 additions and 65 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
firmware/gcc/*
host/secret_sauce.py

View file

@ -40,7 +40,7 @@ class Font:
textw, texth = c_size_t(0), c_size_t(0)
res = lib.framebuffer_get_text_bounds(textbytes, self.font, byref(textw), byref(texth))
if res:
raise ValueError('Invalid text')
raise RuntimeError('Invalid text')
return textw.value, texth.value
def render_text(self, text, offset):
@ -49,7 +49,7 @@ class Font:
res = lib.framebuffer_render_text(textbytes, self.font, self.cbuf,
config.display_width, config.display_height, offset)
if res:
raise ValueError('Invalid text')
raise RuntimeError('Invalid text')
return self.cbuf
unifont = Font()

View file

@ -44,3 +44,7 @@ crap_fw_addr, crap_fw_port = '127.0.0.1', 1338
# USB Serial number of matelight to control as byte string (None for first matelight connected)
ml_usb_serial_match = None
# Maximum width allowed for marquee texts in px. For reference: Using GNU unifont, a normal (half-width) char such as ∀
# is 8px wide, a full-width char such as 水 is 16px wide.
max_marquee_width = 140*8

View file

@ -4,9 +4,12 @@ import socket
import time
import itertools
import sys
import re
from contextlib import suppress
import asyncio
import threading
import functools
import operator
import config
@ -14,17 +17,26 @@ import matelight
import bdf
import crap
import secret_sauce
def log(*args):
print(time.strftime('\x1B[93m[%m-%d %H:%M:%S]\x1B[0m'), ' '.join(str(arg) for arg in args), '\x1B[0m')
sys.stdout.flush()
def addrcolor(addr):
col = 16 + (functools.reduce(operator.xor, (int(e or '0') for e in re.split('[.:]', addr))) % 216)
return '\x1B[38;5;{}m{}\x1B[0m'.format(col, addr)
class TextRenderer:
def __init__(self, text, title='default', font=bdf.unifont):
def __init__(self, text, title='default', checkwidth=False, font=bdf.unifont):
self.text = text
self.font = font
(self.width, _), _testrender = font.compute_text_bounds(text), font.render_text(text, 0)
self.title = title
if self.width > config.max_marquee_width:
raise ValueError()
def __iter__(self):
for i in range(-config.display_width, self.width):
@ -45,16 +57,21 @@ class MatelightTCPServer:
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))
log('\x1B[95mText from\x1B[0m {}: {}\x1B[0m'.format(addrcolor(addr), line))
try:
self.renderqueue.append(TextRenderer(line, title='tcp:'+addr))
except:
secret_sauce.check_spam(str(addr), line)
renderer = TextRenderer(line, title='tcp:'+addr, checkwidth=True)
except secret_sauce.SpamError as err:
log('\x1B[91mMessage rejected from {}: {}'.format(addrcolor(addr), err))
writer.write(b'BLERGH!\n')
except ValueError: # Text too long
writer.write(b'TOO MUCH INFORMATION!\n')
except RuntimeError: # Invalid escape etc.
writer.write(b'STAHPTROLLINK?\n')
else:
self.renderqueue.append(renderer)
writer.write(b'KTHXBYE!\n')
await writer.drain()
writer.close()