]> git.cworth.org Git - turbot/commitdiff
For /puzzle on meta puzzles print all titles/answers of feeder puzzles
authorCarl Worth <cworth@cworth.org>
Sat, 9 Jan 2021 11:59:02 +0000 (03:59 -0800)
committerCarl Worth <cworth@cworth.org>
Sat, 9 Jan 2021 12:23:44 +0000 (04:23 -0800)
Where feeder puzzles are specifically defined as puzzle belonging to the
same round.

TODO
turbot/hunt.py
turbot/interaction.py
turbot/round.py

diff --git a/TODO b/TODO
index 45698211f4ac33e88347615d0ce8182e158a57dc..1bc07a65d0bc51ac8683733251d83dc36c0a7a9a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,9 +1,6 @@
 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)
 
index 1c2ee0e1120c579d8462e65cb721e29c95c122dc..c2e59e2be937c4577e7696f80b01fce51356e05d 100644 (file)
@@ -23,6 +23,18 @@ def find_hunt_for_hunt_id(turb, hunt_id):
     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
@@ -62,13 +74,7 @@ def hunt_blocks(turb, hunt, puzzle_status='unsolved', search_terms=[],
     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'):
index 9e92242c0f64208b3a09a22772968f8ce045dbfd..8bff8bc3cbc656571ca0a953a5002d9f7659ec3d 100644 (file)
@@ -2,7 +2,11 @@ from slack.errors import SlackApiError
 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,
@@ -11,6 +15,7 @@ from turbot.puzzle import (
     puzzle_blocks,
     puzzle_sort_key
 )
+from turbot.round import round_quoted_puzzles_titles_answers
 import turbot.rot
 import turbot.sheets
 import turbot.slack
@@ -664,6 +669,24 @@ def puzzle(turb, body, args):
 
     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'}
index 3e12f5c17eb560c0650b1d8c1c22435a94f2fb1f..73f23d75bc32aa3544b8f0b62569c84ccd10af1d 100644 (file)
@@ -32,3 +32,33 @@ def round_blocks(round, puzzles, omit_header=False):
         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]
+    ) + "```"