summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands/download.rs184
-rw-r--r--src/commands/modification.rs114
-rw-r--r--src/commands/update.rs84
-rw-r--r--src/main.rs184
4 files changed, 293 insertions, 273 deletions
diff --git a/src/commands/download.rs b/src/commands/download.rs
index 7af1066..7ea5c29 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -1,5 +1,3 @@
1#![allow(clippy::too_many_lines)]
2
3use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 1use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
4 2
5use crate::{config::Cfg, List}; 3use crate::{config::Cfg, List};
@@ -35,105 +33,113 @@ pub async fn download(
35 ); 33 );
36 34
37 for current_list in liststack { 35 for current_list in liststack {
38 download_p.set_message(format!("Download in {}", current_list.id)); 36 download_list(config, mp.clone(), download_p.clone(), current_list, clean, delete_old).await?;
39 37 }
40 let downloaded_versions = get_downloaded_versions(&current_list)?;
41 let current_version_ids =
42 match userlist_get_all_current_versions_with_mods(
43 config,
44 &current_list.id,
45 ) {
46 Ok(i) => Ok(i),
47 Err(e) => {
48 Err(MLErr::new(EType::DBError, e.to_string().as_str()))
49 }
50 }?;
51
52 let mut to_download: Vec<String> = vec![];
53 //(mod_id, version_id)
54 let mut to_disable: Vec<(String, String)> = vec![];
55
56 for version in current_version_ids {
57 let mod_id = version.0;
58 let current_version = version.1;
59
60 let current_download = downloaded_versions.get(&mod_id);
61
62 if current_download.is_none() || clean {
63 to_download.push(current_version);
64 } else {
65 let downloaded_version = current_download
66 .ok_or(MLErr::new(EType::Other, "IDK, WTF"))?;
67 if &current_version != downloaded_version {
68 to_disable.push((
69 mod_id.clone(),
70 String::from(downloaded_version),
71 ));
72 to_download.push(current_version);
73 }
74 }
75 }
76 38
77 if clean { 39 download_p.finish_with_message("Downloaded all lists");
78 clean_list_dir(&current_list)?; 40
79 }; 41 Ok(())
42}
43
44async fn download_list(
45 config: &Cfg,
46 mp: MultiProgress,
47 download_p: ProgressBar,
48 current_list: List,
49 clean: bool,
50 delete_old: bool,
51) -> MLE<()> {
52 download_p.set_message(format!("Download in {}", current_list.id));
53
54 let downloaded_versions = get_downloaded_versions(&current_list)?;
55 let current_version_ids = match userlist_get_all_current_versions_with_mods(
56 config,
57 &current_list.id,
58 ) {
59 Ok(i) => Ok(i),
60 Err(e) => Err(MLErr::new(EType::DBError, e.to_string().as_str())),
61 }?;
62
63 let mut to_download: Vec<String> = vec![];
64 //(mod_id, version_id)
65 let mut to_disable: Vec<(String, String)> = vec![];
66
67 for version in current_version_ids {
68 let mod_id = version.0;
69 let current_version = version.1;
80 70
81 if to_download.is_empty() { 71 let current_download = downloaded_versions.get(&mod_id);
82 download_p.println(format!( 72
83 "There are no new versions to download for {}", 73 if current_download.is_none() || clean {
84 current_list.id 74 to_download.push(current_version);
85 ));
86 } else { 75 } else {
87 download_versions( 76 let downloaded_version =
88 current_list.clone(), 77 current_download.ok_or(MLErr::new(EType::Other, "IDK, WTF"))?;
89 config.clone(), 78 if &current_version != downloaded_version {
90 get_raw_versions(&config.apis.modrinth, to_download).await?, 79 to_disable
91 &mp, 80 .push((mod_id.clone(), String::from(downloaded_version)));
92 &download_p, 81 to_download.push(current_version);
93 ) 82 }
94 .await?;
95 } 83 }
84 }
96 85
97 if !to_disable.is_empty() { 86 if clean {
98 let d_p = 87 clean_list_dir(&current_list)?;
99 mp.insert_before( 88 };
100 &download_p, 89
101 ProgressBar::new(to_disable.len().try_into().map_err( 90 if to_download.is_empty() {
102 |_| MLErr::new(EType::Other, "ListStackLen"), 91 download_p.println(format!(
103 )?), 92 "There are no new versions to download for {}",
104 ); 93 current_list.id
105 d_p.set_style( 94 ));
106 ProgressStyle::with_template(STYLE_BAR_POS) 95 } else {
107 .map_err(|_| { 96 download_versions(
108 MLErr::new(EType::LibIndicatif, "template error") 97 current_list.clone(),
109 })? 98 config.clone(),
110 .progress_chars(PROGRESS_CHARS), 99 get_raw_versions(&config.apis.modrinth, to_download).await?,
111 ); 100 &mp,
112 for ver in to_disable { 101 &download_p,
113 if delete_old { 102 )
114 d_p.set_message(format!("Delete version {}", ver.1)); 103 .await?;
115 d_p.inc(1); 104 }
116 delete_version(&current_list, &ver.1)?;
117 } else {
118 d_p.set_message(format!("Disable version {}", ver.1));
119 d_p.inc(1);
120 disable_version(config, &current_list, ver.1, ver.0)?;
121 };
122 }
123 105
124 let del_msg = if delete_old { 106 if !to_disable.is_empty() {
125 "Deleted all old versions" 107 let d_p = mp.insert_before(
108 &download_p,
109 ProgressBar::new(
110 to_disable
111 .len()
112 .try_into()
113 .map_err(|_| MLErr::new(EType::Other, "ListStackLen"))?,
114 ),
115 );
116 d_p.set_style(
117 ProgressStyle::with_template(STYLE_BAR_POS)
118 .map_err(|_| MLErr::new(EType::LibIndicatif, "template error"))?
119 .progress_chars(PROGRESS_CHARS),
120 );
121 for ver in to_disable {
122 if delete_old {
123 d_p.set_message(format!("Delete version {}", ver.1));
124 d_p.inc(1);
125 delete_version(&current_list, &ver.1)?;
126 } else { 126 } else {
127 "Disabled all old versions" 127 d_p.set_message(format!("Disable version {}", ver.1));
128 d_p.inc(1);
129 disable_version(config, &current_list, ver.1, ver.0)?;
128 }; 130 };
129
130 d_p.finish_with_message(del_msg);
131 } 131 }
132 132
133 download_p.inc(1); 133 let del_msg = if delete_old {
134 "Deleted all old versions"
135 } else {
136 "Disabled all old versions"
137 };
138
139 d_p.finish_with_message(del_msg);
134 } 140 }
135 141
136 download_p.finish_with_message("Downloaded all lists"); 142 download_p.inc(1);
137 143
138 Ok(()) 144 Ok(())
139} 145}
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index aa1174a..8f115ee 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,5 +1,3 @@
1#![allow(clippy::too_many_lines)]
2
3use std::collections::HashMap; 1use std::collections::HashMap;
4 2
5use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 3use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
@@ -114,60 +112,7 @@ pub async fn mod_add(
114 ); 112 );
115 113
116 for project in projectinfo { 114 for project in projectinfo {
117 project_p.set_message(format!("Add {}", project.title)); 115 add_project(config, &project_p, &project, &list)?;
118
119 let current_version_id = if project.current_version.is_none() {
120 String::from("NONE")
121 } else {
122 project
123 .current_version
124 .clone()
125 .ok_or(MLErr::new(EType::Other, "cur_ver"))?
126 .id
127 };
128
129 match userlist_insert(
130 config,
131 &list.id,
132 &project.mod_id,
133 &current_version_id,
134 &project.applicable_versions,
135 &project.download_link,
136 project.set_version,
137 ) {
138 Err(e) => {
139 let expected_err = format!(
140 "SQL: UNIQUE constraint failed: {}.mod_id",
141 list.id
142 );
143 if e.to_string() == expected_err {
144 Err(MLErr::new(
145 EType::ModError,
146 "MOD_ALREADY_ON_SELECTED_LIST",
147 ))
148 } else {
149 Err(e)
150 }
151 }
152 Ok(..) => Ok(..),
153 }?;
154
155 match mods_insert(
156 config,
157 &project.mod_id,
158 &project.slug,
159 &project.title,
160 ) {
161 Err(e) => {
162 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" {
163 Ok(..)
164 } else {
165 Err(e)
166 }
167 }
168 Ok(..) => Ok(..),
169 }?;
170
171 if project.current_version.is_some() { 116 if project.current_version.is_some() {
172 downloadstack.push( 117 downloadstack.push(
173 project 118 project
@@ -175,8 +120,6 @@ pub async fn mod_add(
175 .ok_or(MLErr::new(EType::Other, "cur_ver"))?, 120 .ok_or(MLErr::new(EType::Other, "cur_ver"))?,
176 ); 121 );
177 }; 122 };
178
179 project_p.inc(1);
180 } 123 }
181 124
182 project_p.finish_with_message("Added all mods to the database"); 125 project_p.finish_with_message("Added all mods to the database");
@@ -199,6 +142,61 @@ pub async fn mod_add(
199 Ok(()) 142 Ok(())
200} 143}
201 144
145fn add_project(
146 config: &Cfg,
147 project_p: &ProgressBar,
148 project: &ProjectInfo,
149 list: &List,
150) -> MLE<()> {
151 project_p.set_message(format!("Add {}", project.title));
152
153 let current_version_id = if project.current_version.is_none() {
154 String::from("NONE")
155 } else {
156 project
157 .current_version
158 .clone()
159 .ok_or(MLErr::new(EType::Other, "cur_ver"))?
160 .id
161 };
162
163 match userlist_insert(
164 config,
165 &list.id,
166 &project.mod_id,
167 &current_version_id,
168 &project.applicable_versions,
169 &project.download_link,
170 project.set_version,
171 ) {
172 Err(e) => {
173 let expected_err =
174 format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id);
175 if e.to_string() == expected_err {
176 Err(MLErr::new(EType::ModError, "MOD_ALREADY_ON_SELECTED_LIST"))
177 } else {
178 Err(e)
179 }
180 }
181 Ok(..) => Ok(..),
182 }?;
183
184 match mods_insert(config, &project.mod_id, &project.slug, &project.title) {
185 Err(e) => {
186 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" {
187 Ok(..)
188 } else {
189 Err(e)
190 }
191 }
192 Ok(..) => Ok(..),
193 }?;
194
195 project_p.inc(1);
196
197 Ok(())
198}
199
202async fn get_mod_infos( 200async fn get_mod_infos(
203 config: &Cfg, 201 config: &Cfg,
204 mod_ids: Vec<(String, bool)>, 202 mod_ids: Vec<(String, bool)>,
diff --git a/src/commands/update.rs b/src/commands/update.rs
index c7965e3..f83030d 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -1,5 +1,3 @@
1#![allow(clippy::too_many_lines)]
2
3use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 1use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
4 2
5use crate::{ 3use crate::{
@@ -70,44 +68,7 @@ pub async fn update(
70 let mut updatestack: Vec<Version> = vec![]; 68 let mut updatestack: Vec<Version> = vec![];
71 69
72 for id in mods { 70 for id in mods {
73 let info = mods_get_info(config, &id)?; 71 update_mod(config, id, list_u_p.clone(), &current_list, &mut updatestack, &mut current_versions, clean).await?;
74 list_u_p.set_message(format!("Update {}", info.title));
75
76 //Skip check if version is set
77 if userlist_get_set_version(config, &current_list.id, &id)? {
78 list_u_p.inc(1);
79 continue;
80 }
81
82 //Getting current installed version for disable or delete
83 let disable_version =
84 userlist_get_current_version(config, &current_list.id, &id)?;
85
86 updatestack.push(
87 match specific_update(
88 config,
89 clean,
90 current_list.clone(),
91 &id,
92 &list_u_p,
93 )
94 .await
95 {
96 Ok(ver) => {
97 current_versions.push((disable_version, id));
98 ver
99 }
100 Err(e) => {
101 if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" {
102 } else {
103 return Err(e);
104 };
105 list_u_p.inc(1);
106 continue;
107 }
108 },
109 );
110 list_u_p.inc(1);
111 } 72 }
112 73
113 list_u_p.finish_with_message(format!( 74 list_u_p.finish_with_message(format!(
@@ -173,6 +134,49 @@ pub async fn update(
173 Ok(()) 134 Ok(())
174} 135}
175 136
137async fn update_mod(config: &Cfg, id: String, list_u_p: ProgressBar, current_list: &List, updatestack: &mut Vec<Version>, current_versions: &mut Vec<(String, String)>, clean: bool) -> MLE<()> {
138 let info = mods_get_info(config, &id)?;
139 list_u_p.set_message(format!("Update {}", info.title));
140
141 //Skip check if version is set
142 if userlist_get_set_version(config, &current_list.id, &id)? {
143 list_u_p.inc(1);
144 return Ok(());
145 }
146
147 //Getting current installed version for disable or delete
148 let disable_version =
149 userlist_get_current_version(config, &current_list.id, &id)?;
150
151 updatestack.push(
152 match specific_update(
153 config,
154 clean,
155 current_list.clone(),
156 &id,
157 &list_u_p,
158 )
159 .await
160 {
161 Ok(ver) => {
162 current_versions.push((disable_version, id.to_string()));
163 ver
164 }
165 Err(e) => {
166 if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" {
167 } else {
168 return Err(e);
169 };
170 list_u_p.inc(1);
171 return Ok(());
172 }
173 },
174 );
175 list_u_p.inc(1);
176
177 Ok(())
178}
179
176async fn specific_update( 180async fn specific_update(
177 config: &Cfg, 181 config: &Cfg,
178 clean: bool, 182 clean: bool,
diff --git a/src/main.rs b/src/main.rs
index a478ec7..f388a82 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,12 @@
1#![allow(clippy::too_many_lines)]
2
3use clap::{Parser, Subcommand}; 1use clap::{Parser, Subcommand};
4use modlist::{ 2use modlist::{
5 config::Cfg, 3 config::Cfg,
6 db::{config_get_current_list, lists_get, lists_get_all_ids}, 4 db::{config_get_current_list, lists_get, lists_get_all_ids},
7 download, export, get_current_list, import, list_add, list_change, 5 download,
8 list_lists, list_remove, list_version, mod_add, mod_remove, update, AddMod, 6 error::MLE,
9 IDSelector, List, Modloader, VersionLevel, 7 export, get_current_list, import, list_add, list_change, list_lists,
8 list_remove, list_version, mod_add, mod_remove, update, AddMod, IDSelector,
9 List, Modloader, VersionLevel,
10}; 10};
11 11
12#[derive(Parser)] 12#[derive(Parser)]
@@ -163,90 +163,11 @@ async fn main() {
163 let config = Cfg::init(cli.config).await.unwrap(); 163 let config = Cfg::init(cli.config).await.unwrap();
164 164
165 match cli.command { 165 match cli.command {
166 Commands::Mod { command } => match command { 166 Commands::Mod { command } => handle_mod(config, command).await,
167 ModCommands::Add {
168 id,
169 version,
170 list,
171 download,
172 lock,
173 } => {
174 let listf = match list {
175 Some(list) => lists_get(&config, &list).unwrap(),
176 None => lists_get(
177 &config,
178 &config_get_current_list(&config).unwrap(),
179 )
180 .unwrap(),
181 };
182
183 let marked_id = if version {
184 IDSelector::VersionID(id)
185 } else {
186 IDSelector::ModificationID(id)
187 };
188
189 let add_id = AddMod {
190 id: marked_id,
191 set_version: lock,
192 };
193
194 mod_add(&config, vec![add_id], listf, download).await
195 }
196 ModCommands::Remove { id, list } => {
197 let listf = match list {
198 Some(list) => lists_get(&config, &list).unwrap(),
199 None => lists_get(
200 &config,
201 &config_get_current_list(&config).unwrap(),
202 )
203 .unwrap(),
204 };
205 mod_remove(&config, &id, &listf)
206 }
207 },
208 Commands::List { 167 Commands::List {
209 command, 168 command,
210 force_gameupdate, 169 force_gameupdate,
211 } => match command { 170 } => handle_list(config, command, force_gameupdate).await,
212 ListCommands::Add {
213 id,
214 directory,
215 modloader,
216 version,
217 } => {
218 let ml = match modloader {
219 Some(ml) => Modloader::from(&ml).unwrap(),
220 None => config.defaults.modloader.clone(),
221 };
222
223 let versions_path = &config.versions;
224 let ver = match version {
225 Some(ver) => VersionLevel::from(&ver)
226 .get(versions_path, force_gameupdate)
227 .await
228 .unwrap(),
229 None => config
230 .defaults
231 .version
232 .clone()
233 .get(versions_path, force_gameupdate)
234 .await
235 .unwrap(),
236 };
237
238 list_add(&config, &id, &ver, &ml, &directory)
239 }
240 ListCommands::Remove { id } => list_remove(&config, &id),
241 ListCommands::List => list_lists(&config),
242 ListCommands::Change { id } => list_change(&config, &id),
243 ListCommands::Version {
244 id,
245 version,
246 download,
247 remove,
248 } => list_version(&config, &id, version, download, remove).await,
249 },
250 Commands::Update { 171 Commands::Update {
251 all, 172 all,
252 download, 173 download,
@@ -310,3 +231,94 @@ async fn main() {
310 } 231 }
311 .unwrap(); 232 .unwrap();
312} 233}
234
235async fn handle_mod(config: Cfg, command: ModCommands) -> MLE<()> {
236 match command {
237 ModCommands::Add {
238 id,
239 version,
240 list,
241 download,
242 lock,
243 } => {
244 let listf = match list {
245 Some(list) => lists_get(&config, &list).unwrap(),
246 None => lists_get(
247 &config,
248 &config_get_current_list(&config).unwrap(),
249 )
250 .unwrap(),
251 };
252
253 let marked_id = if version {
254 IDSelector::VersionID(id)
255 } else {
256 IDSelector::ModificationID(id)
257 };
258
259 let add_id = AddMod {
260 id: marked_id,
261 set_version: lock,
262 };
263
264 mod_add(&config, vec![add_id], listf, download).await
265 }
266 ModCommands::Remove { id, list } => {
267 let listf = match list {
268 Some(list) => lists_get(&config, &list).unwrap(),
269 None => lists_get(
270 &config,
271 &config_get_current_list(&config).unwrap(),
272 )
273 .unwrap(),
274 };
275 mod_remove(&config, &id, &listf)
276 }
277 }
278}
279
280async fn handle_list(
281 config: Cfg,
282 command: ListCommands,
283 force_gameupdate: bool,
284) -> MLE<()> {
285 match command {
286 ListCommands::Add {
287 id,
288 directory,
289 modloader,
290 version,
291 } => {
292 let ml = match modloader {
293 Some(ml) => Modloader::from(&ml).unwrap(),
294 None => config.defaults.modloader.clone(),
295 };
296
297 let versions_path = &config.versions;
298 let ver = match version {
299 Some(ver) => VersionLevel::from(&ver)
300 .get(versions_path, force_gameupdate)
301 .await
302 .unwrap(),
303 None => config
304 .defaults
305 .version
306 .clone()
307 .get(versions_path, force_gameupdate)
308 .await
309 .unwrap(),
310 };
311
312 list_add(&config, &id, &ver, &ml, &directory)
313 }
314 ListCommands::Remove { id } => list_remove(&config, &id),
315 ListCommands::List => list_lists(&config),
316 ListCommands::Change { id } => list_change(&config, &id),
317 ListCommands::Version {
318 id,
319 version,
320 download,
321 remove,
322 } => list_version(&config, &id, version, download, remove).await,
323 }
324}