From 70db99ebf6f74cbffebf824a731ef64b27432d15 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 09:36:24 -0600 Subject: [PATCH 01/12] starting zip capability --- package-puzzles | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100755 package-puzzles diff --git a/package-puzzles b/package-puzzles new file mode 100755 index 0000000..0304ca4 --- /dev/null +++ b/package-puzzles @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 + +import argparse +import base64 +import glob +import hashlib +import hmac +import io +import json +import os +import markdown +import random +import uuid +import zipfile + +messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + +def djb2hash(buf): + h = 5381 + for c in buf: + h = ((h * 33) + c) & 0xffffffff + return h + +def write_kv_pairs(ziphandle, filename, kv): + filehandle = io.StringIO() + for key in sorted(kv.keys()): + if type(kv[key]) == type([]): + for val in kv[key]: + filehandle.write("%s: %s%s" % (key, val, os.linesep)) + else: + filehandle.write("%s: %s%s" % (key, kv[key], os.linesep)) + filehandle.seek(0) + ziphandle.writestr(filename, filehandle.read()) + +class Puzzle: + def __init__(self, stream): + self.message = bytes(random.choice(messageChars) for i in range(20)) + self.fields = {} + self.answers = [] + self.hashes = [] + + body = [] + header = True + for line in stream: + if header: + line = line.strip() + if not line.strip(): + header = False + continue + key, val = line.split(':', 1) + key = key.lower() + val = val.strip() + self._add_field(key, val) + else: + body.append(line) + self.body = ''.join(body) + + def _add_field(self, key, val): + if key == 'answer': + h = djb2hash(val.encode('utf8')) + self.answers.append(val) + self.hashes.append(h) + else: + self.fields[key] = val + + def publish(self): + obj = { + 'author': self.fields['author'], + 'hashes': self.hashes, + 'body': markdown.markdown(self.body), + } + return obj + + def secrets(self): + obj = { + 'answers': self.answers, + 'summary': self.fields['summary'], + } + return obj + + +parser = argparse.ArgumentParser(description='Build a puzzle category') +parser.add_argument('seed', help='contest seed') +parser.add_argument('puzzledir', nargs='+', help='Directory of puzzle source') +parser.add_argument('outdir', help='Output directory') +args = parser.parse_args() + + +for puzzledir in args.puzzledir: + puzzles = {} + secrets = {} + + + categoryname = os.path.basename(puzzledir.strip(os.sep)) + + # build puzzle seed + puzzle_seed = hashlib.new('sha1') + puzzle_seed.update(categoryname.encode('utf-8')) + puzzle_seed.update(args.seed.encode('utf-8')) + puzzle_seed = puzzle_seed.hexdigest() + + # create zipfile + zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) + if os.path.exists(zipfilename): +# assume blank state for now + pass +# # open and gather some state +# zf = zipfile.ZipFile(zipfilename, 'a') + else: + # create and read in state + zf = zipfile.ZipFile(zipfilename, 'w') + + # read in puzzle details (will be pflarr in future) + for puzzlePath in glob.glob(os.path.join(puzzledir, "*.moth")): + filename = os.path.basename(puzzlePath) + points, ext = os.path.splitext(filename) + points = int(points) + puzzle = Puzzle(open(puzzlePath)) + puzzles[points] = puzzle + + # build mapping, answers, and summary + mapping = {} + answers = {} + summary = {} + for points in sorted(puzzles): + puzzle = puzzles[points] + + mapping[points] = str(uuid.uuid4()) # random uuid + answers[points] = puzzle.answers + summary[points] = puzzle.fields['summary'] + + # write mapping, answers, and summary + write_kv_pairs(zf, os.path.join(categoryname, 'mapping.txt'), mapping) + write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) + write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) + print(mapping) + print(answers) + print(summary) + + # write out puzzles + for points in sorted(puzzles): + puzzle = puzzles[points] + + +#vim:py From f865f3d0a3750a551823458c2a393e548a7843d0 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 09:36:24 -0600 Subject: [PATCH 02/12] starting zip capability --- package-puzzles | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100755 package-puzzles diff --git a/package-puzzles b/package-puzzles new file mode 100755 index 0000000..0304ca4 --- /dev/null +++ b/package-puzzles @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 + +import argparse +import base64 +import glob +import hashlib +import hmac +import io +import json +import os +import markdown +import random +import uuid +import zipfile + +messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + +def djb2hash(buf): + h = 5381 + for c in buf: + h = ((h * 33) + c) & 0xffffffff + return h + +def write_kv_pairs(ziphandle, filename, kv): + filehandle = io.StringIO() + for key in sorted(kv.keys()): + if type(kv[key]) == type([]): + for val in kv[key]: + filehandle.write("%s: %s%s" % (key, val, os.linesep)) + else: + filehandle.write("%s: %s%s" % (key, kv[key], os.linesep)) + filehandle.seek(0) + ziphandle.writestr(filename, filehandle.read()) + +class Puzzle: + def __init__(self, stream): + self.message = bytes(random.choice(messageChars) for i in range(20)) + self.fields = {} + self.answers = [] + self.hashes = [] + + body = [] + header = True + for line in stream: + if header: + line = line.strip() + if not line.strip(): + header = False + continue + key, val = line.split(':', 1) + key = key.lower() + val = val.strip() + self._add_field(key, val) + else: + body.append(line) + self.body = ''.join(body) + + def _add_field(self, key, val): + if key == 'answer': + h = djb2hash(val.encode('utf8')) + self.answers.append(val) + self.hashes.append(h) + else: + self.fields[key] = val + + def publish(self): + obj = { + 'author': self.fields['author'], + 'hashes': self.hashes, + 'body': markdown.markdown(self.body), + } + return obj + + def secrets(self): + obj = { + 'answers': self.answers, + 'summary': self.fields['summary'], + } + return obj + + +parser = argparse.ArgumentParser(description='Build a puzzle category') +parser.add_argument('seed', help='contest seed') +parser.add_argument('puzzledir', nargs='+', help='Directory of puzzle source') +parser.add_argument('outdir', help='Output directory') +args = parser.parse_args() + + +for puzzledir in args.puzzledir: + puzzles = {} + secrets = {} + + + categoryname = os.path.basename(puzzledir.strip(os.sep)) + + # build puzzle seed + puzzle_seed = hashlib.new('sha1') + puzzle_seed.update(categoryname.encode('utf-8')) + puzzle_seed.update(args.seed.encode('utf-8')) + puzzle_seed = puzzle_seed.hexdigest() + + # create zipfile + zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) + if os.path.exists(zipfilename): +# assume blank state for now + pass +# # open and gather some state +# zf = zipfile.ZipFile(zipfilename, 'a') + else: + # create and read in state + zf = zipfile.ZipFile(zipfilename, 'w') + + # read in puzzle details (will be pflarr in future) + for puzzlePath in glob.glob(os.path.join(puzzledir, "*.moth")): + filename = os.path.basename(puzzlePath) + points, ext = os.path.splitext(filename) + points = int(points) + puzzle = Puzzle(open(puzzlePath)) + puzzles[points] = puzzle + + # build mapping, answers, and summary + mapping = {} + answers = {} + summary = {} + for points in sorted(puzzles): + puzzle = puzzles[points] + + mapping[points] = str(uuid.uuid4()) # random uuid + answers[points] = puzzle.answers + summary[points] = puzzle.fields['summary'] + + # write mapping, answers, and summary + write_kv_pairs(zf, os.path.join(categoryname, 'mapping.txt'), mapping) + write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) + write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) + print(mapping) + print(answers) + print(summary) + + # write out puzzles + for points in sorted(puzzles): + puzzle = puzzles[points] + + +#vim:py From 1ba99db98f23c0a8899120285406428bf4d5e1c4 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 10:46:54 -0600 Subject: [PATCH 03/12] puzzle directories are writing --- package-puzzles | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/package-puzzles b/package-puzzles index 0304ca4..8b6f39f 100755 --- a/package-puzzles +++ b/package-puzzles @@ -10,7 +10,6 @@ import json import os import markdown import random -import uuid import zipfile messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -124,22 +123,30 @@ for puzzledir in args.puzzledir: summary = {} for points in sorted(puzzles): puzzle = puzzles[points] + print(args.seed) + print(categoryname) + print(points) - mapping[points] = str(uuid.uuid4()) # random uuid + hashmap = hashlib.sha1(args.seed.encode('utf-8')) + hashmap.update(categoryname.encode('utf-8')) + hashmap.update(str(points).encode('utf-8')) + mapping[points] = hashmap.hexdigest() answers[points] = puzzle.answers summary[points] = puzzle.fields['summary'] # write mapping, answers, and summary - write_kv_pairs(zf, os.path.join(categoryname, 'mapping.txt'), mapping) + write_kv_pairs(zf, os.path.join(categoryname, 'map.txt'), mapping) write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) - print(mapping) - print(answers) - print(summary) # write out puzzles for points in sorted(puzzles): puzzle = puzzles[points] + puzzledir = os.path.join(categoryname, "content", mapping[points]) + # test write + write_kv_pairs(zf, os.path.join(puzzledir, 'summary.txt'), summary) + # build json + #vim:py From 36c93973ccab4ee7cb78889347cf44c23a8d0813 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 15:42:42 -0600 Subject: [PATCH 04/12] some updates to package-puzzles --- package-puzzles | 180 +++++++++++++++++------------------------------- 1 file changed, 65 insertions(+), 115 deletions(-) diff --git a/package-puzzles b/package-puzzles index 8b6f39f..5ea2b0b 100755 --- a/package-puzzles +++ b/package-puzzles @@ -12,15 +12,15 @@ import markdown import random import zipfile -messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - -def djb2hash(buf): - h = 5381 - for c in buf: - h = ((h * 33) + c) & 0xffffffff - return h +import puzzles def write_kv_pairs(ziphandle, filename, kv): + """ Write out a sorted map to file + :param ziphandle: a zipfile object + :param filename: The filename to write within the zipfile object + :param kv: the map to write out + :return: + """ filehandle = io.StringIO() for key in sorted(kv.keys()): if type(kv[key]) == type([]): @@ -30,123 +30,73 @@ def write_kv_pairs(ziphandle, filename, kv): filehandle.write("%s: %s%s" % (key, kv[key], os.linesep)) filehandle.seek(0) ziphandle.writestr(filename, filehandle.read()) + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Build a puzzle category') + parser.add_argument('seed', help='contest seed') + parser.add_argument('puzzledir', nargs='+', help='Directory of puzzle source') + parser.add_argument('outdir', help='Output directory') + args = parser.parse_args() -class Puzzle: - def __init__(self, stream): - self.message = bytes(random.choice(messageChars) for i in range(20)) - self.fields = {} - self.answers = [] - self.hashes = [] - body = [] - header = True - for line in stream: - if header: - line = line.strip() - if not line.strip(): - header = False - continue - key, val = line.split(':', 1) - key = key.lower() - val = val.strip() - self._add_field(key, val) - else: - body.append(line) - self.body = ''.join(body) + for puzzledir in args.puzzledir: + puzzles = {} + secrets = {} - def _add_field(self, key, val): - if key == 'answer': - h = djb2hash(val.encode('utf8')) - self.answers.append(val) - self.hashes.append(h) - else: - self.fields[key] = val - def publish(self): - obj = { - 'author': self.fields['author'], - 'hashes': self.hashes, - 'body': markdown.markdown(self.body), - } - return obj - - def secrets(self): - obj = { - 'answers': self.answers, - 'summary': self.fields['summary'], - } - return obj - + categoryname = os.path.basename(puzzledir.strip(os.sep)) -parser = argparse.ArgumentParser(description='Build a puzzle category') -parser.add_argument('seed', help='contest seed') -parser.add_argument('puzzledir', nargs='+', help='Directory of puzzle source') -parser.add_argument('outdir', help='Output directory') -args = parser.parse_args() + # build puzzle seed + puzzle_seed = hashlib.new('sha1') + puzzle_seed.update(categoryname.encode('utf-8')) + puzzle_seed.update(args.seed.encode('utf-8')) + puzzle_seed = puzzle_seed.hexdigest() + # create zipfile + zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) + if os.path.exists(zipfilename): + # assume blank state for now + pass + # # open and gather some state + # zf = zipfile.ZipFile(zipfilename, 'a') + else: + # create and read in state + zf = zipfile.ZipFile(zipfilename, 'w') -for puzzledir in args.puzzledir: - puzzles = {} - secrets = {} + # read in puzzle details (will be pflarr in future) + for puzzlePath in glob.glob(os.path.join(puzzledir, "*.moth")): + filename = os.path.basename(puzzlePath) + points, ext = os.path.splitext(filename) + points = int(points) + puzzle = puzzles.Puzzle(open(puzzlePath)) + puzzles[points] = puzzle + # build mapping, answers, and summary + mapping = {} + answers = {} + summary = {} + for points in sorted(puzzles): + puzzle = puzzles[points] + hashmap = hashlib.sha1(args.seed.encode('utf-8')) + hashmap.update(categoryname.encode('utf-8')) + hashmap.update(str(points).encode('utf-8')) + mapping[points] = hashmap.hexdigest() + answers[points] = puzzle.answers + summary[points] = puzzle.fields['summary'] - categoryname = os.path.basename(puzzledir.strip(os.sep)) - - # build puzzle seed - puzzle_seed = hashlib.new('sha1') - puzzle_seed.update(categoryname.encode('utf-8')) - puzzle_seed.update(args.seed.encode('utf-8')) - puzzle_seed = puzzle_seed.hexdigest() - - # create zipfile - zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) - if os.path.exists(zipfilename): -# assume blank state for now - pass -# # open and gather some state -# zf = zipfile.ZipFile(zipfilename, 'a') - else: - # create and read in state - zf = zipfile.ZipFile(zipfilename, 'w') - - # read in puzzle details (will be pflarr in future) - for puzzlePath in glob.glob(os.path.join(puzzledir, "*.moth")): - filename = os.path.basename(puzzlePath) - points, ext = os.path.splitext(filename) - points = int(points) - puzzle = Puzzle(open(puzzlePath)) - puzzles[points] = puzzle - - # build mapping, answers, and summary - mapping = {} - answers = {} - summary = {} - for points in sorted(puzzles): - puzzle = puzzles[points] - print(args.seed) - print(categoryname) - print(points) - - hashmap = hashlib.sha1(args.seed.encode('utf-8')) - hashmap.update(categoryname.encode('utf-8')) - hashmap.update(str(points).encode('utf-8')) - mapping[points] = hashmap.hexdigest() - answers[points] = puzzle.answers - summary[points] = puzzle.fields['summary'] - - # write mapping, answers, and summary - write_kv_pairs(zf, os.path.join(categoryname, 'map.txt'), mapping) - write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) - write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) - - # write out puzzles - for points in sorted(puzzles): - puzzle = puzzles[points] - puzzledir = os.path.join(categoryname, "content", mapping[points]) - # test write - write_kv_pairs(zf, os.path.join(puzzledir, 'summary.txt'), summary) - # build json - + # write mapping, answers, and summary + write_kv_pairs(zf, os.path.join(categoryname, 'map.txt'), mapping) + write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) + write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) + # write out puzzles + for points in sorted(puzzles): + puzzle = puzzles[points] + puzzledir = os.path.join(categoryname, 'content', mapping[points]) + # build/write json + ziphandle.writestr(filename, filehandle.read()) + zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ + json.dumps(puzzle.publish())) + # write associated files #vim:py From 4ba361e2768fa9d12ef924667daaf53db8c7d397 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 15:43:14 -0600 Subject: [PATCH 05/12] some changes to package puzzles, still gluing --- package-puzzles | 52 +++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/package-puzzles b/package-puzzles index 5ea2b0b..979feba 100755 --- a/package-puzzles +++ b/package-puzzles @@ -10,6 +10,7 @@ import json import os import markdown import random +import sys import zipfile import puzzles @@ -32,25 +33,23 @@ def write_kv_pairs(ziphandle, filename, kv): ziphandle.writestr(filename, filehandle.read()) if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Build a puzzle category') + parser = argparse.ArgumentParser(description='Build a category package') parser.add_argument('seed', help='contest seed') - parser.add_argument('puzzledir', nargs='+', help='Directory of puzzle source') + parser.add_argument('categorydirs', nargs='+', help='Directory of category source') parser.add_argument('outdir', help='Output directory') args = parser.parse_args() - - for puzzledir in args.puzzledir: - puzzles = {} + for categorydir in args.categorydirs: + puzzles_dict = {} secrets = {} - - categoryname = os.path.basename(puzzledir.strip(os.sep)) + categoryname = os.path.basename(categorydir.strip(os.sep)) - # build puzzle seed - puzzle_seed = hashlib.new('sha1') - puzzle_seed.update(categoryname.encode('utf-8')) - puzzle_seed.update(args.seed.encode('utf-8')) - puzzle_seed = puzzle_seed.hexdigest() + # build category seed + category_seed = hashlib.new('sha1') + category_seed.update(categoryname.encode('utf-8')) + category_seed.update(args.seed.encode('utf-8')) + category_seed = category_seed.hexdigest() # create zipfile zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) @@ -63,20 +62,24 @@ if __name__ == '__main__': # create and read in state zf = zipfile.ZipFile(zipfilename, 'w') - # read in puzzle details (will be pflarr in future) - for puzzlePath in glob.glob(os.path.join(puzzledir, "*.moth")): - filename = os.path.basename(puzzlePath) - points, ext = os.path.splitext(filename) - points = int(points) - puzzle = puzzles.Puzzle(open(puzzlePath)) - puzzles[points] = puzzle + # read in category details (will be pflarr in future) + for categorypath in glob.glob(os.path.join(categorydir, "*", "puzzle.moth")): + points = categorypath.split(os.sep)[-2] # directory before '/puzzle.moth' + categorypath = os.path.dirname(categorypath) + try: + points = int(points) + except: + print("Failed to identify points on: %s" % categorypath, file=sys.stderr) + continue + puzzle = puzzles.Puzzle(open(categorypath), category_seed) + puzzles_dict[points] = puzzle # build mapping, answers, and summary mapping = {} answers = {} summary = {} - for points in sorted(puzzles): - puzzle = puzzles[points] + for points in sorted(puzzles_dict): + puzzle = puzzles_dict[points] hashmap = hashlib.sha1(args.seed.encode('utf-8')) hashmap.update(categoryname.encode('utf-8')) hashmap.update(str(points).encode('utf-8')) @@ -90,13 +93,16 @@ if __name__ == '__main__': write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) # write out puzzles - for points in sorted(puzzles): - puzzle = puzzles[points] + for points in sorted(puzzles_dict): + puzzle = puzzles_dict[points] puzzledir = os.path.join(categoryname, 'content', mapping[points]) # build/write json ziphandle.writestr(filename, filehandle.read()) zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ json.dumps(puzzle.publish())) # write associated files + for fobj in puzzle['files']: + zf.writestr(os.path.join(puzzledir, fobj.name), \ + fobj.handle.read()) #vim:py From ff2c0bc9997f77a300f7bb12644caac77b545ae8 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 16:06:11 -0600 Subject: [PATCH 06/12] checking in what i have --- package-puzzles | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package-puzzles b/package-puzzles index 979feba..18bad55 100755 --- a/package-puzzles +++ b/package-puzzles @@ -66,12 +66,13 @@ if __name__ == '__main__': for categorypath in glob.glob(os.path.join(categorydir, "*", "puzzle.moth")): points = categorypath.split(os.sep)[-2] # directory before '/puzzle.moth' categorypath = os.path.dirname(categorypath) + print(categorypath) try: points = int(points) except: print("Failed to identify points on: %s" % categorypath, file=sys.stderr) continue - puzzle = puzzles.Puzzle(open(categorypath), category_seed) + puzzle = puzzles.Puzzle(category_seed, categorypath) puzzles_dict[points] = puzzle # build mapping, answers, and summary From c388d271a2c0111467f1cb7f014b57972dd19a80 Mon Sep 17 00:00:00 2001 From: slackish Date: Tue, 18 Oct 2016 17:03:42 -0600 Subject: [PATCH 07/12] added a debug message to puzzles.py, got some resemblence of files working on package-puzzles --- package-puzzles | 26 +++++++++++++++++++++----- puzzles.py | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/package-puzzles b/package-puzzles index 6bc6539..1d9c7da 100755 --- a/package-puzzles +++ b/package-puzzles @@ -85,8 +85,9 @@ if __name__ == '__main__': hashmap.update(categoryname.encode('utf-8')) hashmap.update(str(points).encode('utf-8')) mapping[points] = hashmap.hexdigest() - answers[points] = puzzle.answers - summary[points] = puzzle.fields['summary'] + answers[points] = puzzle['answer'] + if len(puzzle['summary']) > 0: + summary[points] = puzzle['summary'] # write mapping, answers, and summary write_kv_pairs(zf, os.path.join(categoryname, 'map.txt'), mapping) @@ -96,13 +97,28 @@ if __name__ == '__main__': # write out puzzles for points in sorted(puzzles_dict): puzzle = puzzles_dict[points] + puzzlebody = [json.dumps(puzzle.publish())] puzzledir = os.path.join(categoryname, 'content', mapping[points]) # build/write json - ziphandle.writestr(filename, filehandle.read()) - zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ - json.dumps(puzzle.publish())) + # write associated files + assoc_files = [] for fobj in puzzle['files']: + if fobj.visible == True: + assoc_files.append(fobj.name) zf.writestr(os.path.join(puzzledir, fobj.name), \ fobj.handle.read()) + + + if len(assoc_files) > 0: + puzzlebody.append("") + puzzlebody.append("## Associated Files:") + for f in assoc_files: + puzzlebody.append(f) + + puzzlebody = os.linesep.join(puzzlebody) + + # non-optimal writing of file-like objects, but it works + zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ + json.dumps(puzzle.publish())) #vim:py diff --git a/puzzles.py b/puzzles.py index 3923f89..b7b3a53 100644 --- a/puzzles.py +++ b/puzzles.py @@ -171,7 +171,7 @@ class Puzzle: # Make sure it actually exists. if not os.path.exists(path): - raise ValueError("Included file {} does not exist.") + raise ValueError("Included file {} does not exist.".format(path)) file = open(path, 'rb') From b0d44f5b859e3595b5331b8162a29b158289df4e Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Thu, 20 Oct 2016 11:32:21 -0600 Subject: [PATCH 08/12] Shuffle files around: keep your campsite neat and tidy --- README.md | 15 +++++++++++++++ TODO.md | 9 --------- CREDITS.md => doc/CREDITS.md | 0 LICENSE.md => doc/LICENSE.md | 0 kothd | 14 -------------- {bin => src/bin}/award | 0 {bin => src/bin}/install-category | 0 {bin => src/bin}/mktokens | 0 {bin => src/bin}/new | 0 {bin => src/bin}/once | 0 {bin => src/bin}/points | 0 {bin => src/bin}/puzzles | 0 mothd => src/mothd | 0 {www => src/www}/cgi-bin/cgi.lua | 0 {www => src/www}/cgi-bin/koth.lua | 0 {www => src/www}/cgi-bin/puzzler.cgi | 0 {www => src/www}/cgi-bin/register.cgi | 0 {www => src/www}/cgi-bin/token.cgi | 0 {www => src/www}/credits.html | 0 {www => src/www}/fonts/MicroFLF-Bold.ttf | Bin {www => src/www}/fonts/MicroFLF-BoldItalic.ttf | Bin {www => src/www}/fonts/MicroFLF-Italic.ttf | Bin {www => src/www}/fonts/MicroFLF.css | 0 {www => src/www}/fonts/MicroFLF.ttf | Bin {www => src/www}/fonts/maven_pro.css | 0 .../www}/fonts/maven_pro_black-webfont.eot | Bin .../www}/fonts/maven_pro_black-webfont.svg | 0 .../www}/fonts/maven_pro_black-webfont.ttf | Bin .../www}/fonts/maven_pro_black-webfont.woff | Bin .../www}/fonts/maven_pro_bold-webfont.eot | Bin .../www}/fonts/maven_pro_bold-webfont.svg | 0 .../www}/fonts/maven_pro_bold-webfont.ttf | Bin .../www}/fonts/maven_pro_bold-webfont.woff | Bin .../www}/fonts/maven_pro_medium-webfont.eot | Bin .../www}/fonts/maven_pro_medium-webfont.svg | 0 .../www}/fonts/maven_pro_medium-webfont.ttf | Bin .../www}/fonts/maven_pro_medium-webfont.woff | Bin .../www}/fonts/maven_pro_regular-webfont.eot | Bin .../www}/fonts/maven_pro_regular-webfont.svg | 0 .../www}/fonts/maven_pro_regular-webfont.ttf | Bin .../www}/fonts/maven_pro_regular-webfont.woff | Bin {www => src/www}/images/brown-circles.jpg | Bin {www => src/www}/images/doe.png | Bin {www => src/www}/images/lanl.png | Bin {www => src/www}/images/sandia.png | Bin {www => src/www}/images/tf6.png | Bin {www => src/www}/images/tf6bg.png | Bin {www => src/www}/index.html | 0 {www => src/www}/projections.json | 0 {www => src/www}/projector.html | 0 {www => src/www}/puzzles.html | 0 {www => src/www}/register.html | 0 {www => src/www}/res/Dosis-Bold.ttf | Bin {www => src/www}/res/Dosis-ExtraBold.ttf | Bin {www => src/www}/res/Dosis-ExtraLight.ttf | Bin {www => src/www}/res/Dosis-Light.ttf | Bin {www => src/www}/res/Dosis-Medium.ttf | Bin {www => src/www}/res/Dosis-Regular.ttf | Bin {www => src/www}/res/Dosis-SemiBold.ttf | Bin {www => src/www}/res/Dosis.css | 0 {www => src/www}/res/Lato-Black.ttf | Bin {www => src/www}/res/Lato-BlackItalic.ttf | Bin {www => src/www}/res/Lato-Bold.ttf | Bin {www => src/www}/res/Lato-BoldItalic.ttf | Bin {www => src/www}/res/Lato-Hairline.ttf | Bin {www => src/www}/res/Lato-HairlineItalic.ttf | Bin {www => src/www}/res/Lato-Italic.ttf | Bin {www => src/www}/res/Lato-Light.ttf | Bin {www => src/www}/res/Lato-LightItalic.ttf | Bin {www => src/www}/res/Lato-Regular.ttf | Bin {www => src/www}/res/Lato.css | 0 {www => src/www}/res/brown-lines.jpg | Bin {www => src/www}/res/common.js | 0 {www => src/www}/res/luna-moth.png | Bin {www => src/www}/res/luna-moth.svg | 0 {www => src/www}/res/main.js | 0 {www => src/www}/res/md5.min.js | 0 {www => src/www}/res/messages.js | 0 {www => src/www}/res/overview.js | 0 {www => src/www}/res/preview.png | Bin {www => src/www}/res/puzzles.js | 0 {www => src/www}/res/scoreboard.js | 0 {www => src/www}/res/style.css | 0 {www => src/www}/res/terminal.js | 0 {www => src/www}/restore.html | 0 {www => src/www}/scoreboard.html | 0 {www => src/www}/scoreboard.js | 0 {www => src/www}/scoring.html | 0 {www => src/www}/style.css | 0 {www => src/www}/terminal.js | 0 answer_words.txt => tools/answer_words.txt | 0 build-puzzles => tools/build-puzzles.py | 0 devel-server.py => tools/devel-server.py | 4 ++-- mistune.py => tools/mistune.py | 0 puzzles.py => tools/moth.py | 0 95 files changed, 17 insertions(+), 25 deletions(-) delete mode 100644 TODO.md rename CREDITS.md => doc/CREDITS.md (100%) rename LICENSE.md => doc/LICENSE.md (100%) delete mode 100755 kothd rename {bin => src/bin}/award (100%) rename {bin => src/bin}/install-category (100%) rename {bin => src/bin}/mktokens (100%) rename {bin => src/bin}/new (100%) rename {bin => src/bin}/once (100%) rename {bin => src/bin}/points (100%) rename {bin => src/bin}/puzzles (100%) rename mothd => src/mothd (100%) rename {www => src/www}/cgi-bin/cgi.lua (100%) rename {www => src/www}/cgi-bin/koth.lua (100%) rename {www => src/www}/cgi-bin/puzzler.cgi (100%) rename {www => src/www}/cgi-bin/register.cgi (100%) rename {www => src/www}/cgi-bin/token.cgi (100%) rename {www => src/www}/credits.html (100%) rename {www => src/www}/fonts/MicroFLF-Bold.ttf (100%) rename {www => src/www}/fonts/MicroFLF-BoldItalic.ttf (100%) rename {www => src/www}/fonts/MicroFLF-Italic.ttf (100%) rename {www => src/www}/fonts/MicroFLF.css (100%) rename {www => src/www}/fonts/MicroFLF.ttf (100%) rename {www => src/www}/fonts/maven_pro.css (100%) rename {www => src/www}/fonts/maven_pro_black-webfont.eot (100%) rename {www => src/www}/fonts/maven_pro_black-webfont.svg (100%) rename {www => src/www}/fonts/maven_pro_black-webfont.ttf (100%) rename {www => src/www}/fonts/maven_pro_black-webfont.woff (100%) rename {www => src/www}/fonts/maven_pro_bold-webfont.eot (100%) rename {www => src/www}/fonts/maven_pro_bold-webfont.svg (100%) rename {www => src/www}/fonts/maven_pro_bold-webfont.ttf (100%) rename {www => src/www}/fonts/maven_pro_bold-webfont.woff (100%) rename {www => src/www}/fonts/maven_pro_medium-webfont.eot (100%) rename {www => src/www}/fonts/maven_pro_medium-webfont.svg (100%) rename {www => src/www}/fonts/maven_pro_medium-webfont.ttf (100%) rename {www => src/www}/fonts/maven_pro_medium-webfont.woff (100%) rename {www => src/www}/fonts/maven_pro_regular-webfont.eot (100%) rename {www => src/www}/fonts/maven_pro_regular-webfont.svg (100%) rename {www => src/www}/fonts/maven_pro_regular-webfont.ttf (100%) rename {www => src/www}/fonts/maven_pro_regular-webfont.woff (100%) rename {www => src/www}/images/brown-circles.jpg (100%) rename {www => src/www}/images/doe.png (100%) rename {www => src/www}/images/lanl.png (100%) rename {www => src/www}/images/sandia.png (100%) rename {www => src/www}/images/tf6.png (100%) rename {www => src/www}/images/tf6bg.png (100%) rename {www => src/www}/index.html (100%) rename {www => src/www}/projections.json (100%) rename {www => src/www}/projector.html (100%) rename {www => src/www}/puzzles.html (100%) rename {www => src/www}/register.html (100%) rename {www => src/www}/res/Dosis-Bold.ttf (100%) rename {www => src/www}/res/Dosis-ExtraBold.ttf (100%) rename {www => src/www}/res/Dosis-ExtraLight.ttf (100%) rename {www => src/www}/res/Dosis-Light.ttf (100%) rename {www => src/www}/res/Dosis-Medium.ttf (100%) rename {www => src/www}/res/Dosis-Regular.ttf (100%) rename {www => src/www}/res/Dosis-SemiBold.ttf (100%) rename {www => src/www}/res/Dosis.css (100%) rename {www => src/www}/res/Lato-Black.ttf (100%) rename {www => src/www}/res/Lato-BlackItalic.ttf (100%) rename {www => src/www}/res/Lato-Bold.ttf (100%) rename {www => src/www}/res/Lato-BoldItalic.ttf (100%) rename {www => src/www}/res/Lato-Hairline.ttf (100%) rename {www => src/www}/res/Lato-HairlineItalic.ttf (100%) rename {www => src/www}/res/Lato-Italic.ttf (100%) rename {www => src/www}/res/Lato-Light.ttf (100%) rename {www => src/www}/res/Lato-LightItalic.ttf (100%) rename {www => src/www}/res/Lato-Regular.ttf (100%) rename {www => src/www}/res/Lato.css (100%) rename {www => src/www}/res/brown-lines.jpg (100%) rename {www => src/www}/res/common.js (100%) rename {www => src/www}/res/luna-moth.png (100%) rename {www => src/www}/res/luna-moth.svg (100%) rename {www => src/www}/res/main.js (100%) rename {www => src/www}/res/md5.min.js (100%) rename {www => src/www}/res/messages.js (100%) rename {www => src/www}/res/overview.js (100%) rename {www => src/www}/res/preview.png (100%) rename {www => src/www}/res/puzzles.js (100%) rename {www => src/www}/res/scoreboard.js (100%) rename {www => src/www}/res/style.css (100%) rename {www => src/www}/res/terminal.js (100%) rename {www => src/www}/restore.html (100%) rename {www => src/www}/scoreboard.html (100%) rename {www => src/www}/scoreboard.js (100%) rename {www => src/www}/scoring.html (100%) rename {www => src/www}/style.css (100%) rename {www => src/www}/terminal.js (100%) rename answer_words.txt => tools/answer_words.txt (100%) rename build-puzzles => tools/build-puzzles.py (100%) rename devel-server.py => tools/devel-server.py (99%) rename mistune.py => tools/mistune.py (100%) rename puzzles.py => tools/moth.py (100%) diff --git a/README.md b/README.md index 37c294e..766f78c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,21 @@ Please check out [the overview](doc/overview.md) for details. +Getting Started Developing +------------------------------- + + $ git clone $your_puzzles_repo puzzles + $ python3 tools/devel-server.py + +Then point a web browser at http://localhost:8080/ +and start hacking on things in your `puzzles` directory. + + +Running A Production Server +==================== + +XXX: Update this + How to set it up -------------------- diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 4228e72..0000000 --- a/TODO.md +++ /dev/null @@ -1,9 +0,0 @@ -* Scoreboard refresh - -Test: - -* awarding points -* points already awarded -* bad team hash -* category doesn't exist -* puzzle doesn't exist diff --git a/CREDITS.md b/doc/CREDITS.md similarity index 100% rename from CREDITS.md rename to doc/CREDITS.md diff --git a/LICENSE.md b/doc/LICENSE.md similarity index 100% rename from LICENSE.md rename to doc/LICENSE.md diff --git a/kothd b/kothd deleted file mode 100755 index ffad247..0000000 --- a/kothd +++ /dev/null @@ -1,14 +0,0 @@ -#! /bin/sh - -cd ${1:-$(dirname $0)} -KOTH_BASE=$(pwd) - -echo "Running koth instances in $KOTH_BASE" - -while true; do - for i in $KOTH_BASE/*/assigned.txt; do - dir=${i%/*} - $dir/bin/once - done - sleep 5 -done diff --git a/bin/award b/src/bin/award similarity index 100% rename from bin/award rename to src/bin/award diff --git a/bin/install-category b/src/bin/install-category similarity index 100% rename from bin/install-category rename to src/bin/install-category diff --git a/bin/mktokens b/src/bin/mktokens similarity index 100% rename from bin/mktokens rename to src/bin/mktokens diff --git a/bin/new b/src/bin/new similarity index 100% rename from bin/new rename to src/bin/new diff --git a/bin/once b/src/bin/once similarity index 100% rename from bin/once rename to src/bin/once diff --git a/bin/points b/src/bin/points similarity index 100% rename from bin/points rename to src/bin/points diff --git a/bin/puzzles b/src/bin/puzzles similarity index 100% rename from bin/puzzles rename to src/bin/puzzles diff --git a/mothd b/src/mothd similarity index 100% rename from mothd rename to src/mothd diff --git a/www/cgi-bin/cgi.lua b/src/www/cgi-bin/cgi.lua similarity index 100% rename from www/cgi-bin/cgi.lua rename to src/www/cgi-bin/cgi.lua diff --git a/www/cgi-bin/koth.lua b/src/www/cgi-bin/koth.lua similarity index 100% rename from www/cgi-bin/koth.lua rename to src/www/cgi-bin/koth.lua diff --git a/www/cgi-bin/puzzler.cgi b/src/www/cgi-bin/puzzler.cgi similarity index 100% rename from www/cgi-bin/puzzler.cgi rename to src/www/cgi-bin/puzzler.cgi diff --git a/www/cgi-bin/register.cgi b/src/www/cgi-bin/register.cgi similarity index 100% rename from www/cgi-bin/register.cgi rename to src/www/cgi-bin/register.cgi diff --git a/www/cgi-bin/token.cgi b/src/www/cgi-bin/token.cgi similarity index 100% rename from www/cgi-bin/token.cgi rename to src/www/cgi-bin/token.cgi diff --git a/www/credits.html b/src/www/credits.html similarity index 100% rename from www/credits.html rename to src/www/credits.html diff --git a/www/fonts/MicroFLF-Bold.ttf b/src/www/fonts/MicroFLF-Bold.ttf similarity index 100% rename from www/fonts/MicroFLF-Bold.ttf rename to src/www/fonts/MicroFLF-Bold.ttf diff --git a/www/fonts/MicroFLF-BoldItalic.ttf b/src/www/fonts/MicroFLF-BoldItalic.ttf similarity index 100% rename from www/fonts/MicroFLF-BoldItalic.ttf rename to src/www/fonts/MicroFLF-BoldItalic.ttf diff --git a/www/fonts/MicroFLF-Italic.ttf b/src/www/fonts/MicroFLF-Italic.ttf similarity index 100% rename from www/fonts/MicroFLF-Italic.ttf rename to src/www/fonts/MicroFLF-Italic.ttf diff --git a/www/fonts/MicroFLF.css b/src/www/fonts/MicroFLF.css similarity index 100% rename from www/fonts/MicroFLF.css rename to src/www/fonts/MicroFLF.css diff --git a/www/fonts/MicroFLF.ttf b/src/www/fonts/MicroFLF.ttf similarity index 100% rename from www/fonts/MicroFLF.ttf rename to src/www/fonts/MicroFLF.ttf diff --git a/www/fonts/maven_pro.css b/src/www/fonts/maven_pro.css similarity index 100% rename from www/fonts/maven_pro.css rename to src/www/fonts/maven_pro.css diff --git a/www/fonts/maven_pro_black-webfont.eot b/src/www/fonts/maven_pro_black-webfont.eot similarity index 100% rename from www/fonts/maven_pro_black-webfont.eot rename to src/www/fonts/maven_pro_black-webfont.eot diff --git a/www/fonts/maven_pro_black-webfont.svg b/src/www/fonts/maven_pro_black-webfont.svg similarity index 100% rename from www/fonts/maven_pro_black-webfont.svg rename to src/www/fonts/maven_pro_black-webfont.svg diff --git a/www/fonts/maven_pro_black-webfont.ttf b/src/www/fonts/maven_pro_black-webfont.ttf similarity index 100% rename from www/fonts/maven_pro_black-webfont.ttf rename to src/www/fonts/maven_pro_black-webfont.ttf diff --git a/www/fonts/maven_pro_black-webfont.woff b/src/www/fonts/maven_pro_black-webfont.woff similarity index 100% rename from www/fonts/maven_pro_black-webfont.woff rename to src/www/fonts/maven_pro_black-webfont.woff diff --git a/www/fonts/maven_pro_bold-webfont.eot b/src/www/fonts/maven_pro_bold-webfont.eot similarity index 100% rename from www/fonts/maven_pro_bold-webfont.eot rename to src/www/fonts/maven_pro_bold-webfont.eot diff --git a/www/fonts/maven_pro_bold-webfont.svg b/src/www/fonts/maven_pro_bold-webfont.svg similarity index 100% rename from www/fonts/maven_pro_bold-webfont.svg rename to src/www/fonts/maven_pro_bold-webfont.svg diff --git a/www/fonts/maven_pro_bold-webfont.ttf b/src/www/fonts/maven_pro_bold-webfont.ttf similarity index 100% rename from www/fonts/maven_pro_bold-webfont.ttf rename to src/www/fonts/maven_pro_bold-webfont.ttf diff --git a/www/fonts/maven_pro_bold-webfont.woff b/src/www/fonts/maven_pro_bold-webfont.woff similarity index 100% rename from www/fonts/maven_pro_bold-webfont.woff rename to src/www/fonts/maven_pro_bold-webfont.woff diff --git a/www/fonts/maven_pro_medium-webfont.eot b/src/www/fonts/maven_pro_medium-webfont.eot similarity index 100% rename from www/fonts/maven_pro_medium-webfont.eot rename to src/www/fonts/maven_pro_medium-webfont.eot diff --git a/www/fonts/maven_pro_medium-webfont.svg b/src/www/fonts/maven_pro_medium-webfont.svg similarity index 100% rename from www/fonts/maven_pro_medium-webfont.svg rename to src/www/fonts/maven_pro_medium-webfont.svg diff --git a/www/fonts/maven_pro_medium-webfont.ttf b/src/www/fonts/maven_pro_medium-webfont.ttf similarity index 100% rename from www/fonts/maven_pro_medium-webfont.ttf rename to src/www/fonts/maven_pro_medium-webfont.ttf diff --git a/www/fonts/maven_pro_medium-webfont.woff b/src/www/fonts/maven_pro_medium-webfont.woff similarity index 100% rename from www/fonts/maven_pro_medium-webfont.woff rename to src/www/fonts/maven_pro_medium-webfont.woff diff --git a/www/fonts/maven_pro_regular-webfont.eot b/src/www/fonts/maven_pro_regular-webfont.eot similarity index 100% rename from www/fonts/maven_pro_regular-webfont.eot rename to src/www/fonts/maven_pro_regular-webfont.eot diff --git a/www/fonts/maven_pro_regular-webfont.svg b/src/www/fonts/maven_pro_regular-webfont.svg similarity index 100% rename from www/fonts/maven_pro_regular-webfont.svg rename to src/www/fonts/maven_pro_regular-webfont.svg diff --git a/www/fonts/maven_pro_regular-webfont.ttf b/src/www/fonts/maven_pro_regular-webfont.ttf similarity index 100% rename from www/fonts/maven_pro_regular-webfont.ttf rename to src/www/fonts/maven_pro_regular-webfont.ttf diff --git a/www/fonts/maven_pro_regular-webfont.woff b/src/www/fonts/maven_pro_regular-webfont.woff similarity index 100% rename from www/fonts/maven_pro_regular-webfont.woff rename to src/www/fonts/maven_pro_regular-webfont.woff diff --git a/www/images/brown-circles.jpg b/src/www/images/brown-circles.jpg similarity index 100% rename from www/images/brown-circles.jpg rename to src/www/images/brown-circles.jpg diff --git a/www/images/doe.png b/src/www/images/doe.png similarity index 100% rename from www/images/doe.png rename to src/www/images/doe.png diff --git a/www/images/lanl.png b/src/www/images/lanl.png similarity index 100% rename from www/images/lanl.png rename to src/www/images/lanl.png diff --git a/www/images/sandia.png b/src/www/images/sandia.png similarity index 100% rename from www/images/sandia.png rename to src/www/images/sandia.png diff --git a/www/images/tf6.png b/src/www/images/tf6.png similarity index 100% rename from www/images/tf6.png rename to src/www/images/tf6.png diff --git a/www/images/tf6bg.png b/src/www/images/tf6bg.png similarity index 100% rename from www/images/tf6bg.png rename to src/www/images/tf6bg.png diff --git a/www/index.html b/src/www/index.html similarity index 100% rename from www/index.html rename to src/www/index.html diff --git a/www/projections.json b/src/www/projections.json similarity index 100% rename from www/projections.json rename to src/www/projections.json diff --git a/www/projector.html b/src/www/projector.html similarity index 100% rename from www/projector.html rename to src/www/projector.html diff --git a/www/puzzles.html b/src/www/puzzles.html similarity index 100% rename from www/puzzles.html rename to src/www/puzzles.html diff --git a/www/register.html b/src/www/register.html similarity index 100% rename from www/register.html rename to src/www/register.html diff --git a/www/res/Dosis-Bold.ttf b/src/www/res/Dosis-Bold.ttf similarity index 100% rename from www/res/Dosis-Bold.ttf rename to src/www/res/Dosis-Bold.ttf diff --git a/www/res/Dosis-ExtraBold.ttf b/src/www/res/Dosis-ExtraBold.ttf similarity index 100% rename from www/res/Dosis-ExtraBold.ttf rename to src/www/res/Dosis-ExtraBold.ttf diff --git a/www/res/Dosis-ExtraLight.ttf b/src/www/res/Dosis-ExtraLight.ttf similarity index 100% rename from www/res/Dosis-ExtraLight.ttf rename to src/www/res/Dosis-ExtraLight.ttf diff --git a/www/res/Dosis-Light.ttf b/src/www/res/Dosis-Light.ttf similarity index 100% rename from www/res/Dosis-Light.ttf rename to src/www/res/Dosis-Light.ttf diff --git a/www/res/Dosis-Medium.ttf b/src/www/res/Dosis-Medium.ttf similarity index 100% rename from www/res/Dosis-Medium.ttf rename to src/www/res/Dosis-Medium.ttf diff --git a/www/res/Dosis-Regular.ttf b/src/www/res/Dosis-Regular.ttf similarity index 100% rename from www/res/Dosis-Regular.ttf rename to src/www/res/Dosis-Regular.ttf diff --git a/www/res/Dosis-SemiBold.ttf b/src/www/res/Dosis-SemiBold.ttf similarity index 100% rename from www/res/Dosis-SemiBold.ttf rename to src/www/res/Dosis-SemiBold.ttf diff --git a/www/res/Dosis.css b/src/www/res/Dosis.css similarity index 100% rename from www/res/Dosis.css rename to src/www/res/Dosis.css diff --git a/www/res/Lato-Black.ttf b/src/www/res/Lato-Black.ttf similarity index 100% rename from www/res/Lato-Black.ttf rename to src/www/res/Lato-Black.ttf diff --git a/www/res/Lato-BlackItalic.ttf b/src/www/res/Lato-BlackItalic.ttf similarity index 100% rename from www/res/Lato-BlackItalic.ttf rename to src/www/res/Lato-BlackItalic.ttf diff --git a/www/res/Lato-Bold.ttf b/src/www/res/Lato-Bold.ttf similarity index 100% rename from www/res/Lato-Bold.ttf rename to src/www/res/Lato-Bold.ttf diff --git a/www/res/Lato-BoldItalic.ttf b/src/www/res/Lato-BoldItalic.ttf similarity index 100% rename from www/res/Lato-BoldItalic.ttf rename to src/www/res/Lato-BoldItalic.ttf diff --git a/www/res/Lato-Hairline.ttf b/src/www/res/Lato-Hairline.ttf similarity index 100% rename from www/res/Lato-Hairline.ttf rename to src/www/res/Lato-Hairline.ttf diff --git a/www/res/Lato-HairlineItalic.ttf b/src/www/res/Lato-HairlineItalic.ttf similarity index 100% rename from www/res/Lato-HairlineItalic.ttf rename to src/www/res/Lato-HairlineItalic.ttf diff --git a/www/res/Lato-Italic.ttf b/src/www/res/Lato-Italic.ttf similarity index 100% rename from www/res/Lato-Italic.ttf rename to src/www/res/Lato-Italic.ttf diff --git a/www/res/Lato-Light.ttf b/src/www/res/Lato-Light.ttf similarity index 100% rename from www/res/Lato-Light.ttf rename to src/www/res/Lato-Light.ttf diff --git a/www/res/Lato-LightItalic.ttf b/src/www/res/Lato-LightItalic.ttf similarity index 100% rename from www/res/Lato-LightItalic.ttf rename to src/www/res/Lato-LightItalic.ttf diff --git a/www/res/Lato-Regular.ttf b/src/www/res/Lato-Regular.ttf similarity index 100% rename from www/res/Lato-Regular.ttf rename to src/www/res/Lato-Regular.ttf diff --git a/www/res/Lato.css b/src/www/res/Lato.css similarity index 100% rename from www/res/Lato.css rename to src/www/res/Lato.css diff --git a/www/res/brown-lines.jpg b/src/www/res/brown-lines.jpg similarity index 100% rename from www/res/brown-lines.jpg rename to src/www/res/brown-lines.jpg diff --git a/www/res/common.js b/src/www/res/common.js similarity index 100% rename from www/res/common.js rename to src/www/res/common.js diff --git a/www/res/luna-moth.png b/src/www/res/luna-moth.png similarity index 100% rename from www/res/luna-moth.png rename to src/www/res/luna-moth.png diff --git a/www/res/luna-moth.svg b/src/www/res/luna-moth.svg similarity index 100% rename from www/res/luna-moth.svg rename to src/www/res/luna-moth.svg diff --git a/www/res/main.js b/src/www/res/main.js similarity index 100% rename from www/res/main.js rename to src/www/res/main.js diff --git a/www/res/md5.min.js b/src/www/res/md5.min.js similarity index 100% rename from www/res/md5.min.js rename to src/www/res/md5.min.js diff --git a/www/res/messages.js b/src/www/res/messages.js similarity index 100% rename from www/res/messages.js rename to src/www/res/messages.js diff --git a/www/res/overview.js b/src/www/res/overview.js similarity index 100% rename from www/res/overview.js rename to src/www/res/overview.js diff --git a/www/res/preview.png b/src/www/res/preview.png similarity index 100% rename from www/res/preview.png rename to src/www/res/preview.png diff --git a/www/res/puzzles.js b/src/www/res/puzzles.js similarity index 100% rename from www/res/puzzles.js rename to src/www/res/puzzles.js diff --git a/www/res/scoreboard.js b/src/www/res/scoreboard.js similarity index 100% rename from www/res/scoreboard.js rename to src/www/res/scoreboard.js diff --git a/www/res/style.css b/src/www/res/style.css similarity index 100% rename from www/res/style.css rename to src/www/res/style.css diff --git a/www/res/terminal.js b/src/www/res/terminal.js similarity index 100% rename from www/res/terminal.js rename to src/www/res/terminal.js diff --git a/www/restore.html b/src/www/restore.html similarity index 100% rename from www/restore.html rename to src/www/restore.html diff --git a/www/scoreboard.html b/src/www/scoreboard.html similarity index 100% rename from www/scoreboard.html rename to src/www/scoreboard.html diff --git a/www/scoreboard.js b/src/www/scoreboard.js similarity index 100% rename from www/scoreboard.js rename to src/www/scoreboard.js diff --git a/www/scoring.html b/src/www/scoring.html similarity index 100% rename from www/scoring.html rename to src/www/scoring.html diff --git a/www/style.css b/src/www/style.css similarity index 100% rename from www/style.css rename to src/www/style.css diff --git a/www/terminal.js b/src/www/terminal.js similarity index 100% rename from www/terminal.js rename to src/www/terminal.js diff --git a/answer_words.txt b/tools/answer_words.txt similarity index 100% rename from answer_words.txt rename to tools/answer_words.txt diff --git a/build-puzzles b/tools/build-puzzles.py similarity index 100% rename from build-puzzles rename to tools/build-puzzles.py diff --git a/devel-server.py b/tools/devel-server.py similarity index 99% rename from devel-server.py rename to tools/devel-server.py index 10133e5..e1903d6 100755 --- a/devel-server.py +++ b/tools/devel-server.py @@ -4,9 +4,9 @@ import cgi import glob import http.server import mistune +import moth import os import pathlib -import puzzles import socketserver import sys import traceback @@ -112,7 +112,7 @@ you are a fool. return fpath = os.path.join("puzzles", parts[2]) - cat = puzzles.Category(fpath, seed) + cat = moth.Category(fpath, seed) if len(parts) == 3: # List all point values in a category body.append("# Puzzles in category `{}`".format(parts[2])) diff --git a/mistune.py b/tools/mistune.py similarity index 100% rename from mistune.py rename to tools/mistune.py diff --git a/puzzles.py b/tools/moth.py similarity index 100% rename from puzzles.py rename to tools/moth.py From 92feb3ab55b23f583f5bd8289997719df6085dfa Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Thu, 20 Oct 2016 11:49:43 -0600 Subject: [PATCH 09/12] link to new style sheet --- tools/devel-server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/devel-server.py b/tools/devel-server.py index e1903d6..8befebc 100755 --- a/tools/devel-server.py +++ b/tools/devel-server.py @@ -27,7 +27,7 @@ def page(title, body): {} - +
From 2b29ffcf3d9e03242473d64a6721d66da3adbbfe Mon Sep 17 00:00:00 2001 From: slackish Date: Thu, 20 Oct 2016 12:48:48 -0600 Subject: [PATCH 10/12] Associated files now included in puzzle.json --- package-puzzles | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/package-puzzles b/package-puzzles index 1d9c7da..3141fb8 100755 --- a/package-puzzles +++ b/package-puzzles @@ -97,9 +97,8 @@ if __name__ == '__main__': # write out puzzles for points in sorted(puzzles_dict): puzzle = puzzles_dict[points] - puzzlebody = [json.dumps(puzzle.publish())] puzzledir = os.path.join(categoryname, 'content', mapping[points]) - # build/write json + puzzlejson = puzzle.publish() # write associated files assoc_files = [] @@ -109,14 +108,8 @@ if __name__ == '__main__': zf.writestr(os.path.join(puzzledir, fobj.name), \ fobj.handle.read()) - if len(assoc_files) > 0: - puzzlebody.append("") - puzzlebody.append("## Associated Files:") - for f in assoc_files: - puzzlebody.append(f) - - puzzlebody = os.linesep.join(puzzlebody) + puzzlejson["associated_files"] = assoc_files # non-optimal writing of file-like objects, but it works zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ From 962fa791f65648417431f9910a7f655062a609f8 Mon Sep 17 00:00:00 2001 From: slackish Date: Thu, 20 Oct 2016 13:27:34 -0600 Subject: [PATCH 11/12] category_seed now getting read or generated --- package-puzzles | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/package-puzzles b/package-puzzles index 3141fb8..344d85a 100755 --- a/package-puzzles +++ b/package-puzzles @@ -1,20 +1,20 @@ #!/usr/bin/env python3 import argparse -import base64 +import binascii import glob import hashlib -import hmac import io import json import os -import markdown -import random +import shutil import sys import zipfile import puzzles +TMPFILE = "%s.tmp" + def write_kv_pairs(ziphandle, filename, kv): """ Write out a sorted map to file :param ziphandle: a zipfile object @@ -34,7 +34,6 @@ def write_kv_pairs(ziphandle, filename, kv): if __name__ == '__main__': parser = argparse.ArgumentParser(description='Build a category package') - parser.add_argument('seed', help='contest seed') parser.add_argument('categorydirs', nargs='+', help='Directory of category source') parser.add_argument('outdir', help='Output directory') args = parser.parse_args() @@ -45,22 +44,20 @@ if __name__ == '__main__': categoryname = os.path.basename(categorydir.strip(os.sep)) - # build category seed - category_seed = hashlib.new('sha1') - category_seed.update(categoryname.encode('utf-8')) - category_seed.update(args.seed.encode('utf-8')) - category_seed = category_seed.hexdigest() - # create zipfile zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname) if os.path.exists(zipfilename): - # assume blank state for now - pass - # # open and gather some state - # zf = zipfile.ZipFile(zipfilename, 'a') - else: - # create and read in state - zf = zipfile.ZipFile(zipfilename, 'w') + # open and gather some state + zf = zipfile.ZipFile(zipfilename, 'r') + try: + category_seed = zf.open(os.path.join(categoryname, "category_seed.txt")).read().strip() + except: + pass + zf.close() + + zf = zipfile.ZipFile(TMPFILE % zipfilename, 'w') + if 'category_seed' not in locals(): + category_seed = binascii.b2a_hex(os.urandom(20)) # read in category details (will be pflarr in future) for categorypath in glob.glob(os.path.join(categorydir, "*", "puzzle.moth")): @@ -81,18 +78,18 @@ if __name__ == '__main__': summary = {} for points in sorted(puzzles_dict): puzzle = puzzles_dict[points] - hashmap = hashlib.sha1(args.seed.encode('utf-8')) - hashmap.update(categoryname.encode('utf-8')) + hashmap = hashlib.sha1(category_seed) hashmap.update(str(points).encode('utf-8')) mapping[points] = hashmap.hexdigest() answers[points] = puzzle['answer'] if len(puzzle['summary']) > 0: summary[points] = puzzle['summary'] - # write mapping, answers, and summary + # write mapping, answers, summary, category_seed write_kv_pairs(zf, os.path.join(categoryname, 'map.txt'), mapping) write_kv_pairs(zf, os.path.join(categoryname, 'answers.txt'), answers) write_kv_pairs(zf, os.path.join(categoryname, 'summary.txt'), summary) + zf.writestr(os.path.join(categoryname, "category_seed.txt"), category_seed) # write out puzzles for points in sorted(puzzles_dict): @@ -114,4 +111,8 @@ if __name__ == '__main__': # non-optimal writing of file-like objects, but it works zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ json.dumps(puzzle.publish())) + + # clean up + zf.close() + shutil.move(TMPFILE % zipfilename, zipfilename) #vim:py From d70d4bf4d25ca6439818943953da66ebc66efb6c Mon Sep 17 00:00:00 2001 From: slackish Date: Fri, 21 Oct 2016 16:11:09 -0600 Subject: [PATCH 12/12] error with writing puzzle --- package-puzzles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-puzzles b/package-puzzles index 344d85a..bf0eb71 100755 --- a/package-puzzles +++ b/package-puzzles @@ -110,7 +110,7 @@ if __name__ == '__main__': # non-optimal writing of file-like objects, but it works zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \ - json.dumps(puzzle.publish())) + json.dumps(puzzlejson)) # clean up zf.close()