diff options
author | fx <[email protected]> | 2023-05-29 18:02:08 +0200 |
---|---|---|
committer | fx <[email protected]> | 2023-05-29 18:02:08 +0200 |
commit | d3870a2efa74e68c643dfb4aef32edc2536503b0 (patch) | |
tree | 116075aaa57c35afca2749719d450c3cb473ab3e /src/commands/update.rs | |
parent | 5a2ea0755b29a8811aeeec1c73679c5783082628 (diff) | |
parent | c7ecf3019a75dc0ab1a0aefeb9b880899fc8a231 (diff) | |
download | modlist-d3870a2efa74e68c643dfb4aef32edc2536503b0.tar modlist-d3870a2efa74e68c643dfb4aef32edc2536503b0.tar.gz modlist-d3870a2efa74e68c643dfb4aef32edc2536503b0.zip |
Merge pull request 'multithreaded' (#6) from multithreaded into master
Reviewed-on: http://raspberrypi.fritz.box:7920/fx/modlist/pulls/6
Diffstat (limited to 'src/commands/update.rs')
-rw-r--r-- | src/commands/update.rs | 222 |
1 files changed, 128 insertions, 94 deletions
diff --git a/src/commands/update.rs b/src/commands/update.rs index d3a282b..c19c02c 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs | |||
@@ -1,49 +1,81 @@ | |||
1 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; | ||
2 | |||
1 | use crate::{ | 3 | use crate::{ |
2 | config::Cfg, | 4 | config::Cfg, |
3 | db::{ | 5 | db::{ |
4 | mods_get_info, userlist_change_versions, userlist_get_all_ids, | 6 | mods_get_info, userlist_change_versions, userlist_get_all_ids, |
5 | userlist_get_applicable_versions, userlist_get_current_version, userlist_get_set_version, | 7 | userlist_get_applicable_versions, userlist_get_current_version, |
8 | userlist_get_set_version, | ||
6 | }, | 9 | }, |
7 | error::{ErrorType, MLError, MLE}, | 10 | error::{ErrorType, MLError, MLE}, |
8 | files::{clean_list_dir, delete_version, disable_version, download_versions}, | 11 | files::{ |
12 | clean_list_dir, delete_version, disable_version, download_versions, | ||
13 | }, | ||
9 | modrinth::{extract_current_version, versions, Version}, | 14 | modrinth::{extract_current_version, versions, Version}, |
10 | List, | 15 | List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION, |
11 | }; | 16 | }; |
12 | 17 | ||
13 | pub async fn update( | 18 | pub async fn update( |
14 | config: Cfg, | 19 | config: &Cfg, |
15 | liststack: Vec<List>, | 20 | liststack: Vec<List>, |
16 | clean: bool, | 21 | clean: bool, |
17 | direct_download: bool, | 22 | direct_download: bool, |
18 | delete_old: bool, | 23 | delete_old: bool, |
19 | ) -> MLE<()> { | 24 | ) -> MLE<()> { |
25 | let mp = MultiProgress::new(); | ||
26 | |||
27 | let update_p = | ||
28 | mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); | ||
29 | update_p.set_style( | ||
30 | ProgressStyle::with_template(STYLE_BAR_POS) | ||
31 | .unwrap() | ||
32 | .progress_chars(PROGRESS_CHARS), | ||
33 | ); | ||
34 | |||
20 | for current_list in liststack { | 35 | for current_list in liststack { |
21 | println!("Update mods in {}", current_list.id); | 36 | update_p.set_message(format!("Update {}", current_list.id)); |
22 | let mods = userlist_get_all_ids(config.clone(), ¤t_list.id)?; | ||
23 | 37 | ||
24 | let mut current_versions: Vec<(String, String)> = vec![]; | 38 | let list_p = mp.insert_before(&update_p, ProgressBar::new(2)); |
39 | list_p | ||
40 | .set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap()); | ||
41 | list_p.set_message("Update mods"); | ||
42 | |||
43 | let mods = userlist_get_all_ids(config, ¤t_list.id)?; | ||
44 | |||
45 | let list_u_p = mp.insert_before( | ||
46 | &list_p, | ||
47 | ProgressBar::new(mods.len().try_into().unwrap()), | ||
48 | ); | ||
49 | list_u_p.set_style( | ||
50 | ProgressStyle::with_template(STYLE_BAR_POS) | ||
51 | .unwrap() | ||
52 | .progress_chars(PROGRESS_CHARS), | ||
53 | ); | ||
25 | 54 | ||
55 | let mut current_versions: Vec<(String, String)> = vec![]; | ||
26 | let mut updatestack: Vec<Version> = vec![]; | 56 | let mut updatestack: Vec<Version> = vec![]; |
27 | 57 | ||
28 | for id in mods { | 58 | for id in mods { |
29 | let info = mods_get_info(config.clone(), &id)?; | 59 | let info = mods_get_info(config, &id)?; |
30 | println!(" ├{}", info.title); | 60 | list_u_p.set_message(format!("Update {}", info.title)); |
31 | 61 | ||
32 | if userlist_get_set_version(config.clone(), ¤t_list.id, &id)? { | 62 | //Skip check if version is set |
33 | println!(" │ └Set version, skipping update"); | 63 | if userlist_get_set_version(config, ¤t_list.id, &id)? { |
64 | list_u_p.inc(1); | ||
34 | continue; | 65 | continue; |
35 | } | 66 | } |
36 | 67 | ||
37 | //Getting current installed version for disable or delete | 68 | //Getting current installed version for disable or delete |
38 | let disable_version = | 69 | let disable_version = |
39 | userlist_get_current_version(config.clone(), ¤t_list.id, &id)?; | 70 | userlist_get_current_version(config, ¤t_list.id, &id)?; |
40 | 71 | ||
41 | updatestack.push( | 72 | updatestack.push( |
42 | match specific_update( | 73 | match specific_update( |
43 | config.clone(), | 74 | config, |
44 | clean, | 75 | clean, |
45 | current_list.clone(), | 76 | current_list.clone(), |
46 | String::from(&id), | 77 | &id, |
78 | &list_u_p, | ||
47 | ) | 79 | ) |
48 | .await | 80 | .await |
49 | { | 81 | { |
@@ -53,46 +85,94 @@ pub async fn update( | |||
53 | } | 85 | } |
54 | Err(e) => { | 86 | Err(e) => { |
55 | if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { | 87 | if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { |
56 | println!( | ||
57 | " │ └No new version found for the specified minecraft version" | ||
58 | ); | ||
59 | } else { | 88 | } else { |
60 | return Err(e); | 89 | return Err(e); |
61 | }; | 90 | }; |
91 | list_u_p.inc(1); | ||
62 | continue; | 92 | continue; |
63 | } | 93 | } |
64 | }, | 94 | }, |
65 | ) | 95 | ); |
96 | list_u_p.inc(1); | ||
66 | } | 97 | } |
67 | 98 | ||
99 | list_u_p.finish_with_message(format!( | ||
100 | "Updated mods in {}", | ||
101 | current_list.id | ||
102 | )); | ||
103 | |||
68 | if clean { | 104 | if clean { |
105 | list_p.set_message("Cleaning"); | ||
69 | clean_list_dir(¤t_list)?; | 106 | clean_list_dir(¤t_list)?; |
70 | }; | 107 | }; |
71 | 108 | ||
72 | if direct_download && !updatestack.is_empty() { | 109 | if direct_download && !updatestack.is_empty() { |
73 | download_versions(current_list.clone(), config.clone(), updatestack).await?; | 110 | download_versions( |
111 | current_list.clone(), | ||
112 | config.clone(), | ||
113 | updatestack, | ||
114 | &mp, | ||
115 | &list_p, | ||
116 | ) | ||
117 | .await?; | ||
74 | 118 | ||
75 | //Disable old versions | 119 | //Disable old versions |
76 | if !clean { | 120 | if !clean { |
121 | let d_p = mp.insert_before( | ||
122 | &list_p, | ||
123 | ProgressBar::new( | ||
124 | current_versions.len().try_into().unwrap(), | ||
125 | ), | ||
126 | ); | ||
127 | d_p.set_style( | ||
128 | ProgressStyle::with_template(STYLE_BAR_POS) | ||
129 | .unwrap() | ||
130 | .progress_chars(PROGRESS_CHARS), | ||
131 | ); | ||
77 | for ver in current_versions { | 132 | for ver in current_versions { |
78 | if delete_old { | 133 | if delete_old { |
79 | println!(" └Delete version {}", ver.0); | 134 | d_p.set_message(format!("Delete version {}", ver.0)); |
80 | delete_version(current_list.clone(), ver.0)?; | 135 | d_p.inc(1); |
136 | delete_version(¤t_list, ver.0)?; | ||
81 | } else if ver.0 != "NONE" { | 137 | } else if ver.0 != "NONE" { |
82 | println!(" └Disable version {}", ver.0); | 138 | d_p.set_message(format!("Disable version {}", ver.0)); |
83 | disable_version(config.clone(), current_list.clone(), ver.0, ver.1)?; | 139 | d_p.inc(1); |
140 | disable_version( | ||
141 | config, | ||
142 | current_list.clone(), | ||
143 | ver.0, | ||
144 | ver.1, | ||
145 | )?; | ||
84 | }; | 146 | }; |
85 | } | 147 | } |
148 | |||
149 | let del_msg = if delete_old { | ||
150 | "Deleted all old versions" | ||
151 | } else { | ||
152 | "Disabled all old versions" | ||
153 | }; | ||
154 | |||
155 | d_p.finish_with_message(del_msg); | ||
86 | } | 156 | } |
87 | }; | 157 | }; |
158 | list_p.finish_with_message(format!("Updated {}", current_list.id)); | ||
159 | update_p.inc(1); | ||
88 | } | 160 | } |
89 | 161 | ||
162 | update_p.finish_with_message("Updated all lists"); | ||
163 | |||
90 | Ok(()) | 164 | Ok(()) |
91 | } | 165 | } |
92 | 166 | ||
93 | async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> MLE<Version> { | 167 | async fn specific_update( |
168 | config: &Cfg, | ||
169 | clean: bool, | ||
170 | list: List, | ||
171 | id: &str, | ||
172 | progress: &ProgressBar, | ||
173 | ) -> MLE<Version> { | ||
94 | let applicable_versions = | 174 | let applicable_versions = |
95 | versions(&config.apis.modrinth, String::from(&id), list.clone()).await; | 175 | versions(&config.apis.modrinth, String::from(id), list.clone()).await; |
96 | 176 | ||
97 | let mut versions: Vec<String> = vec![]; | 177 | let mut versions: Vec<String> = vec![]; |
98 | 178 | ||
@@ -108,19 +188,19 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML | |||
108 | if clean | 188 | if clean |
109 | || (versions.join("|") | 189 | || (versions.join("|") |
110 | != userlist_get_applicable_versions( | 190 | != userlist_get_applicable_versions( |
111 | config.clone(), | 191 | config, |
112 | String::from(&list.id), | 192 | String::from(&list.id), |
113 | String::from(&id), | 193 | String::from(id), |
114 | )?) | 194 | )?) |
115 | { | 195 | { |
116 | let current_str = extract_current_version(applicable_versions.clone())?; | 196 | let current_str = extract_current_version(applicable_versions.clone())?; |
117 | 197 | ||
118 | if clean { | 198 | if !clean { |
119 | println!("\t └Add version to downloadstack"); | 199 | progress.println(format!( |
120 | } else { | 200 | "Found new version for {}", |
121 | println!("\t └Get versions for specified minecraft versions"); | 201 | mods_get_info(config, id).unwrap().title |
122 | println!("\t └New current version: {}", current_str); | 202 | )); |
123 | }; | 203 | } |
124 | 204 | ||
125 | //get new versions | 205 | //get new versions |
126 | let current_ver = match applicable_versions | 206 | let current_ver = match applicable_versions |
@@ -133,73 +213,27 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML | |||
133 | }?; | 213 | }?; |
134 | current.push(current_ver.clone()); | 214 | current.push(current_ver.clone()); |
135 | 215 | ||
136 | let link = match current_ver | 216 | let files = ¤t_ver.files; |
137 | .files | 217 | |
138 | .into_iter() | 218 | let link = match files.clone().into_iter().find(|f| f.primary) { |
139 | .find(|f| f.primary) | 219 | Some(f) => f, |
140 | .ok_or("!no primary in links") | 220 | None => files[0].clone(), |
141 | { | 221 | } |
142 | Ok(p) => Ok(p), | ||
143 | Err(e) => Err(MLError::new(ErrorType::Other, e)), | ||
144 | }? | ||
145 | .url; | 222 | .url; |
146 | userlist_change_versions(config, list.id, current_str, versions.join("|"), link, id)?; | 223 | |
224 | userlist_change_versions( | ||
225 | config, | ||
226 | list.id, | ||
227 | current_str, | ||
228 | versions.join("|"), | ||
229 | link, | ||
230 | id.to_string(), | ||
231 | )?; | ||
147 | } | 232 | } |
148 | 233 | ||
149 | if current.is_empty() { | 234 | if current.is_empty() { |
150 | return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE")); | 235 | return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE")); |
151 | }; | 236 | }; |
152 | 237 | ||
153 | //println!(" └✔️"); | ||
154 | Ok(current[0].clone()) | 238 | Ok(current[0].clone()) |
155 | } | 239 | } |
156 | |||
157 | // #[tokio::test] | ||
158 | // async fn download_updates_test() { | ||
159 | // use crate::{ | ||
160 | // modrinth::{Hash, Version, VersionFile, VersionType}, | ||
161 | // List, Modloader, | ||
162 | // }; | ||
163 | // | ||
164 | // let config = Cfg::init().unwrap(); | ||
165 | // let current_list = List { | ||
166 | // id: String::from("..."), | ||
167 | // mc_version: String::from("..."), | ||
168 | // modloader: Modloader::Fabric, | ||
169 | // download_folder: String::from("./dev/tests/dl"), | ||
170 | // }; | ||
171 | // | ||
172 | // let versions = vec![Version { | ||
173 | // id: "dEqtGnT9".to_string(), | ||
174 | // project_id: "kYuIpRLv".to_string(), | ||
175 | // author_id: "Qnt13hO8".to_string(), | ||
176 | // featured: true, | ||
177 | // name: "1.2.2-1.19 - Fabric".to_string(), | ||
178 | // version_number: "1.2.2-1.19".to_string(), | ||
179 | // changelog: None, | ||
180 | // date_published: "2022-11-02T17:41:43.072267Z".to_string(), | ||
181 | // downloads: 58, | ||
182 | // version_type: VersionType::release, | ||
183 | // files: vec![VersionFile { | ||
184 | // hashes: Hash { | ||
185 | // sha1: "fdc6dc39427fc92cc1d7ad8b275b5b83325e712b".to_string(), | ||
186 | // sha512: "5b372f00d6e5d6a5ef225c3897826b9f6a2be5506905f7f71b9e939779765b41be6f2a9b029cfc752ad0751d0d2d5f8bb4544408df1363eebdde15641e99a849".to_string() | ||
187 | // }, | ||
188 | // url: "https://cdn.modrinth.com/data/kYuIpRLv/versions/dEqtGnT9/waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), | ||
189 | // filename: "waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), | ||
190 | // primary: true, | ||
191 | // size: 323176 | ||
192 | // }], | ||
193 | // game_versions: vec![ | ||
194 | // "1.19".to_string(), | ||
195 | // "1.19.1".to_string(), | ||
196 | // "1.19.2".to_string() | ||
197 | // ], | ||
198 | // loaders: vec![ | ||
199 | // "fabric".to_string() | ||
200 | // ] | ||
201 | // }]; | ||
202 | // assert!(download_versions(current_list, config, versions) | ||
203 | // .await | ||
204 | // .is_ok()) | ||
205 | // } | ||