X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=turbot%2Fpuzzle.py;h=e3a4f741580f711d0c36df9f459a265fd364b266;hb=1efdf784442e0bfc0fb96a18ec833e2801af7973;hp=f0456c6cba4c29d05cf4dcc23ed96953fea5c940;hpb=915b439e07c5b4aaef754f5f41360d862149a3fc;p=turbot diff --git a/turbot/puzzle.py b/turbot/puzzle.py index f0456c6..e3a4f74 100644 --- a/turbot/puzzle.py +++ b/turbot/puzzle.py @@ -6,7 +6,7 @@ from boto3.dynamodb.conditions import Key import turbot.sheets import re -def find_puzzle_for_puzzle_id(turb, hunt_id, puzzle_id): +def find_puzzle_for_sort_key(turb, hunt_id, sort_key): """Given a hunt_id and puzzle_id, return that puzzle Returns None if no puzzle with the given hunt_id and puzzle_id @@ -17,7 +17,7 @@ def find_puzzle_for_puzzle_id(turb, hunt_id, puzzle_id): response = turb.table.get_item( Key={ 'hunt_id': hunt_id, - 'SK': 'puzzle-{}'.format(puzzle_id) + 'SK': sort_key, }) if 'Item' in response: @@ -46,7 +46,7 @@ def find_puzzle_for_url(turb, hunt_id, url): return response['Items'][0] -def puzzle_blocks(puzzle): +def puzzle_blocks(puzzle, include_rounds=False): """Generate Slack blocks for a puzzle The puzzle argument should be a dictionary as returned from the @@ -62,6 +62,7 @@ def puzzle_blocks(puzzle): url = puzzle.get('url', None) sheet_url = puzzle.get('sheet_url', None) state = puzzle.get('state', None) + tags = puzzle.get('tags', []) status_emoji = '' solution_str = '' @@ -73,6 +74,10 @@ def puzzle_blocks(puzzle): if len(solution): solution_str = "*`" + '`, `'.join(solution) + "`*" + meta_str = '' + if puzzle.get('type', 'plain') == 'meta': + meta_str = "*META* " + links = [] if url: links.append("<{}|Puzzle>".format(url)) @@ -81,23 +86,42 @@ def puzzle_blocks(puzzle): state_str = '' if state: - state_str = "\n{}".format(state) + state_str = " State: {}".format(state) + + tags_str = '' + if tags: + tags_str = " Tags: "+" ".join(["`{}`".format(tag) for tag in tags]) + + extra_str = '' + if state_str or tags_str: + extra_str = "\n{}{}".format(tags_str, state_str) + + rounds_str = '' + if include_rounds and 'rounds' in puzzle: + rounds = puzzle['rounds'] + rounds_str = " in round{}: {}".format( + "s" if len(rounds) > 1 else "", + ", ".join(rounds) + ) - puzzle_text = "{}{} <{}|{}> ({}){}".format( - status_emoji, solution_str, + puzzle_text = "{} {}<{}|{}> {} ({}){}{}".format( + status_emoji, + meta_str, channel_url(channel_id), name, - ', '.join(links), state_str + solution_str, + ', '.join(links), rounds_str, + extra_str ) # Combining hunt ID and puzzle ID together here is safe because - # both IDs are restricted to not contain a hyphen, (see + # hunt_id is restricted to not contain a hyphen, (see # valid_id_re in interaction.py) - hunt_and_puzzle = "{}-{}".format(puzzle['hunt_id'], puzzle['puzzle_id']) + hunt_and_sort_key = "{}-{}".format(puzzle['hunt_id'], puzzle['SK']) return [ accessory_block( section_block(text_block(puzzle_text)), - button_block("✏", "edit_puzzle", hunt_and_puzzle) + button_block("✏", "edit_puzzle", hunt_and_sort_key) ) ] @@ -153,6 +177,24 @@ def puzzle_matches_all(puzzle, patterns): def puzzle_id_from_name(name): return re.sub(r'[^a-zA-Z0-9_]', '', name).lower() +def puzzle_sort_key(puzzle): + """Return an appropriate sort key for a puzzle in the database + + The sort key must start with "puzzle-" to distinguish puzzle items + in the database from all non-puzzle items. After that, though, the + only requirements are that each puzzle have a unique key and they + give us the ordering we want. And for ordering, we want meta puzzles + before non-meta puzzles and then alphabetical order by name within + each of those groups. + + So puting a "-meta-" prefix in front of the puzzle ID does the trick. + """ + + return "puzzle-{}{}".format( + "-meta-" if puzzle['type'] == "meta" else "", + puzzle['puzzle_id'] + ) + def puzzle_channel_topic(puzzle): """Compute the channel topic for a puzzle""" @@ -176,6 +218,10 @@ def puzzle_channel_topic(puzzle): if len(links): topic += "({})".format(', '.join(links)) + tags = puzzle.get('tags', []) + if tags: + topic += " {}".format(" ".join(["`{}`".format(t) for t in tags])) + state = puzzle.get('state', None) if state: topic += " {}".format(state) @@ -185,7 +231,7 @@ def puzzle_channel_topic(puzzle): def puzzle_channel_name(puzzle): """Compute the channel name for a puzzle""" - # Note: We don't use puzzle['hunt_id'] here because we're keeping + # Note: We don't use puzzle['puzzle_id'] here because we're keeping # that as a persistent identifier in the database. Instead we # create a new ID-like identifier from the current name. channel_name = "{}-{}".format(