from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key
from turbot.slack import slack_send_message
+import shlex
actions = {}
commands = {}
def hunt(turb, body, args):
"""Implementation of the /hunt command
- The (optional) args string should be one of 'all', 'solved', or
- 'unsolved' to indicate which set of puzzles should be
- displayed. If omitted, this command will default to showing only
- unsolved puzzles.
+ The (optional) args string can be used to filter which puzzles to
+ display. The first word can be one of 'all', 'unsolved', or
+ 'solved' and can be used to display only puzzles with the given
+ status. Any remaining text in the args string will be interpreted
+ as search terms. These will be split into separate terms on space
+ characters, (though quotation marks can be used to include a space
+ 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, 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]
- status = args
- if len(status):
+ if args:
+ # The first word can be a puzzle status and all remaining word
+ # (if any) are search terms. _But_, if the first word is not a
+ # valid puzzle status ('all', 'unsolved', 'solved'), then all
+ # words are search terms and we default status to 'unsolved'.
+ split_args = args.split(' ', 1)
+ status = split_args[0]
+ if (len(split_args) > 1):
+ terms = split_args[1]
if status not in ('unsolved', 'solved', 'all'):
- return bot_reply("Usage: /hunt [all|solved|unsolved]")
+ terms = args
+ status = 'unsolved'
else:
status = 'unsolved'
+ terms = None
+
+ # Separate search terms on spaces (but allow for quotation marks
+ # to capture spaces in a search term)
+ if terms:
+ terms = shlex.split(terms)
hunt = hunt_for_channel(turb, channel_id)
return bot_reply("Sorry, this channel doesn't appear to "
+ "be a hunt or puzzle channel")
- blocks = hunt_blocks(turb, hunt, puzzle_status=status)
+ blocks = hunt_blocks(turb, hunt, puzzle_status=status, search_terms=terms)
requests.post(response_url,
json = { 'blocks': blocks },