From 6afe84d34afa76071f45b0eb9ca4d1f5cd0417c1 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 24 Jan 2016 18:34:03 +0100 Subject: README: Add crate layout guide --- README.rst | 13 ++++++++++++- host/secret_sauce.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f0a5269..6b3caac 100644 --- a/README.rst +++ b/README.rst @@ -27,7 +27,18 @@ Each bottle contains a LED with a WS2801 driver. Each crate contains a chain of 2. Poke a 12mm hole in the lid 3. Put it in a crate 4. Repeat from step 1 -5. Stick a loop of LEDs through the lids of the bottles +5. Stick a loop of LEDs through the lids of the bottles like this: + .. code:: + ┏━━━┯━━━┯━━━┯━━━┯━━━┓ + {start}→┃ ○ → ○ → ○ → ○ → ○ ┃ + ┠───┼───┼───┼───┼─↓─┨ + { end}←┃ ○ │ ○ ← ○ ← ○ ← ○ ┃ + ┠─↑─┼─↓─┼───┼───┼───┨ + ┃ ○ │ ○ → ○ → ○ → ○ ┃ + ┠─↑─┼───┼───┼───┼─↓─┨ + ┃ ○ ← ○ ← ○ ← ○ ← ○ ┃ + ┗━━━┷━━━┷━━━┷━━━┷━━━┛ + 6. Repeat from step 1 7. Stack up a bunch of these crates and tie them together with zip ties and straps 8. Connect all the wires together (mis-)using wonderful XLR connectors diff --git a/host/secret_sauce.py b/host/secret_sauce.py index bf183ac..3682b0e 100644 --- a/host/secret_sauce.py +++ b/host/secret_sauce.py @@ -1,7 +1,56 @@ +from collections import defaultdict +import signal + + +RATELIMIT_THRESHOLD = 20 +GRAYLIST_LENGTH = 8 + class SpamError(ValueError): def __str__(self): return ' '.join(self.args) + +def loadlist(fn): + try: + with open(fn) as f: + return [ l for l in ( l.strip() for l in f.readlines() if not l.startswith('#')) if l ] + except: + return [] + +greenlist = set() + +graylist = [] +def do_graylist(msg): + global graylist + graylist = [msg] + graylist[:GRAYLIST_LENGTH-1] + +blacklist = loadlist('blacklist') +badwords = loadlist('badwords') +def signal_handler(_signum, _frame): + global blacklist, badwords + blacklist = load_blacklist() + badwords = load_badwords() +signal.signal(signal.SIGHUP, signal_handler) + +ratelimitdict = defaultdict(lambda: 0) +def empty_ratelimit(_signum, _frame): + global ratelimitdict + ratelimitdict = defaultdict(lambda: 0) +signal.signal(signal.SIGALRM, empty_ratelimit) +signal.setitimer(signal.ITIMER_REAL, 60) + def check_spam(addr, data): - pass + ratelimitdict[addr] += 1 + try: + if ratelimitdict[addr] > RATELIMIT_THRESHOLD: + raise SpamError('rate-limit') + if any(word in data.lower() for word in badwords): + raise SpamError('badwords filter') + if addr not in greenlist and data in graylist: + raise SpamError('graylist') + except SpamError as err: + do_graylist(data) + blacklist.append(addr) + raise err + greenlist.add(addr) -- cgit