1use std::fs::File;
2use std::io::{self, stderr, Read, Write};
3use std::time::Duration;
4
5use reqwest::{
6 blocking::Client,
7 StatusCode,
8};
9
10use pbr::{ProgressBar, Units};
11
12pub fn download_client() -> Client {
13 Client::builder()
14 .timeout(Duration::new(5, 0))
15 .build()
16 .unwrap()
17}
18
19pub fn download(client: &Client, remote_path: &str, local_path: &str) -> io::Result<()> {
20 let mut stderr = stderr();
21
22 write!(stderr, "* Requesting {}\n", remote_path)?;
23
24 let mut response = match client.get(remote_path).send() {
25 Ok(response) => response,
26 Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)),
27 };
28
29 match response.status() {
30 StatusCode::OK => {
31 let mut count = 0;
32 let length = response.content_length().unwrap_or(0);
33
34 let mut file = File::create(&local_path)?;
35 let mut pb = ProgressBar::new(length as u64);
36 pb.set_max_refresh_rate(Some(Duration::new(1, 0)));
37 pb.set_units(Units::Bytes);
38 loop {
39 let mut buf = [0; 8192];
40 let res = response.read(&mut buf)?;
41 if res == 0 {
42 break;
43 }
44 count += file.write(&buf[..res])?;
45 pb.set(count as u64);
46 }
47 let _ = write!(stderr, "\n");
48
49 file.sync_all()?;
50
51 Ok(())
52 }
53 _ => {
54 let _ = write!(stderr, "* Failure {}\n", response.status());
55
56 Err(io::Error::new(
57 io::ErrorKind::NotFound,
58 format!("{} not found", remote_path),
59 ))
60 }
61 }
62}