From 2e7a201d6606f95ca2644958a515c926591b0285 Mon Sep 17 00:00:00 2001 From: Jacob Henry Date: Sun, 9 Sep 2018 14:22:59 -0400 Subject: [PATCH] Big improves --- .gitignore | 6 ++- identifier.py | 118 +++++++++++++++++++++++++++++++++++++++++++ job_nagger.py | 27 ++++++++++ main.py | 18 +++++-- scroll_util.py | 9 ++-- slack_util.py | 7 ++- sortedfamilytree.txt | 2 +- 7 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 identifier.py create mode 100644 job_nagger.py diff --git a/.gitignore b/.gitignore index 606e8e4..1bdccaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ apitoken.txt killswitch.txt -client_secret.json +sheets_credentials.json +token.json +*.bak +*.dat +*.dir *.pyc *.swp diff --git a/identifier.py b/identifier.py new file mode 100644 index 0000000..d73f822 --- /dev/null +++ b/identifier.py @@ -0,0 +1,118 @@ +""" +Allows users to register their user account as a specific scroll +""" + +import shelve + +import slack_util +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.*" + + +NON_REG_MSG = ("You currently have no scroll registered. To register, type\n" + "i am 666\n" + "except with your scroll instead of 666") + + +def identify_callback(slack, msg, match): + # Sets the users scroll + with shelve.open(DB_NAME) as db: + # Get the query + query = match.group(1).strip() + + try: + user = msg.get("user") + scroll = int(query) + db[user] = scroll + result = "Updated user {} to have scroll {}".format(user, scroll) + except ValueError: + result = "Bad scroll: {}".format(query) + + # Respond + slack_util.reply(slack, msg, result) + + +def identify_other_callback(slack, msg, match): + # Sets the users scroll + with shelve.open(DB_NAME) as db: + # Get the query + user = match.group(1).strip() + scroll_txt = match.group(2).strip() + + try: + scroll = int(scroll_txt) + if user in db: + result = "To prevent trolling, once a users id has been set only they can change it" + else: + db[user] = scroll + result = "Updated user {} to have scroll {}".format(user, scroll) + except ValueError: + result = "Bad scroll: {}".format(scroll_txt) + + # Respond + slack_util.reply(slack, msg, result) + + +def check_callback(slack, msg, match): + # Tells the user their current scroll + with shelve.open(DB_NAME) as db: + try: + scroll = db[msg.get("user")] + result = "You are currently registered with scroll {}".format(scroll) + except KeyError: + result = NON_REG_MSG + slack_util.reply(slack, msg, result) + + +def name_callback(slack, msg, match): + # Tells the user what slack thinks their name is + with shelve.open(DB_NAME) as db: + try: + scroll = db[msg.get("user")] + brother = scroll_util.find_by_scroll(scroll) + if brother: + result = "The bot thinks your name is {}".format(brother["name"]) + else: + result = "The bot couldn't find a name for scroll {}".format(scroll) + except ValueError: + result = NON_REG_MSG + + # Respond + slack_util.reply(slack, msg, result) + + +def lookup_msg_brother(msg): + """ + Finds the real-world name of whoever posted msg. + :return: brother dict or None + """ + with shelve.open(DB_NAME) as db: + try: + scroll = db[msg.get("user")] + return scroll_util.find_by_scroll(scroll) + except ValueError: + return None + + +def lookup_brother_userids(brother): + """ + Returns a list of all userids associated with the given brother. + :param brother: Std brother dict as specc'd in scroll_util + :return: List of user id strings (may be empty) + """ + with shelve.open(DB_NAME) as db: + keys = db.keys() + result = [] + for user_id in keys: + if db[user_id] == brother["scroll"]: + result.append(user_id) + + return result diff --git a/job_nagger.py b/job_nagger.py new file mode 100644 index 0000000..3a76fcb --- /dev/null +++ b/job_nagger.py @@ -0,0 +1,27 @@ +import identifier +import scroll_util +import slack_util + +nag_pattern = r"nag (.*)" + + +def nag_callback(slack, msg, match): + # Get who we want to nag + name = match.group(1) + + # Find them using scroll shit + brother = scroll_util.find_by_name(name) + + # Get the associated user ids + ids = identifier.lookup_brother_userids(brother) + + # Nag them each + if ids: + result = "Hey" + for user_id in ids: + result += " <@{}>".format(user_id) + result += "!" + else: + result = "Nobody has identified themselves as {} ({})... Sad!".format(brother["name"], brother["scroll"]) + + slack_util.reply(slack, msg, result, in_thread=False) diff --git a/main.py b/main.py index 720f072..8ee447e 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,9 @@ from slackclient import SlackClient # Obvious from slack_util import * import scroll_util +import identifier import re +import job_nagger # Read api token from file api_file = open("apitoken.txt", 'r') @@ -17,11 +19,6 @@ kill_switch_file = open("killswitch.txt", 'r') kill_switch = next(kill_switch_file).strip() kill_switch_file.close() -# Authenticate, get sheets service. Done globally so we dont have to do this -# every fucking time, which is probably a bad idea -sheet_credentials = google.get_sheets_credentials() -sheet_service = google._init_sheets_service(sheet_credentials) - def main(): wrapper = ClientWrapper() @@ -32,6 +29,15 @@ def main(): # Add scroll handling wrapper.add_hook(scroll_util.command_pattern, scroll_util.callback) + # 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) + + # Add test nagging functionality + wrapper.add_hook(job_nagger.nag_pattern, job_nagger.nag_callback) + # Add kill switch wrapper.add_hook(kill_switch, die) @@ -58,6 +64,8 @@ class ClientWrapper(object): def listen(self): feed = message_stream(self._slack) for msg in feed: + print(msg) + # We only care about standard messages, not subtypes, as those usually just channel activity if msg.get("subtype"): continue diff --git a/scroll_util.py b/scroll_util.py index 9008f31..69be0d7 100644 --- a/scroll_util.py +++ b/scroll_util.py @@ -4,10 +4,11 @@ Only really kept separate for neatness sake. """ import re -from slack_util import reply -from fuzzywuzzy import fuzz + from fuzzywuzzy import process +from slack_util import reply + # load the family tree familyfile = open("sortedfamilytree.txt", 'r') @@ -23,10 +24,6 @@ brothers = [{ "name": m.group(2) } for m in brothers] -""" -Attempts to look up a user by scroll -""" - def callback(slack, msg, match): # Get the query diff --git a/slack_util.py b/slack_util.py index 7dead1a..f528cab 100644 --- a/slack_util.py +++ b/slack_util.py @@ -5,13 +5,16 @@ Slack helpers. Separated for compartmentalization """ -def reply(slack, msg, text): +def reply(slack, msg, text, in_thread=True): """ Sends message with "text" as its content to the channel that message came from """ channel = msg['channel'] thread_id = msg['ts'] - slack.rtm_send_message(channel=channel, message=text, thread=thread_id) + if in_thread: + slack.rtm_send_message(channel=channel, message=text, thread=thread_id) + else: + slack.rtm_send_message(channel=channel, message=text) def message_stream(slack): diff --git a/sortedfamilytree.txt b/sortedfamilytree.txt index 2aa3ff7..4a3e894 100644 --- a/sortedfamilytree.txt +++ b/sortedfamilytree.txt @@ -733,7 +733,7 @@ scroll~name 1014~Andrew Gregory 1015~John Bonina 1016~Sean McCluskey -1017~Jacob Rems +1017~Jacob Remz 1018~James McAleese 1019~Jacob Henry 1020~James Taylor