summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands/download.rs8
-rw-r--r--src/commands/modification.rs18
-rw-r--r--src/commands/update.rs123
-rw-r--r--src/config.rs35
-rw-r--r--src/db.rs17
-rw-r--r--src/files.rs22
-rw-r--r--src/lib.rs13
-rw-r--r--src/main.rs15
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
2use indicatif::MultiProgress;
3
2use crate::{config::Cfg, List}; 4use crate::{config::Cfg, List};
3use crate::{ 5use 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
12pub async fn download(config: &Cfg, liststack: Vec<List>, clean: bool, delete_old: bool) -> MLE<()> { 14pub 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(&current_list.id), 23 String::from(&current_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 @@
1use std::{io::Write, collections::HashMap}; 1use std::{io::Write, collections::HashMap};
2 2
3use indicatif::{ProgressBar, ProgressStyle}; 3use indicatif::{ProgressBar, ProgressStyle, MultiProgress};
4 4
5use crate::{ 5use 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)]
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, Clone, PartialEq, Eq)] 23#[derive(Debug, PartialEq, Eq)]
24pub enum IDSelector { 24pub 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
15pub async fn update( 15pub 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, &current_list.id)?; 35 let mods = userlist_get_all_ids(config, &current_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, &current_list.id, &id)? { 50 if userlist_get_set_version(config, &current_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, &current_list.id, &id)?; 57 userlist_get_current_version(config, &current_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(&current_list)?; 91 clean_list_dir(&current_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
7use indicatif::{ProgressBar, ProgressStyle};
7use serde::{Deserialize, Serialize}; 8use serde::{Deserialize, Serialize};
8 9
9use crate::{db::db_setup, error::MLE, Modloader, VersionLevel, check_game_versions}; 10use crate::{db::db_setup, error::MLE, Modloader, VersionLevel, check_game_versions};
@@ -79,9 +80,10 @@ impl Cfg {
79} 80}
80 81
81fn create_config(path: &str) -> MLE<()> { 82fn 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
109fn create_database(path: &str) -> MLE<()> { 111fn 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
120fn create_cache(path: &str) -> MLE<()> { 122fn 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
130async fn create_versions_dummy(path: &str) -> MLE<()> { 132async 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}
diff --git a/src/db.rs b/src/db.rs
index 3409298..22085a5 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -121,7 +121,7 @@ pub fn mods_get_info(config: &Cfg, id: &str) -> MLE<ModInfo> {
121} 121}
122 122
123pub fn mods_remove(config: &Cfg, id: String) -> MLE<()> { 123pub 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
20pub async fn download_versions(list: List, config: Cfg, versions: Vec<Version>) -> MLE<()> { 20pub 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
204pub fn clean_list_dir(list: &List) -> MLE<()> { 207pub 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())?;
diff --git a/src/lib.rs b/src/lib.rs
index 69cc650..a7a34ac 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,8 +12,13 @@ pub use apis::*;
12use apis::modrinth::{get_game_versions, GameVersion, GameVersionType}; 12use apis::modrinth::{get_game_versions, GameVersion, GameVersionType};
13pub use commands::*; 13pub use commands::*;
14use error::{ErrorType, MLError, MLE}; 14use error::{ErrorType, MLError, MLE};
15use indicatif::{ProgressStyle, ProgressBar};
15use serde::{Deserialize, Serialize}; 16use serde::{Deserialize, Serialize};
16 17
18pub static STYLE_BAR_POS: &str = "{spinner:.green}{wide_msg}{pos}/{len} [{bar:.green/lime}]";
19pub static STYLE_BAR_BYTE: &str = "{spinner:.green}{wide_msg}{bytes}/{total_bytes} [{bar:.green/lime}]";
20pub static STYLE_SPINNER: &str = "{spinner:.green}{wide_msg}";
21pub static STYLE_MESSAGE: &str = "{wide_msg}";
17pub static PROGRESS_CHARS: &str = "#>-"; 22pub 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
61pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> { 66pub 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 } => {