X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=turbot%2Finteraction.py;h=c1064bfa22cfb2d6e4341163480e5ea1d3edc0b4;hb=f01639c9b18dabbc5eb1c659ea871c3cda6ea727;hp=fb11599034fc1f518a1ec7a19a7d54ade43862be;hpb=1efdf784442e0bfc0fb96a18ec833e2801af7973;p=turbot diff --git a/turbot/interaction.py b/turbot/interaction.py index fb11599..c1064bf 100644 --- a/turbot/interaction.py +++ b/turbot/interaction.py @@ -13,7 +13,8 @@ from turbot.puzzle import ( puzzle_update_channel_and_sheet, puzzle_id_from_name, puzzle_blocks, - puzzle_sort_key + puzzle_sort_key, + puzzle_copy ) from turbot.round import round_quoted_puzzles_titles_answers import turbot.rot @@ -111,8 +112,6 @@ def edit_puzzle_command(turb, body): return edit_puzzle(turb, puzzle, trigger_id) - return lambda_ok - def edit_puzzle_button(turb, payload): """Handler for the action of user pressing an edit_puzzle button""" @@ -338,9 +337,30 @@ def edit_puzzle_submission(turb, payload, metadata): return lambda_ok -def new_hunt(turb, payload): +def new_hunt_command(turb, body): + """Implementation of the '/hunt new' command + + As dispatched from the hunt() function. + """ + + trigger_id = body['trigger_id'][0] + + return new_hunt(turb, trigger_id) + +def new_hunt_button(turb, payload): """Handler for the action of user pressing the new_hunt button""" + trigger_id = payload['trigger_id'] + + return new_hunt(turb, trigger_id) + +def new_hunt(turb, trigger_id): + """Common code for implementing a new hunt dialog + + This implementation is common whether the operations was invoked + by a button (new_hunt_button) or a command (new_hunt_command). + """ + view = { "type": "modal", "private_metadata": json.dumps({}), @@ -356,7 +376,7 @@ def new_hunt(turb, payload): ], } - result = turb.slack_client.views_open(trigger_id=payload['trigger_id'], + result = turb.slack_client.views_open(trigger_id=trigger_id, view=view) if (result['ok']): submission_handlers[result['view']['id']] = new_hunt_submission @@ -685,7 +705,7 @@ def puzzle(turb, body, args): # For a meta puzzle, also display the titles and solutions for all # puzzles in the same round. - if puzzle['type'] == 'meta': + if puzzle.get('type', 'plain') == 'meta': puzzles = hunt_puzzles_for_hunt_id(turb, puzzle['hunt_id']) # Drop this puzzle itself from the report @@ -881,8 +901,8 @@ def state(turb, body, args): return bot_reply( "Sorry, the /state command only works in a puzzle channel") - # Make a copy of the puzzle object - puzzle = old_puzzle.copy() + # Make a deep copy of the puzzle object + puzzle = puzzle_copy(old_puzzle) # Update the puzzle in the database puzzle['state'] = args @@ -926,8 +946,8 @@ def tag(turb, body, args): tag = tag.upper() # Reject a tag that is not alphabetic or underscore A-Z_ - if not re.match(r'^[A-Z_]*$', tag): - return bot_reply("Sorry, tags can only contain letters " + if not re.match(r'^[A-Z0-9_]*$', tag): + return bot_reply("Sorry, tags can only contain letters, numbers, " + "and the underscore character.") if action == 'remove': @@ -941,8 +961,8 @@ def tag(turb, body, args): # OK. Error checking is done. Let's get to work - # Make a copy of the puzzle object - puzzle = old_puzzle.copy() + # Make a deep copy of the puzzle object + puzzle = puzzle_copy(old_puzzle) if action == 'remove': puzzle['tags'] = [t for t in puzzle['tags'] if t != tag] @@ -966,7 +986,7 @@ def solved(turb, body, args): The args string should be a confirmed solution.""" channel_id = body['channel_id'][0] - user_name = body['user_name'][0] + user_id = body['user_id'][0] old_puzzle = puzzle_for_channel(turb, channel_id) @@ -977,8 +997,8 @@ def solved(turb, body, args): return bot_reply( "Error, no solution provided. Usage: `/solved SOLUTION HERE`") - # Make a copy of the puzzle object - puzzle = old_puzzle.copy() + # Make a deep copy of the puzzle object + puzzle = puzzle_copy(old_puzzle) # Set the status and solution fields in the database puzzle['status'] = 'solved' @@ -990,7 +1010,7 @@ def solved(turb, body, args): # Report the solution to the puzzle's channel slack_send_message( turb.slack_client, channel_id, - "Puzzle mark solved by {}: `{}`".format(user_name, args)) + "Puzzle mark solved by <@{}>: `{}`".format(user_id, args)) # Also report the solution to the hunt channel hunt = find_hunt_for_hunt_id(turb, puzzle['hunt_id']) @@ -1023,14 +1043,19 @@ def hunt(turb, body, args): character in a term). All terms must match on a puzzle in order for that puzzle to be included. But a puzzle will be considered to match if any of the puzzle title, round title, puzzle URL, puzzle - state, or puzzle solution match. Matching will be performed - without regard to case sensitivity and the search terms can - include regular expression syntax. + state, puzzle type, tags, or puzzle solution match. Matching will + be performed without regard to case sensitivity and the search + terms can include regular expression syntax. + """ channel_id = body['channel_id'][0] response_url = body['response_url'][0] + # First, farm off "/hunt new" as a separate command + if args == "new": + return new_hunt_command(turb, body) + terms = None if args: # The first word can be a puzzle status and all remaining word