Requires sorttable.js, which should be included
"""
-from turbot.channel import channel_url
+import boto3
from boto3.dynamodb.conditions import Key
+import re
website = "https://halibut.cworth.org/"
#change this if we're using AWS or some other subdomain instead
-def find_hunt_for_hunt_id(turb, hunt_id):
+def filename_from_name(name):
+ """Returns a string derived from name, but with all spaces and slashes
+ replaced with underscores, (for making a clean filename)"""
+ return re.sub(r'[ /]', '_', name)
+
+def channel_url(channel_id):
+ """Given a channel ID, return the URL for that channel."""
+
+ return "https://halibutthatbass.slack.com/archives/{}".format(channel_id)
+
+def find_hunt_for_hunt_id(table, hunt_id):
"""Given a hunt ID find the database item for that hunt
Returns None if hunt ID is not found, otherwise a
dictionary with all fields from the hunt's row in the table,
(channel_id, active, hunt_id, name, url, sheet_url, etc.).
"""
- response = turb.table.get_item(
+ response = table.get_item(
Key={
'hunt_id': hunt_id,
'SK': 'hunt-{}'.format(hunt_id)
else:
return None
-def hunt_puzzles_for_hunt_id(turb, hunt_id):
+def hunt_puzzles_for_hunt_id(table, hunt_id):
"""Return all puzzles that belong to the given hunt_id"""
- response = turb.table.query(
+ response = table.query(
KeyConditionExpression=(
Key('hunt_id').eq(hunt_id) &
Key('SK').begins_with('puzzle-')
#internal links, doesn't open new tab
return '<a href="{}">{}</a>'.format(lin, text)
-def hunt_info(turb, hunt):
+def hunt_info(table, hunt_id):
"""
Retrieves list of rounds, puzzles for the given hunt
"""
+
+ hunt = find_hunt_for_hunt_id(table, hunt_id)
+
name = hunt["name"]
- hunt_id = hunt["hunt_id"]
channel_id = hunt["channel_id"]
- puzzles = hunt_puzzles_for_hunt_id(turb, hunt_id)
+ puzzles = hunt_puzzles_for_hunt_id(table, hunt_id)
rounds = set()
for puzzle in puzzles:
expanding += [
' <div id="b{}" class="containerTab {}" style="display:none;">\n'.format(i, status),
' <span onclick="this.parentElement.style.display=\'none\'" class="closebtn">x</span>\n',
- ' <h2>{}</h2>\n'.format(link(website + "_".join(rnd.split()) + "_round.html", rnd)),
+ ' <h2>{}</h2>\n'.format(link(website + filename_from_name(rnd) + "_round.html", rnd)),
' <table class="sortable">\n',
' <tr>\n',
' <th><u>Puzzle</u></th>\n',
meta = ''
if puzzle['status'] == 'solved':
expanding += [' <tr class=\'solved\';>\n',
- ' <td>{}</td>\n'.format(link(website + "_".join(puzzle['name'].split()) + ".html", puzzle['name']+meta)),
+ ' <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + ".html", puzzle['name']+meta)),
' <td>{}</td>\n'.format(puzzle['solution']),
' </tr>\n']
else:
expanding += [' <tr class=\'unsolved\';>\n',
- ' <td><b>{}</b></td>\n'.format(link(website + "_".join(puzzle['name'].split()) + ".html", puzzle['name']+meta)),
+ ' <td><b>{}</b></td>\n'.format(link(website + filename_from_name(puzzle['name']) + ".html", puzzle['name']+meta)),
' <td></td>\n',
' </tr>\n']
expanding.append(' </table>\n')
if puzzle['status'] == 'solved':
puzzle_list += [ ' <tr>\n',
' <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
- ' <td>{}</td>\n'.format(elink(puzzle['url'], 'Puzzle')),
+ ' <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
' <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
- ' <td>{}</td>\n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')),
+ ' <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
' <td>{}</td>\n'.format(puzzle['solution']),
# ' <td></td>\n',
- ' <td>{}</td>\n'.format("".join(puzzle['tags'])),
+ ' <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
' </tr>\n']
else:
puzzle_list += [ ' <tr>\n',
' <td><b>{}</b></td>\n'.format(elink(slack_url, puzzle['name']+meta)),
- ' <td>{}</td>\n'.format(elink(puzzle['url'], 'Puzzle')),
+ ' <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
' <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
- ' <td>{}</td>\n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')),
+ ' <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
' <td></td>\n',
# ' <td></td>\n',
- ' <td>{}</td>\n'.format(" ".join(puzzle['tags'])),
+ ' <td>{}</td>\n'.format(" ".join(puzzle.get('tags',[]))),
' </tr>\n']
end = [' </tbody>\n',
' </table>\n',
' </body>\n',
'</html>\n']
html = start + puzzle_list + end
- file = "{}_round.html".format('_'.join(rnd.split()))
+ file = "{}_round.html".format(filename_from_name(rnd))
f = open(file, "w")
for line in html:
f.write(line)
else:
meta = ''
slack_url = channel_url(puzzle['channel_id'])
- round_url = [link(website + "_".join(rnd.split()) + "_round.html", rnd) for rnd in puzzle['rounds']]
+ if 'rounds' in puzzle:
+ round_url = [link(website + filename_from_name(rnd) + "_round.html", rnd) for rnd in puzzle['rounds']]
+ else:
+ round_url = ''
if puzzle['status'] == 'solved':
solution = puzzle['solution']
status = 'solved'
' <table class="center">\n',
' <tr>\n',
' <td>{}</td>\n'.format(elink(slack_url, 'Channel')), #slack channel
- ' <td>{}</td>\n'.format(elink(puzzle['url'], 'Puzzle')),
+ ' <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
' <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
' <td>Additional Resources</td>\n',
' </tr>\n',
' <table class="center">\n',
' <tr>\n',
' <td>Round(s): {}</td>\n'.format(" ".join(round_url)), #round page on our site
- ' <td>Tags: {}</td>\n'.format(" ".join(puzzle['tags'])), #add tags
+ ' <td>Tags: {}</td>\n'.format(" ".join(puzzle.get('tags',[]))), #add tags
' </tr>\n',
' <tr>\n',
' <td>Answer: {}</td>\n'.format(solution),
'\n',
'</body>\n',
'</html>\n']
- underscored = "_".join(name.split())
- file = "{}.html".format(underscored)
+ file = "{}.html".format(filename_from_name(name))
f = open(file, "w")
for line in html:
f.write(line)
else:
meta = ''
slack_url = channel_url(puzzle['channel_id'])
- round_url = link(website + "_".join(rnd.split()) + "_round.html", puzzle['rounds'][0])
+ if 'rounds' in puzzle:
+ round_url = link(website + filename_from_name(rnd) + "_round.html", puzzle['rounds'][0])
+ else:
+ round_url = ''
#assuming one round per puzzle for now
solved_code += [' <tr>\n',
' <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
- ' <td>{}</td>\n'.format(elink(puzzle['url'], 'Puzzle')),
+ ' <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
' <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
- ' <td>{}</td>\n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')),
+ ' <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
' <td>{}</td>\n'.format(puzzle['solution']),
' <td>{}</td>\n'.format(round_url),
- ' <td>{}</td>\n'.format("".join(puzzle['tags'])),
+ ' <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
' </tr>\n']
for puzzle in unsolved_puzzles:
if puzzle['type'] == 'meta':
else:
meta = ''
slack_url = channel_url(puzzle['channel_id'])
- round_url = link(website + "_".join(rnd.split()) + "_round.html", puzzle['rounds'][0])
+ if 'rounds' in puzzle:
+ round_url = link(website + filename_from_name(rnd) + "_round.html", puzzle['rounds'][0])
+ else:
+ round_url = ''
#assuming one round per puzzle for now
unsolved_code += [' <tr>\n',
' <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
- ' <td>{}</td>\n'.format(elink(puzzle['url'], 'Puzzle')),
+ ' <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
' <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
- ' <td>{}</td>\n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')),
+ ' <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
' <td></td>\n',
' <td>{}</td>\n'.format(round_url),
- ' <td>{}</td>\n'.format("".join(puzzle['tags'])),
+ ' <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
' </tr>\n']
end = [' </tbody>\n',
' </table>\n',
f.close()
return None
+# Initialize AWS resources to talk to database
+db = boto3.resource('dynamodb')
+table = db.Table("turbot")
+puzzles, rounds = hunt_info(table, "mh2021")
-
-puzzles, rounds = hunt_info(turb, hunt)
-#I am not sure where these come from
overview(puzzles, rounds)
for rnd in rounds:
round_overview(rnd, puzzles)