]> git.cworth.org Git - turbot/blob - turbot/hunt.py
77c179771a17cd7e01eed6f5d3230bf554a225b6
[turbot] / turbot / hunt.py
1 from turbot.blocks import section_block, text_block, divider_block
2 from turbot.round import round_blocks
3 from turbot.puzzle import puzzle_block
4 from turbot.channel import channel_url
5 from boto3.dynamodb.conditions import Key
6
7 def find_hunt_for_hunt_id(turb, hunt_id):
8     """Given a hunt ID find the database item for that hunt
9
10     Returns None if hunt ID is not found, otherwise a
11     dictionary with all fields from the hunt's row in the table,
12     (channel_id, active, hunt_id, name, url, sheet_url, etc.).
13     """
14
15     response = turb.table.get_item(
16         Key={
17             'hunt_id': hunt_id,
18             'SK': 'hunt-{}'.format(hunt_id)
19         })
20
21     if 'Item' in response:
22         return response['Item']
23     else:
24         return None
25
26 def hunt_blocks(turb, hunt):
27     """Generate Slack blocks for a hunt
28
29     The hunt argument should be a dictionary as returned from the
30     database. The return value can be used in a Slack command
31     expecting blocks to provide all the details of a hunt, (puzzles,
32     their state, solution, links to channels and sheets, etc.).
33     """
34
35     name = hunt['name']
36     hunt_id = hunt['hunt_id']
37     channel_id = hunt['channel_id']
38
39     response = turb.table.query(
40         KeyConditionExpression=(
41             Key('hunt_id').eq(hunt_id) &
42             Key('SK').begins_with('puzzle-')
43         )
44     )
45     puzzles = response['Items']
46
47     # Compute the set of rounds across all puzzles
48     rounds = set()
49     for puzzle in puzzles:
50         if 'rounds' not in puzzle:
51             continue
52         for round in puzzle['rounds']:
53             rounds.add(round)
54
55     hunt_text = "*<{}|{}>*".format(channel_url(channel_id), name)
56
57     blocks = [
58         section_block(text_block(hunt_text)),
59     ]
60
61     # Construct blocks for each round
62     for round in rounds:
63         blocks += round_blocks(round, puzzles)
64
65     # Also blocks for any puzzles not in any round
66     stray_puzzles = [puzzle for puzzle in puzzles if 'rounds' not in puzzle]
67     if len(stray_puzzles):
68         stray_text = "*Puzzles with no asigned round*"
69         blocks.append(section_block(text_block(stray_text)))
70         for puzzle in stray_puzzles:
71             blocks.append(puzzle_block(puzzle))
72
73     blocks.append(divider_block())
74
75     return blocks