]> git.cworth.org Git - turbot-web/blobdiff - html_generator.py
Add code to auto-refresh each HTML page
[turbot-web] / html_generator.py
index 7d2c318fbd09293fccec6e371c1f1b76ade0efd9..f18703211897d73f90fdec216645e24f22a53e33 100644 (file)
@@ -22,8 +22,6 @@ import sys
 
 WEBROOT = "/srv/halibut.cworth.org/www"
 
-website = "https://halibut.cworth.org/"
-#change this if we're using AWS or some other subdomain instead
 
 def hunt_file(hunt, name):
     """Return a path file 'name' within the given hunt.
@@ -32,6 +30,12 @@ def hunt_file(hunt, name):
 
     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)"""
@@ -141,6 +145,7 @@ def overview(hunt, puzzles, rounds):
      '<head>\n',
      '  <meta charset="utf-8">\n',
      '  <meta name="viewport" content="width=device-width, initial-scale=1">\n',
+     '  <meta http-equiv="refresh" content = "15">\n',
      '\n',
      '  <link rel="stylesheet" href="/overview.css">\n',
      '  <script type="text/javascript">\n',
@@ -158,12 +163,13 @@ def overview(hunt, puzzles, rounds):
      '  <title>Hunt Overview</title>\n',
      '  <script src="/sorttable.js"></script>\n'
      '</head>\n',
-     '    <div class="sidenav">\n'
-     '      <a href="index.html">Hunt Overview</a>'
-     '      <a href="all.html">All Puzzles</a>\n'
-     '      <a href="unsolved.html">Unsolved</a>\n'
-     '      <a href="solved.html">Solved</a>\n'
-     '    </div>\n'
+     '    <div class="sidenav">\n',
+     '      <a href="index.html">Hunt Overview</a>',
+     '      <a href="all.html">All Puzzles</a>\n',
+     '      <a href="unsolved.html">Unsolved</a>\n',
+     '      <a href="solved.html">Solved</a>\n',
+     '      <a href="https://docs.google.com/document/d/14Ww6vWFO4hx1GYz8zDRxP_rI_v4hmRgdgYmN91F-Lqk/edit" target="_blank" rel="noreferrer noopener">Turbot Docs</a>\n'
+     '    </div>\n',
      '<body>\n',]
     columns = ['  <div class="row">\n']
     expanding = []
@@ -183,7 +189,7 @@ def overview(hunt, puzzles, rounds):
         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 + filename_from_name(rnd) + "_round.html", rnd)),
+        '    <h2>{}</h2>\n'.format(link(internal_link(hunt, filename_from_name(rnd)) + "_round.html", rnd)),
         '    <table class="sortable">\n',
         '      <tr>\n',
         '        <th><u>Puzzle</u></th>\n',
@@ -197,12 +203,12 @@ def overview(hunt, puzzles, rounds):
                 meta = ''
             if puzzle['status'] == 'solved':
                 expanding += ['      <tr class=\'solved\';>\n',
-                '        <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + ".html", puzzle['name']+meta)),
-                '        <td>{}</td>\n'.format(puzzle['solution']),
+                '        <td>{}</td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", puzzle['name']+meta)),
+                '        <td>{}</td>\n'.format(", ".join(puzzle['solution']).upper()),
                 '      </tr>\n']
             else:
                 expanding += ['      <tr class=\'unsolved\';>\n',
-                '        <td><b>{}</b></td>\n'.format(link(website + filename_from_name(puzzle['name']) + ".html", puzzle['name']+meta)),
+                '        <td><b>{}</b></td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", puzzle['name']+meta)),
                 '        <td></td>\n',
                 '      </tr>\n']
         expanding.append('    </table>\n')
@@ -212,10 +218,11 @@ def overview(hunt, puzzles, rounds):
     end = ['</body>\n', '</html>\n']
     html = start + expanding + columns + end
     file = hunt_file(hunt, "index.html")
-    f = open(file, "w")
+    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):
@@ -233,10 +240,11 @@ def round_overview(hunt, rnd, puzzles):
      '        <link rel="stylesheet" href="/individual.css">\n',
      '        <title>Mystery Hunt 2022</title>\n',
      '        <script src="/sorttable.js"></script>\n',
+     '        <meta http-equiv="refresh" content = "15">\n',
      '    </head>\n',
      '    <body class="{}">\n'.format(status),
      '        <h1><b>{}</b></h1>\n'.format(rnd),
-     '        <p>{}</p>\n'.format(link(website + "index.html", 'Hunt Overview')),
+     '        <p>{}</p>\n'.format(link(internal_link(hunt, "index") + ".html", 'Hunt Overview')),
      '        <div>\n',
      '            <table class="center sortable">\n',
      '                <thead>\n',
@@ -264,20 +272,20 @@ def round_overview(hunt, rnd, puzzles):
              '                        <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
              '                        <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
              '                        <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
-             '                        <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
-             '                        <td>{}</td>\n'.format(puzzle['solution']),
+             '                        <td>{}</td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')),
+             '                        <td>{}</td>\n'.format(", ".join(puzzle['solution']).upper()),
             # '                        <td></td>\n',
-             '                        <td>{}</td>\n'.format("".join(puzzle.get('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.get('url',''), 'Puzzle')),
              '                        <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
-             '                        <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
+             '                        <td>{}</td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')),
              '                        <td></td>\n',
             # '                        <td></td>\n',
-             '                        <td>{}</td>\n'.format(" ".join(puzzle.get('tags',[]))),
+             '                        <td>{}</td>\n'.format(", ".join(puzzle.get('tags',[]))),
              '                    </tr>\n']
     end = ['                </tbody>\n',
     '            </table>\n',
@@ -286,10 +294,11 @@ def round_overview(hunt, rnd, puzzles):
     '</html>\n']
     html = start + puzzle_list + end
     file = hunt_file(hunt, "{}_round.html".format(filename_from_name(rnd)))
-    f = open(file, "w")
+    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):
@@ -302,11 +311,11 @@ def puzzle_overview(hunt, puzzle):
         meta = ''
     slack_url = channel_url(puzzle['channel_id'])
     if 'rounds' in puzzle:
-        round_url = [link(website + filename_from_name(rnd) + "_round.html", rnd) for rnd in puzzle['rounds']]
+        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 = puzzle['solution']
+        solution = ", ".join(puzzle['solution']).upper()
         status = 'solved'
     else:
         solution = ""
@@ -316,9 +325,10 @@ def puzzle_overview(hunt, puzzle):
      '<head>\n',
      '    <meta charset="utf-8">\n',
      '    <meta name="viewport" content="width=device-width, initial-scale=1">\n',
+     '    <meta http-equiv="refresh" content = "15">\n',
      '    <link rel="stylesheet" href="/individual.css">\n',
      '    <title>{}</title>\n'.format(name+meta),
-     '    <p>{}</p>'.format(link(website + 'index.html', 'Hunt Overview')),
+     '    <p>{}</p>'.format(link(internal_link(hunt, 'index') + ".html", 'Hunt Overview')),
      '\n',
      '</head>\n',
      '<body class="{}">\n'.format(status),
@@ -335,7 +345,7 @@ def puzzle_overview(hunt, puzzle):
      '        <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.get('tags',[]))), #add tags
+     '                <td>Tags: {}</td>\n'.format(", ".join(puzzle.get('tags',[]))), #add tags
      '            </tr>\n',
      '            <tr>\n',
      '                <td>Answer: {}</td>\n'.format(solution),
@@ -347,9 +357,11 @@ def puzzle_overview(hunt, puzzle):
      '</body>\n',
      '</html>\n']
     file = hunt_file(hunt, "{}.html".format(filename_from_name(name)))
-    f = open(file, "w")
+    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):
@@ -363,16 +375,18 @@ def puzzle_lists(hunt, puzzles, filt):
      '        <link rel="stylesheet" href="/overview.css">\n',
      '        <title>Mystery Hunt 2022</title>\n',
      '        <script src="/sorttable.js"></script>\n',
+     '        <meta http-equiv="refresh" content = "15">\n',
      '    </head>\n',
-     '    <div class="sidenav">\n'
-     '      <a href="index.html">Hunt Overview</a>'
-     '      <a href="all.html">All Puzzles</a>\n'
-     '      <a href="unsolved.html">Unsolved</a>\n'
-     '      <a href="solved.html">Solved</a>\n'
-     '    </div>\n'
+     '    <div class="sidenav">\n',
+     '      <a href="index.html">Hunt Overview</a>',
+     '      <a href="all.html">All Puzzles</a>\n',
+     '      <a href="unsolved.html">Unsolved</a>\n',
+     '      <a href="solved.html">Solved</a>\n',
+     '      <a href="https://docs.google.com/document/d/14Ww6vWFO4hx1GYz8zDRxP_rI_v4hmRgdgYmN91F-Lqk/edit" target="_blank" rel="noreferrer noopener">Turbot Docs</a>\n'
+     '    </div>\n',
      '    <body>\n',
      '        <h1><b>{}</b></h1>\n'.format('{} Puzzles').format(filt),
-     '        <p>{}</p>\n'.format(link(website + "index.html", 'Hunt Overview')),
+     '        <p>{}</p>\n'.format(link(internal_link(hunt, 'index') + ".html", 'Hunt Overview')),
      '        <div>\n',
      '            <table class="center sortable">\n',
      '                <thead>\n',
@@ -396,7 +410,7 @@ def puzzle_lists(hunt, puzzles, filt):
             meta = ''
         slack_url = channel_url(puzzle['channel_id'])
         if 'rounds' in puzzle:
-            round_url = link(website + filename_from_name(puzzle['rounds'][0]) + "_round.html", puzzle['rounds'][0])
+            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
@@ -405,10 +419,10 @@ def puzzle_lists(hunt, puzzles, filt):
          '                        <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
          '                        <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
          '                        <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
-         '                        <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
-         '                        <td>{}</td>\n'.format(puzzle['solution']),
+         '                        <td>{}</td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')),
+         '                        <td>{}</td>\n'.format(", ".join(puzzle['solution']).upper()),
          '                        <td>{}</td>\n'.format(round_url),
-         '                        <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
+         '                        <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
          '                    </tr>\n']
     for puzzle in unsolved_puzzles:
         if puzzle['type'] == 'meta':
@@ -417,7 +431,7 @@ def puzzle_lists(hunt, puzzles, filt):
             meta = ''
         slack_url = channel_url(puzzle['channel_id'])
         if 'rounds' in puzzle:
-            round_url = link(website + filename_from_name(puzzle['rounds'][0]) + "_round.html", puzzle['rounds'][0])
+            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
@@ -426,10 +440,10 @@ def puzzle_lists(hunt, puzzles, filt):
          '                        <td>{}</td>\n'.format(elink(slack_url, puzzle['name']+meta)),
          '                        <td>{}</td>\n'.format(elink(puzzle.get('url',''), 'Puzzle')),
          '                        <td>{}</td>\n'.format(elink(puzzle['sheet_url'], 'Sheet')),
-         '                        <td>{}</td>\n'.format(link(website + filename_from_name(puzzle['name']) + '.html', 'Overview')),
+         '                        <td>{}</td>\n'.format(link(internal_link(hunt, filename_from_name(puzzle['name'])) + ".html", 'Overview')),
          '                        <td></td>\n',
          '                        <td>{}</td>\n'.format(round_url),
-         '                        <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
+         '                        <td>{}</td>\n'.format("".join(puzzle.get('tags',[]))),
          '                    </tr>\n']
     end = ['                </tbody>\n',
     '            </table>\n',
@@ -438,22 +452,25 @@ def puzzle_lists(hunt, puzzles, filt):
     '</html>\n']
     if filt == "All":
         file1 = hunt_file(hunt, 'all.html')
-        f = open(file1, "w")
+        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, 'w')
+        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, 'w')
+        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):
@@ -470,11 +487,12 @@ def generate_for_hunt_id(table, hunt_id):
     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")
+    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')