Files
jacuzzi/docker-entrypoint.sh
2026-06-19 22:03:49 +00:00

85 lines
2.7 KiB
Bash
Executable File

#!/bin/sh
# Supervise the app and keep yt-dlp fresh.
#
# yt-dlp breaks frequently against site changes, so we check PyPI once a day
# for a newer release. The app imports yt_dlp at startup, so a new version
# only takes effect on (re)start -- we therefore restart the app *only* when
# an update was actually installed. If the app exits on its own, we propagate
# its exit status so Docker's restart policy can handle it.
set -e
CHECK_INTERVAL=86400 # check for a new yt-dlp once per day
POLL=60 # how often to check on the app
# Upgrade yt-dlp only if PyPI has a newer version.
# Returns 0 if an update was installed, 1 otherwise (incl. errors / up to date).
# Versions are compared numerically: the installed version can be zero-padded
# (e.g. 2026.06.09) while PyPI reports the normalized form (e.g. 2026.6.9).
check_and_update() {
if python3 - <<'PY'
import json, sys, urllib.request
try:
import yt_dlp
current = yt_dlp.version.__version__
latest = json.load(urllib.request.urlopen(
'https://pypi.org/pypi/yt-dlp/json', timeout=30))['info']['version']
except Exception as e:
print(f"Could not check for yt-dlp updates ({e}); will retry.")
sys.exit(1)
def key(v):
try:
return tuple(int(p) for p in v.split('.'))
except ValueError:
return None
ck, lk = key(current), key(latest)
newer = (lk > ck) if (ck and lk) else (current != latest)
if newer:
print(f"New yt-dlp available: {current} -> {latest}. Updating...")
sys.exit(0)
print(f"yt-dlp is up to date ({current}).")
sys.exit(1)
PY
then
pip install --upgrade --quiet --root-user-action=ignore "yt-dlp[default,curl-cffi]" \
&& return 0
echo "yt-dlp update failed; continuing with the installed version."
fi
return 1
}
# Forward termination to the app so the container stops cleanly.
trap 'kill "$APP_PID" 2>/dev/null; exit 0' TERM INT
while true; do
# Make sure we launch with the latest available yt-dlp.
check_and_update || true
"$@" &
APP_PID=$!
# Periodically check for updates; restart the app only when one is applied.
while true; do
waited=0
while [ "$waited" -lt "$CHECK_INTERVAL" ] && kill -0 "$APP_PID" 2>/dev/null; do
sleep "$POLL"
waited=$((waited + POLL))
done
if ! kill -0 "$APP_PID" 2>/dev/null; then
wait "$APP_PID"
status=$?
echo "App exited with status $status"
exit "$status"
fi
if check_and_update; then
echo "Restarting app to apply yt-dlp update..."
kill "$APP_PID" 2>/dev/null || true
wait "$APP_PID" 2>/dev/null || true
break # outer loop relaunches the app
fi
done
done