diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6b208..6d46bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - URL parameter to points.json to allow returning only the JSON for a single team by its team id (e.g., points.json?id=abc123). - A CONTRIBUTING.md to describe expectations when contributing to MOTH +- Include basic metadata in mothballs ### Fixed - Handle cases where non-legacy puzzles don't have an `author` attribute - Handle YAML-formatted file and script lists as expected diff --git a/Dockerfile.moth-devel b/Dockerfile.moth-devel index 9bdbd23..c1ca075 100644 --- a/Dockerfile.moth-devel +++ b/Dockerfile.moth-devel @@ -17,6 +17,7 @@ COPY devel /app/ COPY example-puzzles /puzzles/ COPY theme /theme/ COPY LICENSE.md /LICENSE +COPY VERSION /VERSION ENTRYPOINT [ "python3", "/app/devel-server.py" ] CMD [ "--bind", "0.0.0.0:8080", "--puzzles", "/puzzles", "--theme", "/theme" ] diff --git a/devel/devel-server.py b/devel/devel-server.py index 7d7b505..e1e6cae 100755 --- a/devel/devel-server.py +++ b/devel/devel-server.py @@ -118,6 +118,7 @@ class MothRequestHandler(http.server.SimpleHTTPRequestHandler): obj["hint"] = puzzle.hint obj["summary"] = puzzle.summary obj["logs"] = puzzle.logs + obj["format"] = puzzle._source_format self.send_response(200) self.send_header("Content-Type", "application/json") diff --git a/devel/moth.py b/devel/moth.py index 3f4374c..95c2c5a 100644 --- a/devel/moth.py +++ b/devel/moth.py @@ -123,6 +123,8 @@ class Puzzle: super().__init__() + self._source_format = "py" + self.points = points self.summary = None self.authors = [] @@ -153,8 +155,10 @@ class Puzzle: line = "" if stream.read(3) == "---": header = "yaml" + self._source_format = "yaml" else: header = "moth" + self._source_format = "moth" stream.seek(0) diff --git a/devel/mothballer.py b/devel/mothballer.py index 19bd46d..e6afbd9 100755 --- a/devel/mothballer.py +++ b/devel/mothballer.py @@ -2,12 +2,14 @@ import argparse import binascii +import datetime import hashlib import io import json import logging import moth import os +import platform import shutil import tempfile import zipfile @@ -61,6 +63,24 @@ def build_category(categorydir, outdir): zipfileraw.close() shutil.move(zipfileraw.name, zipfilename) +def write_metadata(ziphandle, category): + metadata = {"platform": {}, "moth": {}, "category": {}} + + try: + with open("../VERSION", "r") as infile: + version = infile.read().strip() + metadata["moth"]["version"] = version + except IOError: + pass + + metadata["category"]["build_time"] = datetime.datetime.now().strftime("%c") + metadata["category"]["type"] = "catmod" if category.catmod is not None else "traditional" + metadata["platform"]["arch"] = platform.machine() + metadata["platform"]["os"] = platform.system() + metadata["platform"]["version"] = platform.platform() + metadata["platform"]["python_version"] = platform.python_version() + + ziphandle.writestr("meta.json", json.dumps(metadata)) # Returns a file-like object containing the contents of the new zip file def package(categoryname, categorydir, seed): @@ -94,6 +114,7 @@ def package(categoryname, categorydir, seed): write_kv_pairs(zf, 'map.txt', mapping) write_kv_pairs(zf, 'answers.txt', answers) write_kv_pairs(zf, 'summaries.txt', summary) + write_metadata(zf, cat) # clean up zf.close()