From db2cc99cc703c96a5c877d48cdf249ef4ae02b4e Mon Sep 17 00:00:00 2001 From: Jack Miner <3ch01c@gmail.com> Date: Sun, 24 Mar 2019 20:34:01 -0600 Subject: [PATCH 01/18] Added support for mothballing puzzles containing files with spaces in their filenames and creating mothball path if it doesn't exist. --- devel/moth.py | 7 ++++--- devel/mothballer.py | 3 +++ docs/CREDITS.md | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/devel/moth.py b/devel/moth.py index 6a62116..6d04aa2 100644 --- a/devel/moth.py +++ b/devel/moth.py @@ -12,6 +12,7 @@ import os import random import string import tempfile +import shlex messageChars = b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -112,7 +113,7 @@ class Puzzle: elif key == 'name': pass elif key == 'file': - parts = val.split() + parts = shlex.split(val) name = parts[0] hidden = False stream = open(name, 'rb') @@ -264,10 +265,10 @@ class Puzzle: def html_body(self): """Format and return the markdown for the puzzle body.""" return mistune.markdown(self.get_body(), escape=False) - + def package(self, answers=False): """Return a dict packaging of the puzzle.""" - + files = [fn for fn,f in self.files.items() if f.visible] return { 'authors': self.authors, diff --git a/devel/mothballer.py b/devel/mothballer.py index 19bd46d..135034b 100755 --- a/devel/mothballer.py +++ b/devel/mothballer.py @@ -59,6 +59,9 @@ def build_category(categorydir, outdir): mothball = package(categoryname, categorydir, category_seed) shutil.copyfileobj(mothball, zipfileraw) zipfileraw.close() + zipfiledir = os.path.dirname(zipfilename) + if not os.path.exists(zipfiledir): + os.makedirs(zipfiledir) shutil.move(zipfileraw.name, zipfilename) diff --git a/docs/CREDITS.md b/docs/CREDITS.md index ada9f18..367b28c 100644 --- a/docs/CREDITS.md +++ b/docs/CREDITS.md @@ -5,6 +5,7 @@ Being in this list is voluntary. Add your name when you contribute code. * Paul Ferrell * Shannon Steinfadt * John Donaldson +* 3ch01c Word List --------- From 62a69520910551f9aec5e41d1fbfaa9a22258643 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Wed, 10 Apr 2019 19:56:17 +0000 Subject: [PATCH 02/18] Expand helpers.js to have an extendible list of inputs, and allow puzzle author to have them be sorted --- example-puzzles/example/5/helpers.js | 29 +++++++++++++++++++++++++++ example-puzzles/example/5/puzzle.moth | 6 ++++++ 2 files changed, 35 insertions(+) diff --git a/example-puzzles/example/5/helpers.js b/example-puzzles/example/5/helpers.js index 3c566bc..0f7a677 100644 --- a/example-puzzles/example/5/helpers.js +++ b/example-puzzles/example/5/helpers.js @@ -17,6 +17,9 @@ function helperUpdateAnswer(event) { values.push(c.value) } } + if (e.classList.contains("sort")) { + values.sort() + } value = values.join(",") } @@ -33,8 +36,34 @@ function helperUpdateAnswer(event) { answer.dispatchEvent(new InputEvent("input")) } +function helperRemoveInput(e) { + let item = e.target.parentElement + item.remove() +} + +function helperExpandInputs(e) { + let item = e.target.parentElement + let container = item.parentElement + let template = container.firstElementChild + let newElement = template.cloneNode(true) + + // Add remove button + let remove = document.createElement("button") + remove.innerText = "➖" + remove.addEventListener("click", helperRemoveInput) + newElement.appendChild(remove) + + // Zero it out, otherwise whatever's in first element is copied too + newElement.querySelector("input").value = "" + + container.insertBefore(newElement, item) +} + function helperActivate(e) { e.addEventListener("input", helperUpdateAnswer) + if (e.classList.contains("expand")) { + e.addEventListener("click", helperExpandInputs) + } } function helperInit(event) { diff --git a/example-puzzles/example/5/puzzle.moth b/example-puzzles/example/5/puzzle.moth index 9c3be6b..63cd4e2 100644 --- a/example-puzzles/example/5/puzzle.moth +++ b/example-puzzles/example/5/puzzle.moth @@ -31,6 +31,12 @@ Multiple concatenated values +Free input, sorted, concatenated values + + Select from an ordered list of options