diff --git a/README.md b/README.md index 18a7c8e..fb8258d 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ --- -Discarr is a zero-dependency Node.js web UI that bridges your disc ripping workflow with Sonarr and Radarr. Point it at a `VIDEO_TS` or `BDMV` directory, map the title to the right episode or movie in your library, and let it handle the HEVC encode and import. +Discarr is a Node.js web UI (no npm packages) that bridges your disc ripping workflow with Sonarr and Radarr. Point it at a `VIDEO_TS` or `BDMV` directory, map the title to the right episode or movie in your library, and let it handle the HEVC encode and import. -No npm packages. No Python. No config files to edit by hand — just a browser and a config with your API keys. +No npm packages. No Python. No config files to edit by hand — just a browser, your API keys, and the system tools you probably already have (ffmpeg, HandBrake). --- @@ -53,20 +53,51 @@ Open `http://localhost:8603` — paste a disc path and click **Scan**. ## Install -### From source +### Native installer (recommended) + +Handles Node.js, ffmpeg, HandBrake CLI, and DVD libraries automatically. Supports Ubuntu/Debian, Fedora/RHEL, Arch, and macOS. ```bash git clone https://git.opensourcesolarpunk.com/Circuit-Forge/discarr cd discarr +sudo bash install.sh ``` -Requirements: Node.js 18+, ffmpeg, ffprobe (for metadata scanning). +The installer will ask if you want to register a systemd service. Override defaults with env vars: + +```bash +sudo DISCARR_INSTALL_DIR=/opt/discarr DISCARR_PORT=8603 REGISTER_SERVICE=yes bash install.sh +``` + +#### System dependencies installed + +| Dependency | Required | Purpose | +|---|---|---| +| Node.js 18+ | Yes | Runtime | +| ffmpeg + ffprobe | Yes | Disc metadata scanning, encode dispatch | +| HandBrake CLI | Recommended | HEVC encoding (falls back to ffmpeg if absent) | +| libdvdcss | Recommended | CSS-encrypted DVD decryption | +| libdvdread + libdvdnav | Yes (DVD) | DVD structure and navigation reading | + +> **Note on libdvdcss:** Legal in most jurisdictions for personal use. Ubuntu users: `libdvd-pkg` builds it from source. Fedora users: requires RPM Fusion. The installer handles both. ### Docker +Pre-built image (includes ffmpeg, ffprobe, HandBrake, libdvd*, openssh-client): + +```bash +docker run -d \ + -p 8603:8603 \ + -v ~/.config/media-postprocessor:/root/.config/media-postprocessor:ro \ + -v ~/.local/share/discarr:/root/.local/share/discarr \ + -v /path/to/media:/media \ + pyr0ball/discarr:latest +``` + +Or build from source: + ```bash docker build -t discarr . - docker run -d \ -p 8603:8603 \ -v ~/.config/media-postprocessor:/root/.config/media-postprocessor:ro \ @@ -75,7 +106,14 @@ docker run -d \ discarr ``` -The image includes ffmpeg, ffprobe, HandBrake, and openssh-client. +### Manual (from source) + +```bash +git clone https://git.opensourcesolarpunk.com/Circuit-Forge/discarr +cd discarr +# Install deps manually (see table above), then: +node server.js +``` --- diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..81ad4a9 --- /dev/null +++ b/install.sh @@ -0,0 +1,252 @@ +#!/usr/bin/env bash +# Discarr native installer +# Installs Node.js 18+, ffmpeg, HandBrake CLI, and DVD libraries, +# then optionally registers Discarr as a systemd service. +# +# Supported: Ubuntu/Debian (apt), Fedora/RHEL (dnf), Arch (pacman), macOS (brew) +# Run as root or with sudo. + +set -euo pipefail + +DISCARR_INSTALL_DIR="${DISCARR_INSTALL_DIR:-/opt/discarr}" +DISCARR_USER="${DISCARR_USER:-discarr}" +DISCARR_PORT="${DISCARR_PORT:-8603}" +REGISTER_SERVICE="${REGISTER_SERVICE:-ask}" # ask | yes | no + +# ── Colours ──────────────────────────────────────────────────────────────────── +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' +info() { echo -e "${CYAN}→${NC} $*"; } +success() { echo -e "${GREEN}✓${NC} $*"; } +warn() { echo -e "${YELLOW}⚠${NC} $*"; } +die() { echo -e "${RED}✗${NC} $*" >&2; exit 1; } + +# ── Root check ───────────────────────────────────────────────────────────────── +[[ $EUID -eq 0 ]] || die "Run as root or with sudo." + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# ── Detect package manager ───────────────────────────────────────────────────── +detect_pm() { + if command -v apt-get &>/dev/null; then echo "apt" + elif command -v dnf &>/dev/null; then echo "dnf" + elif command -v pacman &>/dev/null; then echo "pacman" + elif command -v brew &>/dev/null; then echo "brew" + else die "Unsupported package manager. Install deps manually and re-run with SKIP_DEPS=1." + fi +} +PM=$(detect_pm) +info "Package manager: $PM" + +# ── Node.js 18+ ──────────────────────────────────────────────────────────────── +install_node() { + if command -v node &>/dev/null; then + local ver + ver=$(node --version | sed 's/v//' | cut -d. -f1) + if [[ $ver -ge 18 ]]; then + success "Node.js $(node --version) already installed." + return + fi + warn "Node.js $ver found but >=18 required. Upgrading via NodeSource." + fi + + info "Installing Node.js 20 LTS via NodeSource..." + case $PM in + apt) + curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + apt-get install -y nodejs + ;; + dnf) + curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - + dnf install -y nodejs + ;; + pacman) + pacman -Sy --noconfirm nodejs npm + ;; + brew) + brew install node@20 + brew link --overwrite node@20 + ;; + esac + success "Node.js $(node --version) installed." +} + +# ── ffmpeg + ffprobe ─────────────────────────────────────────────────────────── +install_ffmpeg() { + if command -v ffmpeg &>/dev/null && command -v ffprobe &>/dev/null; then + success "ffmpeg $(ffmpeg -version 2>&1 | head -1 | awk '{print $3}') already installed." + return + fi + info "Installing ffmpeg..." + case $PM in + apt) apt-get install -y ffmpeg ;; + dnf) + # ffmpeg is in RPM Fusion — enable if not already + if ! dnf repolist enabled | grep -q rpmfusion-free; then + dnf install -y \ + "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm" \ + "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm" + fi + dnf install -y ffmpeg + ;; + pacman) pacman -Sy --noconfirm ffmpeg ;; + brew) brew install ffmpeg ;; + esac + success "ffmpeg installed." +} + +# ── HandBrake CLI (optional but recommended for HEVC encoding) ───────────────── +install_handbrake() { + if command -v HandBrakeCLI &>/dev/null || command -v handbrake-cli &>/dev/null; then + success "HandBrake CLI already installed." + return + fi + info "Installing HandBrake CLI..." + case $PM in + apt) + # handbrake-cli is in universe on Ubuntu 20.04+ + apt-get install -y handbrake-cli 2>/dev/null || { + warn "handbrake-cli not found in apt — skipping. You can install it manually:" + warn " https://handbrake.fr/downloads.php" + } + ;; + dnf) + # Requires RPM Fusion (already enabled for ffmpeg) + dnf install -y HandBrake-cli 2>/dev/null || warn "HandBrake-cli not found — skipping." + ;; + pacman) + pacman -Sy --noconfirm handbrake-cli 2>/dev/null || warn "handbrake-cli not found — skipping." + ;; + brew) + brew install handbrake 2>/dev/null || warn "HandBrake not found in brew — skipping." + ;; + esac +} + +# ── DVD libraries (libdvdcss, libdvdread, libdvdnav) ────────────────────────── +install_dvd_libs() { + info "Installing DVD libraries (libdvdcss, libdvdread, libdvdnav)..." + case $PM in + apt) + apt-get install -y libdvd-pkg libdvdread8 libdvdnav4 2>/dev/null || \ + apt-get install -y libdvdread-dev libdvdnav-dev 2>/dev/null || true + # libdvd-pkg builds libdvdcss from source (legal in most jurisdictions) + if dpkg -l libdvd-pkg &>/dev/null 2>&1; then + DEBIAN_FRONTEND=noninteractive dpkg-reconfigure libdvd-pkg 2>/dev/null || true + fi + ;; + dnf) + if ! dnf repolist enabled | grep -q rpmfusion; then + warn "RPM Fusion not enabled — skipping libdvdcss. Enable RPM Fusion and run: dnf install libdvdcss" + else + dnf install -y libdvdcss libdvdread libdvdnav 2>/dev/null || true + fi + ;; + pacman) + # libdvdcss is in extra; others in core + pacman -Sy --noconfirm libdvdcss libdvdread libdvdnav 2>/dev/null || true + ;; + brew) + brew install libdvdcss 2>/dev/null || warn "libdvdcss not available via brew — skipping." + ;; + esac + success "DVD libraries done (some may need manual install — see README)." +} + +# ── Install Discarr app files ────────────────────────────────────────────────── +install_app() { + info "Installing Discarr to $DISCARR_INSTALL_DIR..." + mkdir -p "$DISCARR_INSTALL_DIR" + cp -r "$SCRIPT_DIR"/server.js "$SCRIPT_DIR"/scanner.js "$SCRIPT_DIR"/public \ + "$SCRIPT_DIR"/scripts "$SCRIPT_DIR"/api-keys.conf.example \ + "$DISCARR_INSTALL_DIR"/ + + # Create a launcher wrapper + cat > /usr/local/bin/discarr </dev/null; then + useradd -r -s /bin/false -d "$DISCARR_INSTALL_DIR" "$DISCARR_USER" + chown -R "$DISCARR_USER:$DISCARR_USER" "$DISCARR_INSTALL_DIR" + fi + + cat > "$SERVICE_FILE" <