mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-17 20:39:13 +00:00
feat(tools): manage the MQTT bridge and Pixlet editor from the Tools tab
PR #544's change, ported onto the api_v3 package split (#553). Identical behaviour; only the placement of the new code differs. The original added 508 lines to web_interface/blueprints/api_v3.py, which #553 deletes, so every hunk of it would conflict irreconcilably. Ported by AST: 26 new top-level items sorted to where the split puts each kind -- __init__.py 2 imports, 11 constants, 7 helpers starlark.py 4 routes (/starlark/editor/{apps,status,start,stop}) misc.py 2 routes (/integrations/mqtt-bridge{,/config}) Everything outside api_v3.py -- the Tools partial, the installer scripts, the JS tests -- applied unchanged. Routes: 111 from the split plus these 6 = 117, and the url-map snapshot is regenerated to match, which is exactly what test_api_v3_url_map.py is designed to make you do when routes are added. Full Python suite: 4,278 passed, 68 skipped, 0 failed. The JS tests this PR ships could not be run here -- node is not installed on this machine -- so test/js/dom/test_tools_sections.js is unverified. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
This commit is contained in:
co-authored by
Claude Opus 5
parent
60d5d19898
commit
56ba235f4c
Regular → Executable
Regular → Executable
+66
-12
@@ -18,20 +18,33 @@
|
||||
# ./scripts/utils/pixlet_config_editor.sh # list installed apps
|
||||
# ./scripts/utils/pixlet_config_editor.sh <app_id> # edit
|
||||
#
|
||||
# Binds loopback only, and there is deliberately no flag to change that:
|
||||
# `pixlet serve` has no authentication, and anything that can reach it can
|
||||
# rewrite the app's config. To edit from another machine, forward the port --
|
||||
# which authenticates as SSH and leaves nothing listening on the LAN:
|
||||
# Binds the LAN by default, matching the web interface, which already serves
|
||||
# 0.0.0.0:5000 with no authentication -- anything that can reach this can
|
||||
# already reconfigure the display there. `pixlet serve` has no authentication
|
||||
# either, so treat both the same way: fine on a home network, not on an open
|
||||
# one. Override the bind and the session length with:
|
||||
#
|
||||
# PIXLET_EDITOR_HOST=127.0.0.1 ./scripts/utils/pixlet_config_editor.sh <app>
|
||||
# PIXLET_EDITOR_TIMEOUT=600 ./scripts/utils/pixlet_config_editor.sh <app>
|
||||
#
|
||||
# For loopback-only editing from another machine, forward the port instead:
|
||||
#
|
||||
# ssh -L 8080:localhost:8080 pi@ledpi.local
|
||||
#
|
||||
# The session always ends by itself after PIXLET_EDITOR_TIMEOUT seconds
|
||||
# (default 30 minutes). The display is stopped while editing, so a session
|
||||
# left open would otherwise leave the panel dark indefinitely -- the timeout
|
||||
# is what makes it safe to start one from the web interface.
|
||||
|
||||
set -eu
|
||||
|
||||
PROJECT_ROOT_DIR=$(cd "$(dirname "$0")/../.." && pwd)
|
||||
APPS_DIR="$PROJECT_ROOT_DIR/starlark-apps"
|
||||
PORT="${PIXLET_EDITOR_PORT:-8080}"
|
||||
# Loopback only. See the header: pixlet serve is unauthenticated.
|
||||
BIND_HOST="127.0.0.1"
|
||||
# LAN by default; see the header for why, and how to force loopback.
|
||||
BIND_HOST="${PIXLET_EDITOR_HOST:-0.0.0.0}"
|
||||
# Hard stop, so the display cannot be left off by a forgotten session.
|
||||
EDITOR_TIMEOUT="${PIXLET_EDITOR_TIMEOUT:-1800}"
|
||||
|
||||
APP_ID="${1:-}"
|
||||
|
||||
@@ -109,6 +122,19 @@ fi
|
||||
# failure worth guarding against.
|
||||
cleanup() {
|
||||
echo ""
|
||||
# Kill the serve child explicitly. `timeout` is started with --foreground so
|
||||
# it shares this script's process group (without that it makes its own, and
|
||||
# a group signal aimed at this script would orphan pixlet with the port
|
||||
# still bound). Belt and braces: signal the recorded pid too, because a
|
||||
# group signal only reaches it while the group is shared.
|
||||
if [ -n "${SERVE_PID:-}" ] && kill -0 "$SERVE_PID" 2>/dev/null; then
|
||||
kill -TERM "$SERVE_PID" 2>/dev/null || true
|
||||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||||
kill -0 "$SERVE_PID" 2>/dev/null || break
|
||||
sleep 0.3
|
||||
done
|
||||
kill -KILL "$SERVE_PID" 2>/dev/null || true
|
||||
fi
|
||||
if [ "$DISPLAY_WAS_RUNNING" = true ]; then
|
||||
echo "Restarting the display service..."
|
||||
sudo systemctl restart ledmatrix || echo "⚠ Could not restart ledmatrix - do it by hand"
|
||||
@@ -122,22 +148,50 @@ if [ "$DISPLAY_WAS_RUNNING" = true ]; then
|
||||
sudo systemctl stop ledmatrix
|
||||
fi
|
||||
|
||||
if [ "$BIND_HOST" = "0.0.0.0" ]; then
|
||||
REACH_HOST="$(hostname).local"
|
||||
else
|
||||
REACH_HOST="localhost"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Editing: $APP_ID"
|
||||
echo "App file: $STAR_FILE"
|
||||
echo "URL: http://localhost:$PORT/"
|
||||
echo "URL: http://$REACH_HOST:$PORT/"
|
||||
echo ""
|
||||
echo "Listening on localhost only -- pixlet serve has no authentication."
|
||||
echo "From another machine, forward the port:"
|
||||
echo " ssh -L $PORT:localhost:$PORT $(whoami)@$(hostname)"
|
||||
if [ "$BIND_HOST" = "0.0.0.0" ]; then
|
||||
echo "Reachable on the LAN, and pixlet serve has no authentication -- the"
|
||||
echo "same footing as the web interface on port 5000. Set"
|
||||
echo "PIXLET_EDITOR_HOST=127.0.0.1 to keep it to this machine."
|
||||
else
|
||||
echo "Listening on $BIND_HOST only. From another machine, forward the port:"
|
||||
echo " ssh -L $PORT:localhost:$PORT $(whoami)@$(hostname)"
|
||||
fi
|
||||
echo ""
|
||||
echo "Changes save straight to the real config as you make them."
|
||||
echo "Press Ctrl+C when finished - the display restarts automatically."
|
||||
echo "This session stops on its own after ${EDITOR_TIMEOUT}s regardless."
|
||||
echo ""
|
||||
|
||||
cd "$APP_DIR"
|
||||
"$PIXLET_BIN" serve "$(basename "$STAR_FILE")" \
|
||||
# `timeout` owns the hard stop rather than the caller: the trap above restarts
|
||||
# the display however this exits, so a session that outlives the person who
|
||||
# started it still gives the panel back. Exit 124 is timeout's own code for
|
||||
# "expired", which is a normal end here, not a failure.
|
||||
# --foreground: stay in this script's process group so one signal reaches the
|
||||
# whole session. Backgrounded + `wait` so the EXIT trap can run while the child
|
||||
# is still alive; a foreground child would leave bash waiting on it instead.
|
||||
timeout --foreground "$EDITOR_TIMEOUT" "$PIXLET_BIN" serve "$(basename "$STAR_FILE")" \
|
||||
--host "$BIND_HOST" \
|
||||
--port "$PORT" \
|
||||
--no-browser \
|
||||
--saveconfig "$CONFIG_FILE"
|
||||
--saveconfig "$CONFIG_FILE" &
|
||||
SERVE_PID=$!
|
||||
|
||||
status=0
|
||||
wait "$SERVE_PID" || status=$?
|
||||
if [ "$status" -eq 124 ]; then
|
||||
echo "Session reached its ${EDITOR_TIMEOUT}s limit."
|
||||
status=0
|
||||
fi
|
||||
exit "$status"
|
||||
|
||||
Reference in New Issue
Block a user