From 8fee14d0e6bf3218aefdff24ff128d8602dfeecd Mon Sep 17 00:00:00 2001 From: Daniel M Date: Wed, 31 Mar 2021 19:22:00 +0200 Subject: [PATCH] Improve CLI & change name --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/download.rs | 14 ++++----- src/main.rs | 79 ++++++++++++++++++++++--------------------------- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e60450d..1b1902f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,7 +150,7 @@ dependencies = [ ] [[package]] -name = "fdl" +name = "ffdl" version = "0.1.0" dependencies = [ "chrono", diff --git a/Cargo.toml b/Cargo.toml index 8d8f271..0a50f1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fdl" +name = "ffdl" version = "0.1.0" authors = ["daniel m "] edition = "2018" diff --git a/src/download.rs b/src/download.rs index a67e5f5..4af145f 100644 --- a/src/download.rs +++ b/src/download.rs @@ -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. // 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?; @@ -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 create_zeroed_file(into_file, content_length as usize + 1).await?; - let chunksize = content_length / numparal as u64; - let rest = content_length % numparal as u64; + let chunksize = content_length / conn_count as u64; + let rest = content_length % conn_count as u64; 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(); - for index in 0 .. numparal { + for index in 0 .. conn_count { let url = url.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 ); - if index == numparal - 1 { + if index == conn_count - 1 { 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 mut update_counter: i32 = 0; - let mut dl_speeds = vec![0.0_f32; numparal as usize]; - let mut progresses = vec![0; numparal as usize]; + let mut dl_speeds = vec![0.0_f32; conn_count as usize]; + let mut progresses = vec![0; conn_count as usize]; while let Some(update) = rx.recv().await { match update.status { diff --git a/src/main.rs b/src/main.rs index 3d926d5..ff8d194 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ mod dlreport; #[tokio::main] async fn main() -> ResBE<()> { - let arguments = App::new("FDL - Fast/File Downloader") + let arguments = App::new("FFDL - Fast File Downloader") .version(crate_version!()) .about("Download files fast") .arg( @@ -27,24 +27,26 @@ async fn main() -> ResBE<()> { .long("outdir") .value_name("OUTPUT DIR") .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::with_name("numdl") + Arg::with_name("file_count") .short("n") - .long("numdl") - .value_name("NUMBER OF CONCURRENT DOWNLOADS") + .long("num-files") + .value_name("NUMBER OF CONCURRENT FILE DOWNLOADS") .takes_value(true) - .help("Specify the number concurrent downloads") + .help("Specify the number concurrent file downloads") ) .arg( - Arg::with_name("boost") - .short("b") - .long("boost") - .value_name("CONNECTIONS PER FILE") + Arg::with_name("conn_count") + .short("c") + .long("connections") + .value_name("NUMBER OF CONNECTIONS") .takes_value(true) - .help("Specify the number connections per single downloads. \ - Files started with boost can't be continued. \ + .help("The number concurrent connections per file download. \ + 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") ) .arg( @@ -77,10 +79,9 @@ async fn main() -> ResBE<()> { .help("Download only the specified URL") ) .arg( - Arg::with_name("resolve") - .short("r") - .long("resolve") - .value_name("URL") + Arg::with_name("zippy-resolve") + .long("zippy-resolve") + .value_name("ZIPPYSHARE URL") .takes_value(true) .group("action") .help("Resolve the zippyshare url to real download url") @@ -93,39 +94,39 @@ async fn main() -> ResBE<()> { None => "./" }; - let numparal = match arguments.value_of("numdl") { + let file_count = match arguments.value_of("file_count") { Some(it) => it, None => "1" }; - let numparal: i32 = match numparal.parse() { + let file_count: i32 = match file_count.parse() { Ok(it) => it, Err(_) => { - eprintln!("Invalid value for numdl: {}", numparal); + eprintln!("Invalid value for num-files: {}", file_count); exit(1); } }; - if numparal <= 0 { - eprintln!("Invalid value for numdl: {}", numparal); + if file_count <= 0 { + eprintln!("Invalid value for num-files: {}", file_count); exit(1); } - let boost = match arguments.value_of("boost") { + let conn_count = match arguments.value_of("conn_count") { Some(it) => it, None => "1" }; - let boost: i32 = match boost.parse() { + let conn_count: i32 = match conn_count.parse() { Ok(it) => it, Err(_) => { - eprintln!("Invalid value for boost: {}", numparal); + eprintln!("Invalid value for connections: {}", conn_count); exit(1); } }; - if boost <= 0 { - eprintln!("Invalid value for boost: {}", boost); + if conn_count <= 0 { + eprintln!("Invalid value for connections: {}", conn_count); exit(1); } @@ -152,23 +153,17 @@ async fn main() -> ResBE<()> { .filter(|url| url.len() > 0 && !url.starts_with("#")) .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") { - let boost = if boost != 1 { - boost - } else { - numparal - }; - - download_multiple(vec![url.to_string()], outdir, 1, boost, is_zippy).await?; + download_multiple(vec![url.to_string()], outdir, 1, conn_count, 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 { Ok(resolved_url) => { @@ -181,14 +176,12 @@ async fn main() -> ResBE<()> { } - } else { - println!("Something went very wrong..."); } Ok(()) } -async fn download_multiple(urls: Vec, outdir: &str, numparal: i32, boost: i32, is_zippy: bool) -> ResBE<()> { +async fn download_multiple(urls: Vec, outdir: &str, file_count: i32, conn_count: i32, is_zippy: bool) -> ResBE<()> { let outdir = Path::new(outdir); if !outdir.exists() { @@ -204,12 +197,12 @@ async fn download_multiple(urls: Vec, outdir: &str, numparal: i32, boost let (tx, rx) = mpsc::unbounded_channel::(); - for offset in 0..numparal { + for offset in 0..file_count { let urls: Vec = urls .iter() .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()) .collect(); @@ -223,7 +216,7 @@ async fn download_multiple(urls: Vec, outdir: &str, numparal: i32, boost let tx = tx.clone(); // 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); @@ -269,14 +262,14 @@ async fn download_multiple(urls: Vec, 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 { rep.send(DlStatus::DoneErr { filename: into_file.to_string() }); } } 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 { filename: into_file.to_string() });