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