From 99dfffda6befec46a1ecee6cae093224ee7cc6d0 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 31 Dec 2020 10:31:24 -0700 Subject: [PATCH] Convert /puzzle puzzle creation to all-one-table database schema So we put the hunt ID into the PK field and the puzzle ID into the SK field, (allowing puzzle items to be distinguished from hunt items in the table). While doing this, we also disable the feature of inviting all hunt users to the new puzzle. This is both because that code hasn't been ported to the new schema, and also because that feature is planned to be eliminated anyway. --- turbot/events.py | 47 ++++++++++++++++++++----------------------- turbot/interaction.py | 25 +++++++++++++++-------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/turbot/events.py b/turbot/events.py index bbc00b6..d701994 100644 --- a/turbot/events.py +++ b/turbot/events.py @@ -140,7 +140,7 @@ def hunt_channel_created(turb, channel_name, channel_id): KeyConditionExpression=Key("channel_id").eq(channel_id) ) if 'Items' not in response: - print("Warning: Cannot find channel_id {} in hunts table. " + print("Warning: Cannot find channel_id {} in turbot table. " .format(channel_id) + "Letting Slack retry this event") return lambda_error @@ -207,28 +207,25 @@ def set_channel_description(turb, puzzle): turb.slack_client.conversations_setTopic(channel=channel_id, topic=description) -def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): +def puzzle_channel_created(turb, channel_name, channel_id): """Creates sheet and invites user for a newly-created puzzle channel""" - hunt_id = puzzle_channel_name.split('-')[0] - # First see if we can find an entry for this puzzle in the database. # If not, simply return an error and let Slack retry - response = turb.table.get_item( - Key={'channel_id': puzzle_channel_id}, - ConsistentRead=True + response = turb.table.query( + IndexName="channel_id_index", + KeyConditionExpression=Key("channel_id").eq(channel_id), ) - if 'Item' not in response: - print("Warning: Cannot find channel_id {} in {} table. " - .format(puzzle_channel_id, hunt_id) - + "Letting Slack retry this event") + if 'Items' not in response: + print("Warning: Cannot find channel_id {} in turbot table. " + .format(channel_id) + "Letting Slack retry this event") return lambda_error - item = response['Item'] + item = response['Items'][0] if 'sheet_url' in item: print("Info: channel_id {} already has sheet_url {}. Exiting." - .format(puzzle_channel_id, item['sheet_url'])) + .format(channel_id, item['sheet_url'])) return lambda_success # Before launching into sheet creation, indicate that we're doing this @@ -236,7 +233,7 @@ def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): # and Slack retries the event, that next event will see this 'pending' # string and cleanly return (eliminating all future retries). item['sheet_url'] = 'pending' - item['channel_url'] = channel_url(puzzle_channel_id) + item['channel_url'] = channel_url(channel_id) turb.table.put_item(Item=item) # Create a sheet for the puzzle @@ -250,14 +247,14 @@ def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): set_channel_description(turb, item) # Lookup and invite all users from this hunt to this new puzzle - hunts_table = turb.db.Table('hunts') - response = hunts_table.scan( - FilterExpression='hunt_id = :hunt_id', - ExpressionAttributeValues={':hunt_id': hunt_id} - ) - - if 'Items' in response: - + # hunts_table = turb.db.Table('hunts') + # response = hunts_table.scan( + # FilterExpression='hunt_id = :hunt_id', + # ExpressionAttributeValues={':hunt_id': hunt_id} + # ) + # + # if 'Items' in response: + if False: hunt_channel_id = response['Items'][0]['channel_id'] # Find all members of the hunt channel @@ -268,7 +265,7 @@ def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): members = [m for m in members if m != TURBOT_USER_ID] slack_send_message( - turb.slack_client, puzzle_channel_id, + turb.slack_client, channel_id, "Inviting all members from the hunt channel: " + "<#{}>".format(hunt_channel_id)) @@ -276,7 +273,7 @@ def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): cursor = 0 while cursor < len(members): turb.slack_client.conversations_invite( - channel=puzzle_channel_id, + channel=channel_id, users=members[cursor:cursor + 500]) cursor += 500 @@ -320,7 +317,7 @@ def puzzle_channel_created(turb, puzzle_channel_name, puzzle_channel_id): ) turb.slack_client.chat_postMessage( - channel=puzzle_channel_id, + channel=channel_id, text="New puzzle: {}".format(item['name']), blocks=[ section_block(text_block(welcome_msg)), diff --git a/turbot/interaction.py b/turbot/interaction.py index 62199eb..8f94a06 100644 --- a/turbot/interaction.py +++ b/turbot/interaction.py @@ -7,6 +7,7 @@ import json import re import requests from botocore.exceptions import ClientError +from boto3.dynamodb.conditions import Key from turbot.slack import slack_send_message actions = {} @@ -275,7 +276,15 @@ def channel_is_hunt(turb, channel_id): Returns a dict (filled with database entries) if there is a hunt for this channel, otherwise returns None.""" - return get_table_item(turb, "channel_id_index", 'channel_id', channel_id) + response = turb.table.query( + IndexName = "channel_id_index", + KeyConditionExpression=Key("channel_id").eq(channel_id) + ) + + if 'Items' not in response: + return None + + return response['Items'][0] def find_hunt_for_hunt_id(turb, hunt_id): """Given a hunt ID find the database for for that hunt @@ -306,7 +315,7 @@ def find_hunt_for_channel(turb, channel_id, channel_name): """ - (hunt, _) = channel_is_hunt(turb, channel_id) + hunt = channel_is_hunt(turb, channel_id) if hunt: return hunt @@ -388,18 +397,18 @@ def puzzle_submission(turb, payload, metadata): "Error creating Slack channel {}: {}" .format(hunt_dash_channel, e.response['error'])) - puzzle_channel_id = response['channel']['id'] + channel_id = response['channel']['id'] # Insert the newly-created puzzle into the database - table = turb.db.Table(hunt_id) - table.put_item( + turb.table.put_item( Item={ - "channel_id": puzzle_channel_id, + "PK": "hunt-{}".format(hunt_id), + "SK": "puzzle-{}".format(puzzle_id), + "puzzle_id": puzzle_id, + "channel_id": channel_id, "solution": [], "status": 'unsolved', - "hunt_id": hunt_id, "name": name, - "puzzle_id": puzzle_id, "url": url, } ) -- 2.43.0