f09d94e34b
Bridge between qBittorrent and Stash that polls for completed torrents, deduplicates via SHA256 hashing and SQLite, and imports new media files. Supports daemon mode (continuous polling) and scan mode (bulk operations). Configuration via environment variables for Docker Swarm compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
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
- Clone this repo
- Configure environment variables in
docker-compose.yaml(or via your swarm/stack config) - Deploy:
# 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.
docker run stash-handler # default command is "daemon"
Scan
Bulk-process files on disk. Useful for bootstrapping the dedup database or one-off imports.
# 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
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)