commit 39d8330276812bfd818aec11a7cc30de50035a97
parent 50e2299d36172417eb2ef7a3bcf8611640d997c5
Author: Michael Camilleri <[email protected]>
Date: Fri, 1 May 2026 06:50:34 +0900
Add scripts to translate JSON to XD
For debuggging purposes, it's useful to be able to translate JSON filees
that are received by Crossmate into the XD format that Crossmate uses
internally. These scripts allow this to be done using the JSON to XD
converter in the application itself.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Diffstat:
3 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -3,6 +3,7 @@
.DS_Store
*.xcuserstate
CLAUDE.md
+cookies.txt
Generated/
examples/
notes/
diff --git a/Scripts/fetch-nyt.sh b/Scripts/fetch-nyt.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+#
+# Fetch a NYT crossword puzzle's raw v6 JSON for inspection.
+#
+# Usage:
+# ./Scripts/fetch-nyt.sh [YYYY-MM-DD] [output-path]
+#
+# Defaults: today (America/New_York), nyt-<date>.json in the cwd.
+# The NYT-S cookie is read from cookies.txt at the repo root (gitignored).
+# Get the value from a signed-in browser session
+# (DevTools → Application → Cookies → https://www.nytimes.com).
+# Override by setting NYT_S in the environment.
+
+set -euo pipefail
+
+repo_root="$(cd "$(dirname "$0")/.." && pwd)"
+cookie_file="${repo_root}/cookies.txt"
+
+if [[ -z "${NYT_S:-}" ]]; then
+ if [[ -f "$cookie_file" ]]; then
+ NYT_S="$(tr -d '[:space:]' < "$cookie_file")"
+ fi
+fi
+
+if [[ -z "${NYT_S:-}" ]]; then
+ echo "error: NYT-S cookie not found" >&2
+ echo " put the cookie value in ${cookie_file}, or set NYT_S in the environment" >&2
+ exit 1
+fi
+
+date_arg="${1:-$(TZ=America/New_York date +%Y-%m-%d)}"
+out_path="${2:-nyt-${date_arg}.json}"
+
+url="https://www.nytimes.com/svc/crosswords/v6/puzzle/daily/${date_arg}.json"
+
+http_code=$(curl -sS \
+ -H "Cookie: NYT-S=${NYT_S}" \
+ -o "${out_path}" \
+ -w "%{http_code}" \
+ "${url}")
+
+if [[ "${http_code}" != "200" ]]; then
+ echo "error: HTTP ${http_code}" >&2
+ echo "body:" >&2
+ cat "${out_path}" >&2
+ rm -f "${out_path}"
+ exit 1
+fi
+
+echo "saved ${out_path} ($(wc -c < "${out_path}") bytes)"
diff --git a/Scripts/nyt-to-xd.sh b/Scripts/nyt-to-xd.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+#
+# Convert a NYT puzzle JSON to XD using the app's NYTToXDConverter.
+#
+# Usage:
+# Scripts/nyt-to-xd.sh --json <path> # convert an existing file
+# Scripts/nyt-to-xd.sh --date YYYY-MM-DD # fetch then convert
+# [--output <path>] # default: stdout
+
+set -euo pipefail
+
+repo_root="$(cd "$(dirname "$0")/.." && pwd)"
+converter="${repo_root}/Crossmate/Services/NYTToXDConverter.swift"
+fetch_script="${repo_root}/Scripts/fetch-nyt.sh"
+
+json_path=""
+date_arg=""
+output_path=""
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --json) json_path="$2"; shift 2 ;;
+ --date) date_arg="$2"; shift 2 ;;
+ --output) output_path="$2"; shift 2 ;;
+ -h|--help)
+ sed -n '2,8p' "$0" | sed 's/^# \{0,1\}//'
+ exit 0
+ ;;
+ *) echo "error: unknown arg '$1'" >&2; exit 2 ;;
+ esac
+done
+
+if [[ -z "$json_path" && -z "$date_arg" ]]; then
+ echo "error: pass --json <path> or --date YYYY-MM-DD" >&2
+ exit 2
+fi
+if [[ -n "$json_path" && -n "$date_arg" ]]; then
+ echo "error: --json and --date are mutually exclusive" >&2
+ exit 2
+fi
+
+tmp_dir="$(mktemp -d)"
+trap 'rm -rf "$tmp_dir"' EXIT
+
+if [[ -n "$date_arg" ]]; then
+ json_path="${tmp_dir}/nyt-${date_arg}.json"
+ bash "$fetch_script" "$date_arg" "$json_path" >/dev/null
+fi
+
+if [[ ! -f "$json_path" ]]; then
+ echo "error: JSON file not found: $json_path" >&2
+ exit 1
+fi
+
+driver="${tmp_dir}/main.swift"
+cat > "$driver" <<'SWIFT'
+import Foundation
+
+guard CommandLine.arguments.count >= 2 else {
+ FileHandle.standardError.write(Data("error: missing JSON path\n".utf8))
+ exit(2)
+}
+let url = URL(fileURLWithPath: CommandLine.arguments[1])
+let data = try Data(contentsOf: url)
+let xd = try NYTToXDConverter.convert(jsonData: data)
+print(xd)
+SWIFT
+
+binary="${tmp_dir}/nyt-to-xd"
+swiftc -O -swift-version 6 "$converter" "$driver" -o "$binary"
+
+if [[ -n "$output_path" ]]; then
+ "$binary" "$json_path" > "$output_path"
+ echo "wrote $output_path" >&2
+else
+ "$binary" "$json_path"
+fi