Ordered punch-list (aiming to complete by 2021-01-08)
-----------------------------------------------------
-• Make `/puzzle` for a meta puzzle also display the names/answers of
- all puzzles in the round.
-
• Add /tag to add/remove tags (will force to all caps and store as a
prefix as part of the state string for now)
else:
return None
+def hunt_puzzles_for_hunt_id(turb, hunt_id):
+ """Return all puzzles that belong to the given hunt_id"""
+
+ response = turb.table.query(
+ KeyConditionExpression=(
+ Key('hunt_id').eq(hunt_id) &
+ Key('SK').begins_with('puzzle-')
+ )
+ )
+
+ return response['Items']
+
def hunt_blocks(turb, hunt, puzzle_status='unsolved', search_terms=[],
limit_to_rounds=None):
"""Generate Slack blocks for a hunt
hunt_id = hunt['hunt_id']
channel_id = hunt['channel_id']
- response = turb.table.query(
- KeyConditionExpression=(
- Key('hunt_id').eq(hunt_id) &
- Key('SK').begins_with('puzzle-')
- )
- )
- puzzles = response['Items']
+ puzzles = hunt_puzzles_for_hunt_id(turb, hunt_id)
# Filter the set of puzzles according the the requested puzzle_status
if puzzle_status in ('solved', 'unsolved'):
from turbot.blocks import (
input_block, section_block, text_block, multi_select_block, checkbox_block
)
-from turbot.hunt import find_hunt_for_hunt_id, hunt_blocks
+from turbot.hunt import (
+ find_hunt_for_hunt_id,
+ hunt_blocks,
+ hunt_puzzles_for_hunt_id
+)
from turbot.puzzle import (
find_puzzle_for_url,
find_puzzle_for_sort_key,
puzzle_blocks,
puzzle_sort_key
)
+from turbot.round import round_quoted_puzzles_titles_answers
import turbot.rot
import turbot.sheets
import turbot.slack
blocks = puzzle_blocks(puzzle, include_rounds=True)
+ # For a meta puzzle, also display the titles and solutions for all
+ # puzzles in the same round.
+ if puzzle['type'] == 'meta':
+ puzzles = hunt_puzzles_for_hunt_id(turb, puzzle['hunt_id'])
+
+ # Drop this puzzle itself from the report
+ puzzles = [p for p in puzzles if p['puzzle_id'] != puzzle['puzzle_id']]
+
+ for round in puzzle.get('rounds', [None]):
+ answers = round_quoted_puzzles_titles_answers(round, puzzles)
+ blocks += [
+ section_block(text_block(
+ "*Feeder solutions from round {}*".format(
+ round if round else "<none>"
+ ))),
+ section_block(text_block(answers))
+ ]
+
requests.post(response_url,
json = {'blocks': blocks},
headers = {'Content-type': 'application/json'}
blocks += puzzle_blocks(puzzle)
return blocks
+
+def round_quoted_puzzles_titles_answers(round, puzzles):
+ answers = []
+ for puzzle in puzzles:
+ if round:
+ if 'rounds' not in puzzle:
+ continue
+ if round not in puzzle['rounds']:
+ continue
+ else:
+ if 'rounds' in puzzle and len(puzzle['rounds']):
+ continue
+ answer = {}
+ answer['name'] = puzzle['name']
+ if puzzle['status'] == 'solved' and 'solution' in puzzle:
+ answer['solution'] = ", ".join(puzzle['solution'])
+ else:
+ answer['solution'] = ""
+ answers.append(answer)
+
+ if not answers:
+ return ""
+
+ longest = max(len(ans['name']) for ans in answers)
+
+ format = "%{}s: %s".format(longest)
+
+ return "```" + "\n".join(
+ [format % (ans['name'], ans['solution']) for ans in answers]
+ ) + "```"