summaryrefslogtreecommitdiff
path: root/src/commands/update.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/update.rs')
-rw-r--r--src/commands/update.rs67
1 files changed, 48 insertions, 19 deletions
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 42d19aa..c8f0880 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -1,9 +1,9 @@
1use std::io::{Error, ErrorKind}; 1use std::{io::{Error, ErrorKind}, fs::{rename, remove_file}};
2 2
3use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get}, List, input::Input, download_file}; 3use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, userlist_add_disabled_versions, mods_change_versions}, List, input::Input, files::get_file_path, download_versions};
4 4
5pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
6 6
7 let mut liststack: Vec<List> = vec![]; 7 let mut liststack: Vec<List> = vec![];
8 if input.all_lists { 8 if input.all_lists {
9 let list_ids = lists_get_all_ids(config.clone())?; 9 let list_ids = lists_get_all_ids(config.clone())?;
@@ -11,18 +11,22 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error:
11 liststack.push(lists_get(config.clone(), id)?); 11 liststack.push(lists_get(config.clone(), id)?);
12 } 12 }
13 } else { 13 } else {
14 liststack.push(get_current_list(config.clone())?) 14 let current = get_current_list(config.clone())?;
15 println!("Checking for updates of mods in {}", current.id);
16 liststack.push(current)
15 } 17 }
16 18
17 for current_list in liststack { 19 for current_list in liststack {
18 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; 20 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?;
21
22 let mut current_versions: Vec<(String, String)> = vec![];
19 23
20 let mut versions = mods_get_versions(config.clone(), mods.clone())?; 24 let mut versions = mods_get_versions(config.clone(), mods.clone())?;
21 versions.sort_by_key(|ver| ver.mod_id.clone()); 25 versions.sort_by_key(|ver| ver.mod_id.clone());
22 26
23 let mut projects = projects(String::from(&config.apis.modrinth), mods).await; 27 let mut projects = projects(String::from(&config.apis.modrinth), mods).await;
24 projects.sort_by_key(|pro| pro.id.clone()); 28 projects.sort_by_key(|pro| pro.id.clone());
25 29
26 let mut updatestack: Vec<Version> = vec![]; 30 let mut updatestack: Vec<Version> = vec![];
27 for (index, project) in projects.into_iter().enumerate() { 31 for (index, project) in projects.into_iter().enumerate() {
28 //Get versions for project and check if they match up 32 //Get versions for project and check if they match up
@@ -30,14 +34,26 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error:
30 let p_id = String::from(&project.id); 34 let p_id = String::from(&project.id);
31 let v_id = &current_version.mod_id; 35 let v_id = &current_version.mod_id;
32 if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) }; 36 if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) };
33 37
38 //Getting current installed version for disable or delete
39 let disable_version = userlist_get_current_version(config.clone(), String::from(&current_list.id), String::from(&project.id))?;
40
41 let version_db_string = project.versions.join("|");
34 42
35 //Adding to stack if not the same versions in the list OR if clean == true 43 //Adding to stack if not the same versions in the list OR if clean == true
36 if input.clone().clean || (project.versions.join("|") != current_version.versions) { 44 if input.clone().clean || (version_db_string != current_version.versions) {
37 updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project.clone()).await { 45 updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project.clone()).await {
38 Ok(ver) => ver, 46 Ok(ver) => {
47 current_versions.push((disable_version, p_id));
48 ver
49 },
39 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE") 50 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE")
40 Err(_) => { println!("({}) No new version found for the specified minecraft version", project.title); continue; }, 51 Err(e) => {
52 //Updating versions in modlist for no repeating version calls
53 mods_change_versions(config.clone(), version_db_string, project.id)?;
54 println!("({}) No new version found for the specified minecraft version({})", project.title, e);
55 continue;
56 },
41 }); 57 });
42 } else { 58 } else {
43 println!("({}) No new version found", project.title); 59 println!("({}) No new version found", project.title);
@@ -53,14 +69,19 @@ pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error:
53 } 69 }
54 } 70 }
55 71
56 if input.direct_download { download_updates(current_list, updatestack).await?; }; 72 if input.direct_download { download_versions(current_list.clone(), updatestack).await?; };
73
74 //Disable old versions
75 for ver in current_versions {
76 if input.delete_old { delete_old(current_list.clone(), ver.0, ver.1)? } else { disable_old(config.clone(), current_list.clone(), ver.0, ver.1)? };
77 }
57 } 78 }
58 79
59 Ok(()) 80 Ok(())
60} 81}
61 82
62async fn specific_update(config: Cfg, input: Input, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> { 83async fn specific_update(config: Cfg, input: Input, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> {
63 print!("Checking update for '{}' in {}", project.title, list.id); 84 println!("Checking update for '{}' in {}", project.title, list.id);
64 85
65 let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; 86 let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await;
66 87
@@ -88,17 +109,25 @@ async fn specific_update(config: Cfg, input: Input, list: List, project: Project
88 Ok(current[0].clone()) 109 Ok(current[0].clone())
89} 110}
90 111
91async fn download_updates(current_list: List, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { 112fn disable_old(config: Cfg, current_list: List, versionid: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> {
113 println!("Disabling version {} for mod {}", versionid, mod_id);
114 let file = get_file_path(current_list.clone(), String::from(&versionid))?;
115 let disabled = format!("{}.disabled", file);
92 116
93 let dl_path = String::from(&current_list.download_folder); 117 rename(file, disabled)?;
94 118
95 for ver in versions { 119 userlist_add_disabled_versions(config, current_list.id, versionid, mod_id)?;
96 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); 120
97 download_file(primary_file.url, current_list.clone().download_folder, primary_file.filename).await?; 121 Ok(())
98 } 122}
99 123
124fn delete_old(current_list: List, versionid: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> {
125 println!("Deleting version {} for mod {}", versionid, mod_id);
126 let file = get_file_path(current_list, String::from(&versionid))?;
127
128 remove_file(file)?;
100 129
101 Ok(dl_path) 130 Ok(())
102} 131}
103 132
104#[tokio::test] 133#[tokio::test]
@@ -138,5 +167,5 @@ async fn download_updates_test() {
138 "fabric".to_string() 167 "fabric".to_string()
139 ] 168 ]
140 }]; 169 }];
141 assert!(download_updates(current_list, versions).await.is_ok()) 170 assert!(download_versions(current_list, versions).await.is_ok())
142} 171}