summaryrefslogblamecommitdiff
path: root/src/commands/download.rs
blob: 7ea5c297fe6d189238247fc550620288578ae08b (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                           
 
                               
            
                                                    
                               
            

                                                                           


                               

                                           
            





                         
                                  





                                                                    

                                                   
                                                                            

                                            
 
                                   

                                                                                                      
 






























                                                                                
 



                                                                
                






                                                                              
         
     
 


















                                                                        
 



















                                                                                
                    


                                                                      
              
         
 






                                         

     
                      
 
          
 
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

use crate::{config::Cfg, List};
use crate::{
    db::userlist_get_all_current_versions_with_mods,
    error::{EType, MLErr, MLE},
    files::{
        clean_list_dir, delete_version, disable_version, download_versions,
        get_downloaded_versions,
    },
    modrinth::get_raw_versions,
};
use crate::{PROGRESS_CHARS, STYLE_BAR_POS};

/// # Errors
pub async fn download(
    config: &Cfg,
    liststack: Vec<List>,
    clean: bool,
    delete_old: bool,
) -> MLE<()> {
    let mp = MultiProgress::new();
    let download_p = mp.add(ProgressBar::new(
        liststack
            .len()
            .try_into()
            .map_err(|_| MLErr::new(EType::Other, "ListStackLen"))?,
    ));
    download_p.set_style(
        ProgressStyle::with_template(STYLE_BAR_POS)
            .map_err(|_| MLErr::new(EType::LibIndicatif, "template error"))?
            .progress_chars(PROGRESS_CHARS),
    );

    for current_list in liststack {
        download_list(config, mp.clone(), download_p.clone(), current_list, clean, delete_old).await?;
    }

    download_p.finish_with_message("Downloaded all lists");

    Ok(())
}

async fn download_list(
    config: &Cfg,
    mp: MultiProgress,
    download_p: ProgressBar,
    current_list: List,
    clean: bool,
    delete_old: bool,
) -> MLE<()> {
    download_p.set_message(format!("Download in {}", current_list.id));

    let downloaded_versions = get_downloaded_versions(&current_list)?;
    let current_version_ids = match userlist_get_all_current_versions_with_mods(
        config,
        &current_list.id,
    ) {
        Ok(i) => Ok(i),
        Err(e) => Err(MLErr::new(EType::DBError, e.to_string().as_str())),
    }?;

    let mut to_download: Vec<String> = vec![];
    //(mod_id, version_id)
    let mut to_disable: Vec<(String, String)> = vec![];

    for version in current_version_ids {
        let mod_id = version.0;
        let current_version = version.1;

        let current_download = downloaded_versions.get(&mod_id);

        if current_download.is_none() || clean {
            to_download.push(current_version);
        } else {
            let downloaded_version =
                current_download.ok_or(MLErr::new(EType::Other, "IDK, WTF"))?;
            if &current_version != downloaded_version {
                to_disable
                    .push((mod_id.clone(), String::from(downloaded_version)));
                to_download.push(current_version);
            }
        }
    }

    if clean {
        clean_list_dir(&current_list)?;
    };

    if to_download.is_empty() {
        download_p.println(format!(
            "There are no new versions to download for {}",
            current_list.id
        ));
    } else {
        download_versions(
            current_list.clone(),
            config.clone(),
            get_raw_versions(&config.apis.modrinth, to_download).await?,
            &mp,
            &download_p,
        )
        .await?;
    }

    if !to_disable.is_empty() {
        let d_p = mp.insert_before(
            &download_p,
            ProgressBar::new(
                to_disable
                    .len()
                    .try_into()
                    .map_err(|_| MLErr::new(EType::Other, "ListStackLen"))?,
            ),
        );
        d_p.set_style(
            ProgressStyle::with_template(STYLE_BAR_POS)
                .map_err(|_| MLErr::new(EType::LibIndicatif, "template error"))?
                .progress_chars(PROGRESS_CHARS),
        );
        for ver in to_disable {
            if delete_old {
                d_p.set_message(format!("Delete version {}", ver.1));
                d_p.inc(1);
                delete_version(&current_list, &ver.1)?;
            } else {
                d_p.set_message(format!("Disable version {}", ver.1));
                d_p.inc(1);
                disable_version(config, &current_list, ver.1, ver.0)?;
            };
        }

        let del_msg = if delete_old {
            "Deleted all old versions"
        } else {
            "Disabled all old versions"
        };

        d_p.finish_with_message(del_msg);
    }

    download_p.inc(1);

    Ok(())
}