Partially implement BEP 53
This enables `--select-only 1,2,3` which gets appended to the magnet link as `&so=1,2,3`. It's a partial implementation because we're missing support for file ranges ie `--select-only 4-6` type: added fixes: - https://github.com/casey/intermodal/issues/245
This commit is contained in:
parent
6185d6c8a2
commit
cb8b5a6919
|
@ -2,9 +2,10 @@ Changelog
|
|||
=========
|
||||
|
||||
|
||||
UNRELEASED - 2020-04-12
|
||||
UNRELEASED - 2020-04-13
|
||||
-----------------------
|
||||
- :books: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Add table of packages to readme ([#372](https://github.com/casey/intermodal/pull/372)) - Fixes [#369](https://github.com/casey/intermodal/issues/369) - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
- :sparkles: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Partially implement BEP 53 - Fixes [#245](https://github.com/casey/intermodal/issues/245) - _strickinato <aaronstrick@gmail.com>_
|
||||
- :books: [`6185d6c8a27c`](https://github.com/casey/intermodal/commit/6185d6c8a27c0d603f0434e98000c8e4a868dcc8) Add table of packages to readme ([#372](https://github.com/casey/intermodal/pull/372)) - Fixes [#369](https://github.com/casey/intermodal/issues/369) - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
- :wrench: [`ddf097c83690`](https://github.com/casey/intermodal/commit/ddf097c8369002748992165f81e9a1bdbe6eff98) Fix `publish` recipe ([#368](https://github.com/casey/intermodal/pull/368)) - _Casey Rodarmor <casey@rodarmor.com>_
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,12 @@ FLAGS:
|
|||
-V, --version Print version number.
|
||||
|
||||
OPTIONS:
|
||||
-i, --input <METAINFO> Generate magnet link from metainfo at `PATH`. If
|
||||
`PATH` is `-`, read metainfo from standard input.
|
||||
-p, --peer <PEER>... Add `PEER` to magnet link.
|
||||
-s, --select-only <INDICES>...
|
||||
Specify files that torrent clients select for download. Values are
|
||||
indices into the info.files list. e.g. `--select-only 1,2,3`
|
||||
-i, --input <METAINFO>
|
||||
Generate magnet link from metainfo at `PATH`. If `PATH` is `-`, read
|
||||
metainfo from standard input.
|
||||
-p, --peer <PEER>... Add `PEER` to magnet link.
|
||||
|
||||
```
|
|
@ -245,7 +245,7 @@ _imdl() {
|
|||
return 0
|
||||
;;
|
||||
imdl__torrent__link)
|
||||
opts=" -O -h -V -i -p --open --help --version --input --peer "
|
||||
opts=" -O -h -V -i -p -s --open --help --version --input --peer --select-only "
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
@ -268,6 +268,14 @@ _imdl() {
|
|||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--select-only)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-s)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=()
|
||||
;;
|
||||
|
|
|
@ -124,8 +124,10 @@ Sort in ascending order by size, break ties in descending path order:
|
|||
cand --input 'Generate magnet link from metainfo at `PATH`. If `PATH` is `-`, read metainfo from standard input.'
|
||||
cand -p 'Add `PEER` to magnet link.'
|
||||
cand --peer 'Add `PEER` to magnet link.'
|
||||
cand -O 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows'
|
||||
cand --open 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows'
|
||||
cand -s 'Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.'
|
||||
cand --select-only 'Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.'
|
||||
cand -O 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.'
|
||||
cand --open 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.'
|
||||
cand -h 'Print help message.'
|
||||
cand --help 'Print help message.'
|
||||
cand -V 'Print version number.'
|
||||
|
|
|
@ -69,7 +69,8 @@ complete -c imdl -n "__fish_seen_subcommand_from create" -l help -d 'Print help
|
|||
complete -c imdl -n "__fish_seen_subcommand_from create" -s V -l version -d 'Print version number.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s i -l input -d 'Generate magnet link from metainfo at `PATH`. If `PATH` is `-`, read metainfo from standard input.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s p -l peer -d 'Add `PEER` to magnet link.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s O -l open -d 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s s -l select-only -d 'Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s O -l open -d 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s h -l help -d 'Print help message.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from link" -s V -l version -d 'Print version number.'
|
||||
complete -c imdl -n "__fish_seen_subcommand_from piece-length" -s h -l help -d 'Print help message.'
|
||||
|
|
|
@ -132,8 +132,10 @@ Sort in ascending order by size, break ties in descending path order:
|
|||
[CompletionResult]::new('--input', 'input', [CompletionResultType]::ParameterName, 'Generate magnet link from metainfo at `PATH`. If `PATH` is `-`, read metainfo from standard input.')
|
||||
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Add `PEER` to magnet link.')
|
||||
[CompletionResult]::new('--peer', 'peer', [CompletionResultType]::ParameterName, 'Add `PEER` to magnet link.')
|
||||
[CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows')
|
||||
[CompletionResult]::new('--open', 'open', [CompletionResultType]::ParameterName, 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows')
|
||||
[CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.')
|
||||
[CompletionResult]::new('--select-only', 'select-only', [CompletionResultType]::ParameterName, 'Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.')
|
||||
[CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.')
|
||||
[CompletionResult]::new('--open', 'open', [CompletionResultType]::ParameterName, 'Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help message.')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help message.')
|
||||
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version number.')
|
||||
|
|
|
@ -135,8 +135,10 @@ _arguments "${_arguments_options[@]}" \
|
|||
'--input=[Generate magnet link from metainfo at `PATH`. If `PATH` is `-`, read metainfo from standard input.]' \
|
||||
'*-p+[Add `PEER` to magnet link.]' \
|
||||
'*--peer=[Add `PEER` to magnet link.]' \
|
||||
'-O[Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows]' \
|
||||
'--open[Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows]' \
|
||||
'*-s+[Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.]' \
|
||||
'*--select-only=[Select files to download. Values are indices into the `info.files` list, e.g. `--select-only 1,2,3`.]' \
|
||||
'-O[Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.]' \
|
||||
'--open[Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; `open` on macOS; and `cmd /C start` on Windows.]' \
|
||||
'-h[Print help message.]' \
|
||||
'--help[Print help message.]' \
|
||||
'-V[Print version number.]' \
|
||||
|
|
|
@ -19,6 +19,10 @@ and `cmd \fI\,/C\/\fP start` on Windows
|
|||
Print version number.
|
||||
.SH "OPTIONS:"
|
||||
.TP
|
||||
\fB\-s\fR, \fB\-\-select\-only\fR <INDICES>...
|
||||
Specify files that torrent clients select for download. Values are indices into
|
||||
the info.files list. e.g. `\-\-select\-only 1,2,3`
|
||||
.TP
|
||||
\fB\-i\fR, \fB\-\-input\fR <METAINFO>
|
||||
Generate magnet link from metainfo at `PATH`. If `PATH` is `\-`, read metainfo from
|
||||
standard input.
|
||||
|
|
|
@ -5,6 +5,7 @@ pub(crate) struct MagnetLink {
|
|||
name: Option<String>,
|
||||
peers: Vec<HostPort>,
|
||||
trackers: Vec<Url>,
|
||||
indices: BTreeSet<u64>,
|
||||
}
|
||||
|
||||
impl MagnetLink {
|
||||
|
@ -26,6 +27,7 @@ impl MagnetLink {
|
|||
name: None,
|
||||
peers: Vec::new(),
|
||||
trackers: Vec::new(),
|
||||
indices: BTreeSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +45,10 @@ impl MagnetLink {
|
|||
self.trackers.push(tracker);
|
||||
}
|
||||
|
||||
pub(crate) fn add_index(&mut self, index: u64) {
|
||||
self.indices.insert(index);
|
||||
}
|
||||
|
||||
pub(crate) fn to_url(&self) -> Url {
|
||||
let mut url = Url::parse("magnet:").unwrap();
|
||||
|
||||
|
@ -63,6 +69,16 @@ impl MagnetLink {
|
|||
query.push_str(&peer.to_string());
|
||||
}
|
||||
|
||||
if !self.indices.is_empty() {
|
||||
query.push_str("&so=");
|
||||
for (i, selection_index) in self.indices.iter().enumerate() {
|
||||
if i > 0 {
|
||||
query.push(',');
|
||||
}
|
||||
query.push_str(&selection_index.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
url.set_query(Some(&query));
|
||||
|
||||
url
|
||||
|
@ -129,6 +145,19 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_indices() {
|
||||
let mut link = MagnetLink::with_infohash(Infohash::from_bencoded_info_dict("".as_bytes()));
|
||||
link.add_index(4);
|
||||
link.add_index(6);
|
||||
link.add_index(6);
|
||||
link.add_index(2);
|
||||
assert_eq!(
|
||||
link.to_url().as_str(),
|
||||
"magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709&so=2,4,6"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex() {
|
||||
let mut link = MagnetLink::with_infohash(Infohash::from_bencoded_info_dict("".as_bytes()));
|
||||
|
|
|
@ -21,7 +21,7 @@ pub(crate) struct Link {
|
|||
long = "open",
|
||||
short = "O",
|
||||
help = "Open generated magnet link. Uses `xdg-open`, `gnome-open`, or `kde-open` on Linux; \
|
||||
`open` on macOS; and `cmd /C start` on Windows"
|
||||
`open` on macOS; and `cmd /C start` on Windows."
|
||||
)]
|
||||
open: bool,
|
||||
#[structopt(
|
||||
|
@ -31,6 +31,15 @@ pub(crate) struct Link {
|
|||
help = "Add `PEER` to magnet link."
|
||||
)]
|
||||
peers: Vec<HostPort>,
|
||||
#[structopt(
|
||||
long = "select-only",
|
||||
short = "s",
|
||||
value_name = "INDICES",
|
||||
use_delimiter = true,
|
||||
help = "Select files to download. Values are indices into the `info.files` list, e.g. \
|
||||
`--select-only 1,2,3`."
|
||||
)]
|
||||
indices: Vec<u64>,
|
||||
}
|
||||
|
||||
impl Link {
|
||||
|
@ -52,6 +61,10 @@ impl Link {
|
|||
link.add_peer(peer);
|
||||
}
|
||||
|
||||
for index in self.indices {
|
||||
link.add_index(index);
|
||||
}
|
||||
|
||||
let url = link.to_url();
|
||||
|
||||
outln!(env, "{}", url)?;
|
||||
|
@ -194,6 +207,42 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_indices() {
|
||||
let mut env = test_env! {
|
||||
args: [
|
||||
"torrent",
|
||||
"link",
|
||||
"--input",
|
||||
"foo.torrent",
|
||||
"--select-only",
|
||||
"2,4",
|
||||
"--select-only",
|
||||
"4,6",
|
||||
],
|
||||
tree: {
|
||||
"foo.torrent": "d\
|
||||
8:announce24:https://foo.com/announce\
|
||||
4:infod6:lengthi0e4:name3:foo12:piece lengthi1e6:pieces0:e\
|
||||
e",
|
||||
}
|
||||
};
|
||||
|
||||
env.assert_ok();
|
||||
|
||||
const INFO: &str = "d6:lengthi0e4:name3:foo12:piece lengthi1e6:pieces0:e";
|
||||
|
||||
let infohash = Sha1Digest::from_data(INFO.as_bytes());
|
||||
|
||||
assert_eq!(
|
||||
env.out(),
|
||||
format!(
|
||||
"magnet:?xt=urn:btih:{}&dn=foo&tr=https://foo.com/announce&so=2,4,6\n",
|
||||
infohash
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infohash_correct_with_nonstandard_info_dict() {
|
||||
let mut env = test_env! {
|
||||
|
|
Loading…
Reference in New Issue
Block a user