Added black/white lists
This commit is contained in:
parent
1bd0f272bb
commit
8b58939ff5
|
|
@ -10,10 +10,8 @@ BOTZONE = "C3BF2MFKM"
|
||||||
|
|
||||||
NOT_ALLOWED_HERE = "There's a time and place for everything, but not here!"
|
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):
|
def channel_check_callback(slack, msg, match):
|
||||||
# Sets the users scroll
|
# Sets the users scroll
|
||||||
# with shelve.open(DB_NAME) as db:
|
# 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 += "Channel id: {}\n".format(msg["channel"])
|
||||||
response += "Escaped message: {}\n".format(rest_of_msg)
|
response += "Escaped message: {}\n".format(rest_of_msg)
|
||||||
slack_util.reply(slack, msg, response)
|
slack_util.reply(slack, msg, response)
|
||||||
|
|
||||||
|
|
||||||
|
channel_check_hook = slack_util.Hook(channel_check_callback, pattern=r"channel id\s*(.*)")
|
||||||
|
|
|
||||||
2
dummy.py
2
dummy.py
|
|
@ -5,7 +5,7 @@ msg = {
|
||||||
"type": "message",
|
"type": "message",
|
||||||
"channel": channel_util.COMMAND_CENTER_ID,
|
"channel": channel_util.COMMAND_CENTER_ID,
|
||||||
"user": "U0Q1PKL92",
|
"user": "U0Q1PKL92",
|
||||||
"text": "nagjobs tuesday",
|
"text": "my name",
|
||||||
"ts": "1355517523.000005"
|
"ts": "1355517523.000005"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,7 @@ import scroll_util
|
||||||
# The following db maps SLACK_USER_ID -> SCROLL_INTEGER
|
# The following db maps SLACK_USER_ID -> SCROLL_INTEGER
|
||||||
DB_NAME = "user_scrolls"
|
DB_NAME = "user_scrolls"
|
||||||
|
|
||||||
# Initialize the db
|
# Initialize the hooks
|
||||||
identify_pattern = r"i am (.*)"
|
|
||||||
identify_other_pattern = r"<@(.*)>\s+has scroll\s+(.*)"
|
|
||||||
check_pattern = r"my scroll.*"
|
|
||||||
name_pattern = r"my name.*"
|
|
||||||
|
|
||||||
|
|
||||||
NON_REG_MSG = ("You currently have no scroll registered. To register, type\n"
|
NON_REG_MSG = ("You currently have no scroll registered. To register, type\n"
|
||||||
"i am 666\n"
|
"i am 666\n"
|
||||||
"except with your scroll instead of 666")
|
"except with your scroll instead of 666")
|
||||||
|
|
@ -61,6 +55,7 @@ def identify_other_callback(slack, msg, match):
|
||||||
slack_util.reply(slack, msg, result)
|
slack_util.reply(slack, msg, result)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def check_callback(slack, msg, match):
|
def check_callback(slack, msg, match):
|
||||||
# Tells the user their current scroll
|
# Tells the user their current scroll
|
||||||
with shelve.open(DB_NAME) as db:
|
with shelve.open(DB_NAME) as db:
|
||||||
|
|
@ -72,6 +67,7 @@ def check_callback(slack, msg, match):
|
||||||
slack_util.reply(slack, msg, result)
|
slack_util.reply(slack, msg, result)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def name_callback(slack, msg, match):
|
def name_callback(slack, msg, match):
|
||||||
# Tells the user what slack thinks their name is
|
# Tells the user what slack thinks their name is
|
||||||
with shelve.open(DB_NAME) as db:
|
with shelve.open(DB_NAME) as db:
|
||||||
|
|
@ -116,3 +112,9 @@ def lookup_brother_userids(brother):
|
||||||
result.append(user_id)
|
result.append(user_id)
|
||||||
|
|
||||||
return result
|
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")
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ import slack_util
|
||||||
import google_api
|
import google_api
|
||||||
import channel_util
|
import channel_util
|
||||||
|
|
||||||
nag_pattern = r"nagjobs\s*(.*)"
|
|
||||||
|
|
||||||
|
|
||||||
SHEET_ID = "1lPj9GjB00BuIq9GelOWh5GmiGsheLlowPnHLnWBvMOM"
|
SHEET_ID = "1lPj9GjB00BuIq9GelOWh5GmiGsheLlowPnHLnWBvMOM"
|
||||||
eight_job_range = "House Jobs!A2:C25" # Format: Job Day Bro
|
eight_job_range = "House Jobs!A2:C25" # Format: Job Day Bro
|
||||||
fiftythree_job_range = "House Jobs!E2:G6"
|
fiftythree_job_range = "House Jobs!E2:G6"
|
||||||
|
|
@ -48,10 +45,13 @@ def nag_callback(slack, msg, match):
|
||||||
response += "({}) {} -- ".format(job.house, job.job_name)
|
response += "({}) {} -- ".format(job.house, job.job_name)
|
||||||
ids = job.lookup_brother_slack_id()
|
ids = job.lookup_brother_slack_id()
|
||||||
if ids:
|
if ids:
|
||||||
for id in ids:
|
for slack_id in ids:
|
||||||
response += "<@{}> ".format(id)
|
response += "<@{}> ".format(slack_id)
|
||||||
else:
|
else:
|
||||||
response += "{} (scroll missing. Please register for @ pings!)".format(job.brother_name)
|
response += "{} (scroll missing. Please register for @ pings!)".format(job.brother_name)
|
||||||
response += "\n"
|
response += "\n"
|
||||||
|
|
||||||
slack_util.reply(slack, msg, response, in_thread=False, to_channel=channel_util.GENERAL)
|
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
50
main.py
|
|
@ -1,15 +1,11 @@
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
import google_api as google # For read drive
|
|
||||||
from slackclient import SlackClient # Obvious
|
from slackclient import SlackClient # Obvious
|
||||||
import slack_util
|
|
||||||
|
|
||||||
import scroll_util
|
|
||||||
import identifier
|
|
||||||
import re
|
|
||||||
import channel_util
|
import channel_util
|
||||||
|
import identifier
|
||||||
import job_nagger
|
import job_nagger
|
||||||
import management_commands
|
import management_commands
|
||||||
|
import scroll_util
|
||||||
|
import slack_util
|
||||||
from dummy import FakeClient
|
from dummy import FakeClient
|
||||||
|
|
||||||
# Read api token from file
|
# Read api token from file
|
||||||
|
|
@ -22,39 +18,38 @@ DEBUG_MODE = False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
wrapper = ClientWrapper()
|
wrap = ClientWrapper()
|
||||||
|
|
||||||
# DEBUG: Add blanked handling
|
# DEBUG: Add blanked handling
|
||||||
# wrapper.add_hook(".*", print)
|
# wrapper.add_hook(".*", print)
|
||||||
|
|
||||||
# Add scroll handling
|
# Add scroll handling
|
||||||
wrapper.add_hook(scroll_util.command_pattern, scroll_util.callback)
|
wrap.add_hook(scroll_util.scroll_hook)
|
||||||
|
|
||||||
# Add id handling
|
# Add id handling
|
||||||
wrapper.add_hook(identifier.check_pattern, identifier.check_callback)
|
wrap.add_hook(identifier.check_hook)
|
||||||
wrapper.add_hook(identifier.identify_pattern, identifier.identify_callback)
|
wrap.add_hook(identifier.identify_hook)
|
||||||
wrapper.add_hook(identifier.identify_other_pattern, identifier.identify_other_callback)
|
wrap.add_hook(identifier.identify_other_hook)
|
||||||
wrapper.add_hook(identifier.name_pattern, identifier.name_callback)
|
wrap.add_hook(identifier.name_hook)
|
||||||
|
|
||||||
# Added channel utility
|
# 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
|
# Add nagging functionality
|
||||||
wrapper.add_hook(job_nagger.nag_pattern, job_nagger.nag_callback)
|
wrap.add_hook(job_nagger.nag_hook)
|
||||||
|
|
||||||
# Add kill switch
|
# Add kill switch
|
||||||
wrapper.add_hook(management_commands.reboot_pattern, management_commands.reboot_callback)
|
wrap.add_hook(management_commands.reboot_hook)
|
||||||
|
|
||||||
# Add help
|
# Add help
|
||||||
help_callback = management_commands.list_hooks_callback_gen(wrapper.hooks.keys())
|
help_callback = management_commands.list_hooks_callback_gen(wrap.hooks)
|
||||||
wrapper.add_hook(management_commands.bot_help_pattern, help_callback)
|
wrap.add_hook(slack_util.Hook(help_callback, pattern=management_commands.bot_help_pattern))
|
||||||
|
|
||||||
wrapper.listen()
|
wrap.listen()
|
||||||
|
|
||||||
|
|
||||||
# Callback to list command hooks
|
# Callback to list command hooks
|
||||||
|
|
||||||
|
|
||||||
class ClientWrapper(object):
|
class ClientWrapper(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Init slack
|
# Init slack
|
||||||
|
|
@ -64,10 +59,10 @@ class ClientWrapper(object):
|
||||||
self.slack = SlackClient(SLACK_API)
|
self.slack = SlackClient(SLACK_API)
|
||||||
|
|
||||||
# Hooks go regex -> callback on (slack, msg, match)
|
# Hooks go regex -> callback on (slack, msg, match)
|
||||||
self.hooks = OrderedDict()
|
self.hooks = []
|
||||||
|
|
||||||
def add_hook(self, pattern, callback):
|
def add_hook(self, hook):
|
||||||
self.hooks[pattern] = callback
|
self.hooks.append(hook)
|
||||||
|
|
||||||
def listen(self):
|
def listen(self):
|
||||||
feed = slack_util.message_stream(self.slack)
|
feed = slack_util.message_stream(self.slack)
|
||||||
|
|
@ -78,19 +73,16 @@ class ClientWrapper(object):
|
||||||
if msg.get("subtype") is not None:
|
if msg.get("subtype") is not None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Never deal with general
|
# Never deal with general, EVER!
|
||||||
if msg.get("channel") == channel_util.GENERAL:
|
if msg.get("channel") == channel_util.GENERAL:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Handle Message
|
# Handle Message
|
||||||
text = msg['text'].strip()
|
text = msg['text'].strip()
|
||||||
success = False
|
success = False
|
||||||
for regex, callback in self.hooks.items():
|
for hook in self.hooks:
|
||||||
match = re.match(regex, text, flags=re.IGNORECASE)
|
if hook.check(self.slack, msg):
|
||||||
if match:
|
|
||||||
success = True
|
success = True
|
||||||
print("Matched on callback {}".format(callback))
|
|
||||||
callback(self.slack, msg, match)
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,17 @@
|
||||||
import identifier
|
|
||||||
import scroll_util
|
|
||||||
import slack_util
|
|
||||||
import google_api
|
|
||||||
import channel_util
|
import channel_util
|
||||||
|
import slack_util
|
||||||
bot_help_pattern = r"bot help"
|
|
||||||
|
|
||||||
|
|
||||||
def list_hooks_callback_gen(hook_strings):
|
def list_hooks_callback_gen(hooks):
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def callback(slack, msg, match):
|
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
|
return callback
|
||||||
|
|
||||||
|
|
||||||
# Gracefully reboot to reload code changes
|
# Gracefully reboot to reload code changes
|
||||||
reboot_pattern = r"reboot"
|
# noinspection PyUnusedLocal
|
||||||
|
|
||||||
|
|
||||||
def reboot_callback(slack, msg, match):
|
def reboot_callback(slack, msg, match):
|
||||||
if msg["channel"] != channel_util.COMMAND_CENTER_ID:
|
if msg["channel"] != channel_util.COMMAND_CENTER_ID:
|
||||||
response = channel_util.NOT_ALLOWED_HERE
|
response = channel_util.NOT_ALLOWED_HERE
|
||||||
|
|
@ -29,3 +23,8 @@ def reboot_callback(slack, msg, match):
|
||||||
slack_util.reply(slack, msg, response)
|
slack_util.reply(slack, msg, response)
|
||||||
if reboot:
|
if reboot:
|
||||||
exit(0)
|
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")
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,11 @@ import re
|
||||||
|
|
||||||
from fuzzywuzzy import process
|
from fuzzywuzzy import process
|
||||||
|
|
||||||
from slack_util import reply
|
import slack_util
|
||||||
|
|
||||||
# load the family tree
|
# load the family tree
|
||||||
familyfile = open("sortedfamilytree.txt", 'r')
|
familyfile = open("sortedfamilytree.txt", 'r')
|
||||||
|
|
||||||
|
|
||||||
command_pattern = r"scroll\s+(.*)"
|
|
||||||
|
|
||||||
# Parse out
|
# Parse out
|
||||||
brother_match = re.compile(r"([0-9]*)~(.*)")
|
brother_match = re.compile(r"([0-9]*)~(.*)")
|
||||||
brothers = [brother_match.match(line) for line in familyfile]
|
brothers = [brother_match.match(line) for line in familyfile]
|
||||||
|
|
@ -25,7 +22,7 @@ brothers = [{
|
||||||
} for m in brothers]
|
} for m in brothers]
|
||||||
|
|
||||||
|
|
||||||
def callback(slack, msg, match):
|
def scroll_callback(slack, msg, match):
|
||||||
# Get the query
|
# Get the query
|
||||||
query = match.group(1).strip()
|
query = match.group(1).strip()
|
||||||
|
|
||||||
|
|
@ -41,7 +38,7 @@ def callback(slack, msg, match):
|
||||||
result = "Couldn't find brother {}".format(query)
|
result = "Couldn't find brother {}".format(query)
|
||||||
|
|
||||||
# Respond
|
# Respond
|
||||||
reply(slack, msg, result)
|
slack_util.reply(slack, msg, result)
|
||||||
|
|
||||||
|
|
||||||
def find_by_scroll(scroll):
|
def find_by_scroll(scroll):
|
||||||
|
|
@ -57,3 +54,6 @@ def find_by_name(name):
|
||||||
|
|
||||||
# Do fuzzy match
|
# Do fuzzy match
|
||||||
return process.extractOne(name, brothers, processor=lambda b: b["name"])[0]
|
return process.extractOne(name, brothers, processor=lambda b: b["name"])[0]
|
||||||
|
|
||||||
|
|
||||||
|
scroll_hook = slack_util.Hook(scroll_callback, pattern=r"scroll\s+(.*)")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
import re
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Slack helpers. Separated for compartmentalization
|
Slack helpers. Separated for compartmentalization
|
||||||
|
|
@ -39,3 +40,46 @@ def message_stream(slack):
|
||||||
|
|
||||||
sleep(15)
|
sleep(15)
|
||||||
print("Connection failed - retrying")
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue