import re
def find_puzzle_for_sort_key(turb, hunt_id, sort_key):
- """Given a hunt_id and puzzle_id, return that puzzle
+ """Given a hunt_id and sort_key, return that puzzle
- Returns None if no puzzle with the given hunt_id and puzzle_id
+ Returns None if no puzzle with the given hunt_id and sort_key
exists in the database, otherwise a dictionary with all fields
from the puzzle's row in the database.
+
+ Note: The sort_key is a modified version of the puzzle_id, (used
+ to make metapuzzles appear in the ordering before non-metapuzzles).
+ If you've been handed a sort_key, then looking up a puzzle by
+ sort_key is the right thing to do. But if you instead have just
+ a puzzle_id, see find_puzzle_for_puzzle_id rather than trying
+ to convert the puzzle_id into a sort_key to use this function.
"""
response = turb.table.get_item(
else:
return None
+def find_puzzle_for_puzzle_id(turb, hunt_id, puzzle_id):
+ """Given a hunt_id and puzzle_id, return that puzzle
+
+ Returns None if no puzzle with the given hunt_id and puzzle_id
+ exists in the database, otherwise a dictionary with all fields
+ from the puzzle's row in the database.
+
+ Note: The sort_key is a modified version of the puzzle_id, (used
+ to make metapuzzles appear in the ordering before non-metapuzzles).
+ If you've been handed a sort_key, then looking up a puzzle by
+ sort_key is the right thing to do. But if you instead have just
+ a puzzle_id, see find_puzzle_for_puzzle_id rather than trying
+ to convert the puzzle_id into a sort_key to use this function.
+ """
+
+ response = turb.table.query(
+ IndexName='puzzle_id_index',
+ KeyConditionExpression=(
+ Key('hunt_id').eq(hunt_id) &
+ Key('puzzle_id').eq(puzzle_id)
+ )
+ )
+
+ if response['Count'] == 0:
+ return None
+
+ return response['Items'][0]
+
def find_puzzle_for_url(turb, hunt_id, url):
"""Given a hunt_id and URL, return the puzzle with that URL
if puzzle['status'] == 'solved':
topic += "SOLVED: `{}` ".format('`, `'.join(puzzle['solution']))
- topic += puzzle['name']
-
links = []
url = puzzle.get('url', None)
links.append("<{}|Sheet>".format(sheet_url))
if len(links):
- topic += "({})".format(', '.join(links))
+ topic += "({}) ".format(', '.join(links))
tags = puzzle.get('tags', [])
if tags:
return topic
+def puzzle_channel_description(puzzle):
+ """Compute the channel description for a puzzle"""
+
+ url = puzzle.get('url', None)
+ sheet_url = puzzle.get('sheet_url', None)
+ tags = puzzle.get('tags', [])
+ state = puzzle.get('state', None)
+
+ description = (
+ "Discussion to solve the puzzle \"{}\".\n".format(puzzle['name'])
+ )
+
+ if url:
+ description += "See the <{}|Original puzzle>\n".format(url)
+
+ if sheet_url:
+ description += (
+ "Actual solving work takes place in the "
+ + "<{}|shared spreadsheet>\n".format(sheet_url)
+ )
+
+ if tags:
+ description += "This puzzle has the following tags: {}\n".format(
+ " ".join(["`{}`".format(t) for t in tags]))
+
+ if state:
+ description += "This puzzle has a state of: {}\n".format(state)
+
+ description += (
+ "You can see a summary of this information at any point "
+ + "by issuing the `/puzzle` command and you can edit any of "
+ + "this information by issuing the `/edit` command"
+ )
+
+ return description
+
def puzzle_channel_name(puzzle):
"""Compute the channel name for a puzzle"""
round = '-' + puzzle_id_from_name(puzzle['rounds'][0])
meta = ''
- if puzzle['type'] == 'meta':
- meta = '-m'
+ if puzzle.get('type', 'plain') == 'meta':
+ meta = '--m'
# Note: We don't use puzzle['puzzle_id'] here because we're keeping
# that as a persistent identifier in the database. Instead we
turb.slack_client.conversations_setTopic(channel=channel_id,
topic=channel_topic)
+ # Compute the channel description and set it if it has changed
+ channel_description = puzzle_channel_description(puzzle)
+
+ old_channel_description = None
+ if old_puzzle:
+ old_channel_description = puzzle_channel_description(old_puzzle)
+
+ if channel_description != old_channel_description:
+ turb.slack_client.conversations_setPurpose(channel=channel_id,
+ purpose=channel_description)
+
# Compute the sheet name and set it if it has changed
sheet_name = puzzle_sheet_name(puzzle)
if 'tags' in old_puzzle:
new_puzzle['tags'] = old_puzzle['tags'].copy()
+ if 'solution' in old_puzzle:
+ new_puzzle['solution'] = old_puzzle['solution'].copy()
+
return new_puzzle