Reconstruct torrent content from existing files on disk by scanning source directories, matching pieces by hash, and writing verified data to an output directory managed by a torrent client.
- Scans your local files to find data that matches torrent pieces, avoiding redundant downloads.
- Integrates directly with qBittorrent via its Web API to import torrents, verify pieces, and trigger rechecks.
- Handles multi-file torrents where pieces span file boundaries.
- Uses reflink (copy-on-write) when available for near-instant file creation on supported filesystems (btrfs, xfs).
- Parallel piece solving with configurable worker threads and work stealing.
- A running qBittorrent instance with the Web API enabled.
- Rust toolchain (stable).
Create a torrent-bootstrap.toml in your working directory:
[client]
api = "qbittorrent"
url = "http://localhost:8080"
username = "admin"
password = "your_password"torrent-bootstrap [OPTIONS] --output <OUTPUT> --source <SOURCE>
Options:
--import <PATH> Import a .torrent file into the torrent client and process it
--all Process all torrents in the torrent client
--info-hash <HASH> Process specific torrents by their v1 info hashes (repeatable)
--output <OUTPUT> Base output directory for reconstructed torrent content
--source <SOURCE> Directories to scan for source data (repeatable)
--workers <WORKERS> Number of hashing worker threads [default: 1]
--skip-failed-torrents Continue processing when a torrent fails
--generate-md5sums Generate MD5SUMS files for completed torrents
-h, --help Print help
Import a torrent and reconstruct from source files:
torrent-bootstrap \
--import /path/to/file.torrent \
--output /mnt/storage/Downloads \
--source /mnt/storage \
--workers 4Process all incomplete torrents in the client:
torrent-bootstrap \
--all \
--output /mnt/storage/Downloads \
--source /mnt/storage \
--workers 4Process specific torrents by hash:
torrent-bootstrap \
--info-hash abc123... \
--info-hash def456... \
--output /mnt/storage/Downloads \
--source /mnt/storage \
--workers 4Each torrent's content is organized under the output directory by its info hash:
output/
{info_hash}/
{info_hash}.torrent
Data/
{torrent content files}
- Connect to the torrent client and fetch torrent metadata (files, pieces, hashes).
- Ensure paths by moving each torrent's save path to
output/{hash}/Data/if needed, with recheck after each move. - Save the
.torrentfile tooutput/{hash}/{hash}.torrent. - Scan source directories to build a file cache indexed by size.
- Match candidates for each incomplete piece by finding source files with matching sizes.
- Solve pieces in parallel across worker threads. For each candidate combination, read the relevant byte ranges, SHA-1 hash the result, and compare to the expected hash.
- Write matched data to the output. Uses reflink when the target file doesn't exist and the filesystem supports it; otherwise patches individual pieces.
- Recheck each torrent in the client after writing, smallest first.
When --generate-md5sums is passed, an MD5SUMS file is generated in each torrent's output directory (output/{hash}/MD5SUMS) after writing and rechecking. Only files whose pieces are all verified complete are included. The file follows the standard md5sum format (hash path), with paths relative to the torrent directory. Files already listed in an existing MD5SUMS are skipped, so the command is safe to run repeatedly — new entries are appended as more files become complete.
- Source files are never modified. The tool only reads from source directories.
- Existing target files are never deleted or replaced. When a target file already exists, only the specific pieces that need updating are written.
- Writes use
truncate(false)to preserve existing content at unmodified offsets. - Torrents are added to the client in a stopped state to prevent downloading during processing.
cargo build --releaseThe binary will be at target/release/torrent-bootstrap.