Skip to content

Commit

Permalink
Merge pull request #2 from ksk001100/feature/async
Browse files Browse the repository at this point in the history
async download
  • Loading branch information
ksk001100 authored Jun 2, 2020
2 parents 6460c61 + 9652d09 commit 09e2aab
Show file tree
Hide file tree
Showing 11 changed files with 669 additions and 1,199 deletions.
1,410 changes: 488 additions & 922 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ruget"
version = "0.3.1"
version = "0.4.0"
authors = ["ksk001100 <[email protected]>"]
edition = "2018"
repository = "https://github.com/ksk001100/ruget"
Expand All @@ -10,7 +10,7 @@ readme = "README.md"
description = "Alternative to wget written in Rust"

[dependencies]
reqwest = "0.9"
rayon = "1.1"
num_cpus = "1.0"
seahorse = "0.6.1"
seahorse = "1.0.0"
async-std = "1.6.0"
surf = "1.0.3"
chrono = "0.4.11"
File renamed without changes.
112 changes: 112 additions & 0 deletions src/lib/download/parallel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use crate::lib::utils::{content_length, get_file_size, get_filename};
use async_std::sync::Mutex;
use async_std::task;
use chrono::{DateTime, Local};
use seahorse::{color, Context};
use std::fs::{create_dir, metadata, remove_dir_all, File};
use std::io::{stdout, BufReader, BufWriter, Read, Write};
use std::path::Path;
use std::sync::Arc;
use surf::{self, http, url, Request};

const TMP_SIZE: usize = 300000;
const TMP_DIR: &str = "ruget_tmp_dir";

pub fn combine_files(filename: &str, count: usize) {
print!("\n");
let mut output = BufWriter::new(File::create(filename).unwrap());

for i in 0..count {
let mut buf: Vec<u8> = Vec::new();
let path = format!("{}/{}.tmp", TMP_DIR, i);
let mut file = BufReader::new(File::open(&path).unwrap());
file.read_to_end(&mut buf).expect("read failed...");
output.write_all(&buf).expect("write failed...");
print!(
"\rWriting : [{} / {}]",
get_file_size(((i + 1) as u64 * metadata(&path).unwrap().len()) as f32),
get_file_size((count as u64 * metadata(&path).unwrap().len()) as f32)
);
stdout().flush().unwrap();
}

remove_dir_all(TMP_DIR).expect("remove tmp file failed...");
}

pub async fn spawn_args(url: &str) -> Result<Vec<(usize, String, usize)>, surf::Exception> {
let content_length = content_length(url).await?;
let split_num = content_length / TMP_SIZE;
let ranges: Vec<usize> = (0..split_num)
.map(|n| (content_length + n) / split_num)
.collect();

Ok((&ranges)
.iter()
.enumerate()
.map(|(index, x)| {
let s = match index {
0 => 0,
_ => (&ranges[..index]).iter().fold(0, |sum, y| sum + *y) + 1,
};
let e = (&ranges[..index]).iter().fold(0, |sum, y| sum + *y) + *x;
let range = format!("bytes={}-{}", s, e);
(index, range, e - s)
})
.collect())
}

pub fn action(c: &Context) {
task::block_on(async {
if !Path::new(TMP_DIR).exists() {
create_dir(TMP_DIR).expect("create tmp dir failed...");
}

let uri = if c.args.len() == 1 {
c.args[0].to_owned()
} else {
println!("{}", color::red("Argument error..."));
println!("{}", color::red("Please call `--help`"));
std::process::exit(0);
};

let args = spawn_args(&uri).await.expect("");
let total_count = args.len();
let downloaded_count = Arc::new(Mutex::new(0));
let mut tasks = Vec::new();

for arg in args {
let downloaded_count = downloaded_count.clone();
let tmp = format!("{}/{}.tmp", TMP_DIR, arg.0);
let mut file = File::create(tmp).unwrap();
let url = url::Url::parse(&uri).expect("");
tasks.push(task::spawn(async move {
let req = Request::new(http::Method::GET, url);
let res = req.set_header("Range", arg.1).recv_bytes().await.expect("");
file.write(&res).expect("");
*downloaded_count.lock().await += 1;
print!(
"\rDownloading : [{} / {}]",
get_file_size((*downloaded_count.lock().await * arg.2) as f32),
get_file_size((total_count * arg.2) as f32)
);
stdout().flush().unwrap();
}));
}

for t in tasks {
t.await;
}

let output = match c.string_flag("output") {
Ok(o) => Some(o),
Err(_) => None,
};

let filename = get_filename(uri, output);

combine_files(&filename, total_count);

let local_datetime: DateTime<Local> = Local::now();
println!("\n{} - '{}' saved", local_datetime, &filename);
});
}
23 changes: 23 additions & 0 deletions src/lib/download/single.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// use std::fs::File;
// use seahorse::Context;
// use crate::lib::utils::{content_length, get_filename, get_file_size};
// use async_std::task;
//
// TODO
// pub fn action(c: &Context) {
// task::block_on(async {
// let uri = if c.args.len() == 1 {
// c.args[0].to_owned()
// } else {
// c.help();
// std::process::exit(0);
// };
//
// let fs = content_length(&uri).await.unwrap();
// });
// }
//
// async fn downlaod(url: String) -> Result<(), surf::Exception> {
// let res = surf::get(url).await?;
//
// }
21 changes: 0 additions & 21 deletions src/lib/download_manager.rs

This file was deleted.

155 changes: 0 additions & 155 deletions src/lib/downloader/parallel.rs

This file was deleted.

41 changes: 0 additions & 41 deletions src/lib/downloader/single.rs

This file was deleted.

3 changes: 1 addition & 2 deletions src/lib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub mod download_manager;
pub mod downloader;
pub mod download;
pub mod utils;
Loading

0 comments on commit 09e2aab

Please sign in to comment.