114 lines
2.7 KiB
Bash
Executable File
114 lines
2.7 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
IMMICH_URL="${IMMICH_URL:?IMMICH_URL is required}" # e.g. http://immich:8080
|
|
IMMICH_API_KEY="${IMMICH_API_KEY:?IMMICH_API_KEY is required}"
|
|
SCAN_DIR="${SCAN_DIR:-/drop}"
|
|
DELETE_ON_SUCCESS="${DELETE_ON_SUCCESS:-true}"
|
|
SCAN_INTERVAL="${SCAN_INTERVAL:-5}"
|
|
ALLOW_INSECURE_SSL="${ALLOW_INSECURE_SSL:-false}"
|
|
CONCURRENCY="${CONCURRENCY:-4}"
|
|
IDLE_SLEEP="${IDLE_SLEEP:-3}"
|
|
|
|
case "$CONCURRENCY" in
|
|
''|*[!0-9]*) CONCURRENCY=1 ;;
|
|
esac
|
|
[ "$CONCURRENCY" -lt 1 ] && CONCURRENCY=1
|
|
|
|
echo "[uploader] Target: ${IMMICH_URL}"
|
|
echo "[uploader] Source (drop): ${SCAN_DIR} (scan every ${SCAN_INTERVAL}s, concurrency ${CONCURRENCY})"
|
|
|
|
CURL_OPTS="-sS -m 5 -o /dev/null -w %{http_code}"
|
|
[ "$ALLOW_INSECURE_SSL" = "true" ] && CURL_OPTS="$CURL_OPTS -k"
|
|
PING="${IMMICH_URL%/}/api/server-info"
|
|
|
|
wait_for_immich() {
|
|
backoff=1
|
|
max_backoff=30
|
|
last=""
|
|
while :; do
|
|
code="$(curl $CURL_OPTS "$PING" 2>/dev/null || true)"
|
|
case "$code" in
|
|
2*|3*|4*) [ "$last" != "up" ] && echo "[uploader] Immich is up (HTTP $code)."; return 0 ;;
|
|
*) [ "$last" != "down" ] && echo "[uploader] Waiting for Immich at $PING ...";;
|
|
esac
|
|
last="down"
|
|
sleep "$backoff"
|
|
[ "$backoff" -lt "$max_backoff" ] && backoff=$((backoff*2))
|
|
[ "$backoff" -gt "$max_backoff" ] && backoff="$max_backoff"
|
|
done
|
|
}
|
|
|
|
prune_empty_parents() {
|
|
dir="$(dirname "$1")"
|
|
while [ "$dir" != "$SCAN_DIR" ]; do
|
|
rmdir "$dir" 2>/dev/null || break
|
|
dir="$(dirname "$dir")"
|
|
done
|
|
}
|
|
|
|
upload_one() {
|
|
f="$1"
|
|
if immich-go upload from-folder \
|
|
--server "${IMMICH_URL}" \
|
|
--api-key "${IMMICH_API_KEY}" \
|
|
--no-ui --on-server-errors continue \
|
|
--pause-immich-jobs=false \
|
|
--recursive=false \
|
|
"$f" >/dev/null 2>&1
|
|
then
|
|
echo "[uploader] OK: $(basename "$f")"
|
|
if [ "$DELETE_ON_SUCCESS" = "true" ]; then
|
|
rm -f -- "$f" || true
|
|
prune_empty_parents "$f"
|
|
fi
|
|
else
|
|
echo "[uploader] FAIL: $(basename "$f") — will retry next loop"
|
|
fi
|
|
}
|
|
|
|
upload_batch() {
|
|
count="$#"
|
|
echo "[uploader] Found $count file(s) to upload"
|
|
running=0
|
|
pids=""
|
|
|
|
for f in "$@"; do
|
|
upload_one "$f" &
|
|
pid=$!
|
|
pids="$pids $pid"
|
|
running=$((running+1))
|
|
|
|
if [ "$running" -ge "$CONCURRENCY" ]; then
|
|
set -- $pids
|
|
pid_to_wait="$1"
|
|
pids="${pids# $pid_to_wait}"
|
|
wait "$pid_to_wait" || true
|
|
running=$((running-1))
|
|
fi
|
|
done
|
|
|
|
for pid in $pids; do
|
|
wait "$pid" || true
|
|
done
|
|
}
|
|
|
|
while :; do
|
|
wait_for_immich
|
|
|
|
file_list="$(find "$SCAN_DIR" -type f -size +0c -print0 | xargs -0 -I{} printf '%s\n' "{}")"
|
|
if [ -z "$file_list" ]; then
|
|
sleep "$IDLE_SLEEP"
|
|
continue
|
|
fi
|
|
|
|
oldifs="$IFS"
|
|
IFS='
|
|
'
|
|
set -- $file_list
|
|
IFS="$oldifs"
|
|
|
|
upload_batch "$@"
|
|
sleep "$SCAN_INTERVAL"
|
|
done
|