Added black/white lists

This commit is contained in:
Jacob Henry 2018-09-14 01:04:41 -04:00
parent 1bd0f272bb
commit 8b58939ff5
9 changed files with 103 additions and 65 deletions

View File

@ -10,10 +10,8 @@ BOTZONE = "C3BF2MFKM"
NOT_ALLOWED_HERE = "There's a time and place for everything, but not here!"
# Define our patterns
channel_check_pattern = r"channel id\s*(.*)"
# Callback for telling what channel we in
def channel_check_callback(slack, msg, match):
# Sets the users scroll
# with shelve.open(DB_NAME) as db:
@ -27,3 +25,6 @@ def channel_check_callback(slack, msg, match):
response += "Channel id: {}\n".format(msg["channel"])
response += "Escaped message: {}\n".format(rest_of_msg)
slack_util.reply(slack, msg, response)
channel_check_hook = slack_util.Hook(channel_check_callback, pattern=r"channel id\s*(.*)")

View File

@ -5,7 +5,7 @@ msg = {
"type": "message",
"channel": channel_util.COMMAND_CENTER_ID,
"user": "U0Q1PKL92",
"text": "nagjobs tuesday",
"text": "my name",
"ts": "1355517523.000005"
}

View File

@ -10,13 +10,7 @@ import scroll_util
# The following db maps SLACK_USER_ID -> SCROLL_INTEGER
DB_NAME = "user_scrolls"
# Initialize the db
identify_pattern = r"i am (.*)"
identify_other_pattern = r"<@(.*)>\s+has scroll\s+(.*)"
check_pattern = r"my scroll.*"
name_pattern = r"my name.*"
# Initialize the hooks
NON_REG_MSG = ("You currently have no scroll registered. To register, type\n"
"i am 666\n"
"except with your scroll instead of 666")
@ -61,6 +55,7 @@ def identify_other_callback(slack, msg, match):
slack_util.reply(slack, msg, result)
# noinspection PyUnusedLocal
def check_callback(slack, msg, match):
# Tells the user their current scroll
with shelve.open(DB_NAME) as db:
@ -72,6 +67,7 @@ def check_callback(slack, msg, match):
slack_util.reply(slack, msg, result)
# noinspection PyUnusedLocal
def name_callback(slack, msg, match):
# Tells the user what slack thinks their name is
with shelve.open(DB_NAME) as db:
@ -116,3 +112,9 @@ def lookup_brother_userids(brother):
result.append(user_id)
return result
identify_hook = slack_util.Hook(identify_callback, pattern=r"i am (.*)")
identify_other_hook = slack_util.Hook(identify_other_callback, pattern=r"<@(.*)>\s+has scroll\s+(.*)")
check_hook = slack_util.Hook(check_callback, pattern=r"my scroll")
name_hook = slack_util.Hook(name_callback, pattern=r"my name")

View File

@ -4,9 +4,6 @@ import slack_util
import google_api
import channel_util
nag_pattern = r"nagjobs\s*(.*)"
SHEET_ID = "1lPj9GjB00BuIq9GelOWh5GmiGsheLlowPnHLnWBvMOM"
eight_job_range = "House Jobs!A2:C25" # Format: Job Day Bro
fiftythree_job_range = "House Jobs!E2:G6"
@ -48,10 +45,13 @@ def nag_callback(slack, msg, match):
response += "({}) {} -- ".format(job.house, job.job_name)
ids = job.lookup_brother_slack_id()
if ids:
for id in ids:
response += "<@{}> ".format(id)
for slack_id in ids:
response += "<@{}> ".format(slack_id)
else:
response += "{} (scroll missing. Please register for @ pings!)".format(job.brother_name)
response += "\n"
slack_util.reply(slack, msg, response, in_thread=False, to_channel=channel_util.GENERAL)
nag_hook = slack_util.Hook(nag_callback, pattern=r"nagjobs\s*(.*)")

50
main.py
View File

@ -1,15 +1,11 @@
from collections import OrderedDict
import google_api as google # For read drive
from slackclient import SlackClient # Obvious
import slack_util
import scroll_util
import identifier
import re
import channel_util
import identifier
import job_nagger
import management_commands
import scroll_util
import slack_util
from dummy import FakeClient
# Read api token from file
@ -22,39 +18,38 @@ DEBUG_MODE = False
def main():
wrapper = ClientWrapper()
wrap = ClientWrapper()
# DEBUG: Add blanked handling
# wrapper.add_hook(".*", print)
# Add scroll handling
wrapper.add_hook(scroll_util.command_pattern, scroll_util.callback)
wrap.add_hook(scroll_util.scroll_hook)
# Add id handling
wrapper.add_hook(identifier.check_pattern, identifier.check_callback)
wrapper.add_hook(identifier.identify_pattern, identifier.identify_callback)
wrapper.add_hook(identifier.identify_other_pattern, identifier.identify_other_callback)
wrapper.add_hook(identifier.name_pattern, identifier.name_callback)
wrap.add_hook(identifier.check_hook)
wrap.add_hook(identifier.identify_hook)
wrap.add_hook(identifier.identify_other_hook)
wrap.add_hook(identifier.name_hook)
# Added channel utility
wrapper.add_hook(channel_util.channel_check_pattern, channel_util.channel_check_callback)
wrap.add_hook(channel_util.channel_check_hook)
# Add nagging functionality
wrapper.add_hook(job_nagger.nag_pattern, job_nagger.nag_callback)
wrap.add_hook(job_nagger.nag_hook)
# Add kill switch
wrapper.add_hook(management_commands.reboot_pattern, management_commands.reboot_callback)
wrap.add_hook(management_commands.reboot_hook)
# Add help
help_callback = management_commands.list_hooks_callback_gen(wrapper.hooks.keys())
wrapper.add_hook(management_commands.bot_help_pattern, help_callback)
help_callback = management_commands.list_hooks_callback_gen(wrap.hooks)
wrap.add_hook(slack_util.Hook(help_callback, pattern=management_commands.bot_help_pattern))
wrapper.listen()
wrap.listen()
# Callback to list command hooks
class ClientWrapper(object):
def __init__(self):
# Init slack
@ -64,10 +59,10 @@ class ClientWrapper(object):
self.slack = SlackClient(SLACK_API)
# Hooks go regex -> callback on (slack, msg, match)
self.hooks = OrderedDict()
self.hooks = []
def add_hook(self, pattern, callback):
self.hooks[pattern] = callback
def add_hook(self, hook):
self.hooks.append(hook)
def listen(self):
feed = slack_util.message_stream(self.slack)
@ -78,19 +73,16 @@ class ClientWrapper(object):
if msg.get("subtype") is not None:
continue
# Never deal with general
# Never deal with general, EVER!
if msg.get("channel") == channel_util.GENERAL:
continue
# Handle Message
text = msg['text'].strip()
success = False
for regex, callback in self.hooks.items():
match = re.match(regex, text, flags=re.IGNORECASE)
if match:
for hook in self.hooks:
if hook.check(self.slack, msg):
success = True
print("Matched on callback {}".format(callback))
callback(self.slack, msg, match)
break
if not success:

View File

@ -1,23 +1,17 @@
import identifier
import scroll_util
import slack_util
import google_api
import channel_util
bot_help_pattern = r"bot help"
import slack_util
def list_hooks_callback_gen(hook_strings):
def list_hooks_callback_gen(hooks):
# noinspection PyUnusedLocal
def callback(slack, msg, match):
slack_util.reply(slack, msg, "\n".join(hook_strings))
slack_util.reply(slack, msg, "\n".join(hook.pattern for hook in hooks))
return callback
# Gracefully reboot to reload code changes
reboot_pattern = r"reboot"
# noinspection PyUnusedLocal
def reboot_callback(slack, msg, match):
if msg["channel"] != channel_util.COMMAND_CENTER_ID:
response = channel_util.NOT_ALLOWED_HERE
@ -29,3 +23,8 @@ def reboot_callback(slack, msg, match):
slack_util.reply(slack, msg, response)
if reboot:
exit(0)
# Make hooks
bot_help_pattern = r"bot help" # Can't init this directly, as it relies on us knowing all other hooks. handle in main
reboot_hook = slack_util.Hook(reboot_callback, pattern=r"reboot")

View File

@ -7,14 +7,11 @@ import re
from fuzzywuzzy import process
from slack_util import reply
import slack_util
# load the family tree
familyfile = open("sortedfamilytree.txt", 'r')
command_pattern = r"scroll\s+(.*)"
# Parse out
brother_match = re.compile(r"([0-9]*)~(.*)")
brothers = [brother_match.match(line) for line in familyfile]
@ -25,7 +22,7 @@ brothers = [{
} for m in brothers]
def callback(slack, msg, match):
def scroll_callback(slack, msg, match):
# Get the query
query = match.group(1).strip()
@ -41,7 +38,7 @@ def callback(slack, msg, match):
result = "Couldn't find brother {}".format(query)
# Respond
reply(slack, msg, result)
slack_util.reply(slack, msg, result)
def find_by_scroll(scroll):
@ -57,3 +54,6 @@ def find_by_name(name):
# Do fuzzy match
return process.extractOne(name, brothers, processor=lambda b: b["name"])[0]
scroll_hook = slack_util.Hook(scroll_callback, pattern=r"scroll\s+(.*)")

View File

@ -1,4 +1,5 @@
from time import sleep
import re
"""
Slack helpers. Separated for compartmentalization
@ -39,3 +40,46 @@ def message_stream(slack):
sleep(15)
print("Connection failed - retrying")
class Hook(object):
def __init__(self, callback, pattern=None, channel_whitelist=None, channel_blacklist=None):
# Save all
self.pattern = pattern
self.channel_whitelist = channel_whitelist
self.channel_blacklist = channel_blacklist
self.callback = callback
# Remedy some sensible defaults
if self.pattern is None:
self.pattern = ".*"
if self.channel_blacklist is None:
import channel_util
self.channel_blacklist = [channel_util.GENERAL]
elif self.channel_whitelist is None:
pass # We leave as none to show no whitelisting in effect
else:
raise Exception("Cannot whitelist and blacklist")
def check(self, slack, msg):
# Fail if pattern invalid
match = re.match(self.pattern, msg['text'], flags=re.IGNORECASE)
if match is None:
print("Missed pattern")
return False
# Fail if whitelist defined, and we aren't there
if self.channel_whitelist is not None and msg["channel"] not in self.channel_whitelist:
print("Missed whitelist")
return False
# Fail if blacklist defined, and we are there
if self.channel_blacklist is not None and msg["channel"] in self.channel_blacklist:
print("Hit blacklist")
return False
# Otherwise do callback and return success
print("Matched on pattern {} callback {}".format(self.pattern, self.callback))
self.callback(slack, msg, match)
return True

0
slavestothemachine.py Normal file
View File