# StashHandler A Docker service that bridges qBittorrent and Stash. It polls qBittorrent for completed torrents, hashes media files, deduplicates them against a SQLite database, and moves new files into Stash's import directory. ## Why - **No reimports** — If you delete a file in Stash, StashHandler remembers its hash and won't import it again. - **Deduplication** — Duplicate files are caught before they reach Stash. - **Bulk bootstrap** — Record hashes of your existing Stash library so future downloads are checked against it. ## Quick Start 1. Clone this repo 2. Configure environment variables in `docker-compose.yaml` (or via your swarm/stack config) 3. Deploy: ```bash # Docker Compose docker compose up -d --build # Docker Swarm docker stack deploy -c docker-compose.yaml stash-handler ``` ## Modes ### Daemon (default) Runs continuously, polling qBittorrent for completed torrents. ```bash docker run stash-handler # default command is "daemon" ``` ### Scan Bulk-process files on disk. Useful for bootstrapping the dedup database or one-off imports. ```bash # Record hashes of existing files (no files moved) docker exec stash-handler python stash_handler.py scan /staging # Record and import new files to Stash docker exec stash-handler python stash_handler.py scan --import /staging # Record hashes from your existing Stash library (mount read-only) docker exec stash-handler python stash_handler.py scan /stash-library ``` ## Configuration All configuration is via environment variables. No config files needed — works with Docker Swarm secrets and stack deploys. | Variable | Default | Description | |---|---|---| | `QBIT_URL` | `http://qbittorrent:8080` | qBittorrent Web UI URL | | `QBIT_USERNAME` | `admin` | qBit username | | `QBIT_PASSWORD` | `adminadmin` | qBit password | | `STAGING_DIR` | `/staging` | qBit download directory mount | | `IMPORT_DIR` | `/import` | Stash import directory mount | | `DB_PATH` | `/data/seen.db` | SQLite database path | | `POLL_INTERVAL` | `60` | Seconds between polls | | `MEDIA_EXTENSIONS` | `.mp4,.mkv,.avi,.wmv,.mov,.webm,.flv,.m4v` | Comma-separated extensions | | `HASH_ALGORITHM` | `sha256` | `sha256` or `blake3` | | `MOVE_MODE` | `move` | `move`, `hardlink`, or `copy` | | `LOG_LEVEL` | `INFO` | Python log level | ## Volumes ```yaml volumes: - /data/staging:/staging:ro # qBit downloads (read-only) - /data/stash-import:/import # Stash import dir (read-write) - /data/stash-handler:/data # SQLite database (persistent) ```