]> git.cworth.org Git - turbot/blobdiff - turbot/interaction.py
Refuse to create a new puzzle with the same URL as an existing puzzle
[turbot] / turbot / interaction.py
index 76eb061d024a29475bc01a368ab67abd3b3e162f..f2a35ee13066a8d8cdafc5c66d8f8c6db72ea134 100644 (file)
@@ -3,6 +3,7 @@ from turbot.blocks import (
     input_block, section_block, text_block, multi_select_block
 )
 from turbot.hunt import find_hunt_for_hunt_id
+from turbot.puzzle import find_puzzle_for_url
 import turbot.rot
 import turbot.sheets
 import turbot.slack
@@ -119,13 +120,14 @@ def new_hunt_submission(turb, payload, metadata):
             TableName='turbot',
             KeySchema=[
                 {'AttributeName': 'hunt_id', 'KeyType': 'HASH'},
-                {'AttributeName': 'SK', 'KeyType': 'RANGE'},
+                {'AttributeName': 'SK', 'KeyType': 'RANGE'}
             ],
             AttributeDefinitions=[
                 {'AttributeName': 'hunt_id', 'AttributeType': 'S'},
                 {'AttributeName': 'SK', 'AttributeType': 'S'},
                 {'AttributeName': 'channel_id', 'AttributeType': 'S'},
                 {'AttributeName': 'is_hunt', 'AttributeType': 'S'},
+                {'AttributeName': 'url', 'AttributeType': 'S'}
             ],
             ProvisionedThroughput={
                 'ReadCapacityUnits': 5,
@@ -158,6 +160,18 @@ def new_hunt_submission(turb, payload, metadata):
                         'WriteCapacityUnits': 5
                     }
                 }
+            ],
+            LocalSecondaryIndexes = [
+                {
+                    'IndexName': 'url_index',
+                    'KeySchema': [
+                        {'AttributeName': 'hunt_id', 'KeyType': 'HASH'},
+                        {'AttributeName': 'url', 'KeyType': 'RANGE'},
+                    ],
+                    'Projection': {
+                        'ProjectionType': 'ALL'
+                    }
+                }
             ]
         )
         return submission_error(
@@ -409,6 +423,7 @@ def puzzle_submission(turb, payload, metadata):
     This is the modal view presented to the user by the puzzle function
     above."""
 
+    # First, read all the various data from the request
     meta = json.loads(metadata)
     hunt_id = meta['hunt_id']
 
@@ -422,6 +437,15 @@ def puzzle_submission(turb, payload, metadata):
         rounds = []
     new_rounds = state['new_rounds']['new_rounds']['value']
 
+    # Before doing anything, reject this puzzle if a puzzle already
+    # exists with the same URL.
+    if url:
+        existing = find_puzzle_for_url(turb, hunt_id, url)
+        if existing:
+            return submission_error(
+                "url",
+                "Error: A puzzle with this URL already exists.")
+
     # Create a Slack-channel-safe puzzle_id
     puzzle_id = re.sub(r'[^a-zA-Z0-9_]', '', name).lower()