From e71df5a381d9e9bb3f5a11ecc42eacb62c5a45d5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 22 Oct 2020 17:24:28 -0700 Subject: [PATCH] Add a /state command to let users indicate the state of a puzzle And this state is shoved into the channel topic. --- turbot/interaction.py | 95 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/turbot/interaction.py b/turbot/interaction.py index 7a4f3e6..18dc4d2 100644 --- a/turbot/interaction.py +++ b/turbot/interaction.py @@ -205,6 +205,50 @@ def rot(turb, body, args): commands["/rot"] = rot +def get_table_item(turb, table_name, key, value): + """Get an item from the database 'table_name' with 'key' as 'value' + + Returns a tuple of (item, table) if found and (None, None) otherwise.""" + + table = turb.db.Table(table_name) + + response = table.get_item(Key={key: value}) + + if 'Item' in response: + return (response['Item'], table) + else: + return None + +def channel_is_puzzle(turb, channel_id, channel_name): + """Given a channel ID/name return the database item for the puzzle + + If this channel is a puzzle, this function returns a tuple: + + (puzzle, table) + + Where puzzle is dict filled with database entries, and table is a + database table that can be used to update the puzzle in the + database. + + Otherwise, this function returns (None, None).""" + + hunt_id = channel_name.split('-')[0] + + # Not a puzzle channel if there is no hyphen in the name + if hunt_id == channel_name: + return (None, None) + + return get_table_item(turb, hunt_id, 'channel_id', channel_id) + +def channel_is_hunt(turb, channel_id): + + """Given a channel ID/name return the database item for the hunt + + Returns a dict (filled with database entries) if there is a hunt + for this channel, otherwise returns None.""" + + return get_table_item(turb, "hunts", 'channel_id', channel_id) + def find_hunt_for_channel(turb, channel_id, channel_name): """Given a channel ID/name find the id/name of the hunt for this channel @@ -213,12 +257,10 @@ def find_hunt_for_channel(turb, channel_id, channel_name): Returns a tuple of (hunt_name, hunt_id) or (None, None).""" - hunts_table = turb.db.Table("hunts") - response = hunts_table.get_item(Key={'channel_id': channel_id}) + (hunt, hunts_table) = channel_is_hunt(turb, channel_id) - if 'Item' in response: - item = response['Item'] - return (item['hunt_id'], item['name']) + if hunt: + return (hunt['hunt_id'], hunt['name']) # So we're not a hunt channel, let's look to see if we are a # puzzle channel with a hunt-id prefix. @@ -332,3 +374,46 @@ def puzzle_submission(turb, payload, metadata): return { 'statusCode': 200 } + +# XXX: This duplicates functionality eith events.py:set_channel_description +def set_channel_topic(turb, puzzle): + channel_id = puzzle['channel_id'] + description = puzzle['name'] + url = puzzle.get('url', None) + sheet_url = puzzle.get('sheet_url', None) + state = puzzle.get('state', None) + + links = [] + if url: + links.append("<{}|Puzzle>".format(url)) + if sheet_url: + links.append("<{}|Sheet>".format(sheet_url)) + + if len(links): + description += "({})".format(', '.join(links)) + + if state: + description += " {}".format(state) + + turb.slack_client.conversations_setTopic(channel=channel_id, + topic=description) + +def state(turb, body, args): + """Implementation of the /state command + + The args string should be a brief sentence describing where things + stand or what's needed.""" + + channel_id = body['channel_id'][0] + channel_name = body['channel_name'][0] + + (puzzle, table) = channel_is_puzzle(turb, channel_id, channel_name) + + if not puzzle: + return bot_reply("Sorry, this is not a puzzle channel.") + + # Set the state field in the database + puzzle['state'] = args + table.put_item(Item=puzzle) + + set_channel_topic(turb, puzzle) -- 2.43.0