+ puzzle={}
+
+ # First, read all the various data from the request
+ meta = json.loads(metadata)
+ puzzle['hunt_id'] = meta['hunt_id']
+ puzzle['SK'] = meta['SK']
+ puzzle['puzzle_id'] = meta['puzzle_id']
+ puzzle['channel_id'] = meta['channel_id']
+ puzzle['channel_url'] = meta['channel_url']
+ puzzle['sheet_url'] = meta['sheet_url']
+
+ state = payload['view']['state']['values']
+
+ puzzle['name'] = state['name']['name']['value']
+ url = state['url']['url']['value']
+ if url:
+ puzzle['url'] = url
+ rounds = [option['value'] for option in
+ state['rounds']['rounds']['selected_options']]
+ if rounds:
+ puzzle['rounds'] = rounds
+ new_rounds = state['new_rounds']['new_rounds']['value']
+ puzzle_state = state['state']['state']['value']
+ if puzzle_state:
+ puzzle['state'] = puzzle_state
+ if state['solved']['solved']['selected_options']:
+ puzzle['status'] = 'solved'
+ else:
+ puzzle['status'] = 'unsolved'
+ puzzle['solution'] = []
+ solution = state['solution']['solution']['value']
+ if solution:
+ puzzle['solution'] = [
+ sol.strip() for sol in solution.split(',')
+ ]
+
+ # Add any new rounds to the database
+ if new_rounds:
+ if 'rounds' not in puzzle:
+ puzzle['rounds'] = []
+ for round in new_rounds.split(','):
+ # Drop any leading/trailing spaces from the round name
+ round = round.strip()
+ # Ignore any empty string
+ if not len(round):
+ continue
+ puzzle['rounds'].append(round)
+ turb.table.put_item(
+ Item={
+ 'hunt_id': puzzle['hunt_id'],
+ 'SK': 'round-' + round
+ }
+ )
+
+ # Update the puzzle in the database
+ turb.table.put_item(Item=puzzle)
+
+ # We need to set the channel topic if any of puzzle name, url,
+ # state, status, or solution, has changed. Let's just do that
+ # unconditionally here.
+
+ # XXX: What we really want here is a single function that sets the
+ # channel name, the channel topic, and the sheet name. That single
+ # function should be called anywhere there is code changing any of
+ # these things. This function could then also accept an optional
+ # "old_puzzle" argument and avoid changing any of those things
+ # that are unnecessary.
+ set_channel_topic(turb, puzzle)
+