sync with develop

This commit is contained in:
J. Patrick Avery, Jr 2016-10-24 13:43:31 -06:00
commit b36aa1a50e
No known key found for this signature in database
GPG Key ID: 65EEAB4FC83CACB6
96 changed files with 136 additions and 26 deletions

View File

@ -25,6 +25,21 @@ Please check out [the overview](doc/overview.md)
for details. 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 How to set it up
-------------------- --------------------

View File

@ -1,9 +0,0 @@
* Scoreboard refresh
Test:
* awarding points
* points already awarded
* bad team hash
* category doesn't exist
* puzzle doesn't exist

14
kothd
View File

@ -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

118
package-puzzles Executable file
View File

@ -0,0 +1,118 @@
#!/usr/bin/env python3
import argparse
import binascii
import glob
import hashlib
import io
import json
import os
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
: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([]):
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())
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Build a category package')
parser.add_argument('categorydirs', nargs='+', help='Directory of category source')
parser.add_argument('outdir', help='Output directory')
args = parser.parse_args()
for categorydir in args.categorydirs:
puzzles_dict = {}
secrets = {}
categoryname = os.path.basename(categorydir.strip(os.sep))
# create zipfile
zipfilename = os.path.join(args.outdir, "%s.zip" % categoryname)
if os.path.exists(zipfilename):
# 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")):
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(category_seed, categorypath)
puzzles_dict[points] = puzzle
# build mapping, answers, and summary
mapping = {}
answers = {}
summary = {}
for points in sorted(puzzles_dict):
puzzle = puzzles_dict[points]
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, 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):
puzzle = puzzles_dict[points]
puzzledir = os.path.join(categoryname, 'content', mapping[points])
puzzlejson = 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:
puzzlejson["associated_files"] = assoc_files
# non-optimal writing of file-like objects, but it works
zf.writestr(os.path.join(puzzledir, 'puzzle.json'), \
json.dumps(puzzlejson))
# clean up
zf.close()
shutil.move(TMPFILE % zipfilename, zipfilename)
#vim:py

View File

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

View File

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -4,9 +4,9 @@ import cgi
import glob import glob
import http.server import http.server
import mistune import mistune
import moth
import os import os
import pathlib import pathlib
import puzzles
import socketserver import socketserver
import sys import sys
import traceback import traceback
@ -27,7 +27,7 @@ def page(title, body):
<html> <html>
<head> <head>
<title>{}</title> <title>{}</title>
<link rel="stylesheet" href="/files/www/res/style.css"> <link rel="stylesheet" href="/files/src/www/res/style.css">
</head> </head>
<body> <body>
<div id="preview" class="terminal"> <div id="preview" class="terminal">
@ -112,7 +112,7 @@ you are a fool.
return return
fpath = os.path.join("puzzles", parts[2]) fpath = os.path.join("puzzles", parts[2])
cat = puzzles.Category(fpath, seed) cat = moth.Category(fpath, seed)
if len(parts) == 3: if len(parts) == 3:
# List all point values in a category # List all point values in a category
body.append("# Puzzles in category `{}`".format(parts[2])) body.append("# Puzzles in category `{}`".format(parts[2]))