mirror of
https://github.com/ALLFATHER-BV/wadamesh.git
synced 2026-11-11 22:07:37 +00:00
The device downloads a language into one buffer of at most 128 KB and reports anything larger as "Server or connection failed". Every v30 file was over it (Polish 149 KB, Greek 163 KB), so no language could be downloaded, and seven were already over it in v29. deploy-apps.sh now publishes from a staging copy in which pack-lang.py keeps the headers and the last row per key, drops rows that equal the English key (the device falls back to the key anyway), and, for a file still over 120 KB, keys no current firmware looks up. A file over 128 KB aborts the deploy. The repo keeps the full files for translators. Served v30: 72-107 KB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
4.2 KiB
Bash
Executable File
93 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# wadamesh app+language store deploy: publish deploy/apps/ to the firmware VPS.
|
|
#
|
|
# The device reads BOTH catalogs from the firmware host, NOT the site host:
|
|
# http://firmware.wadamesh.com/apps/apps.json <- Store > Apps
|
|
# http://firmware.wadamesh.com/apps/langs.json <- Store > Languages
|
|
# http://firmware.wadamesh.com/apps/lang/<ver>/<code>.lang
|
|
# so this tree lives under the FIRMWARE web root, alongside releases/ and latest*/.
|
|
#
|
|
# WHY THIS SCRIPT EXISTS: there wasn't one. release.sh rsyncs out/firmware/ (which
|
|
# does not contain apps/) and deploy-site.sh rsyncs deploy/site/ — so the store was
|
|
# only ever updated by someone remembering to rsync it by hand, and twice they did
|
|
# not. Translations sat at v8 on the server while the repo had v9/v10/v11, and a
|
|
# published app never appeared at all. Editing deploy/apps/ is not publishing it;
|
|
# running this is.
|
|
#
|
|
# Usage:
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh # deploy
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh --dry-run # preview only
|
|
#
|
|
# Optional:
|
|
# WADAMESH_FW_PATH=/srv/wadamesh/firmware # override the firmware web root
|
|
#
|
|
# The VPS target comes from the environment — never commit it.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SRC="$ROOT/deploy/apps/"
|
|
DEST="${WADAMESH_VPS:?set WADAMESH_VPS=user@host}"
|
|
DEST_PATH="${WADAMESH_FW_PATH:-/srv/wadamesh/firmware}/apps"
|
|
|
|
DRY=""
|
|
[ "${1:-}" = "--dry-run" ] && DRY="--dry-run"
|
|
|
|
# Sanity-check the catalogs before shipping them: a device that gets malformed JSON
|
|
# shows an empty store with no clue why, and the versioned .lang dir each catalog
|
|
# entry points at has to actually exist or the download 404s on the device.
|
|
python3 - "$ROOT" <<'PY'
|
|
import json, os, sys
|
|
root = sys.argv[1]
|
|
apps_dir = os.path.join(root, "deploy", "apps")
|
|
langs = json.load(open(os.path.join(apps_dir, "langs.json")))["langs"]
|
|
missing = [f"{l['code']} v{l['ver']}" for l in langs
|
|
if not os.path.isfile(os.path.join(apps_dir, "lang", str(l["ver"]), l["code"] + ".lang"))]
|
|
if missing:
|
|
sys.exit("ABORT: langs.json points at files that do not exist: " + ", ".join(missing))
|
|
|
|
# The catalog version is what makes a device re-download a language. If it does
|
|
# not match the "# ver:" line inside the file, translators' work is published to
|
|
# a version nobody fetches and the change is invisible on device.
|
|
import re
|
|
drift = []
|
|
for l in langs:
|
|
f = os.path.join(apps_dir, "lang", str(l["ver"]), l["code"] + ".lang")
|
|
m = re.search(r"^# ver:\s*(\S+)", open(f, encoding="utf-8").read(), re.M)
|
|
if m and m.group(1) != str(l["ver"]):
|
|
drift.append(f"{l['code']}: catalog v{l['ver']} but file says v{m.group(1)}")
|
|
if drift:
|
|
sys.exit("ABORT: langs.json and the .lang headers disagree: " + "; ".join(drift))
|
|
|
|
# Same check for apps: an entry whose <id>/<ver>/<id>.lua is absent shows up in the
|
|
# Store and then fails to install, with nothing on screen to say why.
|
|
apps = json.load(open(os.path.join(apps_dir, "apps.json")))["apps"]
|
|
bad = []
|
|
for a in apps:
|
|
base = os.path.join(apps_dir, a["id"], a["ver"])
|
|
for f in (a["id"] + ".lua", a["id"] + ".json"):
|
|
if not os.path.isfile(os.path.join(base, f)):
|
|
bad.append(f'{a["id"]} v{a["ver"]}: {f}')
|
|
if bad:
|
|
sys.exit("ABORT: apps.json points at files that do not exist: " + ", ".join(bad))
|
|
print(f"catalogs ok: {len(langs)} languages and {len(apps)} apps, every referenced file present")
|
|
PY
|
|
|
|
# --delete mirrors the repo: the store is generated content, the repo is the source
|
|
# of truth, and stale versioned dirs left on the server are how a device ends up
|
|
# offered a language file nothing points at any more.
|
|
# Publish from a staging copy whose .lang files are slimmed for the device's download
|
|
# buffer (scripts/build/pack-lang.py); the repo keeps the complete files for translators.
|
|
STAGE="$(mktemp -d)"
|
|
trap 'rm -rf "$STAGE"' EXIT
|
|
rsync -a "$SRC" "$STAGE/"
|
|
python3 "$ROOT/scripts/build/pack-lang.py" "$STAGE" "$ROOT" | tail -3
|
|
rsync -avz $DRY --delete "$STAGE/" "$DEST:$DEST_PATH/"
|
|
|
|
if [ -z "$DRY" ]; then
|
|
echo
|
|
echo "deployed deploy/apps/ -> $DEST:$DEST_PATH"
|
|
echo "verify:"
|
|
echo " curl -s http://firmware.wadamesh.com/apps/langs.json"
|
|
echo " curl -s http://firmware.wadamesh.com/apps/apps.json"
|
|
fi
|