Add queueing and rendering util
This commit is contained in:
parent
7622cc99ca
commit
16677fac94
2 changed files with 131 additions and 1 deletions
|
|
@ -6,7 +6,7 @@ async def migrate(conn):
|
|||
moderated INTEGER,
|
||||
remote_ip TEXT,
|
||||
timestamp_received TEXT DEFAULT (datetime('now')),
|
||||
timestamp_displayed TEXT DEFAULT NULL
|
||||
timestamp_displayed TEXT DEFAULT NULL,
|
||||
)''')
|
||||
|
||||
await conn.execute('''CREATE TABLE IF NOT EXISTS shitlist (
|
||||
|
|
|
|||
130
queue.py
Normal file
130
queue.py
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import math
|
||||
import time
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
|
||||
import serial
|
||||
import click
|
||||
|
||||
seg_map = {
|
||||
" ": 0x00,
|
||||
"a": 0x2e,
|
||||
"b": 0xd6,
|
||||
"c": 0xd0,
|
||||
"d": 0xc5,
|
||||
"e": 0x59,
|
||||
"f": 0x98,
|
||||
"g": 0xd4,
|
||||
"h": 0x8c,
|
||||
"i": 0x5c,
|
||||
"j": 0x78,
|
||||
"k": 0x8e,
|
||||
"l": 0xc0,
|
||||
"m": 0xa3,
|
||||
"n": 0xa5,
|
||||
"o": 0xf0,
|
||||
"p": 0x93,
|
||||
"q": 0xf4,
|
||||
"r": 0x9e,
|
||||
"s": 0x55,
|
||||
"t": 0xc8,
|
||||
"u": 0xe0,
|
||||
"v": 0x8a,
|
||||
"w": 0xac,
|
||||
"x": 0x0f,
|
||||
"y": 0x0b,
|
||||
"z": 0x5a,
|
||||
"0": 0x13,
|
||||
"1": 0x20,
|
||||
"2": 0x16,
|
||||
"3": 0x56,
|
||||
"4": 0x23,
|
||||
"5": 0x1c,
|
||||
"6": 0x4e,
|
||||
"7": 0x1a,
|
||||
"8": 0x5f,
|
||||
"9": 0x33,
|
||||
"/": 0x0a,
|
||||
"\\": 0x05,
|
||||
".": 0x04,
|
||||
",": 0x08,
|
||||
"_": 0x40,
|
||||
"!": 0x53,
|
||||
"?": 0x52,
|
||||
"*": 0x0f,
|
||||
":": 0x50,
|
||||
"(": 0x06,
|
||||
"<": 0x06,
|
||||
"[": 0xd0,
|
||||
")": 0x09,
|
||||
">": 0x09,
|
||||
"]": 0x70,
|
||||
"|": 0x20,
|
||||
"#": 0xff,
|
||||
}
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('-b', '--baudrate', type=int, default=9600)
|
||||
@click.option('-w', '--display-width', type=int, default=32)
|
||||
@click.option('-i', '--message-interval', type=float, default=30)
|
||||
@click.argument('database')
|
||||
@click.argument('port')
|
||||
def cli(database, port, baudrate, message_interval, display_width):
|
||||
db = sqlite3.connect(database)
|
||||
ser = serial.Serial(port, baudrate)
|
||||
|
||||
discard = 0
|
||||
while True:
|
||||
count, = db.execute('''
|
||||
SELECT COUNT(*) FROM messages
|
||||
WHERE suppress_display = 0 AND timestamp_displayed IS NULL
|
||||
ORDER BY timestamp_received''').fetchone()
|
||||
|
||||
if count == 0:
|
||||
print(f'Queue is empty. Sleeping.')
|
||||
time.sleep(1)
|
||||
continue
|
||||
|
||||
queue_pressure = max(0, min((math.log10(max(1, count-3)) - 0.3) * message_interval*2/3, message_interval*1/3))
|
||||
interval = message_interval - queue_pressure
|
||||
|
||||
rowid, message, timestamp, remote_ip, suppress_display = db.execute('''
|
||||
SELECT rowid, message, timestamp_received, remote_ip, suppress_display FROM messages
|
||||
WHERE timestamp_displayed IS NULL
|
||||
ORDER BY timestamp_received LIMIT 1
|
||||
''').fetchone()
|
||||
timestamp = datetime.fromisoformat(timestamp)
|
||||
delta = (datetime.utcnow() - timestamp).total_seconds()
|
||||
|
||||
db.execute('UPDATE messages SET timestamp_displayed = datetime("now") WHERE rowid=?', (rowid,))
|
||||
db.commit()
|
||||
|
||||
if suppress_display:
|
||||
discard += 1
|
||||
|
||||
else:
|
||||
if discard > 0:
|
||||
print(f'Discarded {discard} messages.')
|
||||
discard = 0
|
||||
|
||||
print(f'Queueing message by {remote_ip} received at {timestamp} ({delta//60:.0f}m {delta%60:.0f}s ago):')
|
||||
print(' ', repr(message))
|
||||
|
||||
lines = [ line for line in message.splitlines() if line.strip() ]
|
||||
interval = max(5, interval/len(lines))
|
||||
for i, line in enumerate(lines):
|
||||
print(f' [Line {i+1}/{len(lines)}] Waiting interval of {message_interval:.1f} s with queue pressure {queue_pressure:.1f} from n={count} items for a total of {interval:.1f} s')
|
||||
|
||||
line = line.center(display_width)[:display_width]
|
||||
line_mapped = [seg_map.get(c, seg_map['#']) for c in line]
|
||||
formatted = ''.join(f'{d:02x}' for d in line_mapped) + '\n'
|
||||
time.sleep(interval)
|
||||
ser.write(formatted)
|
||||
ser.flush()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
Loading…
Add table
Add a link
Reference in a new issue