X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=turbot%2Finteraction.py;h=86f438c372b5358c8641d3497809d4d1b5b6ba3f;hb=a9f4ac01df4aca618a8e059f4eddcc4f80eb3a1f;hp=a3fe496c81adb8dc1ceca981c04d3d16a911058e;hpb=d63943a1adccccda1ddf43e609701a0615577670;p=turbot diff --git a/turbot/interaction.py b/turbot/interaction.py index a3fe496..86f438c 100644 --- a/turbot/interaction.py +++ b/turbot/interaction.py @@ -10,7 +10,9 @@ from turbot.hunt import ( from turbot.puzzle import ( find_puzzle_for_url, find_puzzle_for_sort_key, + find_puzzle_for_puzzle_id, puzzle_update_channel_and_sheet, + puzzle_channel_name, puzzle_id_from_name, puzzle_blocks, puzzle_sort_key, @@ -185,7 +187,7 @@ def edit_puzzle(turb, puzzle, trigger_id): solved = True solution_str = None - solution_list = puzzle.get("solution", []) + solution_list = puzzle.get("solution", ()) if solution_list: solution_str = ", ".join(solution_list) @@ -265,10 +267,11 @@ def edit_puzzle_submission(turb, payload, metadata): puzzle['type'] = 'meta' else: puzzle['type'] = 'plain' - rounds = [option['value'] for option in - state['rounds']['rounds']['selected_options']] - if rounds: - puzzle['rounds'] = rounds + if 'rounds' in state: + rounds = [option['value'] for option in + state['rounds']['rounds']['selected_options']] + if rounds: + puzzle['rounds'] = rounds new_rounds = state['new_rounds']['new_rounds']['value'] puzzle_state = state['state']['state']['value'] if puzzle_state: @@ -277,12 +280,13 @@ def edit_puzzle_submission(turb, payload, metadata): puzzle['status'] = 'solved' else: puzzle['status'] = 'unsolved' - puzzle['solution'] = [] + puzzle['solution'] = () solution = state['solution']['solution']['value'] if solution: - puzzle['solution'] = [ + # Construct a list from a set to avoid any duplicates + puzzle['solution'] = list({ sol.strip() for sol in solution.split(',') - ] + }) # Verify that there's a solution if the puzzle is mark solved if puzzle['status'] == 'solved' and not puzzle['solution']: @@ -532,7 +536,7 @@ def new_hunt(turb, trigger_id): return lambda_ok -actions['button']['new_hunt'] = new_hunt +actions['button']['new_hunt'] = new_hunt_button def new_hunt_submission(turb, payload, metadata): """Handler for the user submitting the new hunt modal @@ -926,13 +930,20 @@ def new_puzzle(turb, body): return bot_reply("Sorry, this channel doesn't appear to " + "be a hunt or puzzle channel") + # We used puzzle (if available) to select the initial round(s) + puzzle = puzzle_for_channel(turb, channel_id) + initial_rounds = None + if puzzle: + initial_rounds=puzzle.get("rounds", None) + round_options = hunt_rounds(turb, hunt['hunt_id']) if len(round_options): round_options_block = [ multi_select_block("Round(s)", "rounds", "Existing round(s) this puzzle belongs to", - round_options) + round_options, + initial_options=initial_rounds) ] else: round_options_block = [] @@ -978,12 +989,18 @@ def new_puzzle_submission(turb, payload, metadata): hunt_id = meta['hunt_id'] state = payload['view']['state']['values'] - name = state['name']['name']['value'] + + # And start loading data into a puzzle dict + puzzle = {} + puzzle['hunt_id'] = hunt_id + puzzle['name'] = state['name']['name']['value'] url = state['url']['url']['value'] + if url: + puzzle['url'] = url if state['meta']['meta']['selected_options']: - puzzle_type = 'meta' + puzzle['type'] = 'meta' else: - puzzle_type = 'plain' + puzzle['type'] = 'plain' if 'rounds' in state: rounds = [option['value'] for option in state['rounds']['rounds']['selected_options']] @@ -991,8 +1008,17 @@ def new_puzzle_submission(turb, payload, metadata): rounds = [] new_rounds = state['new_rounds']['new_rounds']['value'] + # Create a Slack-channel-safe puzzle_id + puzzle['puzzle_id'] = puzzle_id_from_name(puzzle['name']) + # Before doing anything, reject this puzzle if a puzzle already - # exists with the same URL. + # exists with the same puzzle_id or url + existing = find_puzzle_for_puzzle_id(turb, hunt_id, puzzle['puzzle_id']) + if existing: + return submission_error( + "name", + "Error: This name collides with an existing puzzle.") + if url: existing = find_puzzle_for_url(turb, hunt_id, url) if existing: @@ -1000,23 +1026,6 @@ def new_puzzle_submission(turb, payload, metadata): "url", "Error: A puzzle with this URL already exists.") - # Create a Slack-channel-safe puzzle_id - puzzle_id = puzzle_id_from_name(name) - - # Create a channel for the puzzle - hunt_dash_channel = "{}-{}".format(hunt_id, puzzle_id) - - try: - response = turb.slack_client.conversations_create( - name=hunt_dash_channel) - except SlackApiError as e: - return submission_error( - "name", - "Error creating Slack channel {}: {}" - .format(hunt_dash_channel, e.response['error'])) - - channel_id = response['channel']['id'] - # Add any new rounds to the database if new_rounds: for round in new_rounds.split(','): @@ -1033,21 +1042,26 @@ def new_puzzle_submission(turb, payload, metadata): } ) - # Construct a puzzle dict - puzzle = { - "hunt_id": hunt_id, - "puzzle_id": puzzle_id, - "channel_id": channel_id, - "solution": [], - "status": 'unsolved', - "name": name, - "type": puzzle_type - } - if url: - puzzle['url'] = url if rounds: puzzle['rounds'] = rounds + puzzle['solution'] = () + puzzle['status'] = 'unsolved' + + # Create a channel for the puzzle + channel_name = puzzle_channel_name(puzzle) + + try: + response = turb.slack_client.conversations_create( + name=channel_name) + except SlackApiError as e: + return submission_error( + "name", + "Error creating Slack channel {}: {}" + .format(channel_name, e.response['error'])) + + puzzle['channel_id'] = response['channel']['id'] + # Finally, compute the appropriate sort key puzzle["SK"] = puzzle_sort_key(puzzle) @@ -1171,7 +1185,10 @@ def solved(turb, body, args): # Set the status and solution fields in the database puzzle['status'] = 'solved' - puzzle['solution'].append(args) + + # Don't append a duplicate solution + if args not in puzzle['solution']: + puzzle['solution'].append(args) if 'state' in puzzle: del puzzle['state'] turb.table.put_item(Item=puzzle) @@ -1257,10 +1274,13 @@ def hunt(turb, body, args): blocks = hunt_blocks(turb, hunt, puzzle_status=status, search_terms=terms) - requests.post(response_url, - json = { 'blocks': blocks }, - headers = {'Content-type': 'application/json'} - ) + for block in blocks: + if len(block) > 100: + block = block[:100] + requests.post(response_url, + json = { 'blocks': block }, + headers = {'Content-type': 'application/json'} + ) return lambda_ok @@ -1331,10 +1351,13 @@ def round(turb, body, args): limit_to_rounds=puzzle.get('rounds', []) ) - requests.post(response_url, - json = { 'blocks': blocks }, - headers = {'Content-type': 'application/json'} - ) + for block in blocks: + if len(block) > 100: + block = block[:100] + requests.post(response_url, + json = { 'blocks': block }, + headers = {'Content-type': 'application/json'} + ) return lambda_ok