summaryrefslogtreecommitdiff
path: root/src/commands/download.rs
blob: db0fc93b5a073940ff30b9b02da6df580906ef77 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use std::{io::Write, fs::File};

use reqwest::Client;

use futures_util::StreamExt;

use crate::{List, get_current_list, config::Cfg, db::userlist_get_all_downloads, input::Input};

pub async fn download(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
    let list = get_current_list(config.clone())?;

    let links = userlist_get_all_downloads(config.clone(), list.clone().id)?;

    download_links(config, input, list, links).await?;

    Ok(())
}

async fn download_links(config: Cfg, input: Input, current_list: List, links: Vec<String>) -> Result<String, Box<dyn std::error::Error>> {

    let dl_path = String::from(&config.downloads);

    if input.clean {
        let dl_path = &current_list.download_folder;
        println!("Cleaning {}", dl_path);
        for entry in std::fs::read_dir(dl_path)? {
            let entry = entry?;
            std::fs::remove_file(entry.path())?;
        }
    }

    for link in links {
        let filename = link.split('/').last().unwrap();
        let dl_path_file = format!("{}/{}", config.downloads, filename);
        println!("Downloading {}", link);

        let res = Client::new()
            .get(String::from(&link))
            .send()
            .await
            .or(Err(format!("Failed to GET from '{}'", &link)))?;
        
        // download chunks
        let mut file = File::create(String::from(&dl_path_file)).or(Err(format!("Failed to create file '{}'", dl_path_file)))?;
        let mut stream = res.bytes_stream();

        while let Some(item) = stream.next().await {
            let chunk = item.or(Err("Error while downloading file"))?;
            file.write_all(&chunk)
                .or(Err("Error while writing to file"))?;
        }
    }

    Ok(dl_path)
}