fix: wire settings.json to actually drive runtime behavior

Settings page saved to /config/settings.json but nothing downstream read
that file. Schedule changes were silently ignored; max_quality and
sleep_interval changes were silently ignored. The "Settings saved
successfully" flash was a lie.

Fix:
- sync.sh reads max_quality + sleep_interval from settings.json on each
  run (jq -er ... // empty, falling back to env vars on missing/malformed
  file)
- entrypoint.sh reads sync_schedule from settings.json before setting up
  cron, and writes the crond PID to /var/run/crond.pid so Flask can
  SIGHUP it
- app.py adds apply_schedule(): rewrites /etc/crontabs/root, signals
  crond via the recorded PID, restarts crond if the PID is stale, drops
  the crontab when schedule is set to "manual". save_settings_route
  invokes it only when the schedule actually changed; any failure
  flashes a warning so the save still succeeds with the user informed
- bare `except: pass` in get_settings replaced with explicit exception
  types + stderr warning so debugging malformed settings is possible
- sync.sh: one bad channel no longer aborts the whole loop under set -e
- Dockerfile adds jq for the JSON reads in sync.sh / entrypoint.sh
- README: two stale github.com URLs fixed to Gitea; new Running Tests
  section under Building From Source
- tests/test_settings.py: 3 pytest cases covering get_settings()'s
  three branches (missing file, valid file, malformed JSON)

Settings hierarchy unchanged: env-var defaults seed the UI; settings.json
wins when present and parseable.

Timezone (TZ) is not applied live - tzdata is locked in at process start.
Same behavior as before; not in scope for this commit.
This commit is contained in:
ComputerGuru
2026-05-31 19:21:43 -07:00
parent 71ba63ffe3
commit ef903c86d1
8 changed files with 216 additions and 5 deletions

View File

@@ -8,6 +8,16 @@ echo "YouTube Channel Sync Docker"
echo "=========================================="
echo "Download Directory: $DOWNLOAD_DIR"
echo "Config Directory: $CONFIG_DIR"
# settings.json (managed via the web UI) overrides the env-var defaults
# baked into the image / docker-compose. Same hierarchy as app.py:get_settings().
SETTINGS_FILE="${CONFIG_DIR}/settings.json"
if [ -f "$SETTINGS_FILE" ]; then
if VAL=$(jq -er '.sync_schedule // empty' "$SETTINGS_FILE" 2>/dev/null); then
SYNC_SCHEDULE="$VAL"
fi
fi
echo "Sync Schedule: $SYNC_SCHEDULE"
echo "Max Quality: ${MAX_QUALITY}p"
echo "Sleep Interval: ${SLEEP_INTERVAL}s"
@@ -45,6 +55,8 @@ if [ "$SYNC_SCHEDULE" != "manual" ]; then
# Start crond in the background
crond -f -l 2 &
CRON_PID=$!
# Record PID so the Flask UI can SIGHUP crond when the schedule changes.
echo "$CRON_PID" > /var/run/crond.pid
echo "[INFO] Cron daemon started (PID: $CRON_PID)"
else
echo "[INFO] Manual mode enabled. Use Web UI to trigger syncs."