Print magnet link to stdout with --link
Magnet links can be printed to standard output with: imdl torrent create --input PATH --link type: added
This commit is contained in:
parent
901fa150ff
commit
0d7c1c0c27
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -94,9 +94,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
|||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.11"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48"
|
||||
checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -195,9 +195,9 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
|||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "807e5847c39ad6a11eac66de492ed1406f76a260eb8656e8740cad9eabc69c27"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
|
@ -265,9 +265,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
|||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
|
||||
checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
|
@ -379,9 +379,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
|
||||
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
@ -589,9 +589,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.4"
|
||||
version = "1.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
|
||||
checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -601,9 +601,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.16"
|
||||
version = "0.6.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1"
|
||||
checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
|
|
|
@ -8,6 +8,18 @@ pub(crate) struct MagnetLink {
|
|||
}
|
||||
|
||||
impl MagnetLink {
|
||||
pub(crate) fn from_metainfo(metainfo: &Metainfo) -> Result<MagnetLink> {
|
||||
let mut link = Self::with_infohash(metainfo.infohash()?);
|
||||
|
||||
link.set_name(metainfo.info.name.clone());
|
||||
|
||||
for tracker in metainfo.trackers() {
|
||||
link.add_tracker(tracker?);
|
||||
}
|
||||
|
||||
Ok(link)
|
||||
}
|
||||
|
||||
pub(crate) fn with_infohash(infohash: Infohash) -> MagnetLink {
|
||||
MagnetLink {
|
||||
infohash,
|
||||
|
@ -57,12 +69,27 @@ impl MagnetLink {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for MagnetLink {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.to_url())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn display() {
|
||||
let link = MagnetLink::with_infohash(Infohash::from_bencoded_info_dict("".as_bytes()));
|
||||
assert_eq!(
|
||||
link.to_string(),
|
||||
"magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic() {
|
||||
let link = MagnetLink::with_infohash(Infohash::from_bencoded_info_dict("".as_bytes()));
|
||||
|
|
|
@ -90,10 +90,18 @@ impl Metainfo {
|
|||
}
|
||||
|
||||
pub(crate) fn trackers<'a>(&'a self) -> impl Iterator<Item = Result<Url>> + 'a {
|
||||
let mut seen = HashSet::new();
|
||||
iter::once(&self.announce)
|
||||
.flatten()
|
||||
.chain(self.announce_list.iter().flatten().flatten())
|
||||
.map(|text| text.parse().context(error::AnnounceUrlParse))
|
||||
.filter_map(move |text| {
|
||||
if seen.contains(text) {
|
||||
None
|
||||
} else {
|
||||
seen.insert(text.clone());
|
||||
Some(text.parse().context(error::AnnounceUrlParse))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn infohash(&self) -> Result<Infohash> {
|
||||
|
@ -414,4 +422,46 @@ mod tests {
|
|||
|
||||
representation(value, want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trackers() {
|
||||
let mut metainfo = Metainfo {
|
||||
announce: Some("http://foo".into()),
|
||||
announce_list: None,
|
||||
nodes: None,
|
||||
comment: None,
|
||||
created_by: None,
|
||||
creation_date: None,
|
||||
encoding: None,
|
||||
info: Info {
|
||||
private: Some(false),
|
||||
piece_length: Bytes(1024),
|
||||
source: None,
|
||||
name: "NAME".into(),
|
||||
pieces: PieceList::from_pieces(&["fae50"]),
|
||||
mode: Mode::Single {
|
||||
length: Bytes(5),
|
||||
md5sum: None,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let trackers = metainfo.trackers().collect::<Result<Vec<Url>>>().unwrap();
|
||||
assert_eq!(trackers, &["http://foo".parse().unwrap()]);
|
||||
|
||||
metainfo.announce_list = Some(vec![
|
||||
vec!["http://bar".into(), "http://baz".into()],
|
||||
vec!["http://foo".into()],
|
||||
]);
|
||||
|
||||
let trackers = metainfo.trackers().collect::<Result<Vec<Url>>>().unwrap();
|
||||
assert_eq!(
|
||||
trackers,
|
||||
&[
|
||||
"http://foo".parse().unwrap(),
|
||||
"http://bar".parse().unwrap(),
|
||||
"http://baz".parse().unwrap(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,11 @@ pub(crate) struct Create {
|
|||
parse(from_os_str)
|
||||
)]
|
||||
input: PathBuf,
|
||||
#[structopt(
|
||||
long = "link",
|
||||
help = "Print created torrent `magnet:` URL to standard output"
|
||||
)]
|
||||
print_magnet_link: bool,
|
||||
#[structopt(
|
||||
long = "md5",
|
||||
short = "M",
|
||||
|
@ -152,6 +157,13 @@ pub(crate) struct Create {
|
|||
parse(from_os_str)
|
||||
)]
|
||||
output: Option<OutputTarget>,
|
||||
#[structopt(
|
||||
long = "peer",
|
||||
value_name = "PEER",
|
||||
help = "Add `PEER` to magnet link.",
|
||||
requires("print-magnet-link")
|
||||
)]
|
||||
peers: Vec<HostPort>,
|
||||
#[structopt(
|
||||
long = "piece-length",
|
||||
short = "p",
|
||||
|
@ -391,7 +403,15 @@ impl Create {
|
|||
errln!(env, "\u{2728}\u{2728} Done! \u{2728}\u{2728}")?;
|
||||
|
||||
if self.show {
|
||||
TorrentSummary::from_metainfo(metainfo)?.write(env)?;
|
||||
TorrentSummary::from_metainfo(metainfo.clone())?.write(env)?;
|
||||
}
|
||||
|
||||
if self.print_magnet_link {
|
||||
let mut link = MagnetLink::from_metainfo(&metainfo)?;
|
||||
for peer in self.peers {
|
||||
link.add_peer(peer);
|
||||
}
|
||||
outln!(env, "{}", link)?;
|
||||
}
|
||||
|
||||
if let OutputTarget::File(path) = output {
|
||||
|
@ -2288,4 +2308,116 @@ Content Size 9 bytes
|
|||
|
||||
assert_matches!(env.run(), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_print_magnet_link() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"create",
|
||||
"--input",
|
||||
"foo",
|
||||
],
|
||||
tree: {
|
||||
foo: "",
|
||||
},
|
||||
};
|
||||
|
||||
assert_matches!(env.run(), Ok(()));
|
||||
assert_eq!(env.out(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_magnet_link() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"create",
|
||||
"--input",
|
||||
"foo",
|
||||
"--link",
|
||||
],
|
||||
tree: {
|
||||
foo: "",
|
||||
},
|
||||
};
|
||||
|
||||
assert_matches!(env.run(), Ok(()));
|
||||
assert_eq!(
|
||||
env.out(),
|
||||
"magnet:?xt=urn:btih:516735f4b80f2b5487eed5f226075bdcde33a54e&dn=foo\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_magnet_link_with_announce() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"create",
|
||||
"--input",
|
||||
"foo",
|
||||
"--link",
|
||||
"--announce",
|
||||
"http://foo.com/announce",
|
||||
],
|
||||
tree: {
|
||||
foo: "",
|
||||
},
|
||||
};
|
||||
|
||||
assert_matches!(env.run(), Ok(()));
|
||||
assert_eq!(
|
||||
env.out(),
|
||||
"magnet:\
|
||||
?xt=urn:btih:516735f4b80f2b5487eed5f226075bdcde33a54e\
|
||||
&dn=foo\
|
||||
&tr=http://foo.com/announce\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peer_requires_link() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"create",
|
||||
"--input",
|
||||
"foo",
|
||||
"--peer",
|
||||
],
|
||||
tree: {
|
||||
foo: "",
|
||||
},
|
||||
};
|
||||
|
||||
assert_matches!(env.run(), Err(Error::Clap { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn link_with_peers() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"create",
|
||||
"--input",
|
||||
"foo",
|
||||
"--peer",
|
||||
"foo:1337",
|
||||
"--peer",
|
||||
"bar:666",
|
||||
"--link"
|
||||
],
|
||||
tree: {
|
||||
foo: "",
|
||||
},
|
||||
};
|
||||
|
||||
assert_matches!(env.run(), Ok(()));
|
||||
assert_eq!(
|
||||
env.out(),
|
||||
"magnet:?xt=urn:btih:516735f4b80f2b5487eed5f226075bdcde33a54e&dn=foo&x.pe=foo:1337&x.pe=bar:\
|
||||
666\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,13 +41,8 @@ impl Link {
|
|||
|
||||
link.set_name(&metainfo.info.name);
|
||||
|
||||
let mut trackers = HashSet::new();
|
||||
for result in metainfo.trackers() {
|
||||
let tracker = result?;
|
||||
if !trackers.contains(&tracker) {
|
||||
trackers.insert(tracker.clone());
|
||||
link.add_tracker(tracker);
|
||||
}
|
||||
link.add_tracker(result?);
|
||||
}
|
||||
|
||||
for peer in self.peers {
|
||||
|
|
Loading…
Reference in New Issue
Block a user