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']
- 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',
- ' \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',
+ '\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',
+ '