Detect files on disk not tracked by any qBittorrent torrent
Project description
qbittorrent-orphaned is a lightweight utility that identifies orphaned files -- files that exist on disk but are not tracked by any torrent in your qBittorrent instance. It connects to the qBittorrent Web API v2, walks the directories you configure, cross-references every file against every torrent, and reports what does not belong.
What Are Orphaned Files?
When you remove a torrent from qBittorrent but keep the data on disk, or when external tools (transcoders, renaming scripts, etc.) create files that were never part of a torrent, those files become orphans. They consume storage without being seeded or managed. This tool finds them so you can decide what to keep and what to reclaim.
Features
- Single-file, pure Python -- no build step, no complex dependencies, just
requests. - Web API v2 -- authenticates and queries qBittorrent over HTTP; works locally or across a network.
- Case-insensitive matching -- handles mixed-case filenames on Windows and Linux alike.
- Category-aware grouping -- results are organized by qBittorrent category, with uncategorized torrents collected under
__UNCATEGORIZED__. - Human-readable sizes -- every orphan is printed alongside its size in KiB, MiB, GiB, etc.
- Configurable metadata ignore list -- common metadata files (
.nfo,.jpg,.png,.srt,.sub,.idx,.txt,.bin,.svg) are skipped by default. You can extend this list. - Exclude patterns -- filter out known non-torrent files (e.g., transcoded 720p copies) by substring match.
- macOS-safe -- automatically skips
._resource fork files.
Quick Start
Install from PyPI
pip install qbittorrent-orphaned
Standalone
QBIT_HOST=http://localhost:8080 \
QBIT_USER=admin \
QBIT_PASS=yourpassword \
CATEGORY_FOLDERS="Films=/mnt/media/films;Shows=/mnt/media/shows" \
qbittorrent-orphaned
You can also run the script directly without installing:
pip install requests
QBIT_HOST=http://localhost:8080 \
QBIT_USER=admin \
QBIT_PASS=yourpassword \
CATEGORY_FOLDERS="Films=/mnt/media/films;Shows=/mnt/media/shows" \
python orphan_detector.py
Docker
There is no pre-built image yet, but you can run it easily with a one-liner:
docker run --rm \
-e QBIT_HOST=http://qbittorrent:8080 \
-e QBIT_USER=admin \
-e QBIT_PASS=yourpassword \
-e CATEGORY_FOLDERS="Films=/media/films;Shows=/media/shows" \
-v /mnt/media:/media:ro \
--network=host \
python:3-alpine sh -c "pip install --quiet requests && python /app/orphan_detector.py"
Mount the script into the container if you prefer a cleaner approach:
docker run --rm \
-v "$(pwd)/orphan_detector.py:/app/orphan_detector.py:ro" \
-v /mnt/media:/media:ro \
-e QBIT_HOST=http://qbittorrent:8080 \
-e QBIT_USER=admin \
-e QBIT_PASS=yourpassword \
-e CATEGORY_FOLDERS="Films=/media/films;Shows=/media/shows" \
python:3-alpine sh -c "pip install --quiet requests && python /app/orphan_detector.py"
Tip: If qBittorrent runs in its own container, make sure both containers share a Docker network (or use
--network=host) so the hostname resolves.
Configuration
All configuration is done through environment variables.
| Variable | Default | Description |
|---|---|---|
QBIT_HOST |
http://qbittorrent:8080 |
qBittorrent Web UI URL |
QBIT_USER |
admin |
Username for Web UI authentication |
QBIT_PASS |
password |
Password for Web UI authentication |
CATEGORY_FOLDERS |
Films=W:\Films;Shows=X:\Series |
Semicolon-separated Category=Path pairs. Categories must match those configured in qBittorrent. |
EXCLUDE_PATTERNS |
(empty) | Comma-separated substrings. Any file whose relative path contains one of these patterns (case-insensitive) is skipped. |
IGNORE_SUFFIXES |
(empty) | Comma-separated file extensions to ignore in addition to the built-in list. Leading dots are optional (e.g., ass,ssa or .ass,.ssa). |
Category Folders Format
CATEGORY_NAME=ABSOLUTE_PATH;CATEGORY_NAME2=ABSOLUTE_PATH2
Each category name must match exactly what is configured in qBittorrent. Torrents with no category are grouped under the key __UNCATEGORIZED__.
Example Output
===== Films =====
/mnt/media/films/Some.Movie.2023/Some.Movie.2023.mkv (4,215 MiB)
/mnt/media/films/Old.Film.1999/Old.Film.1999.avi (702 MiB)
===== Shows =====
/mnt/media/shows/Series.Name.S01/Episode.05.mkv (1,102 MiB)
When no orphans are found the output is simply:
No orphaned files found.
How It Works
- Authenticate -- the script logs in to qBittorrent via
/api/v2/auth/loginand obtains a session cookie. - Fetch torrents -- it retrieves the full torrent list from
/api/v2/torrents/info, then for each torrent calls/api/v2/torrents/filesto get every file path the torrent manages. - Index by category -- all torrent file paths are normalized (forward slashes, lowercase) and grouped into a lookup set per category.
- Walk the filesystem -- for each configured category folder, the script recursively enumerates files, skipping ignored suffixes, macOS resource forks, and exclude-pattern matches.
- Cross-reference -- every disk file is checked against the corresponding category set. Files not present in any torrent are reported as orphans with their absolute path and human-readable size.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qbittorrent_orphaned-1.0.0.tar.gz.
File metadata
- Download URL: qbittorrent_orphaned-1.0.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d66ca7e10347d0425bcef1cca426d37507f0cc6f98b21af4f3d8f3be008f9a4
|
|
| MD5 |
4c3a25f814228ced749464195692c279
|
|
| BLAKE2b-256 |
1c73dea0b21d5ea80fa4125e70b9832183d65318049a4384400f80b910d0944b
|
File details
Details for the file qbittorrent_orphaned-1.0.0-py3-none-any.whl.
File metadata
- Download URL: qbittorrent_orphaned-1.0.0-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03f03d2c1a2bae915f64abcf1c60354415a438baef2d4805927c6d36217c5bb8
|
|
| MD5 |
7929dbbe0a51d631734a0ba76073199a
|
|
| BLAKE2b-256 |
aa9e588cde538091282efe492af7ebb589e683701e85d66cdaebceb6c902d81d
|