X-Git-Url: https://git.cworth.org/git?p=turbot-web;a=blobdiff_plain;f=html_generator.py;h=0fef3d421c3f1b9158a7e97932f07b43342b24a6;hp=1ba3ac5bcf985dea3fe027ff11b0b92b23488a89;hb=HEAD;hpb=b8a3ad3918a6367744d4a7bff7cdb27f12155702 diff --git a/html_generator.py b/html_generator.py index 1ba3ac5..f187032 100644 --- a/html_generator.py +++ b/html_generator.py @@ -1,438 +1,512 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Jan 6 23:35:23 2022 - -@author: Avram Gottschlich -""" -""" -I copied several functions from your code; -if it's easier to refer to them rather than copying them that's absolutely fine - -This rewrites the html each time it is called -If it's easy to call the puzzle/round functions each time they're updated, -that would be great - -Requires sorttable.js, which should be included -""" -from turbot.channel import channel_url -from boto3.dynamodb.conditions import Key - -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): - """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( - Key={ - 'hunt_id': hunt_id, - 'SK': 'hunt-{}'.format(hunt_id) - }) - - if 'Item' in response: - return response['Item'] - 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 elink(lin, text): - #shortcutting function for creating html links - #opens in a new tab for external links - return '{}'.format(lin, text) - -def link(lin, text): - #internal links, doesn't open new tab - return '{}'.format(lin, text) - -def hunt_info(turb, hunt): - """ - Retrieves list of rounds, puzzles for the given hunt - """ - name = hunt["name"] - hunt_id = hunt["hunt_id"] - channel_id = hunt["channel_id"] - - puzzles = hunt_puzzles_for_hunt_id(turb, hunt_id) - - rounds = set() - for puzzle in puzzles: - if "rounds" not in puzzle: - continue - for rnd in puzzle["rounds"]: - rounds.add(rnd) - rounds = list(rounds) - rounds.sort() - - return puzzles, rounds - -def round_stat(rnd, puzzles): - #Counts puzzles, solved, list of puzzles for a given round - puzzle_count = 0 - solved_count = 0 - solved_puzzles = [] - unsolved_puzzles = [] - metas = [] - meta_solved = 0 - for puzzle in puzzles: - if "rounds" not in puzzle: - continue - if rnd in puzzle["rounds"]: - if puzzle['type'] == 'meta': - metas.append(puzzle) - if puzzle['status'] == 'solved': - meta_solved += 1 - else: - puzzle_count += 1 - if puzzle['status'] == 'solved': - solved_count += 1 - solved_puzzles.append(puzzle) - else: - unsolved_puzzles.append(puzzle) - solved_puzzles = sorted(solved_puzzles, key = lambda i: i['name']) - unsolved_puzzles = sorted(unsolved_puzzles, key = lambda i: i['name']) - rnd_puzzles = metas + unsolved_puzzles + solved_puzzles - return puzzle_count, solved_count, rnd_puzzles, meta_solved, len(metas) - - - -def overview(puzzles, rounds): - #big board, main page. saves as index.html - start = ['\n', - '\n', - '\n', - ' \n', - ' \n', - '\n', - ' \n', - ' \n', - '\n', - ' Hunt Overview\n', - ' \n' - '\n', - '
\n' - ' Hunt Overview' - ' All Puzzles\n' - ' Unsolved\n' - ' Solved\n' - '
\n' - '\n',] - columns = ['
\n'] - expanding = [] - i = 1 - for rnd in rounds: - puzzle_count, solved_count, rnd_puzzles, meta_solved, metas = round_stat(rnd, puzzles) - if metas == meta_solved and metas > 0: - status = 'solved' - else: - status = 'unsolved' - columns += ['
\n'.format(status, i), - '

{}

\n'.format(rnd), - '

Puzzles: {}/{}

\n'.format(solved_count, puzzle_count), - '

Metas: {}/{}

\n'.format(meta_solved, metas), - '
\n'] - - expanding += [ - ' \n') - i += 1 - columns.append('
\n') - end = ['\n', '\n'] - html = start + expanding + columns + end - file = "index.html" - f = open(file, "w") - for line in html: - f.write(line) - f.close() - return None - -def round_overview(rnd, puzzles): - #inputs: round name, puzzles - #round overview page - #saves as (round name)_round.html, in case meta/round share names. - #underscores replace spaces for links. - rnd_puzzles, meta_solved, metas = round_stat(rnd, puzzles)[2:] - if meta_solved == metas and metas > 0: - status = 'solved' - else: - status = 'unsolved' - start = ['\n', - ' \n', - ' \n', - ' Mystery Hunt 2022\n', - ' \n', - ' \n', - ' \n'.format(status), - '

{}

\n'.format(rnd), - '

{}

\n'.format(link(website + "index.html", 'Hunt Overview')), - '
\n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - #' \n', - ' \n', - ' \n', - ' \n', - ' \n'] - puzzle_list = [] - for puzzle in rnd_puzzles: - if puzzle['type'] == 'meta': - meta = ' [META]' - else: - meta = '' - slack_url = channel_url(puzzle['channel_id']) - - if puzzle['status'] == 'solved': - puzzle_list += [ ' \n', - ' \n'.format(elink(slack_url, puzzle['name']+meta)), - ' \n'.format(elink(puzzle['url'], 'Puzzle')), - ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), - ' \n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')), - ' \n'.format(puzzle['solution']), - # ' \n', - ' \n'.format("".join(puzzle['tags'])), - ' \n'] - else: - puzzle_list += [ ' \n', - ' \n'.format(elink(slack_url, puzzle['name']+meta)), - ' \n'.format(elink(puzzle['url'], 'Puzzle')), - ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), - ' \n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')), - ' \n', - # ' \n', - ' \n'.format(" ".join(puzzle['tags'])), - ' \n'] - end = [' \n', - '
Puzzle Title/SlackPuzzle LinkSheetOverviewAnswerExtra LinksTags
{}{}{}{}{}{}
{}{}{}{}{}
\n', - '
\n', - ' \n', - '\n'] - html = start + puzzle_list + end - file = "{}_round.html".format('_'.join(rnd.split())) - f = open(file, "w") - for line in html: - f.write(line) - f.close() - return None - -def puzzle_overview(puzzle): - #overview page for individual puzzles. saves as (name of puzzle).html, - #with underscores rather than spaces - name = puzzle['name'] - if puzzle['type'] == 'meta': - meta = ' [META]' - 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 puzzle['status'] == 'solved': - solution = puzzle['solution'] - status = 'solved' - else: - solution = "" - status = 'unsolved' - html = ['\n', - '\n', - '\n', - ' \n', - ' \n', - ' \n', - ' {}\n'.format(name+meta), - '

{}

'.format(link(website + 'index.html', 'Hunt Overview')), - '\n', - '\n', - '\n'.format(status), - '

{}

\n'.format(name+meta), - '
\n', - ' \n', - ' \n', - ' \n'.format(elink(slack_url, 'Channel')), #slack channel - ' \n'.format(elink(puzzle['url'], 'Puzzle')), - ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), - ' \n', - ' \n', - '
{}{}{}Additional Resources
\n', - ' \n', - ' \n', - ' \n'.format(" ".join(round_url)), #round page on our site - ' \n'.format(" ".join(puzzle['tags'])), #add tags - ' \n', - ' \n', - ' \n'.format(solution), - ' \n'.format(puzzle['status']), - ' \n', - '
Round(s): {}Tags: {}
Answer: {}State: {}
\n', - '
\n', - '\n', - '\n', - '\n'] - underscored = "_".join(name.split()) - file = "{}.html".format(underscored) - f = open(file, "w") - for line in html: - f.write(line) - return None - -def puzzle_lists(puzzles, filt): - #filt is one of "All", "Solved", "Unsolved" and spits out the appropriate list of puzzles - #generates pages for all puzzles, solved puzzles, unsolved puzzles - #saves as all/solved/unsolved.html, has a sidebar to link to each other and to the big board - solved_puzzles = [puzzle for puzzle in puzzles if puzzle['status'] == 'solved'] - unsolved_puzzles = [puzzle for puzzle in puzzles if puzzle['status'] != 'solved'] - start = ['\n', - ' \n', - ' \n', - ' Mystery Hunt 2022\n', - ' \n', - ' \n', - '
\n' - ' Hunt Overview' - ' All Puzzles\n' - ' Unsolved\n' - ' Solved\n' - '
\n' - ' \n', - '

{}

\n'.format('{} Puzzles').format(filt), - '

{}

\n'.format(link(website + "index.html", 'Hunt Overview')), - '
\n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n', - ' \n'] - solved_code = [] - unsolved_code = [] - for puzzle in solved_puzzles: - if puzzle['type'] == 'meta': - meta = ' [META]' - else: - meta = '' - slack_url = channel_url(puzzle['channel_id']) - round_url = link(website + "_".join(rnd.split()) + "_round.html", puzzle['rounds'][0]) - #assuming one round per puzzle for now - - solved_code += [' \n', - ' \n'.format(elink(slack_url, puzzle['name']+meta)), - ' \n'.format(elink(puzzle['url'], 'Puzzle')), - ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), - ' \n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')), - ' \n'.format(puzzle['solution']), - ' \n'.format(round_url), - ' \n'.format("".join(puzzle['tags'])), - ' \n'] - for puzzle in unsolved_puzzles: - if puzzle['type'] == 'meta': - meta = ' [META]' - else: - meta = '' - slack_url = channel_url(puzzle['channel_id']) - round_url = link(website + "_".join(rnd.split()) + "_round.html", puzzle['rounds'][0]) - #assuming one round per puzzle for now - - unsolved_code += [' \n', - ' \n'.format(elink(slack_url, puzzle['name']+meta)), - ' \n'.format(elink(puzzle['url'], 'Puzzle')), - ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), - ' \n'.format(link(website + "_".join(puzzle['name'].split()) + '.html', 'Overview')), - ' \n', - ' \n'.format(round_url), - ' \n'.format("".join(puzzle['tags'])), - ' \n'] - end = [' \n', - '
Puzzle Title/SlackPuzzle LinkSheetOverviewAnswerRound(s)Tags
{}{}{}{}{}{}{}
{}{}{}{}{}{}
\n', - '
\n', - ' \n', - '\n'] - if filt == "All": - file1 = 'all.html' - f = open(file1, "w") - for line in start + unsolved_code + solved_code + end: - f.write(line) - f.close() - elif filt == "Solved": - file2 = 'solved.html' - f = open(file2, 'w') - for line in start + solved_code + end: - f.write(line) - f.close() - elif filt == "Unsolved": - file3 = 'unsolved.html' - f = open(file3, 'w') - for line in start + unsolved_code + end: - f.write(line) - f.close() - return None - - - -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) -for puzzle in puzzles: - puzzle_overview(puzzle) -puzzle_lists(puzzles, "All") -puzzle_lists(puzzles, "Solved") -puzzle_lists(puzzles, "Unsolved") \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 6 23:35:23 2022 + +@author: Avram Gottschlich +""" +""" +I copied several functions from your code; +if it's easier to refer to them rather than copying them that's absolutely fine + +This rewrites the html each time it is called +If it's easy to call the puzzle/round functions each time they're updated, +that would be great + +Requires sorttable.js, which should be included +""" +import boto3 +from boto3.dynamodb.conditions import Key +import os +import re +import sys + +WEBROOT = "/srv/halibut.cworth.org/www" + + +def hunt_file(hunt, name): + """Return a path file 'name' within the given hunt. + + This will be withing WEBROOT and in a hunt-specific path.""" + + return "{}/{}/{}".format(WEBROOT, hunt['channel_id'], name) + +def internal_link(hunt, name): + """Returns a path for a link on this site.""" + + # Just generate a relative link, (which is just the name itself) + return "{}".format(name) + +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 = table.get_item( + Key={ + 'hunt_id': hunt_id, + 'SK': 'hunt-{}'.format(hunt_id) + }) + + if 'Item' in response: + return response['Item'] + else: + return None + +def hunt_puzzles_for_hunt_id(table, hunt_id): + """Return all puzzles that belong to the given hunt_id""" + + response = table.query( + KeyConditionExpression=( + Key('hunt_id').eq(hunt_id) & + Key('SK').begins_with('puzzle-') + ) + ) + + return response['Items'] + +def elink(lin, text): + #shortcutting function for creating html links + #opens in a new tab for external links + return '{}'.format(lin, text) + +def link(lin, text): + #internal links, doesn't open new tab + return '{}'.format(lin, text) + +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"] + channel_id = hunt["channel_id"] + + puzzles = hunt_puzzles_for_hunt_id(table, hunt_id) + + rounds = set() + for puzzle in puzzles: + if "rounds" not in puzzle: + continue + for rnd in puzzle["rounds"]: + rounds.add(rnd) + rounds = list(rounds) + rounds.sort() + + return hunt, puzzles, rounds + +def round_stat(rnd, puzzles): + #Counts puzzles, solved, list of puzzles for a given round + puzzle_count = 0 + solved_count = 0 + solved_puzzles = [] + unsolved_puzzles = [] + metas = [] + meta_solved = 0 + for puzzle in puzzles: + if "rounds" not in puzzle: + continue + if rnd in puzzle["rounds"]: + if puzzle['type'] == 'meta': + metas.append(puzzle) + if puzzle['status'] == 'solved': + meta_solved += 1 + else: + puzzle_count += 1 + if puzzle['status'] == 'solved': + solved_count += 1 + solved_puzzles.append(puzzle) + else: + unsolved_puzzles.append(puzzle) + solved_puzzles = sorted(solved_puzzles, key = lambda i: i['name']) + unsolved_puzzles = sorted(unsolved_puzzles, key = lambda i: i['name']) + rnd_puzzles = metas + unsolved_puzzles + solved_puzzles + return puzzle_count, solved_count, rnd_puzzles, meta_solved, len(metas) + + + +def overview(hunt, puzzles, rounds): + #big board, main page. saves as index.html + start = ['\n', + '\n', + '\n', + ' \n', + ' \n', + ' \n', + '\n', + ' \n', + ' \n', + '\n', + ' Hunt Overview\n', + ' \n' + '\n', + '
\n', + ' Hunt Overview', + ' All Puzzles\n', + ' Unsolved\n', + ' Solved\n', + ' Turbot Docs\n' + '
\n', + '\n',] + columns = ['
\n'] + expanding = [] + i = 1 + for rnd in rounds: + puzzle_count, solved_count, rnd_puzzles, meta_solved, metas = round_stat(rnd, puzzles) + if metas == meta_solved and metas > 0: + status = 'solved' + else: + status = 'unsolved' + columns += ['
\n'.format(status, i), + '

{}

\n'.format(rnd), + '

Puzzles: {}/{}

\n'.format(solved_count, puzzle_count), + '

Metas: {}/{}

\n'.format(meta_solved, metas), + '
\n'] + + expanding += [ + ' \n') + i += 1 + columns.append('
\n') + end = ['\n', '\n'] + html = start + expanding + columns + end + file = hunt_file(hunt, "index.html") + f = open(file + ".tmp", "w") + for line in html: + f.write(line) + f.close() + os.rename(file + ".tmp", file) + return None + +def round_overview(hunt, rnd, puzzles): + #inputs: round name, puzzles + #round overview page + #saves as (round name)_round.html, in case meta/round share names. + #underscores replace spaces for links. + rnd_puzzles, meta_solved, metas = round_stat(rnd, puzzles)[2:] + if meta_solved == metas and metas > 0: + status = 'solved' + else: + status = 'unsolved' + start = ['\n', + ' \n', + ' \n', + ' Mystery Hunt 2022\n', + ' \n', + ' \n', + ' \n', + ' \n'.format(status), + '

{}

\n'.format(rnd), + '

{}

\n'.format(link(internal_link(hunt, "index") + ".html", 'Hunt Overview')), + '
\n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + #' \n', + ' \n', + ' \n', + ' \n', + ' \n'] + puzzle_list = [] + for puzzle in rnd_puzzles: + if puzzle['type'] == 'meta': + meta = ' [META]' + else: + meta = '' + slack_url = channel_url(puzzle['channel_id']) + + if puzzle['status'] == 'solved': + puzzle_list += [ ' \n', + ' \n'.format(elink(slack_url, puzzle['name']+meta)), + ' \n'.format(elink(puzzle.get('url',''), 'Puzzle')), + ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), + ' \n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')), + ' \n'.format(", ".join(puzzle['solution']).upper()), + # ' \n', + ' \n'.format(", ".join(puzzle.get('tags',[]))), + ' \n'] + else: + puzzle_list += [ ' \n', + ' \n'.format(elink(slack_url, puzzle['name']+meta)), + ' \n'.format(elink(puzzle.get('url',''), 'Puzzle')), + ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), + ' \n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')), + ' \n', + # ' \n', + ' \n'.format(", ".join(puzzle.get('tags',[]))), + ' \n'] + end = [' \n', + '
Puzzle Title/SlackPuzzle LinkSheetOverviewAnswerExtra LinksTags
{}{}{}{}{}{}
{}{}{}{}{}
\n', + '
\n', + ' \n', + '\n'] + html = start + puzzle_list + end + file = hunt_file(hunt, "{}_round.html".format(filename_from_name(rnd))) + f = open(file + ".tmp", "w") + for line in html: + f.write(line) + f.close() + os.rename(file + ".tmp", file) + return None + +def puzzle_overview(hunt, puzzle): + #overview page for individual puzzles. saves as (name of puzzle).html, + #with underscores rather than spaces + name = puzzle['name'] + if puzzle['type'] == 'meta': + meta = ' [META]' + else: + meta = '' + slack_url = channel_url(puzzle['channel_id']) + if 'rounds' in puzzle: + round_url = [link(internal_link(hunt, filename_from_name(rnd)) + "_round.html", rnd) for rnd in puzzle['rounds']] + else: + round_url = '' + if puzzle['status'] == 'solved': + solution = ", ".join(puzzle['solution']).upper() + status = 'solved' + else: + solution = "" + status = 'unsolved' + html = ['\n', + '\n', + '\n', + ' \n', + ' \n', + ' \n', + ' \n', + ' {}\n'.format(name+meta), + '

{}

'.format(link(internal_link(hunt, 'index') + ".html", 'Hunt Overview')), + '\n', + '\n', + '\n'.format(status), + '

{}

\n'.format(name+meta), + '
\n', + ' \n', + ' \n', + ' \n'.format(elink(slack_url, 'Channel')), #slack channel + ' \n'.format(elink(puzzle.get('url',''), 'Puzzle')), + ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), + ' \n', + ' \n', + '
{}{}{}Additional Resources
\n', + ' \n', + ' \n', + ' \n'.format(" ".join(round_url)), #round page on our site + ' \n'.format(", ".join(puzzle.get('tags',[]))), #add tags + ' \n', + ' \n', + ' \n'.format(solution), + ' \n'.format(puzzle['status']), + ' \n', + '
Round(s): {}Tags: {}
Answer: {}State: {}
\n', + '
\n', + '\n', + '\n', + '\n'] + file = hunt_file(hunt, "{}.html".format(filename_from_name(name))) + f = open(file + ".tmp", "w") + for line in html: + f.write(line) + f.close() + os.rename(file + ".tmp", file) + return None + +def puzzle_lists(hunt, puzzles, filt): + #filt is one of "All", "Solved", "Unsolved" and spits out the appropriate list of puzzles + #generates pages for all puzzles, solved puzzles, unsolved puzzles + #saves as all/solved/unsolved.html, has a sidebar to link to each other and to the big board + solved_puzzles = [puzzle for puzzle in puzzles if puzzle['status'] == 'solved'] + unsolved_puzzles = [puzzle for puzzle in puzzles if puzzle['status'] != 'solved'] + start = ['\n', + ' \n', + ' \n', + ' Mystery Hunt 2022\n', + ' \n', + ' \n', + ' \n', + '
\n', + ' Hunt Overview', + ' All Puzzles\n', + ' Unsolved\n', + ' Solved\n', + ' Turbot Docs\n' + '
\n', + ' \n', + '

{}

\n'.format('{} Puzzles').format(filt), + '

{}

\n'.format(link(internal_link(hunt, 'index') + ".html", 'Hunt Overview')), + '
\n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n', + ' \n'] + solved_code = [] + unsolved_code = [] + for puzzle in solved_puzzles: + if puzzle['type'] == 'meta': + meta = ' [META]' + else: + meta = '' + slack_url = channel_url(puzzle['channel_id']) + if 'rounds' in puzzle: + round_url = link(internal_link(hunt, filename_from_name(puzzle['rounds'][0])) + "_round.html", puzzle['rounds'][0]) + else: + round_url = '' + #assuming one round per puzzle for now + + solved_code += [' \n', + ' \n'.format(elink(slack_url, puzzle['name']+meta)), + ' \n'.format(elink(puzzle.get('url',''), 'Puzzle')), + ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), + ' \n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')), + ' \n'.format(", ".join(puzzle['solution']).upper()), + ' \n'.format(round_url), + ' \n'.format(", ".join(puzzle.get('tags',[]))), + ' \n'] + for puzzle in unsolved_puzzles: + if puzzle['type'] == 'meta': + meta = ' [META]' + else: + meta = '' + slack_url = channel_url(puzzle['channel_id']) + if 'rounds' in puzzle: + round_url = link(internal_link(hunt, filename_from_name(puzzle['rounds'][0])) + "_round.html", puzzle['rounds'][0]) + else: + round_url = '' + #assuming one round per puzzle for now + + unsolved_code += [' \n', + ' \n'.format(elink(slack_url, puzzle['name']+meta)), + ' \n'.format(elink(puzzle.get('url',''), 'Puzzle')), + ' \n'.format(elink(puzzle['sheet_url'], 'Sheet')), + ' \n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')), + ' \n', + ' \n'.format(round_url), + ' \n'.format(", ".join(puzzle.get('tags',[]))), + ' \n'] + end = [' \n', + '
Puzzle Title/SlackPuzzle LinkSheetOverviewAnswerRound(s)Tags
{}{}{}{}{}{}{}
{}{}{}{}{}{}
\n', + '
\n', + ' \n', + '\n'] + if filt == "All": + file1 = hunt_file(hunt, 'all.html') + f = open(file1 + ".tmp", "w") + for line in start + unsolved_code + solved_code + end: + f.write(line) + f.close() + os.rename(file1 + ".tmp", file1) + elif filt == "Solved": + file2 = hunt_file(hunt, 'solved.html') + f = open(file2 + ".tmp", 'w') + for line in start + solved_code + end: + f.write(line) + f.close() + os.rename(file2 + ".tmp", file2) + elif filt == "Unsolved": + file3 = hunt_file(hunt, 'unsolved.html') + f = open(file3 + ".tmp", 'w') + for line in start + unsolved_code + end: + f.write(line) + f.close() + os.rename(file3 + ".tmp", file3) + return None + +def generate_for_hunt_id(table, hunt_id): + hunt, puzzles, rounds = hunt_info(table, hunt_id) + + # Create a directory for the hunt in the WEBROOT + root = hunt_file(hunt, "") + try: + os.mkdir(root) + except FileExistsError: + # We're happy as a clam if the directory already exists + pass + + overview(hunt, puzzles, rounds) + for rnd in rounds: + round_overview(hunt, rnd, puzzles) + for puzzle in puzzles: + puzzle_overview(hunt, puzzle) + puzzle_lists(hunt, puzzles, "All") + puzzle_lists(hunt, puzzles, "Solved") + puzzle_lists(hunt, puzzles, "Unsolved") + + +# Initialize AWS resources to talk to the database +db = boto3.resource('dynamodb') +table = db.Table("turbot") + +def usage(): + print("Usage: {} hunt_id [...]") + print("") + print("Generates pages (under {}) ".format(WEBROOT)) + print("for the specified hunt_id(s).") + +if len(sys.argv) < 2: + usage() + sys.exit(1) + +for hunt_id in sys.argv[1:]: + generate_for_hunt_id(table, hunt_id)