summaryrefslogtreecommitdiff
path: root/src/commands
diff options
context:
space:
mode:
authorfxqnlr <[email protected]>2023-05-26 17:40:27 +0200
committerfxqnlr <[email protected]>2023-05-26 17:40:27 +0200
commit2d7e0a2fbf1c8a4187e2bf3fdcd592631ab273a0 (patch)
treecc8f3522670245775e4be7ac2a1e2ad4fd818c8f /src/commands
parentd8554e30029bf43dccce72e982784cd01857b0c4 (diff)
downloadmodlist-2d7e0a2fbf1c8a4187e2bf3fdcd592631ab273a0.tar
modlist-2d7e0a2fbf1c8a4187e2bf3fdcd592631ab273a0.tar.gz
modlist-2d7e0a2fbf1c8a4187e2bf3fdcd592631ab273a0.zip
added full progress? cargo fmt
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/download.rs39
-rw-r--r--src/commands/io.rs34
-rw-r--r--src/commands/list.rs54
-rw-r--r--src/commands/modification.rs114
-rw-r--r--src/commands/update.rs95
5 files changed, 209 insertions, 127 deletions
diff --git a/src/commands/download.rs b/src/commands/download.rs
index 7aa0156..dd00ffb 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -1,7 +1,5 @@
1use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
1 2
2use indicatif::{MultiProgress, ProgressStyle, ProgressBar};
3
4use crate::{STYLE_BAR_POS, PROGRESS_CHARS};
5use crate::{config::Cfg, List}; 3use crate::{config::Cfg, List};
6use crate::{ 4use crate::{
7 db::userlist_get_all_current_versions_with_mods, 5 db::userlist_get_all_current_versions_with_mods,
@@ -11,12 +9,21 @@ use crate::{
11 }, 9 },
12 modrinth::get_raw_versions, 10 modrinth::get_raw_versions,
13}; 11};
14 12use crate::{PROGRESS_CHARS, STYLE_BAR_POS};
15pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_old: bool) -> MLE<()> { 13
16 14pub async fn download(
15 config: &Cfg,
16 liststack: Vec<List>,
17 clean: bool,
18 delete_old: bool,
19) -> MLE<()> {
17 let mp = MultiProgress::new(); 20 let mp = MultiProgress::new();
18 let download_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); 21 let download_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap()));
19 download_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 22 download_p.set_style(
23 ProgressStyle::with_template(STYLE_BAR_POS)
24 .unwrap()
25 .progress_chars(PROGRESS_CHARS),
26 );
20 27
21 for current_list in liststack { 28 for current_list in liststack {
22 download_p.set_message(format!("Download in {}", current_list.id)); 29 download_p.set_message(format!("Download in {}", current_list.id));
@@ -67,17 +74,27 @@ pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_ol
67 ) 74 )
68 .await?; 75 .await?;
69 } else { 76 } else {
70 download_p.println(format!("There are no new versions to download for {}", current_list.id)); 77 download_p.println(format!(
78 "There are no new versions to download for {}",
79 current_list.id
80 ));
71 } 81 }
72 82
73 if !to_disable.is_empty() { 83 if !to_disable.is_empty() {
74 let d_p = mp.insert_before(&download_p, ProgressBar::new(to_disable.len().try_into().unwrap())); 84 let d_p = mp.insert_before(
75 d_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 85 &download_p,
86 ProgressBar::new(to_disable.len().try_into().unwrap()),
87 );
88 d_p.set_style(
89 ProgressStyle::with_template(STYLE_BAR_POS)
90 .unwrap()
91 .progress_chars(PROGRESS_CHARS),
92 );
76 for ver in to_disable { 93 for ver in to_disable {
77 if delete_old { 94 if delete_old {
78 d_p.set_message(format!("Delete version {}", ver.1)); 95 d_p.set_message(format!("Delete version {}", ver.1));
79 d_p.inc(1); 96 d_p.inc(1);
80 delete_version(current_list.clone(), ver.1)?; 97 delete_version(&current_list, ver.1)?;
81 } else { 98 } else {
82 d_p.set_message(format!("Disable version {}", ver.1)); 99 d_p.set_message(format!("Disable version {}", ver.1));
83 d_p.inc(1); 100 d_p.inc(1);
diff --git a/src/commands/io.rs b/src/commands/io.rs
index 45e363e..2501583 100644
--- a/src/commands/io.rs
+++ b/src/commands/io.rs
@@ -1,12 +1,16 @@
1use indicatif::{ProgressBar, ProgressStyle};
1use serde::{Deserialize, Serialize}; 2use serde::{Deserialize, Serialize};
2use std::fs::File; 3use std::fs::File;
3use std::io::prelude::*; 4use std::io::prelude::*;
4 5
5use crate::{ 6use crate::{
6 config::Cfg, 7 config::Cfg,
7 db::{lists_get, lists_get_all_ids, lists_insert, userlist_get_set_version, userlist_get_all_ids, userlist_get_current_version}, 8 db::{
9 lists_get, lists_get_all_ids, lists_insert, userlist_get_all_ids,
10 userlist_get_current_version, userlist_get_set_version,
11 },
8 error::MLE, 12 error::MLE,
9 mod_add, IDSelector, List, Modloader, AddMod, 13 mod_add, AddMod, IDSelector, List, Modloader, STYLE_OPERATION,
10}; 14};
11 15
12#[derive(Debug, Serialize, Deserialize)] 16#[derive(Debug, Serialize, Deserialize)]
@@ -17,14 +21,14 @@ struct Export {
17#[derive(Debug, Serialize, Deserialize)] 21#[derive(Debug, Serialize, Deserialize)]
18struct ExportVersion { 22struct ExportVersion {
19 version: String, 23 version: String,
20 set: bool 24 set: bool,
21} 25}
22 26
23impl ExportVersion { 27impl ExportVersion {
24 fn from(config: &Cfg, list_id: &str, mod_id: &str) -> MLE<Self> { 28 fn from(config: &Cfg, list_id: &str, mod_id: &str) -> MLE<Self> {
25 Ok(Self { 29 Ok(Self {
26 version: userlist_get_current_version(config, list_id, mod_id)?, 30 version: userlist_get_current_version(config, list_id, mod_id)?,
27 set: userlist_get_set_version(config, list_id, mod_id)? 31 set: userlist_get_set_version(config, list_id, mod_id)?,
28 }) 32 })
29 } 33 }
30} 34}
@@ -64,23 +68,36 @@ impl ExportList {
64} 68}
65 69
66pub fn export(config: &Cfg, list: Option<String>) -> MLE<()> { 70pub fn export(config: &Cfg, list: Option<String>) -> MLE<()> {
71 let progress = ProgressBar::new_spinner();
72 progress.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
73
67 let mut list_ids: Vec<String> = vec![]; 74 let mut list_ids: Vec<String> = vec![];
68 if list.is_none() { 75 if list.is_none() {
69 list_ids = lists_get_all_ids(config)?; 76 list_ids = lists_get_all_ids(config)?;
70 } else { 77 } else {
71 list_ids.push(lists_get(config, &list.unwrap())?.id); 78 list_ids.push(lists_get(config, &list.unwrap())?.id);
72 } 79 }
80
73 let mut lists: Vec<ExportList> = vec![]; 81 let mut lists: Vec<ExportList> = vec![];
74 for list_id in list_ids { 82 for list_id in list_ids {
83 progress.set_message(format!("Export {}", list_id));
84 //TODO download option/ new download on import
75 lists.push(ExportList::from(config, &list_id, true)?); 85 lists.push(ExportList::from(config, &list_id, true)?);
76 } 86 }
77 87
78 let toml = toml::to_string(&Export { lists })?; 88 let toml = toml::to_string(&Export { lists })?;
79 89
80 let filestr = dirs::home_dir().unwrap().join("mlexport.toml"); 90 let filestr = dirs::home_dir()
91 .unwrap()
92 .join("mlexport.toml")
93 .into_os_string()
94 .into_string()
95 .unwrap();
81 96
82 let mut file = File::create(filestr.into_os_string().into_string().unwrap().as_str())?; 97 progress.set_message("Create file");
98 let mut file = File::create(&filestr)?;
83 file.write_all(toml.as_bytes())?; 99 file.write_all(toml.as_bytes())?;
100 progress.finish_with_message(format!("Exported to {}", filestr));
84 101
85 Ok(()) 102 Ok(())
86} 103}
@@ -108,7 +125,10 @@ pub async fn import(config: &Cfg, file_str: &str, direct_download: bool) -> MLE<
108 125
109 let mut ver_ids = vec![]; 126 let mut ver_ids = vec![];
110 for id in exportlist.versions { 127 for id in exportlist.versions {
111 ver_ids.push(AddMod { id: IDSelector::VersionID(id.version), set_version: id.set} ); 128 ver_ids.push(AddMod {
129 id: IDSelector::VersionID(id.version),
130 set_version: id.set,
131 });
112 } 132 }
113 mod_add(config, ver_ids, list, direct_download).await?; 133 mod_add(config, ver_ids, list, direct_download).await?;
114 } 134 }
diff --git a/src/commands/list.rs b/src/commands/list.rs
index 52f14f2..b0a082d 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -1,11 +1,13 @@
1use indicatif::{ProgressBar, ProgressStyle};
2
1use crate::{ 3use crate::{
2 config::Cfg, 4 config::Cfg,
3 db::{ 5 db::{
4 config_change_current_list, config_get_current_list, lists_get, lists_insert, lists_remove, 6 config_change_current_list, config_get_current_list, lists_get, lists_get_all_ids,
5 lists_version, lists_get_all_ids, 7 lists_insert, lists_remove, lists_version,
6 }, 8 },
7 error::{MLE, MLError, ErrorType}, 9 error::{ErrorType, MLError, MLE},
8 update, Modloader, 10 update, Modloader, STYLE_OPERATION,
9}; 11};
10 12
11#[derive(Debug, Clone, PartialEq, Eq)] 13#[derive(Debug, Clone, PartialEq, Eq)]
@@ -28,20 +30,35 @@ pub fn list_add(
28 modloader: &Modloader, 30 modloader: &Modloader,
29 directory: &str, 31 directory: &str,
30) -> MLE<()> { 32) -> MLE<()> {
31 lists_insert(config, id, mc_version, modloader, directory) 33 let p = ProgressBar::new_spinner();
34 p.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
35 p.set_message(format!("Create {}", id));
36 lists_insert(config, id, mc_version, modloader, directory)?;
37 p.finish_with_message(format!("Created {}", id));
38 Ok(())
32} 39}
33 40
34pub fn list_change(config: &Cfg, id: String) -> MLE<()> { 41pub fn list_change(config: &Cfg, id: &str) -> MLE<()> {
42 let p = ProgressBar::new_spinner();
43 p.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
44 p.set_message(format!("Change default list to {}", id));
45
35 if !lists_get_all_ids(config)?.into_iter().any(|l| l == id) { 46 if !lists_get_all_ids(config)?.into_iter().any(|l| l == id) {
36 return Err(MLError::new(ErrorType::ArgumentError, "List not found")); 47 return Err(MLError::new(ErrorType::ArgumentError, "List not found"));
37 }; 48 };
38 println!("Change default list to: {}", id); 49 config_change_current_list(config, id)?;
39 config_change_current_list(config, id) 50
51 p.finish_with_message(format!("Changed default list to {}", id));
52 Ok(())
40} 53}
41 54
42pub fn list_remove(config: &Cfg, id: String) -> MLE<()> { 55pub fn list_remove(config: &Cfg, id: &str) -> MLE<()> {
43 //TODO add logging 56 let p = ProgressBar::new_spinner();
44 lists_remove(config, id) 57 p.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
58 p.set_message(format!("Remove {}", id));
59 lists_remove(config, id)?;
60 p.finish_with_message(format!("Removed {}", id));
61 Ok(())
45} 62}
46 63
47///Changing the current lists version and updating it 64///Changing the current lists version and updating it
@@ -57,17 +74,20 @@ pub async fn list_version(
57 download: bool, 74 download: bool,
58 delete: bool, 75 delete: bool,
59) -> MLE<()> { 76) -> MLE<()> {
60 println!( 77 let p = ProgressBar::new_spinner();
78 p.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
79 p.set_message(format!(
61 "Change version for list {} to minecraft version: {}", 80 "Change version for list {} to minecraft version: {}",
62 id, mc_version 81 id, mc_version
63 ); 82 ));
64 83
65 lists_version(config, id, &mc_version)?; 84 lists_version(config, id, &mc_version)?;
66 85
67 println!( 86 p.finish_with_message(format!(
68 "\nCheck for updates for new minecraft version in list {}", 87 "Changed version for list {} to minecraft version: {}",
69 id 88 id, mc_version
70 ); 89 ));
90
71 let list = lists_get(config, id)?; 91 let list = lists_get(config, id)?;
72 update(config, vec![list], true, download, delete).await 92 update(config, vec![list], true, download, delete).await
73} 93}
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 8abf913..fdb70c7 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,23 +1,23 @@
1use std::{io::Write, collections::HashMap}; 1use std::collections::HashMap;
2 2
3use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; 3use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
4 4
5use crate::{ 5use crate::{
6 config::Cfg, 6 config::Cfg,
7 db::{ 7 db::{
8 lists_get_all_ids, mods_get_id, mods_insert, mods_remove, userlist_get_all_ids, 8 lists_get_all_ids, mods_get_id, mods_get_info, mods_insert, mods_remove,
9 userlist_get_current_version, userlist_insert, userlist_remove, mods_get_info, 9 userlist_get_all_ids, userlist_get_current_version, userlist_insert, userlist_remove,
10 }, 10 },
11 error::{ErrorType, MLError, MLE}, 11 error::{ErrorType, MLError, MLE},
12 files::{delete_version, download_versions}, 12 files::{delete_version, download_versions},
13 modrinth::{extract_current_version, get_raw_versions, project, projects, versions, Version}, 13 modrinth::{extract_current_version, get_raw_versions, project, projects, versions, Version},
14 List, PROGRESS_CHARS, STYLE_BAR_POS, 14 List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION,
15}; 15};
16 16
17#[derive(Debug)] 17#[derive(Debug)]
18pub struct AddMod { 18pub struct AddMod {
19 pub id: IDSelector, 19 pub id: IDSelector,
20 pub set_version: bool 20 pub set_version: bool,
21} 21}
22 22
23#[derive(Debug, PartialEq, Eq)] 23#[derive(Debug, PartialEq, Eq)]
@@ -47,9 +47,13 @@ pub async fn mod_add(
47 47
48 let mut mod_ids: Vec<(String, bool)> = Vec::new(); 48 let mut mod_ids: Vec<(String, bool)> = Vec::new();
49 let mut ver_ids: Vec<(String, bool)> = Vec::new(); 49 let mut ver_ids: Vec<(String, bool)> = Vec::new();
50 50
51 let add_p = mp.add(ProgressBar::new(mods.len().try_into().unwrap())); 51 let add_p = mp.add(ProgressBar::new(mods.len().try_into().unwrap()));
52 add_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 52 add_p.set_style(
53 ProgressStyle::with_template(STYLE_BAR_POS)
54 .unwrap()
55 .progress_chars(PROGRESS_CHARS),
56 );
53 add_p.set_message("Sort ids"); 57 add_p.set_message("Sort ids");
54 58
55 //"Sort" project ids from version ids to be able to handle them differently but in a batch 59 //"Sort" project ids from version ids to be able to handle them differently but in a batch
@@ -62,7 +66,7 @@ pub async fn mod_add(
62 } 66 }
63 67
64 add_p.set_message("Get infos"); 68 add_p.set_message("Get infos");
65 69
66 let mut projectinfo: Vec<ProjectInfo> = Vec::new(); 70 let mut projectinfo: Vec<ProjectInfo> = Vec::new();
67 if !mod_ids.is_empty() { 71 if !mod_ids.is_empty() {
68 projectinfo.append(&mut get_mod_infos(config, mod_ids, list.clone()).await?); 72 projectinfo.append(&mut get_mod_infos(config, mod_ids, list.clone()).await?);
@@ -80,11 +84,17 @@ pub async fn mod_add(
80 let mut downloadstack: Vec<Version> = Vec::new(); 84 let mut downloadstack: Vec<Version> = Vec::new();
81 85
82 //Adding each mod to the lists and downloadstack 86 //Adding each mod to the lists and downloadstack
83 let project_p = mp.insert_before(&add_p, ProgressBar::new(projectinfo.len().try_into().unwrap())); 87 let project_p = mp.insert_before(
84 project_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 88 &add_p,
89 ProgressBar::new(projectinfo.len().try_into().unwrap()),
90 );
91 project_p.set_style(
92 ProgressStyle::with_template(STYLE_BAR_POS)
93 .unwrap()
94 .progress_chars(PROGRESS_CHARS),
95 );
85 96
86 for project in projectinfo { 97 for project in projectinfo {
87
88 project_p.set_message(format!("Add {}", project.title)); 98 project_p.set_message(format!("Add {}", project.title));
89 99
90 let current_version_id = if project.current_version.is_none() { 100 let current_version_id = if project.current_version.is_none() {
@@ -116,12 +126,7 @@ pub async fn mod_add(
116 Ok(..) => Ok(..), 126 Ok(..) => Ok(..),
117 }?; 127 }?;
118 128
119 match mods_insert( 129 match mods_insert(config, &project.mod_id, &project.slug, &project.title) {
120 config,
121 &project.mod_id,
122 &project.slug,
123 &project.title,
124 ) {
125 Err(e) => { 130 Err(e) => {
126 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" { 131 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" {
127 Ok(..) 132 Ok(..)
@@ -152,8 +157,11 @@ pub async fn mod_add(
152 Ok(()) 157 Ok(())
153} 158}
154 159
155async fn get_mod_infos(config: &Cfg, mod_ids: Vec<(String, bool)>, list: List) -> MLE<Vec<ProjectInfo>> { 160async fn get_mod_infos(
156 161 config: &Cfg,
162 mod_ids: Vec<(String, bool)>,
163 list: List,
164) -> MLE<Vec<ProjectInfo>> {
157 let mut setmap: HashMap<String, bool> = HashMap::new(); 165 let mut setmap: HashMap<String, bool> = HashMap::new();
158 166
159 let mut ids = vec![]; 167 let mut ids = vec![];
@@ -197,19 +205,15 @@ async fn get_mod_infos(config: &Cfg, mod_ids: Vec<(String, bool)>, list: List) -
197 .find(|v| v.id == current_id) 205 .find(|v| v.id == current_id)
198 .unwrap(), 206 .unwrap(),
199 ); 207 );
200 208
201 // match primary, if none? 209 // match primary, if none?
202 let files = current_version 210 let files = current_version.clone().ok_or("").unwrap().files;
203 .clone()
204 .ok_or("")
205 .unwrap()
206 .files;
207 211
208 file = match files.clone().into_iter().find(|f| f.primary) { 212 file = match files.clone().into_iter().find(|f| f.primary) {
209 Some(f) => f, 213 Some(f) => f,
210 None => { files[0].clone() } 214 None => files[0].clone(),
211 } 215 }
212 .url; 216 .url;
213 217
214 for ver in available_versions { 218 for ver in available_versions {
215 available_versions_vec.push(ver.id); 219 available_versions_vec.push(ver.id);
@@ -247,7 +251,6 @@ async fn get_mod_infos(config: &Cfg, mod_ids: Vec<(String, bool)>, list: List) -
247} 251}
248 252
249async fn get_ver_info(config: &Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<ProjectInfo>> { 253async fn get_ver_info(config: &Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<ProjectInfo>> {
250
251 let mut setmap: HashMap<String, bool> = HashMap::new(); 254 let mut setmap: HashMap<String, bool> = HashMap::new();
252 255
253 let mut ids = vec![]; 256 let mut ids = vec![];
@@ -271,15 +274,13 @@ async fn get_ver_info(config: &Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<Pro
271 for (i, project) in v_projects.into_iter().enumerate() { 274 for (i, project) in v_projects.into_iter().enumerate() {
272 let version = &v_versions[i]; 275 let version = &v_versions[i];
273 276
274 let files = version 277 let files = version.clone().files;
275 .clone()
276 .files;
277 278
278 let file = match files.clone().into_iter().find(|f| f.primary) { 279 let file = match files.clone().into_iter().find(|f| f.primary) {
279 Some(f) => f, 280 Some(f) => f,
280 None => { files[0].clone() } 281 None => files[0].clone(),
281 } 282 }
282 .url; 283 .url;
283 284
284 projectinfo.push(ProjectInfo { 285 projectinfo.push(ProjectInfo {
285 mod_id: String::from(&project.id), 286 mod_id: String::from(&project.id),
@@ -300,34 +301,31 @@ async fn get_ver_info(config: &Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<Pro
300/// * `config` - config struct 301/// * `config` - config struct
301/// * `id` - name, slug or id of the mod 302/// * `id` - name, slug or id of the mod
302/// * `list` - List struct 303/// * `list` - List struct
303pub fn mod_remove(config: &Cfg, id: &str, list: List) -> MLE<()> { 304pub fn mod_remove(config: &Cfg, id: &str, list: &List) -> MLE<()> {
305 let progress = ProgressBar::new_spinner();
306 progress.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
307
304 let mod_id = mods_get_id(&config.data, id)?; 308 let mod_id = mods_get_id(&config.data, id)?;
305 309
306 println!("Remove mod {} from {}", mods_get_info(config, &mod_id)?.title, list.id); 310 let info = mods_get_info(config, &mod_id)?;
311
312 progress.set_message(format!("Remove {} from {}", info.title, list.id));
313
307 let version = userlist_get_current_version(config, &list.id, &mod_id)?; 314 let version = userlist_get_current_version(config, &list.id, &mod_id)?;
308 315
309 print!(" └Remove from list");
310 //Force flush of stdout, else print! doesn't print instantly
311 std::io::stdout().flush()?;
312 userlist_remove(config, &list.id, &mod_id)?; 316 userlist_remove(config, &list.id, &mod_id)?;
313 println!(" ✓");
314 317
315 print!(" └Delete file"); 318 progress.set_message("Delete file");
316 //Force flush of stdout, else print! doesn't print instantly
317 std::io::stdout().flush()?;
318 match delete_version(list, version) { 319 match delete_version(list, version) {
319 Ok(_) => (), 320 Ok(_) => (),
320 Err(err) => { 321 Err(err) => {
321 if err.to_string() != "User input not accepted: VERSION_NOT_FOUND_IN_FILES" { 322 if err.to_string() != "User input not accepted: VERSION_NOT_FOUND_IN_FILES" {
322 return Err(err); 323 return Err(err);
323 }; 324 };
324 }, 325 }
325 }; 326 };
326 println!(" ✓");
327 327
328 print!(" └Clean main db table"); 328 progress.set_message("Check main list");
329 //Force flush of stdout, else print! doesn't print instantly
330 std::io::stdout().flush()?;
331 let list_ids = lists_get_all_ids(config)?; 329 let list_ids = lists_get_all_ids(config)?;
332 330
333 // Remove mod from main list if not used elsewhere 331 // Remove mod from main list if not used elsewhere
@@ -336,11 +334,11 @@ pub fn mod_remove(config: &Cfg, id: &str, list: List) -> MLE<()> {
336 let mods = match userlist_get_all_ids(config, &id) { 334 let mods = match userlist_get_all_ids(config, &id) {
337 Ok(m) => m, 335 Ok(m) => m,
338 Err(err) => { 336 Err(err) => {
339 if err.to_string() == "Database: NO_MODS_USERLIST" { 337 if err.to_string() == "Database: NO_MODS_USERLIST" {
340 println!(" ✓"); 338 println!(" ✓");
341 return Ok(()); 339 return Ok(());
342 }; 340 };
343 return Err(err) 341 return Err(err);
344 } 342 }
345 }; 343 };
346 if mods.contains(&mod_id) { 344 if mods.contains(&mod_id) {
@@ -350,9 +348,11 @@ pub fn mod_remove(config: &Cfg, id: &str, list: List) -> MLE<()> {
350 } 348 }
351 349
352 if !mod_used { 350 if !mod_used {
353 mods_remove(config, mod_id)?; 351 progress.set_message("Remove from main list");
352 mods_remove(config, &mod_id)?;
354 }; 353 };
355 println!(" ✓"); 354
355 progress.finish_with_message(format!("Removed {} from {}", info.title, list.id));
356 356
357 Ok(()) 357 Ok(())
358} 358}
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 194bbe5..3aae002 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -1,4 +1,4 @@
1use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; 1use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
2 2
3use crate::{ 3use crate::{
4 config::Cfg, 4 config::Cfg,
@@ -19,11 +19,14 @@ pub async fn update(
19 direct_download: bool, 19 direct_download: bool,
20 delete_old: bool, 20 delete_old: bool,
21) -> MLE<()> { 21) -> MLE<()> {
22
23 let mp = MultiProgress::new(); 22 let mp = MultiProgress::new();
24 23
25 let update_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); 24 let update_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap()));
26 update_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 25 update_p.set_style(
26 ProgressStyle::with_template(STYLE_BAR_POS)
27 .unwrap()
28 .progress_chars(PROGRESS_CHARS),
29 );
27 30
28 for current_list in liststack { 31 for current_list in liststack {
29 update_p.set_message(format!("Update {}", current_list.id)); 32 update_p.set_message(format!("Update {}", current_list.id));
@@ -35,7 +38,11 @@ pub async fn update(
35 let mods = userlist_get_all_ids(config, &current_list.id)?; 38 let mods = userlist_get_all_ids(config, &current_list.id)?;
36 39
37 let list_u_p = mp.insert_before(&list_p, ProgressBar::new(mods.len().try_into().unwrap())); 40 let list_u_p = mp.insert_before(&list_p, ProgressBar::new(mods.len().try_into().unwrap()));
38 list_u_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 41 list_u_p.set_style(
42 ProgressStyle::with_template(STYLE_BAR_POS)
43 .unwrap()
44 .progress_chars(PROGRESS_CHARS),
45 );
39 46
40 let mut current_versions: Vec<(String, String)> = vec![]; 47 let mut current_versions: Vec<(String, String)> = vec![];
41 let mut updatestack: Vec<Version> = vec![]; 48 let mut updatestack: Vec<Version> = vec![];
@@ -43,7 +50,7 @@ pub async fn update(
43 for id in mods { 50 for id in mods {
44 let info = mods_get_info(config, &id)?; 51 let info = mods_get_info(config, &id)?;
45 list_u_p.set_message(format!("Update {}", info.title)); 52 list_u_p.set_message(format!("Update {}", info.title));
46 53
47 //Skip check if version is set 54 //Skip check if version is set
48 if userlist_get_set_version(config, &current_list.id, &id)? { 55 if userlist_get_set_version(config, &current_list.id, &id)? {
49 list_u_p.inc(1); 56 list_u_p.inc(1);
@@ -51,19 +58,10 @@ pub async fn update(
51 } 58 }
52 59
53 //Getting current installed version for disable or delete 60 //Getting current installed version for disable or delete
54 let disable_version = 61 let disable_version = userlist_get_current_version(config, &current_list.id, &id)?;
55 userlist_get_current_version(config, &current_list.id, &id)?;
56 62
57 updatestack.push( 63 updatestack.push(
58 match specific_update( 64 match specific_update(config, clean, current_list.clone(), &id, &list_u_p).await {
59 config,
60 clean,
61 current_list.clone(),
62 &id,
63 &list_u_p
64 )
65 .await
66 {
67 Ok(ver) => { 65 Ok(ver) => {
68 current_versions.push((disable_version, id)); 66 current_versions.push((disable_version, id));
69 ver 67 ver
@@ -89,17 +87,31 @@ pub async fn update(
89 }; 87 };
90 88
91 if direct_download && !updatestack.is_empty() { 89 if direct_download && !updatestack.is_empty() {
92 download_versions(current_list.clone(), config.clone(), updatestack, &mp, &list_p).await?; 90 download_versions(
91 current_list.clone(),
92 config.clone(),
93 updatestack,
94 &mp,
95 &list_p,
96 )
97 .await?;
93 98
94 //Disable old versions 99 //Disable old versions
95 if !clean { 100 if !clean {
96 let d_p = mp.insert_before(&list_p, ProgressBar::new(current_versions.len().try_into().unwrap())); 101 let d_p = mp.insert_before(
97 d_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); 102 &list_p,
103 ProgressBar::new(current_versions.len().try_into().unwrap()),
104 );
105 d_p.set_style(
106 ProgressStyle::with_template(STYLE_BAR_POS)
107 .unwrap()
108 .progress_chars(PROGRESS_CHARS),
109 );
98 for ver in current_versions { 110 for ver in current_versions {
99 if delete_old { 111 if delete_old {
100 d_p.set_message(format!("Delete version {}", ver.0)); 112 d_p.set_message(format!("Delete version {}", ver.0));
101 d_p.inc(1); 113 d_p.inc(1);
102 delete_version(current_list.clone(), ver.0)?; 114 delete_version(&current_list, ver.0)?;
103 } else if ver.0 != "NONE" { 115 } else if ver.0 != "NONE" {
104 d_p.set_message(format!("Disable version {}", ver.0)); 116 d_p.set_message(format!("Disable version {}", ver.0));
105 d_p.inc(1); 117 d_p.inc(1);
@@ -125,9 +137,14 @@ pub async fn update(
125 Ok(()) 137 Ok(())
126} 138}
127 139
128async fn specific_update(config: &Cfg, clean: bool, list: List, id: &str, progress: &ProgressBar) -> MLE<Version> { 140async fn specific_update(
129 let applicable_versions = 141 config: &Cfg,
130 versions(&config.apis.modrinth, String::from(id), list.clone()).await; 142 clean: bool,
143 list: List,
144 id: &str,
145 progress: &ProgressBar,
146) -> MLE<Version> {
147 let applicable_versions = versions(&config.apis.modrinth, String::from(id), list.clone()).await;
131 148
132 let mut versions: Vec<String> = vec![]; 149 let mut versions: Vec<String> = vec![];
133 150
@@ -142,15 +159,16 @@ async fn specific_update(config: &Cfg, clean: bool, list: List, id: &str, progre
142 let mut current: Vec<Version> = vec![]; 159 let mut current: Vec<Version> = vec![];
143 if clean 160 if clean
144 || (versions.join("|") 161 || (versions.join("|")
145 != userlist_get_applicable_versions( 162 != userlist_get_applicable_versions(config, String::from(&list.id), String::from(id))?)
146 config,
147 String::from(&list.id),
148 String::from(id),
149 )?)
150 { 163 {
151 let current_str = extract_current_version(applicable_versions.clone())?; 164 let current_str = extract_current_version(applicable_versions.clone())?;
152 165
153 if !clean { progress.println(format!("Found new version for {}", mods_get_info(config, id).unwrap().title)); } 166 if !clean {
167 progress.println(format!(
168 "Found new version for {}",
169 mods_get_info(config, id).unwrap().title
170 ));
171 }
154 172
155 //get new versions 173 //get new versions
156 let current_ver = match applicable_versions 174 let current_ver = match applicable_versions
@@ -166,12 +184,19 @@ async fn specific_update(config: &Cfg, clean: bool, list: List, id: &str, progre
166 let files = &current_ver.files; 184 let files = &current_ver.files;
167 185
168 let link = match files.clone().into_iter().find(|f| f.primary) { 186 let link = match files.clone().into_iter().find(|f| f.primary) {
169 Some(f) => f, 187 Some(f) => f,
170 None => { files[0].clone() } 188 None => files[0].clone(),
171 } 189 }
172 .url; 190 .url;
173 191
174 userlist_change_versions(config, list.id, current_str, versions.join("|"), link, id.to_string())?; 192 userlist_change_versions(
193 config,
194 list.id,
195 current_str,
196 versions.join("|"),
197 link,
198 id.to_string(),
199 )?;
175 } 200 }
176 201
177 if current.is_empty() { 202 if current.is_empty() {