diff options
-rw-r--r-- | src/commands/download.rs | 8 | ||||
-rw-r--r-- | src/commands/modification.rs | 18 | ||||
-rw-r--r-- | src/commands/update.rs | 123 | ||||
-rw-r--r-- | src/config.rs | 35 | ||||
-rw-r--r-- | src/db.rs | 17 | ||||
-rw-r--r-- | src/files.rs | 22 | ||||
-rw-r--r-- | src/lib.rs | 13 | ||||
-rw-r--r-- | src/main.rs | 15 |
8 files changed, 109 insertions, 142 deletions
diff --git a/src/commands/download.rs b/src/commands/download.rs index fea3f34..e9a96b5 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | 1 | ||
2 | use indicatif::MultiProgress; | ||
3 | |||
2 | use crate::{config::Cfg, List}; | 4 | use crate::{config::Cfg, List}; |
3 | use crate::{ | 5 | use crate::{ |
4 | db::userlist_get_all_current_versions_with_mods, | 6 | db::userlist_get_all_current_versions_with_mods, |
@@ -10,10 +12,12 @@ use crate::{ | |||
10 | }; | 12 | }; |
11 | 13 | ||
12 | pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_old: bool) -> MLE<()> { | 14 | pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_old: bool) -> MLE<()> { |
15 | |||
16 | let mp = MultiProgress::new(); | ||
17 | |||
13 | for current_list in liststack { | 18 | for current_list in liststack { |
14 | println!("Downloading current versions of mods in {}", current_list.id); | 19 | println!("Downloading current versions of mods in {}", current_list.id); |
15 | let downloaded_versions = get_downloaded_versions(current_list.clone())?; | 20 | let downloaded_versions = get_downloaded_versions(current_list.clone())?; |
16 | // println!("To download: {:#?}", downloaded_versions); | ||
17 | let current_version_ids = match userlist_get_all_current_versions_with_mods( | 21 | let current_version_ids = match userlist_get_all_current_versions_with_mods( |
18 | config, | 22 | config, |
19 | String::from(¤t_list.id), | 23 | String::from(¤t_list.id), |
@@ -54,6 +58,8 @@ pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_ol | |||
54 | current_list.clone(), | 58 | current_list.clone(), |
55 | config.clone(), | 59 | config.clone(), |
56 | get_raw_versions(&config.apis.modrinth, to_download).await, | 60 | get_raw_versions(&config.apis.modrinth, to_download).await, |
61 | &mp, | ||
62 | None | ||
57 | ) | 63 | ) |
58 | .await?; | 64 | .await?; |
59 | } else { | 65 | } else { |
diff --git a/src/commands/modification.rs b/src/commands/modification.rs index 31931f8..d369c4b 100644 --- a/src/commands/modification.rs +++ b/src/commands/modification.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::{io::Write, collections::HashMap}; | 1 | use std::{io::Write, collections::HashMap}; |
2 | 2 | ||
3 | use indicatif::{ProgressBar, ProgressStyle}; | 3 | use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | config::Cfg, | 6 | config::Cfg, |
@@ -11,16 +11,16 @@ use crate::{ | |||
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, | 14 | List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_SPINNER, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #[derive(Debug, Clone)] | 17 | #[derive(Debug)] |
18 | pub struct AddMod { | 18 | pub 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, Clone, PartialEq, Eq)] | 23 | #[derive(Debug, PartialEq, Eq)] |
24 | pub enum IDSelector { | 24 | pub enum IDSelector { |
25 | ModificationID(String), | 25 | ModificationID(String), |
26 | VersionID(String), | 26 | VersionID(String), |
@@ -43,12 +43,11 @@ pub async fn mod_add( | |||
43 | list: List, | 43 | list: List, |
44 | direct_download: bool, | 44 | direct_download: bool, |
45 | ) -> MLE<()> { | 45 | ) -> MLE<()> { |
46 | let spinner_style = ProgressStyle::with_template("{spinner:.green}{msg}").unwrap(); | ||
47 | let bar_style = ProgressStyle::with_template("{spinner:.green}{wide_msg}{pos}/{len} [{bar:.green/lime}]").unwrap().progress_chars(PROGRESS_CHARS); | ||
48 | 46 | ||
49 | // println!("Add mods to {}", list.id); | 47 | //TODO MultiProgress |
50 | // println!(" └Add mods:"); | ||
51 | 48 | ||
49 | let spinner_style = ProgressStyle::with_template(STYLE_SPINNER).unwrap(); | ||
50 | let bar_style = ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS); | ||
52 | let mut mod_ids: Vec<(String, bool)> = Vec::new(); | 51 | let mut mod_ids: Vec<(String, bool)> = Vec::new(); |
53 | let mut ver_ids: Vec<(String, bool)> = Vec::new(); | 52 | let mut ver_ids: Vec<(String, bool)> = Vec::new(); |
54 | 53 | ||
@@ -153,7 +152,8 @@ pub async fn mod_add( | |||
153 | 152 | ||
154 | //Download all the added mods | 153 | //Download all the added mods |
155 | if direct_download { | 154 | if direct_download { |
156 | download_versions(list.clone(), config.clone(), downloadstack).await?; | 155 | let mp = MultiProgress::new(); |
156 | download_versions(list.clone(), config.clone(), downloadstack, &mp, None).await?; | ||
157 | }; | 157 | }; |
158 | 158 | ||
159 | Ok(()) | 159 | Ok(()) |
diff --git a/src/commands/update.rs b/src/commands/update.rs index 7482e43..bde6896 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs | |||
@@ -9,7 +9,7 @@ use crate::{ | |||
9 | error::{ErrorType, MLError, MLE}, | 9 | error::{ErrorType, MLError, MLE}, |
10 | files::{clean_list_dir, delete_version, disable_version, download_versions}, | 10 | files::{clean_list_dir, delete_version, disable_version, download_versions}, |
11 | modrinth::{extract_current_version, versions, Version}, | 11 | modrinth::{extract_current_version, versions, Version}, |
12 | List, PROGRESS_CHARS, | 12 | List, PROGRESS_CHARS, STYLE_BAR_POS, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub async fn update( | 15 | pub async fn update( |
@@ -23,35 +23,32 @@ pub async fn update( | |||
23 | let mp = MultiProgress::new(); | 23 | let mp = MultiProgress::new(); |
24 | 24 | ||
25 | let update_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); | 25 | let update_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); |
26 | let bar_style = ProgressStyle::with_template("{spinner:.green}{wide_msg}{pos}/{len} [{bar:.green/lime}]").unwrap().progress_chars(PROGRESS_CHARS); | 26 | let bar_style = ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS); |
27 | let spinner_style = ProgressStyle::with_template("{spinner:.green}{msg}").unwrap(); | ||
28 | update_p.set_style(bar_style.clone()); | 27 | update_p.set_style(bar_style.clone()); |
29 | update_p.set_message("Update"); | 28 | update_p.set_message("Update"); |
30 | 29 | ||
31 | for current_list in liststack { | 30 | for current_list in liststack { |
31 | let list_p = mp.insert_before(&update_p, ProgressBar::new(2)); | ||
32 | list_p.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); | ||
33 | list_p.set_message(format!("Update {}", current_list.id)); | ||
32 | 34 | ||
33 | // println!("Update mods in {}", current_list.id); | ||
34 | let mods = userlist_get_all_ids(config, ¤t_list.id)?; | 35 | let mods = userlist_get_all_ids(config, ¤t_list.id)?; |
35 | 36 | ||
36 | let list_p = mp.insert_before(&update_p, ProgressBar::new(mods.len().try_into().unwrap())); | 37 | let list_u_p = mp.insert_before(&list_p, ProgressBar::new(mods.len().try_into().unwrap())); |
37 | list_p.set_style(bar_style.clone()); | 38 | list_u_p.set_style(bar_style.clone()); |
38 | list_p.set_message(format!("Update {}", current_list.id)); | 39 | list_u_p.set_message(format!("Update {}", current_list.id)); |
39 | 40 | ||
40 | let mut current_versions: Vec<(String, String)> = vec![]; | 41 | let mut current_versions: Vec<(String, String)> = vec![]; |
41 | 42 | ||
42 | let mut updatestack: Vec<Version> = vec![]; | 43 | let mut updatestack: Vec<Version> = vec![]; |
43 | 44 | ||
44 | for id in mods { | 45 | for id in mods { |
45 | let mod_p = mp.insert_before(&list_p, ProgressBar::new(1)); | ||
46 | mod_p.set_style(spinner_style.clone()); | ||
47 | |||
48 | let info = mods_get_info(config, &id)?; | 46 | let info = mods_get_info(config, &id)?; |
49 | mod_p.set_message(format!("Update {}", info.title)); | 47 | list_u_p.set_message(format!("Update {}", info.title)); |
50 | // println!(" ├{}", info.title); | 48 | |
51 | 49 | //Skip check if version is set | |
52 | if userlist_get_set_version(config, ¤t_list.id, &id)? { | 50 | if userlist_get_set_version(config, ¤t_list.id, &id)? { |
53 | // println!(" │ └Set version, skipping update"); | 51 | list_u_p.inc(1); |
54 | list_p.inc(1); | ||
55 | continue; | 52 | continue; |
56 | } | 53 | } |
57 | 54 | ||
@@ -59,15 +56,13 @@ pub async fn update( | |||
59 | let disable_version = | 56 | let disable_version = |
60 | userlist_get_current_version(config, ¤t_list.id, &id)?; | 57 | userlist_get_current_version(config, ¤t_list.id, &id)?; |
61 | 58 | ||
62 | mod_p.inc(1); | ||
63 | |||
64 | updatestack.push( | 59 | updatestack.push( |
65 | match specific_update( | 60 | match specific_update( |
66 | config, | 61 | config, |
67 | clean, | 62 | clean, |
68 | current_list.clone(), | 63 | current_list.clone(), |
69 | &id, | 64 | &id, |
70 | &mod_p | 65 | &list_u_p |
71 | ) | 66 | ) |
72 | .await | 67 | .await |
73 | { | 68 | { |
@@ -77,44 +72,55 @@ pub async fn update( | |||
77 | } | 72 | } |
78 | Err(e) => { | 73 | Err(e) => { |
79 | if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { | 74 | if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { |
80 | // println!( | ||
81 | // " │ └No new version found for the specified minecraft version" | ||
82 | // ); | ||
83 | } else { | 75 | } else { |
84 | return Err(e); | 76 | return Err(e); |
85 | }; | 77 | }; |
86 | list_p.inc(1); | 78 | list_u_p.inc(1); |
87 | continue; | 79 | continue; |
88 | } | 80 | } |
89 | }, | 81 | }, |
90 | ); | 82 | ); |
91 | list_p.inc(1); | 83 | list_u_p.inc(1); |
92 | } | 84 | } |
93 | 85 | ||
94 | list_p.finish_with_message(format!("Updated {}", current_list.id)); | 86 | list_u_p.finish_with_message(format!("Updated mods in {}", current_list.id)); |
87 | list_p.inc(1); | ||
95 | 88 | ||
96 | if clean { | 89 | if clean { |
97 | update_p.set_message("Cleaning"); | 90 | list_p.set_message("Cleaning"); |
98 | update_p.inc(1); | ||
99 | clean_list_dir(¤t_list)?; | 91 | clean_list_dir(¤t_list)?; |
100 | }; | 92 | }; |
101 | 93 | ||
102 | if direct_download && !updatestack.is_empty() { | 94 | if direct_download && !updatestack.is_empty() { |
103 | download_versions(current_list.clone(), config.clone(), updatestack).await?; | 95 | download_versions(current_list.clone(), config.clone(), updatestack, &mp, Some(&list_p)).await?; |
104 | 96 | ||
105 | //Disable old versions | 97 | //Disable old versions |
106 | if !clean { | 98 | if !clean { |
99 | let d_p = mp.insert_before(&list_p, ProgressBar::new(current_versions.len().try_into().unwrap())); | ||
100 | d_p.set_style(bar_style.clone()); | ||
107 | for ver in current_versions { | 101 | for ver in current_versions { |
108 | if delete_old { | 102 | if delete_old { |
109 | println!(" └Delete version {}", ver.0); | 103 | d_p.set_message(format!("Delete version {}", ver.0)); |
104 | d_p.inc(1); | ||
110 | delete_version(current_list.clone(), ver.0)?; | 105 | delete_version(current_list.clone(), ver.0)?; |
111 | } else if ver.0 != "NONE" { | 106 | } else if ver.0 != "NONE" { |
112 | println!(" └Disable version {}", ver.0); | 107 | d_p.set_message(format!("Disable version {}", ver.0)); |
108 | d_p.inc(1); | ||
113 | disable_version(config, current_list.clone(), ver.0, ver.1)?; | 109 | disable_version(config, current_list.clone(), ver.0, ver.1)?; |
114 | }; | 110 | }; |
115 | } | 111 | } |
112 | |||
113 | let del_msg = if delete_old { | ||
114 | "Deleted all old versions" | ||
115 | } else { | ||
116 | "Disabled all old versions" | ||
117 | }; | ||
118 | |||
119 | d_p.finish_with_message(del_msg); | ||
116 | } | 120 | } |
117 | }; | 121 | }; |
122 | list_p.inc(1); | ||
123 | list_p.finish_with_message(format!("Updated {}", current_list.id)); | ||
118 | update_p.inc(1); | 124 | update_p.inc(1); |
119 | } | 125 | } |
120 | 126 | ||
@@ -149,13 +155,7 @@ async fn specific_update(config: &Cfg, clean: bool, list: List, id: &str, progre | |||
149 | { | 155 | { |
150 | let current_str = extract_current_version(applicable_versions.clone())?; | 156 | let current_str = extract_current_version(applicable_versions.clone())?; |
151 | 157 | ||
152 | if clean { | 158 | if !clean { progress.println(format!("Found new version for {}", mods_get_info(config, id).unwrap().title)); } |
153 | // println!("\t └Add version to downloadstack"); | ||
154 | } else { | ||
155 | progress.println(format!("Found new version for {}", mods_get_info(config, id).unwrap().title)); | ||
156 | // println!("\t └Get versions for specified minecraft versions"); | ||
157 | // println!("\t └New current version: {}", current_str); | ||
158 | }; | ||
159 | 159 | ||
160 | //get new versions | 160 | //get new versions |
161 | let current_ver = match applicable_versions | 161 | let current_ver = match applicable_versions |
@@ -183,56 +183,5 @@ async fn specific_update(config: &Cfg, clean: bool, list: List, id: &str, progre | |||
183 | return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE")); | 183 | return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE")); |
184 | }; | 184 | }; |
185 | 185 | ||
186 | //println!(" └✔️"); | ||
187 | Ok(current[0].clone()) | 186 | Ok(current[0].clone()) |
188 | } | 187 | } |
189 | |||
190 | // #[tokio::test] | ||
191 | // async fn download_updates_test() { | ||
192 | // use crate::{ | ||
193 | // modrinth::{Hash, Version, VersionFile, VersionType}, | ||
194 | // List, Modloader, | ||
195 | // }; | ||
196 | // | ||
197 | // let config = Cfg::init().unwrap(); | ||
198 | // let current_list = List { | ||
199 | // id: String::from("..."), | ||
200 | // mc_version: String::from("..."), | ||
201 | // modloader: Modloader::Fabric, | ||
202 | // download_folder: String::from("./dev/tests/dl"), | ||
203 | // }; | ||
204 | // | ||
205 | // let versions = vec![Version { | ||
206 | // id: "dEqtGnT9".to_string(), | ||
207 | // project_id: "kYuIpRLv".to_string(), | ||
208 | // author_id: "Qnt13hO8".to_string(), | ||
209 | // featured: true, | ||
210 | // name: "1.2.2-1.19 - Fabric".to_string(), | ||
211 | // version_number: "1.2.2-1.19".to_string(), | ||
212 | // changelog: None, | ||
213 | // date_published: "2022-11-02T17:41:43.072267Z".to_string(), | ||
214 | // downloads: 58, | ||
215 | // version_type: VersionType::release, | ||
216 | // files: vec![VersionFile { | ||
217 | // hashes: Hash { | ||
218 | // sha1: "fdc6dc39427fc92cc1d7ad8b275b5b83325e712b".to_string(), | ||
219 | // sha512: "5b372f00d6e5d6a5ef225c3897826b9f6a2be5506905f7f71b9e939779765b41be6f2a9b029cfc752ad0751d0d2d5f8bb4544408df1363eebdde15641e99a849".to_string() | ||
220 | // }, | ||
221 | // url: "https://cdn.modrinth.com/data/kYuIpRLv/versions/dEqtGnT9/waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), | ||
222 | // filename: "waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), | ||
223 | // primary: true, | ||
224 | // size: 323176 | ||
225 | // }], | ||
226 | // game_versions: vec![ | ||
227 | // "1.19".to_string(), | ||
228 | // "1.19.1".to_string(), | ||
229 | // "1.19.2".to_string() | ||
230 | // ], | ||
231 | // loaders: vec![ | ||
232 | // "fabric".to_string() | ||
233 | // ] | ||
234 | // }]; | ||
235 | // assert!(download_versions(current_list, config, versions) | ||
236 | // .await | ||
237 | // .is_ok()) | ||
238 | // } | ||
diff --git a/src/config.rs b/src/config.rs index a952d40..54cf768 100644 --- a/src/config.rs +++ b/src/config.rs | |||
@@ -4,6 +4,7 @@ use std::{ | |||
4 | path::Path, | 4 | path::Path, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use indicatif::{ProgressBar, ProgressStyle}; | ||
7 | use serde::{Deserialize, Serialize}; | 8 | use serde::{Deserialize, Serialize}; |
8 | 9 | ||
9 | use crate::{db::db_setup, error::MLE, Modloader, VersionLevel, check_game_versions}; | 10 | use crate::{db::db_setup, error::MLE, Modloader, VersionLevel, check_game_versions}; |
@@ -79,9 +80,10 @@ impl Cfg { | |||
79 | } | 80 | } |
80 | 81 | ||
81 | fn create_config(path: &str) -> MLE<()> { | 82 | fn create_config(path: &str) -> MLE<()> { |
82 | print!("No config file found, create default"); | 83 | let p = ProgressBar::new(1); |
83 | //Force flush of stdout, else print! doesn't print instantly | 84 | p.set_style(ProgressStyle::with_template("{wide_msg}").unwrap()); |
84 | std::io::stdout().flush()?; | 85 | p.set_message("Create default config"); |
86 | |||
85 | let cache_dir = dirs::cache_dir() | 87 | let cache_dir = dirs::cache_dir() |
86 | .unwrap() | 88 | .unwrap() |
87 | .join("modlist") | 89 | .join("modlist") |
@@ -102,37 +104,36 @@ fn create_config(path: &str) -> MLE<()> { | |||
102 | create_dir_all(path.split("config.toml").collect::<Vec<&str>>()[0])?; | 104 | create_dir_all(path.split("config.toml").collect::<Vec<&str>>()[0])?; |
103 | let mut file = File::create(path)?; | 105 | let mut file = File::create(path)?; |
104 | file.write_all(toml::to_string(&default_cfg)?.as_bytes())?; | 106 | file.write_all(toml::to_string(&default_cfg)?.as_bytes())?; |
105 | println!(" ✓"); | 107 | p.finish_with_message(format!("Created default config ({})", path)); |
106 | Ok(()) | 108 | Ok(()) |
107 | } | 109 | } |
108 | 110 | ||
109 | fn create_database(path: &str) -> MLE<()> { | 111 | fn create_database(path: &str) -> MLE<()> { |
110 | print!("No database found, create base"); | 112 | let p = ProgressBar::new(1); |
111 | //Force flush of stdout, else print! doesn't print instantly | 113 | p.set_style(ProgressStyle::with_template("{wide_msg}").unwrap()); |
112 | std::io::stdout().flush()?; | 114 | p.set_message("Create database"); |
113 | 115 | ||
114 | File::create(path)?; | 116 | File::create(path)?; |
115 | db_setup(path)?; | 117 | db_setup(path)?; |
116 | println!(" ✓"); | 118 | p.finish_with_message(format!("Created database ({})", path)); |
117 | Ok(()) | 119 | Ok(()) |
118 | } | 120 | } |
119 | 121 | ||
120 | fn create_cache(path: &str) -> MLE<()> { | 122 | fn create_cache(path: &str) -> MLE<()> { |
121 | print!("No cache direcory found, create one"); | 123 | let p = ProgressBar::new(1); |
122 | //Force flush of stdout, else print! doesn't print instantly | 124 | p.set_style(ProgressStyle::with_template("{wide_msg}").unwrap()); |
123 | std::io::stdout().flush()?; | 125 | p.set_message("Create cache"); |
124 | 126 | ||
125 | create_dir_all(path)?; | 127 | create_dir_all(path)?; |
126 | println!(" ✓"); | 128 | p.finish_with_message(format!("Created cache ({})", path)); |
127 | Ok(()) | 129 | Ok(()) |
128 | } | 130 | } |
129 | 131 | ||
130 | async fn create_versions_dummy(path: &str) -> MLE<()> { | 132 | async fn create_versions_dummy(path: &str) -> MLE<()> { |
131 | print!("No version file found, create dummy"); | 133 | let p = ProgressBar::new(1); |
132 | //Force flush of stdout, else print! doesn't print instantly | 134 | p.set_style(ProgressStyle::with_template("{wide_msg}").unwrap()); |
133 | std::io::stdout().flush()?; | 135 | p.set_message("Create version file"); |
134 | |||
135 | File::create(path)?; | 136 | File::create(path)?; |
136 | println!(" ✓"); | 137 | p.finish_with_message(format!("Created version file ({})", path)); |
137 | Ok(()) | 138 | Ok(()) |
138 | } | 139 | } |
@@ -121,7 +121,7 @@ pub fn mods_get_info(config: &Cfg, id: &str) -> MLE<ModInfo> { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | pub fn mods_remove(config: &Cfg, id: String) -> MLE<()> { | 123 | pub fn mods_remove(config: &Cfg, id: String) -> MLE<()> { |
124 | println!("Removing mod {} from database", id); | 124 | // println!("Removing mod {} from database", id); |
125 | 125 | ||
126 | let data = format!("{}/data.db", config.data); | 126 | let data = format!("{}/data.db", config.data); |
127 | let connection = Connection::open(data)?; | 127 | let connection = Connection::open(data)?; |
@@ -167,10 +167,10 @@ pub fn mods_get_versions(config: &Cfg, mods: Vec<String>) -> MLE<Vec<DBModlistVe | |||
167 | 167 | ||
168 | for ver in id_iter { | 168 | for ver in id_iter { |
169 | let version = ver?; | 169 | let version = ver?; |
170 | println!( | 170 | // println!( |
171 | "\t({}) Get versions from the database", | 171 | // "\t({}) Get versions from the database", |
172 | String::from(&version[2]) | 172 | // String::from(&version[2]) |
173 | ); | 173 | // ); |
174 | //println!("Found versions {} for mod {}", version[1], version[0]); | 174 | //println!("Found versions {} for mod {}", version[1], version[0]); |
175 | versionmaps.push(DBModlistVersions { | 175 | versionmaps.push(DBModlistVersions { |
176 | mod_id: String::from(&version[0]), | 176 | mod_id: String::from(&version[0]), |
@@ -229,12 +229,11 @@ pub fn userlist_get_all_ids(config: &Cfg, list_id: &str) -> MLE<Vec<String>> { | |||
229 | let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; | 229 | let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; |
230 | 230 | ||
231 | for id in id_iter { | 231 | for id in id_iter { |
232 | //println!("Found id {:?}", id.as_ref().unwrap()); | ||
233 | mod_ids.push(id?) | 232 | mod_ids.push(id?) |
234 | } | 233 | } |
235 | 234 | ||
236 | match mod_ids.is_empty() { | 235 | match mod_ids.is_empty() { |
237 | true => Err(MLError::new(ErrorType::DBError, "NO_MODS_USERLIST")), | 236 | true => Err(MLError::new(ErrorType::DBError, &format!("NO_MODS_USERLIST{}", list_id))), |
238 | false => Ok(mod_ids), | 237 | false => Ok(mod_ids), |
239 | } | 238 | } |
240 | } | 239 | } |
@@ -475,7 +474,7 @@ pub fn userlist_get_all_downloads( | |||
475 | 474 | ||
476 | for link in link_iter { | 475 | for link in link_iter { |
477 | let l = link?; | 476 | let l = link?; |
478 | println!("Found link {}", String::from(&l)); | 477 | // println!("Found link {}", String::from(&l)); |
479 | links.push(l) | 478 | links.push(l) |
480 | } | 479 | } |
481 | 480 | ||
@@ -498,7 +497,7 @@ pub fn lists_insert( | |||
498 | mod_loader: &Modloader, | 497 | mod_loader: &Modloader, |
499 | download_folder: &str, | 498 | download_folder: &str, |
500 | ) -> MLE<()> { | 499 | ) -> MLE<()> { |
501 | println!("Creating list {}", id); | 500 | // println!("Creating list {}", id); |
502 | 501 | ||
503 | let data = format!("{}/data.db", config.data); | 502 | let data = format!("{}/data.db", config.data); |
504 | let connection = Connection::open(data)?; | 503 | let connection = Connection::open(data)?; |
diff --git a/src/files.rs b/src/files.rs index 565d2b6..2830a5f 100644 --- a/src/files.rs +++ b/src/files.rs | |||
@@ -14,24 +14,27 @@ use crate::{ | |||
14 | db::{mods_get_info, userlist_add_disabled_versions}, | 14 | db::{mods_get_info, userlist_add_disabled_versions}, |
15 | error::{ErrorType, MLError, MLE}, | 15 | error::{ErrorType, MLError, MLE}, |
16 | modrinth::Version, | 16 | modrinth::Version, |
17 | List, PROGRESS_CHARS, | 17 | List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_SPINNER, STYLE_BAR_BYTE, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | pub async fn download_versions(list: List, config: Cfg, versions: Vec<Version>) -> MLE<()> { | 20 | pub async fn download_versions(list: List, config: Cfg, versions: Vec<Version>, progress: &MultiProgress, progress_before: Option<&ProgressBar>) -> MLE<()> { |
21 | let cached = get_cached_versions(&config.cache); | 21 | let cached = get_cached_versions(&config.cache); |
22 | 22 | ||
23 | let mp = MultiProgress::new(); | ||
24 | |||
25 | let mut js = JoinSet::new(); | 23 | let mut js = JoinSet::new(); |
26 | 24 | ||
27 | let style_spinner = ProgressStyle::with_template("{spinner:.green}{wide_msg}").unwrap(); | 25 | let style_spinner = ProgressStyle::with_template(STYLE_SPINNER).unwrap(); |
26 | |||
27 | let all = match progress_before { | ||
28 | Some(p) => progress.insert_before(p, ProgressBar::new(versions.len().try_into().unwrap())), | ||
29 | None => progress.add(ProgressBar::new(versions.len().try_into().unwrap())), | ||
28 | 30 | ||
29 | let all = mp.add(ProgressBar::new(versions.len().try_into().unwrap())); | 31 | |
30 | all.set_style(ProgressStyle::with_template("{wide_msg}{pos}/{len} [{bar:.green/lime}]").unwrap().progress_chars(PROGRESS_CHARS)); | 32 | }; |
33 | all.set_style(ProgressStyle::with_template(STYLE_BAR_POS).unwrap().progress_chars(PROGRESS_CHARS)); | ||
31 | all.set_message("Downloading"); | 34 | all.set_message("Downloading"); |
32 | 35 | ||
33 | for ver in versions { | 36 | for ver in versions { |
34 | let p = mp.insert_before(&all, ProgressBar::new(1)); | 37 | let p = progress.insert_before(&all, ProgressBar::new(1)); |
35 | p.set_style(style_spinner.clone()); | 38 | p.set_style(style_spinner.clone()); |
36 | js.spawn(download_version(config.clone(), list.clone(), ver, cached.clone(), p)); | 39 | js.spawn(download_version(config.clone(), list.clone(), ver, cached.clone(), p)); |
37 | // std::thread::sleep(std::time::Duration::from_millis(200)); | 40 | // std::thread::sleep(std::time::Duration::from_millis(200)); |
@@ -103,7 +106,7 @@ async fn download_file(url: &str, path: &str, name: &str, progress: &ProgressBar | |||
103 | 106 | ||
104 | let size = res.content_length().expect("Couldn't get content length"); | 107 | let size = res.content_length().expect("Couldn't get content length"); |
105 | 108 | ||
106 | let style_bar_byte = ProgressStyle::with_template("{spinner:.green}{wide_msg}{bytes}/{total_bytes} [{bar:.green/lime}]") | 109 | let style_bar_byte = ProgressStyle::with_template(STYLE_BAR_BYTE) |
107 | .unwrap() | 110 | .unwrap() |
108 | .progress_chars(PROGRESS_CHARS); | 111 | .progress_chars(PROGRESS_CHARS); |
109 | 112 | ||
@@ -203,7 +206,6 @@ pub fn get_downloaded_versions(list: List) -> MLE<HashMap<String, String>> { | |||
203 | 206 | ||
204 | pub fn clean_list_dir(list: &List) -> MLE<()> { | 207 | pub fn clean_list_dir(list: &List) -> MLE<()> { |
205 | let dl_path = &list.download_folder; | 208 | let dl_path = &list.download_folder; |
206 | println!(" └Clean directory for: {}", list.id); | ||
207 | for entry in std::fs::read_dir(dl_path)? { | 209 | for entry in std::fs::read_dir(dl_path)? { |
208 | let entry = entry?; | 210 | let entry = entry?; |
209 | std::fs::remove_file(entry.path())?; | 211 | std::fs::remove_file(entry.path())?; |
@@ -12,8 +12,13 @@ pub use apis::*; | |||
12 | use apis::modrinth::{get_game_versions, GameVersion, GameVersionType}; | 12 | use apis::modrinth::{get_game_versions, GameVersion, GameVersionType}; |
13 | pub use commands::*; | 13 | pub use commands::*; |
14 | use error::{ErrorType, MLError, MLE}; | 14 | use error::{ErrorType, MLError, MLE}; |
15 | use indicatif::{ProgressStyle, ProgressBar}; | ||
15 | use serde::{Deserialize, Serialize}; | 16 | use serde::{Deserialize, Serialize}; |
16 | 17 | ||
18 | pub static STYLE_BAR_POS: &str = "{spinner:.green}{wide_msg}{pos}/{len} [{bar:.green/lime}]"; | ||
19 | pub static STYLE_BAR_BYTE: &str = "{spinner:.green}{wide_msg}{bytes}/{total_bytes} [{bar:.green/lime}]"; | ||
20 | pub static STYLE_SPINNER: &str = "{spinner:.green}{wide_msg}"; | ||
21 | pub static STYLE_MESSAGE: &str = "{wide_msg}"; | ||
17 | pub static PROGRESS_CHARS: &str = "#>-"; | 22 | pub static PROGRESS_CHARS: &str = "#>-"; |
18 | 23 | ||
19 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] | 24 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] |
@@ -59,15 +64,19 @@ pub enum VersionLevel { | |||
59 | /// Checks if update needed (time) | 64 | /// Checks if update needed (time) |
60 | /// if yes: get versions, update | 65 | /// if yes: get versions, update |
61 | pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> { | 66 | pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> { |
67 | let p = ProgressBar::new(1); | ||
68 | p.set_style(ProgressStyle::with_template(STYLE_MESSAGE).unwrap()); | ||
69 | p.set_message("Update minecraft versions"); | ||
70 | |||
62 | let creation_time = fs::metadata(path)?.created()?; | 71 | let creation_time = fs::metadata(path)?.created()?; |
63 | if !force && creation_time.elapsed().unwrap() < Duration::from_secs(60 * 60 * 24) { return Ok(()); } | 72 | if !force && creation_time.elapsed().unwrap() < Duration::from_secs(60 * 60 * 24) { return Ok(()); } |
64 | print!("Update minecraft versions"); | ||
65 | std::io::stdout().flush()?; | 73 | std::io::stdout().flush()?; |
66 | let versions = get_game_versions().await; | 74 | let versions = get_game_versions().await; |
67 | remove_file(path)?; | 75 | remove_file(path)?; |
68 | let mut file = File::create(path)?; | 76 | let mut file = File::create(path)?; |
69 | file.write_all(serde_json::to_string_pretty(&versions)?.as_bytes())?; | 77 | file.write_all(serde_json::to_string_pretty(&versions)?.as_bytes())?; |
70 | println!(" ✓"); | 78 | |
79 | p.finish_with_message("Updated minecraft versions"); | ||
71 | Ok(()) | 80 | Ok(()) |
72 | } | 81 | } |
73 | 82 | ||
diff --git a/src/main.rs b/src/main.rs index 0e040b6..7e00368 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -15,10 +15,6 @@ struct Cli { | |||
15 | /// config file path | 15 | /// config file path |
16 | #[arg(short, long)] | 16 | #[arg(short, long)] |
17 | config: Option<String>, | 17 | config: Option<String>, |
18 | |||
19 | /// Force GameVersion update | ||
20 | #[arg(long)] | ||
21 | force_gameupdate: bool, | ||
22 | } | 18 | } |
23 | 19 | ||
24 | #[derive(Subcommand)] | 20 | #[derive(Subcommand)] |
@@ -30,6 +26,10 @@ enum Commands { | |||
30 | List { | 26 | List { |
31 | #[command(subcommand)] | 27 | #[command(subcommand)] |
32 | command: ListCommands, | 28 | command: ListCommands, |
29 | |||
30 | /// Force GameVersion update | ||
31 | #[arg(long)] | ||
32 | force_gameupdate: bool, | ||
33 | }, | 33 | }, |
34 | Download { | 34 | Download { |
35 | /// download all lists | 35 | /// download all lists |
@@ -200,7 +200,7 @@ async fn main() { | |||
200 | } | 200 | } |
201 | } | 201 | } |
202 | } | 202 | } |
203 | Commands::List { command } => { | 203 | Commands::List { command, force_gameupdate } => { |
204 | match command { | 204 | match command { |
205 | ListCommands::Add { | 205 | ListCommands::Add { |
206 | id, | 206 | id, |
@@ -215,8 +215,8 @@ async fn main() { | |||
215 | 215 | ||
216 | let versions_path = &config.versions; | 216 | let versions_path = &config.versions; |
217 | let ver = match version { | 217 | let ver = match version { |
218 | Some(ver) => VersionLevel::from(&ver).get(versions_path, cli.force_gameupdate).await.unwrap(), | 218 | Some(ver) => VersionLevel::from(&ver).get(versions_path, force_gameupdate).await.unwrap(), |
219 | None => config.defaults.version.clone().get(versions_path, cli.force_gameupdate).await.unwrap(), | 219 | None => config.defaults.version.clone().get(versions_path, force_gameupdate).await.unwrap(), |
220 | }; | 220 | }; |
221 | 221 | ||
222 | list_add(&config, &id, &ver, &ml, &directory) | 222 | list_add(&config, &id, &ver, &ml, &directory) |
@@ -254,6 +254,7 @@ async fn main() { | |||
254 | }; | 254 | }; |
255 | liststack.push(current) | 255 | liststack.push(current) |
256 | } | 256 | } |
257 | |||
257 | update(&config, liststack, clean, download, remove).await | 258 | update(&config, liststack, clean, download, remove).await |
258 | } | 259 | } |
259 | Commands::Download { all, clean, remove, list } => { | 260 | Commands::Download { all, clean, remove, list } => { |