GitHub | crates.io | Issues | Changelog
demagnetize is a Rust program for converting one or more BitTorrent magnet
links into .torrent files
by downloading the torrent info from active peers.
At the moment, demagnetize only supports basic features of the BitTorrent
protocol. The following notable features are supported:
- BitTorrent protocol v1
- HTTP (including compact and IPv6 extensions) and UDP trackers
- magnet URIs with info hashes encoded in either hexadecimal or base32
- Fast extension (BEP 6)
- UDP tracker protocol extensions (BEP 41)
- MSE/PE Encryption
The following features are not currently supported but are planned, in no particular order:
- Distributed hash tables
- BitTorrent protocol v2
x.peparameters in magnet links- uTP
demagnetize is a translation of a Python program by the same author; you can
find the Python version at https://github.com/jwodder/demagnetize.
Prebuilt binaries for the most common platforms are available as GitHub release assets. The page for the latest release lists these under "Assets", along with installer scripts for both Unix-like systems and Windows.
As an alternative to the installer scripts, if you have
cargo-binstall on your
system, you can use it to download & install the appropriate release asset for
your system for the latest version of demagnetize by running cargo binstall demagnetize.
If you have Rust and Cargo
installed, you can build the latest
release of demagnetize from source and install it in ~/.cargo/bin by
running:
cargo install demagnetize
demagnetize has the following Cargo features, selectable via the --features <LIST> option to cargo install:
-
native-tls— Usenative-tlsfor TLS support. This feature is enabled by default. -
native-tls-vendored— Likenative-tls, but compile a vendored copy of OpenSSL intodemagnetizeinstead of using the platform's copy at runtime. This makes it possible to builddemagnetizeon one system and run it on another system that has a different version of OpenSSL.This feature has no effect on Windows and macOS, where OpenSSL is not used.
-
rustls— Userustlsfor TLS support. When selecting this feature, be sure to also supply the--no-default-featuresoption in order to disablenative-tls.- The release assets are built using this feature.
demagnetize [<global options>] <subcommand> ...
The demagnetize command has two main general-purpose subcommands, get (for
converting a single magnet link) and batch (for converting a file of magnet
links). There are also two low-level commands, query-tracker (for getting a
list of peers from a single tracker) and query-peer (for getting torrent
metadata from a single peer).
-
-c <file>,--config <file>— Specify the configuration file to use. See "Configuration" below for the default config file location. -
-l <level>,--log-level <level>— Set the log level to the given value. Possible values are "OFF", "ERROR", "WARN", "INFO", "DEBUG", and "TRACE" (all case-insensitive). [default value:INFO] -
--no-config— Use the default configuration settings and do not read from any configuration files
demagnetize [<global options>] get [<options>] <magnet-link>
Convert a single magnet link specified on the command line to a .torrent
file. (Note that you will likely have to quote the link in order to prevent it
from being interpreted by the shell.) By default, the file is saved at
{name}.torrent, where {name} is replaced by the value of the name field
from the torrent info, but a different path can be set via the --outfile
option.
-o PATH,--outfile PATH— Save the.torrentfile to the given path. The path may contain a{name}placeholder, which will be replaced by the (sanitized) name of the torrent, and/or a{hash}placeholder, which will be replaced by the torrent's info hash in hexadecimal. Specifying-will cause the torrent to be written to standard output. [default:{name}.torrent]
demagnetize [<global options>] batch [<options>] <file>
Read magnet links from <file> (or from standard input if <file> is -),
one per line (ignoring empty lines and lines that start with #), and convert
each one to a .torrent file. By default, each file is saved at
{name}.torrent, where {name} is replaced by the value of the name field
from the torrent info, but a different path can be set via the --outfile
option.
-o PATH,--outfile PATH— Save the.torrentfiles to the given path. The path may contain a{name}placeholder, which will be replaced by the (sanitized) name of each torrent, and/or a{hash}placeholder, which will be replaced by each torrent's info hash in hexadecimal. [default:{name}.torrent]
demagnetize [<global options>] query-tracker [<options>] <tracker> <info-hash>
Query the given tracker (specified as an HTTP or UDP URL) for peers serving the torrent with the given info hash (specified as a 40-character hex string or 32-character base32 string), and print out the the retrieved peers' addresses in the form "IP:PORT".
-
-J,--json— Print out the peers as JSON objects, one per line -
--no-crypto— Do not tell the tracker anything about our encryption support. Overrides thegeneral.encryptconfiguration setting. -
--require-crypto— Tell the tracker that we require peers with encryption support. Overrides thegeneral.encryptconfiguration setting. -
--support-crypto— Tell the tracker that we support the encrypted peer protocol. Overrides thegeneral.encryptconfiguration setting.
demagnetize [<global options>] query-peer [<options>] <peer> <info-hash>
Query the given peer (specified as an address in "IPv4:PORT" or "[IPv6]:PORT"
format) for the metadata of the torrent with the given info hash (specified as
a 40-character hex string or 32-character base32 string), and save the metadata
to a file. By default, the file is saved at {name}.torrent, where {name}
is replaced by the value of the name field from the torrent info, but a
different path can be set via the --outfile option.
Note that, unlike the .torrent files produced by the get and batch
commands, the files produced by this command will not contain tracker
information.
-
--encrypt— Create an encrypted connection to the peer. Overrides thegeneral.encryptconfiguration setting. -
--no-encrypt— Create an unencrypted connection to the peer. Overrides thegeneral.encryptconfiguration setting. -
-o PATH,--outfile PATH— Save the.torrentfile to the given path. The path may contain a{name}placeholder, which will be replaced by the (sanitized) name of the torrent, and/or a{hash}placeholder, which will be replaced by the torrent's info hash in hexadecimal. Specifying-will cause the torrent to be written to standard output. [default:{name}.torrent] -
--prefer-encrypt— Attempt to create an encrypted connection to the peer; if that fails, try again without encryption. Overrides thegeneral.encryptconfiguration setting.
demagnetize can be configured via a TOML file whose
default location depends on your OS:
- Linux —
~/.config/demagnetize/config.tomlor$XDG_CONFIG_HOME/demagnetize/config.toml - macOS —
~/Library/Application Support/demagnetize/config.toml - Windows —
%USERPROFILE%\AppData\Local\demagnetize\config.toml
This file may contain the following tables & keys, all of which are optional:
-
[general]— settings that don't fit anywhere more specificbatch-jobs(positive integer; default 50) — the maximum number of magnet links that thebatchcommand will operate on at onceencrypt— Configures when to use MSE/PE encryption when connecting to peers and what to tell HTTP trackers about encryption support. The possible options are:"always"– Always use encryption with peers, and include arequirecrypto=1parameter in announcements to HTTP trackers"prefer"— Try creating an encrypted connection to a peer first; if the encryption handshake fails, and the peer does not require encryption, try again without encryption. Also include asupportcrypto=1parameter in announcements to HTTP trackers.- This is the default.
- Note that falling back to an unencrypted connection resets the
peer handshake timeout (See
peers.handshake-timeoutbelow).
"if-required"— Only use encryption if the returning tracker indicated that the peer requires encryption, and include asupportcrypto=1parameter in announcements to HTTP trackers."never"— Do not use encryption; do not attempt to connect to peers that require encryption; do not include any crypto parameters in announcements to HTTP trackers
-
[peers]— settings for interacting with peersdh-exchange-timeout(nonnegative integer; default 30) — When performing the handshake for an encrypted peer connection, wait this many seconds for the remote peer to send its portion of the Diffie-Hellman key exchange.handshake-timeout(nonnegative integer; default 60) — When connecting to a peer, if the TCP connection, encryption handshake, and BitTorrent handshake are not all completed within this many seconds, the peer is abandoned.jobs-per-magnet(positive integer; default 30) — the maximum number of peers per magnet link thatdemagnetizewill communicate with at once
-
[trackers]— settings for interacting with trackersannounce-timeout(nonnegative integer; default 30) — When sending a "started" announcement to a tracker & receiving a list of peers in response, if the task does not complete within this many seconds, the tracker is abandoned.jobs-per-magnet(positive integer; default 30) — the maximum number of trackers per magnet link thatdemagnetizewill communicate with at oncelocal-port— the port number thatdemagnetizewill tell trackers it's receiving peer connections on- This can be either a port number or a string containing two port
numbers separated by a hyphen (in which case a port in the given
inclusive range will be chosen at random). The default is
"1025-65535", which selects any nonprivileged port at random. - Note that
demagnetizedoes not actually use the port in question, and no attempt is made to ensure the port is not already in use. On the other hand,demagnetizesends a "stop" announcement to each tracker immediately after receiving the list of peers, so hopefully no other peers will see the port number.
- This can be either a port number or a string containing two port
numbers separated by a hyphen (in which case a port in the given
inclusive range will be chosen at random). The default is
numwant(positive integer; default 50) — the number of peers to request from each trackershutdown-timeout(nonnegative integer; default 3) — At the end of program operation, wait this many seconds for any outstanding "stopped" announcements to complete; any tasks still running after the timeout are forcibly cancelled.