Files
StashHandler/README.md
T
bvandeusen f09d94e34b Initial commit: StashHandler
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>
2026-02-16 11:25:05 -05:00

76 lines
2.5 KiB
Markdown

# 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)
```