Improve CLI & change name
This commit is contained in:
parent
36ad1263b4
commit
8fee14d0e6
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -150,7 +150,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdl"
|
name = "ffdl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fdl"
|
name = "ffdl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["daniel m <danielm@dnml.de>"]
|
authors = ["daniel m <danielm@dnml.de>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|||||||
@ -208,7 +208,7 @@ pub async fn download_feedback_chunks(url: &str, into_file: &str, rep: DlReporte
|
|||||||
|
|
||||||
// This will spin up multiple tasks that and manage the status updates for them.
|
// This will spin up multiple tasks that and manage the status updates for them.
|
||||||
// The combined status will be reported back to the caller
|
// The combined status will be reported back to the caller
|
||||||
pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter, numparal: i32) -> ResBE<()> {
|
pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter, conn_count: i32) -> ResBE<()> {
|
||||||
|
|
||||||
let (content_length, _) = http_get_filesize_and_range_support(url).await?;
|
let (content_length, _) = http_get_filesize_and_range_support(url).await?;
|
||||||
|
|
||||||
@ -216,8 +216,8 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
|
|||||||
// completion and can indicate that the file is not suitable for continuation
|
// completion and can indicate that the file is not suitable for continuation
|
||||||
create_zeroed_file(into_file, content_length as usize + 1).await?;
|
create_zeroed_file(into_file, content_length as usize + 1).await?;
|
||||||
|
|
||||||
let chunksize = content_length / numparal as u64;
|
let chunksize = content_length / conn_count as u64;
|
||||||
let rest = content_length % numparal as u64;
|
let rest = content_length % conn_count as u64;
|
||||||
|
|
||||||
let mut joiners = Vec::new();
|
let mut joiners = Vec::new();
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
|
|||||||
|
|
||||||
let t_start = SystemTime::now();
|
let t_start = SystemTime::now();
|
||||||
|
|
||||||
for index in 0 .. numparal {
|
for index in 0 .. conn_count {
|
||||||
|
|
||||||
let url = url.clone().to_owned();
|
let url = url.clone().to_owned();
|
||||||
let into_file = into_file.clone().to_owned();
|
let into_file = into_file.clone().to_owned();
|
||||||
@ -241,7 +241,7 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
|
|||||||
(index+1) as u64 * chunksize - 1
|
(index+1) as u64 * chunksize - 1
|
||||||
);
|
);
|
||||||
|
|
||||||
if index == numparal - 1 {
|
if index == conn_count - 1 {
|
||||||
from_to.1 += rest;
|
from_to.1 += rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,8 +263,8 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
|
|||||||
|
|
||||||
let rep = rep_task;
|
let rep = rep_task;
|
||||||
let mut update_counter: i32 = 0;
|
let mut update_counter: i32 = 0;
|
||||||
let mut dl_speeds = vec![0.0_f32; numparal as usize];
|
let mut dl_speeds = vec![0.0_f32; conn_count as usize];
|
||||||
let mut progresses = vec![0; numparal as usize];
|
let mut progresses = vec![0; conn_count as usize];
|
||||||
|
|
||||||
while let Some(update) = rx.recv().await {
|
while let Some(update) = rx.recv().await {
|
||||||
match update.status {
|
match update.status {
|
||||||
|
|||||||
79
src/main.rs
79
src/main.rs
@ -18,7 +18,7 @@ mod dlreport;
|
|||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> ResBE<()> {
|
async fn main() -> ResBE<()> {
|
||||||
|
|
||||||
let arguments = App::new("FDL - Fast/File Downloader")
|
let arguments = App::new("FFDL - Fast File Downloader")
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.about("Download files fast")
|
.about("Download files fast")
|
||||||
.arg(
|
.arg(
|
||||||
@ -27,24 +27,26 @@ async fn main() -> ResBE<()> {
|
|||||||
.long("outdir")
|
.long("outdir")
|
||||||
.value_name("OUTPUT DIR")
|
.value_name("OUTPUT DIR")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Set the output directory")
|
.help("Set the output directory. The directory will be created \
|
||||||
|
if it doesn't exit yet")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("numdl")
|
Arg::with_name("file_count")
|
||||||
.short("n")
|
.short("n")
|
||||||
.long("numdl")
|
.long("num-files")
|
||||||
.value_name("NUMBER OF CONCURRENT DOWNLOADS")
|
.value_name("NUMBER OF CONCURRENT FILE DOWNLOADS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Specify the number concurrent downloads")
|
.help("Specify the number concurrent file downloads")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("boost")
|
Arg::with_name("conn_count")
|
||||||
.short("b")
|
.short("c")
|
||||||
.long("boost")
|
.long("connections")
|
||||||
.value_name("CONNECTIONS PER FILE")
|
.value_name("NUMBER OF CONNECTIONS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Specify the number connections per single downloads. \
|
.help("The number concurrent connections per file download. \
|
||||||
Files started with boost can't be continued. \
|
Downloads might fail when the number of connections is too high. \
|
||||||
|
Files started with multiple connections can't be continued. \
|
||||||
NOTE: This will likely cause IO bottlenecks on HDDs")
|
NOTE: This will likely cause IO bottlenecks on HDDs")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@ -77,10 +79,9 @@ async fn main() -> ResBE<()> {
|
|||||||
.help("Download only the specified URL")
|
.help("Download only the specified URL")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("resolve")
|
Arg::with_name("zippy-resolve")
|
||||||
.short("r")
|
.long("zippy-resolve")
|
||||||
.long("resolve")
|
.value_name("ZIPPYSHARE URL")
|
||||||
.value_name("URL")
|
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.group("action")
|
.group("action")
|
||||||
.help("Resolve the zippyshare url to real download url")
|
.help("Resolve the zippyshare url to real download url")
|
||||||
@ -93,39 +94,39 @@ async fn main() -> ResBE<()> {
|
|||||||
None => "./"
|
None => "./"
|
||||||
};
|
};
|
||||||
|
|
||||||
let numparal = match arguments.value_of("numdl") {
|
let file_count = match arguments.value_of("file_count") {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => "1"
|
None => "1"
|
||||||
};
|
};
|
||||||
|
|
||||||
let numparal: i32 = match numparal.parse() {
|
let file_count: i32 = match file_count.parse() {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
eprintln!("Invalid value for numdl: {}", numparal);
|
eprintln!("Invalid value for num-files: {}", file_count);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if numparal <= 0 {
|
if file_count <= 0 {
|
||||||
eprintln!("Invalid value for numdl: {}", numparal);
|
eprintln!("Invalid value for num-files: {}", file_count);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let boost = match arguments.value_of("boost") {
|
let conn_count = match arguments.value_of("conn_count") {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => "1"
|
None => "1"
|
||||||
};
|
};
|
||||||
|
|
||||||
let boost: i32 = match boost.parse() {
|
let conn_count: i32 = match conn_count.parse() {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
eprintln!("Invalid value for boost: {}", numparal);
|
eprintln!("Invalid value for connections: {}", conn_count);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if boost <= 0 {
|
if conn_count <= 0 {
|
||||||
eprintln!("Invalid value for boost: {}", boost);
|
eprintln!("Invalid value for connections: {}", conn_count);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,23 +153,17 @@ async fn main() -> ResBE<()> {
|
|||||||
.filter(|url| url.len() > 0 && !url.starts_with("#"))
|
.filter(|url| url.len() > 0 && !url.starts_with("#"))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
download_multiple(urls, outdir, numparal, boost, is_zippy).await?;
|
download_multiple(urls, outdir, file_count, conn_count, is_zippy).await?;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(url) = arguments.value_of("download") {
|
if let Some(url) = arguments.value_of("download") {
|
||||||
|
|
||||||
let boost = if boost != 1 {
|
download_multiple(vec![url.to_string()], outdir, 1, conn_count, is_zippy).await?;
|
||||||
boost
|
|
||||||
} else {
|
|
||||||
numparal
|
|
||||||
};
|
|
||||||
|
|
||||||
download_multiple(vec![url.to_string()], outdir, 1, boost, is_zippy).await?;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(url) = arguments.value_of("resolve") {
|
if let Some(url) = arguments.value_of("zippy-resolve") {
|
||||||
|
|
||||||
match zippy::resolve_link(&url).await {
|
match zippy::resolve_link(&url).await {
|
||||||
Ok(resolved_url) => {
|
Ok(resolved_url) => {
|
||||||
@ -181,14 +176,12 @@ async fn main() -> ResBE<()> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
println!("Something went very wrong...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_multiple(urls: Vec<String>, outdir: &str, numparal: i32, boost: i32, is_zippy: bool) -> ResBE<()> {
|
async fn download_multiple(urls: Vec<String>, outdir: &str, file_count: i32, conn_count: i32, is_zippy: bool) -> ResBE<()> {
|
||||||
let outdir = Path::new(outdir);
|
let outdir = Path::new(outdir);
|
||||||
|
|
||||||
if !outdir.exists() {
|
if !outdir.exists() {
|
||||||
@ -204,12 +197,12 @@ async fn download_multiple(urls: Vec<String>, outdir: &str, numparal: i32, boost
|
|||||||
|
|
||||||
let (tx, rx) = mpsc::unbounded_channel::<DlReport>();
|
let (tx, rx) = mpsc::unbounded_channel::<DlReport>();
|
||||||
|
|
||||||
for offset in 0..numparal {
|
for offset in 0..file_count {
|
||||||
|
|
||||||
let urls: Vec<String> = urls
|
let urls: Vec<String> = urls
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(index, _)| (index) % numparal as usize == offset as usize)
|
.filter(|(index, _)| (index) % file_count as usize == offset as usize)
|
||||||
.map(|(_, v)| v.to_owned())
|
.map(|(_, v)| v.to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -223,7 +216,7 @@ async fn download_multiple(urls: Vec<String>, outdir: &str, numparal: i32, boost
|
|||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
|
|
||||||
// Recalculated index in the main url vector, used as id
|
// Recalculated index in the main url vector, used as id
|
||||||
let global_url_index = i as i32 * numparal + offset;
|
let global_url_index = i as i32 * file_count + offset;
|
||||||
|
|
||||||
let rep = DlReporter::new(global_url_index, tx);
|
let rep = DlReporter::new(global_url_index, tx);
|
||||||
|
|
||||||
@ -269,14 +262,14 @@ async fn download_multiple(urls: Vec<String>, outdir: &str, numparal: i32, boost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if boost == 1 {
|
if conn_count == 1 {
|
||||||
if let Err(_e) = download::download_feedback(&url, &into_file, rep.clone()).await {
|
if let Err(_e) = download::download_feedback(&url, &into_file, rep.clone()).await {
|
||||||
rep.send(DlStatus::DoneErr {
|
rep.send(DlStatus::DoneErr {
|
||||||
filename: into_file.to_string()
|
filename: into_file.to_string()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(_e) = download::download_feedback_multi(&url, &into_file, rep.clone(), boost).await {
|
if let Err(_e) = download::download_feedback_multi(&url, &into_file, rep.clone(), conn_count).await {
|
||||||
rep.send(DlStatus::DoneErr {
|
rep.send(DlStatus::DoneErr {
|
||||||
filename: into_file.to_string()
|
filename: into_file.to_string()
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user