download_lp/
lib.rs

1extern crate reqwest;
2extern crate indicatif;
3#[macro_use] extern crate failure; use failure::Error;
4#[macro_use] extern crate log;
5
6use std::path::{ Path, PathBuf };
7use std::fs;
8use std::io::prelude::*;
9
10mod tools;
11
12pub fn download<P:AsRef<Path>>(link : &str, path : P) -> Result<(String,usize),Error>
13    where std::path::PathBuf: std::convert::From<P>, P : std::fmt::Display,
14{
15    //! No frills downloader.
16    //! 
17    //! Pick a link and a path and it will download to that path. Designed to be 
18    //! a super simple way to quickly download a file.AsMut
19    //! 
20    //! Uses [log](https://crates.io/crates/log) so some output is available for 
21    //! debugging purposes. 
22
23    info!("Downloading '{}' to path '{}'",link,path);
24
25    let (file,ext) = tools::split_name_and_extension(link);
26
27    let mut download_path : PathBuf = PathBuf::from(path);
28    // checks if the download path exists, and tries to create the folders if it doesn't
29    if !download_path.exists() {
30        warn!("Download path of '{:?}' doesn't exist, attempting to create it.",&download_path);
31        fs::create_dir_all(&download_path)?;
32        info!("Folders created successfully");
33    }
34
35    download_path.push(format!("{}.{}",file,ext));
36
37    if download_path.exists() {
38        info!("File already seems to exist, skipping download.");
39        return Ok((format!("{}.{}",file,ext),0));
40    }
41
42     let client = reqwest::Client::new();
43    let mut resp = client.get(link).send()?;
44
45    if resp.status().is_success() {
46        let len : u64 = resp.headers().get(reqwest::header::CONTENT_LENGTH)
47            .and_then(|l| l.to_str().ok())
48            .and_then(|l| l.parse().ok())
49            .unwrap_or(0);
50        
51        // let progress = indicatif::ProgressBar::new(len);
52        let progress = indicatif::ProgressBar::new_spinner();
53        // progress.println(format!("Downloading: {}",file));
54        progress.set_message(&format!("Downloading: {}",file));
55
56        let chunk_size = 1024usize;
57
58        let mut buffer : Vec<u8> = Vec::new();
59        let mut total : usize = 0;
60
61        loop {
62            let mut small_buffer = vec![0; chunk_size];
63            let small_buffer_read = resp.read(&mut small_buffer[..])?;
64            small_buffer.truncate(small_buffer_read);
65
66            match small_buffer.is_empty() {
67                true => break,
68                false => {
69                    buffer.extend(small_buffer);
70                    total += small_buffer_read;
71                    //progress.inc(small_buffer_read as u64);
72                    progress.set_message(&format!("{}.{} : {} / {}",file,ext,total,len));
73                },
74            }
75        }
76
77        let mut disk_file = fs::File::create(&download_path)?;
78        let size_disk = disk_file.write(&buffer)?;
79
80        progress.finish_with_message(&format!("{}.{} : Done",file,ext));
81
82        Ok((format!("{}.{}",file,ext),size_disk))
83
84    } else {
85        Err(format_err!("No response, are you connected to the internet?"))
86    }
87}