summaryrefslogblamecommitdiff
path: root/src/commands/update.rs
blob: 1fe664ed882350bd9f8c299dbb87fdf28ca785a0 (plain) (tree)


















                                                                                                 
                                   
                                                       
                                                                                  
 
                                                                 
 
                                                   
 
                        
                                                           
                                            
 
                                                                                 
                                                                

                         
 
                                                                     

                                                                                     
 
                             







                                         
                                
                                                                     
                           
                     
                               
                                                                        
                                     
                                                                                                 
                              


                                          
                                 
                     
                  
             
         
 


                                           
 
                                                       
                                                                                        

                                  


                                             
                                                                    
                                                                     
                                               
                                                                     


                                                                                             

             
     



          
                                                                                            


                                                                               
                                           
 





                                                 
     
 
                                           







                                                
                                                                                








                                                                             




                                                                


                                                             

                                          





                                          

                                                             

             
                                                                                              
     
 



                                                                             
                             

                          
 
















































                                                                                                                                                                                 
use crate::{
    config::Cfg,
    db::{
        mods_get_info, userlist_change_versions, userlist_get_all_ids,
        userlist_get_applicable_versions, userlist_get_current_version, userlist_get_set_version,
    },
    error::{ErrorType, MLError, MLE},
    files::{clean_list_dir, delete_version, disable_version, download_versions},
    modrinth::{extract_current_version, versions, Version},
    List,
};

pub async fn update(
    config: Cfg,
    liststack: Vec<List>,
    clean: bool,
    direct_download: bool,
    delete_old: bool,
) -> MLE<()> {
    for current_list in liststack {
        println!("Update mods in {}", current_list.id);
        let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?;

        let mut current_versions: Vec<(String, String)> = vec![];

        let mut updatestack: Vec<Version> = vec![];

        for id in mods {
            let info = mods_get_info(config.clone(), &id)?;
            println!("  └{}", info.title);

            if userlist_get_set_version(config.clone(), &current_list.id, &id)? {
                println!("    └Set version, skipping update");
                continue;
            }

            //Getting current installed version for disable or delete
            let disable_version =
                userlist_get_current_version(config.clone(), &current_list.id, &id)?;

            updatestack.push(
                match specific_update(
                    config.clone(),
                    clean,
                    current_list.clone(),
                    String::from(&id),
                )
                .await
                {
                    Ok(ver) => {
                        current_versions.push((disable_version, id));
                        ver
                    }
                    Err(e) => {
                        if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" {
                            println!(
                                "    └No new version found for the specified minecraft version"
                            );
                        } else {
                            return Err(e);
                        };
                        continue;
                    }
                },
            )
        }

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

        if direct_download && !updatestack.is_empty() {
            download_versions(current_list.clone(), config.clone(), updatestack).await?;

            //Disable old versions
            if !clean {
                for ver in current_versions {
                    if delete_old {
                        println!("    └Delete version {}", ver.0);
                        delete_version(current_list.clone(), ver.0)?;
                    } else if ver.0 != "NONE" {
                        println!("    └Disable version {}", ver.0);
                        disable_version(config.clone(), current_list.clone(), ver.0, ver.1)?;
                    };
                }
            }
        };
    }

    Ok(())
}

async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> MLE<Version> {
    let applicable_versions =
        versions(&config.apis.modrinth, String::from(&id), list.clone()).await;

    let mut versions: Vec<String> = vec![];

    if !applicable_versions.is_empty() {
        for ver in &applicable_versions {
            versions.push(String::from(&ver.id));
        }
    } else {
        versions.push(String::from("NONE"));
    }

    let mut current: Vec<Version> = vec![];
    if clean
        || (versions.join("|")
            != userlist_get_applicable_versions(
                config.clone(),
                String::from(&list.id),
                String::from(&id),
            )?)
    {
        let current_str = extract_current_version(applicable_versions.clone())?;

        if clean {
            println!("\t  └Add version to downloadstack");
        } else {
            println!("\t  └Get versions for specified minecraft versions");
            println!("\t  └New current version: {}", current_str);
        };

        //get new versions
        let current_ver = match applicable_versions
            .into_iter()
            .find(|ver| ver.id == current_str)
            .ok_or("!no current version in applicable_versions")
        {
            Ok(v) => Ok(v),
            Err(e) => Err(MLError::new(ErrorType::Other, e)),
        }?;
        current.push(current_ver.clone());

        let link = match current_ver
            .files
            .into_iter()
            .find(|f| f.primary)
            .ok_or("!no primary in links")
        {
            Ok(p) => Ok(p),
            Err(e) => Err(MLError::new(ErrorType::Other, e)),
        }?
        .url;
        userlist_change_versions(config, list.id, current_str, versions.join("|"), link, id)?;
    }

    if current.is_empty() {
        return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE"));
    };

    //println!(" └✔️");
    Ok(current[0].clone())
}

// #[tokio::test]
// async fn download_updates_test() {
//     use crate::{
//         modrinth::{Hash, Version, VersionFile, VersionType},
//         List, Modloader,
//     };
//
//     let config = Cfg::init().unwrap();
//     let current_list = List {
//         id: String::from("..."),
//         mc_version: String::from("..."),
//         modloader: Modloader::Fabric,
//         download_folder: String::from("./dev/tests/dl"),
//     };
//
//     let versions = vec![Version {
//             id: "dEqtGnT9".to_string(),
//             project_id: "kYuIpRLv".to_string(),
//             author_id: "Qnt13hO8".to_string(),
//             featured: true,
//             name: "1.2.2-1.19 - Fabric".to_string(),
//             version_number: "1.2.2-1.19".to_string(),
//             changelog: None,
//             date_published: "2022-11-02T17:41:43.072267Z".to_string(),
//             downloads: 58,
//             version_type: VersionType::release,
//             files: vec![VersionFile {
//                     hashes: Hash {
//                         sha1: "fdc6dc39427fc92cc1d7ad8b275b5b83325e712b".to_string(),
//                         sha512: "5b372f00d6e5d6a5ef225c3897826b9f6a2be5506905f7f71b9e939779765b41be6f2a9b029cfc752ad0751d0d2d5f8bb4544408df1363eebdde15641e99a849".to_string()
//                     },
//                     url: "https://cdn.modrinth.com/data/kYuIpRLv/versions/dEqtGnT9/waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(),
//                     filename: "waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(),
//                     primary: true,
//                     size: 323176
//             }],
//             game_versions: vec![
//                 "1.19".to_string(),
//                 "1.19.1".to_string(),
//                 "1.19.2".to_string()
//             ],
//             loaders: vec![
//                 "fabric".to_string()
//             ]
//         }];
//     assert!(download_versions(current_list, config, versions)
//         .await
//         .is_ok())
// }