diff options
author | jaseg <code@jaseg.net> | 2016-01-24 18:34:03 +0100 |
---|---|---|
committer | jaseg <code@jaseg.net> | 2016-01-24 18:40:10 +0100 |
commit | 6afe84d34afa76071f45b0eb9ca4d1f5cd0417c1 (patch) | |
tree | 6cf1c087f68859c8ccda9f3d0a24cbc97f58216e | |
parent | 96ce1aeef68f0cad397bea43b82eff1a5e407c2c (diff) | |
download | matelight-6afe84d34afa76071f45b0eb9ca4d1f5cd0417c1.tar.gz matelight-6afe84d34afa76071f45b0eb9ca4d1f5cd0417c1.tar.bz2 matelight-6afe84d34afa76071f45b0eb9ca4d1f5cd0417c1.zip |
README: Add crate layout guide
-rw-r--r-- | README.rst | 13 | ||||
-rw-r--r-- | host/secret_sauce.py | 51 |
2 files changed, 62 insertions, 2 deletions
@@ -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) |