Expand .env.example with ports, AI, Usenet, WireGuard, demo logins, and bootstrap flags. One script creates dirs, downloads the model, starts compose, heals gluetun, and configures SABnzbd from the same file.
177 lines
6.3 KiB
Bash
Executable file
177 lines
6.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Bootstrap SABnzbd folders + Usenet servers from secrets/.env
|
|
# Run on the stack host after: docker compose up -d sabnzbd
|
|
#
|
|
# ./scripts/configure-usenet.sh
|
|
# SECRETS_FILE=./secrets/.env SAB_URL=http://127.0.0.1:8085 ./scripts/configure-usenet.sh
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
STACK_DIR="${STACK_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
SECRETS_FILE="${SECRETS_FILE:-$STACK_DIR/secrets/.env}"
|
|
SAB_URL="${SAB_URL:-http://127.0.0.1:8085}"
|
|
|
|
log() { echo "[configure-usenet] $*"; }
|
|
die() { log "ERROR: $*"; exit 1; }
|
|
|
|
# Prefer secrets/.env; fall back to root .env (tech-demo: everything in one file)
|
|
if [[ ! -f "$SECRETS_FILE" && -f "$STACK_DIR/.env" ]]; then
|
|
SECRETS_FILE="$STACK_DIR/.env"
|
|
log "using $SECRETS_FILE (no secrets/.env)"
|
|
fi
|
|
[[ -f "$SECRETS_FILE" ]] || die "missing $SECRETS_FILE (see secrets/.env.example or .env.example)"
|
|
|
|
# shellcheck disable=SC1090
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
source "$SECRETS_FILE"
|
|
set +a
|
|
|
|
# Accept clean names AND the variable names used in secrets/.env
|
|
# NZBgeek
|
|
NZBGEEK_API_KEY="${NZBGEEK_API_KEY:-${NZBKEEPKEY:-${NZBGEEKKEY:-}}}"
|
|
NZBGEEK_URL="${NZBGEEK_URL:-${NZBGEEKAPI:-https://api.nzbgeek.info/}}"
|
|
NZBGEEK_USERNAME="${NZBGEEK_USERNAME:-${NZBGEEKUSERNAME:-}}"
|
|
|
|
# Newshosting (provider host often in NEWSHOSTINGAPI)
|
|
NEWSHOSTING_HOST="${NEWSHOSTING_HOST:-${NEWSHOSTINGAPI:-news.newshosting.com}}"
|
|
NEWSHOSTING_PORT="${NEWSHOSTING_PORT:-${NEWSHOSTINGSSLPORT:-563}}"
|
|
[[ "$NEWSHOSTING_PORT" == "653" ]] && NEWSHOSTING_PORT=563 # common typo for 563
|
|
NEWSHOSTING_USER="${NEWSHOSTING_USER:-${NEWSHOSTINGUSER:-}}"
|
|
NEWSHOSTING_PASS="${NEWSHOSTING_PASS:-${HNEWSHOSTINGPASS:-${NEWSHOSTINGPASS:-${NEWSHOSTINGPASSWORD:-}}}}"
|
|
NEWSHOSTING_CONNECTIONS="${NEWSHOSTING_CONNECTIONS:-${NEWSHOSTINGCONNECTIONS:-20}}"
|
|
|
|
# Tweaknews (secrets use TWEAKNEWSLOGIN / TWEAKNEWSPASSWORD / TWEAKNEWSAPI as host)
|
|
TWEAKNEWS_HOST="${TWEAKNEWS_HOST:-${TWEAKNEWSAPI:-${TWEAKNEWSHOST:-news.tweaknews.eu}}}"
|
|
TWEAKNEWS_PORT="${TWEAKNEWS_PORT:-${TWEAKNEWSSSLPORT:-${TWEAKNEWSPORT:-563}}}"
|
|
TWEAKNEWS_USER="${TWEAKNEWS_USER:-${TWEAKNEWSLOGIN:-${TWEAKNEWSUSER:-${TWEAKNEWSUSERNAME:-}}}}"
|
|
TWEAKNEWS_PASS="${TWEAKNEWS_PASS:-${TWEAKNEWSPASSWORD:-${TWEAKNEWSPASS:-}}}"
|
|
TWEAKNEWS_CONNECTIONS="${TWEAKNEWS_CONNECTIONS:-${TWEAKNEWSCONNECTIONS:-10}}"
|
|
|
|
find_api_key() {
|
|
local f
|
|
for f in \
|
|
"${CONFIG_DIR:-$STACK_DIR/config}/sabnzbd/sabnzbd.ini" \
|
|
"$STACK_DIR/config/sabnzbd/sabnzbd.ini" \
|
|
"/opt/stack/config/sabnzbd/sabnzbd.ini" \
|
|
; do
|
|
if [[ -f "$f" ]]; then
|
|
grep -E '^api_key[[:space:]]*=' "$f" | head -1 | cut -d= -f2- | tr -d '[:space:]'
|
|
return 0
|
|
fi
|
|
done
|
|
# docker exec fallback
|
|
if command -v docker >/dev/null 2>&1; then
|
|
docker exec sabnzbd sh -c 'grep -E "^api_key" /config/sabnzbd.ini 2>/dev/null | head -1' \
|
|
| cut -d= -f2- | tr -d '[:space:]' || true
|
|
fi
|
|
}
|
|
|
|
log "Waiting for SABnzbd at $SAB_URL ..."
|
|
for i in $(seq 1 90); do
|
|
if curl -fsS "$SAB_URL/api?mode=version&output=json" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
[[ $i -eq 90 ]] && die "SABnzbd not reachable — is the container up? (docker compose up -d sabnzbd)"
|
|
done
|
|
|
|
api_key="$(find_api_key)"
|
|
[[ -n "$api_key" ]] || die "no api_key yet — open $SAB_URL once to finish first-run, then re-run this script"
|
|
|
|
sab_set() {
|
|
# set_config: section + keyword + value OR servers with name= + fields
|
|
curl -fsS -G "${SAB_URL}/api" \
|
|
--data-urlencode "mode=set_config" \
|
|
--data-urlencode "apikey=${api_key}" \
|
|
--data-urlencode "output=json" \
|
|
"$@"
|
|
}
|
|
|
|
log "Folders: incomplete + complete under /data/usenet"
|
|
sab_set --data-urlencode "section=misc" --data-urlencode "keyword=download_dir" \
|
|
--data-urlencode "value=/data/usenet/incomplete" >/dev/null
|
|
sab_set --data-urlencode "section=misc" --data-urlencode "keyword=complete_dir" \
|
|
--data-urlencode "value=/data/usenet/complete" >/dev/null
|
|
|
|
# Relative category folders under complete_dir
|
|
add_category() {
|
|
local name="$1"
|
|
sab_set \
|
|
--data-urlencode "section=categories" \
|
|
--data-urlencode "name=${name}" \
|
|
--data-urlencode "dir=${name}" \
|
|
--data-urlencode "pp=3" \
|
|
>/dev/null || true
|
|
}
|
|
add_category movies
|
|
add_category tv
|
|
add_category music
|
|
|
|
add_server() {
|
|
local name="$1" host="$2" port="$3" user="$4" pass="$5" conns="$6"
|
|
if [[ -z "$user" || -z "$pass" ]]; then
|
|
log "skip server '$name' (missing user/password in secrets)"
|
|
return 0
|
|
fi
|
|
log "Usenet server: $name → $host:$port (ssl, ${conns} conn)"
|
|
# https://sabnzbd.org/wiki/configuration/5.0/api — servers via set_config + name=
|
|
sab_set \
|
|
--data-urlencode "section=servers" \
|
|
--data-urlencode "name=${name}" \
|
|
--data-urlencode "displayline=${name}" \
|
|
--data-urlencode "host=${host}" \
|
|
--data-urlencode "port=${port}" \
|
|
--data-urlencode "username=${user}" \
|
|
--data-urlencode "password=${pass}" \
|
|
--data-urlencode "connections=${conns}" \
|
|
--data-urlencode "ssl=1" \
|
|
--data-urlencode "enable=1" \
|
|
--data-urlencode "priority=0" \
|
|
--data-urlencode "timeout=60" \
|
|
>/dev/null
|
|
}
|
|
|
|
add_server "Newshosting" \
|
|
"$NEWSHOSTING_HOST" "$NEWSHOSTING_PORT" \
|
|
"$NEWSHOSTING_USER" "$NEWSHOSTING_PASS" \
|
|
"$NEWSHOSTING_CONNECTIONS"
|
|
|
|
add_server "Tweaknews" \
|
|
"$TWEAKNEWS_HOST" "$TWEAKNEWS_PORT" \
|
|
"$TWEAKNEWS_USER" "$TWEAKNEWS_PASS" \
|
|
"$TWEAKNEWS_CONNECTIONS"
|
|
|
|
log "Restart SABnzbd to pick up servers"
|
|
if command -v docker >/dev/null 2>&1 && docker ps --format '{{.Names}}' | grep -qx sabnzbd; then
|
|
docker restart sabnzbd >/dev/null
|
|
sleep 5
|
|
fi
|
|
|
|
log ""
|
|
log "=== SABnzbd ready ==="
|
|
log "UI: $SAB_URL"
|
|
log "API: (Config → General) — use this key in Prowlarr/*arr"
|
|
log ""
|
|
log "=== Prowlarr (NZBgeek) ==="
|
|
log "Indexers → Add Indexer → NZBgeek"
|
|
log " URL: ${NZBGEEK_URL}"
|
|
if [[ -n "$NZBGEEK_API_KEY" ]]; then
|
|
log " API Key: ${NZBGEEK_API_KEY}"
|
|
else
|
|
log " API Key: (set NZBKEEPKEY or NZBGEEK_API_KEY in secrets/.env)"
|
|
fi
|
|
log ""
|
|
log "Download Clients → Add → SABnzbd"
|
|
log " Host: sabnzbd Port: 8080 API Key: (from SABnzbd)"
|
|
log " (sync to apps so Sonarr/Radarr get SABnzbd too, or add per-app)"
|
|
log ""
|
|
log "=== Sonarr / Radarr / Lidarr ==="
|
|
log "Download Clients → SABnzbd → Host sabnzbd Port 8080"
|
|
log " Category: tv | movies | music"
|
|
log "Root folders still /data/media/{tv,movies,music} (hardlinks on same /data)"
|
|
log ""
|
|
if [[ -z "$TWEAKNEWS_USER" || -z "$TWEAKNEWS_PASS" ]]; then
|
|
log "NOTE: Tweaknews user/pass not in secrets — add TWEAKNEWS_USER / TWEAKNEWS_PASS and re-run."
|
|
fi
|