summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands/io.rs41
-rw-r--r--src/commands/list.rs17
-rw-r--r--src/commands/modification.rs68
-rw-r--r--src/commands/update.rs10
-rw-r--r--src/db.rs10
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs9
7 files changed, 106 insertions, 50 deletions
diff --git a/src/commands/io.rs b/src/commands/io.rs
index e072f00..dd294bc 100644
--- a/src/commands/io.rs
+++ b/src/commands/io.rs
@@ -4,9 +4,9 @@ use std::io::prelude::*;
4 4
5use crate::{ 5use crate::{
6 config::Cfg, 6 config::Cfg,
7 db::{lists_get, lists_get_all_ids, lists_insert, userlist_get_all_ids}, 7 db::{lists_get, lists_get_all_ids, lists_insert, userlist_get_set_version, userlist_get_all_ids, userlist_get_current_version},
8 error::MLE, 8 error::MLE,
9 mod_add, IDSelector, List, Modloader, 9 mod_add, IDSelector, List, Modloader, AddMod,
10}; 10};
11 11
12#[derive(Debug, Serialize, Deserialize)] 12#[derive(Debug, Serialize, Deserialize)]
@@ -15,9 +15,24 @@ struct Export {
15} 15}
16 16
17#[derive(Debug, Serialize, Deserialize)] 17#[derive(Debug, Serialize, Deserialize)]
18struct ExportVersion {
19 version: String,
20 set: bool
21}
22
23impl ExportVersion {
24 fn from(config: Cfg, list_id: &str, mod_id: &str) -> MLE<Self> {
25 Ok(Self {
26 version: userlist_get_current_version(config.clone(), list_id, mod_id)?,
27 set: userlist_get_set_version(config.clone(), list_id, mod_id)?
28 })
29 }
30}
31
32#[derive(Debug, Serialize, Deserialize)]
18struct ExportList { 33struct ExportList {
19 id: String, 34 id: String,
20 mods: String, 35 versions: Vec<ExportVersion>,
21 launcher: String, 36 launcher: String,
22 mc_version: String, 37 mc_version: String,
23 download_folder: Option<String>, 38 download_folder: Option<String>,
@@ -32,11 +47,15 @@ impl ExportList {
32 dl_folder = Some(list.download_folder) 47 dl_folder = Some(list.download_folder)
33 }; 48 };
34 49
35 let mods = userlist_get_all_ids(config, list_id)?.join("|"); 50 let mods = userlist_get_all_ids(config.clone(), &list_id)?;
51 let mut versions = vec![];
52 for m in mods {
53 versions.push(ExportVersion::from(config.clone(), &list_id, &m)?)
54 }
36 55
37 Ok(Self { 56 Ok(Self {
38 id: list.id, 57 id: list.id,
39 mods, 58 versions,
40 launcher: list.modloader.to_string(), 59 launcher: list.modloader.to_string(),
41 mc_version: list.mc_version, 60 mc_version: list.mc_version,
42 download_folder: dl_folder, 61 download_folder: dl_folder,
@@ -86,14 +105,12 @@ pub async fn import(config: Cfg, file_str: String, direct_download: bool) -> MLE
86 list.modloader.clone(), 105 list.modloader.clone(),
87 String::from(&list.download_folder), 106 String::from(&list.download_folder),
88 )?; 107 )?;
89 let mods: Vec<&str> = exportlist.mods.split('|').collect(); 108
90 let mut mod_ids = vec![]; 109 let mut ver_ids = vec![];
91 for mod_id in mods { 110 for id in exportlist.versions {
92 mod_ids.push(IDSelector::ModificationID(String::from(mod_id))); 111 ver_ids.push(AddMod { id: IDSelector::VersionID(id.version), set_version: id.set} );
93 } 112 }
94 //TODO impl set_version and good direct download 113 mod_add(config.clone(), ver_ids, list, direct_download).await?;
95 //TODO impl all at once, dafuck ?done?
96 mod_add(config.clone(), mod_ids, list, direct_download, false).await?;
97 } 114 }
98 Ok(()) 115 Ok(())
99} 116}
diff --git a/src/commands/list.rs b/src/commands/list.rs
index 13176f4..4aa4306 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -2,9 +2,9 @@ use crate::{
2 config::Cfg, 2 config::Cfg,
3 db::{ 3 db::{
4 config_change_current_list, config_get_current_list, lists_get, lists_insert, lists_remove, 4 config_change_current_list, config_get_current_list, lists_get, lists_insert, lists_remove,
5 lists_version, 5 lists_version, lists_get_all_ids,
6 }, 6 },
7 error::MLE, 7 error::{MLE, MLError, ErrorType},
8 update, Modloader, 8 update, Modloader,
9}; 9};
10 10
@@ -32,7 +32,9 @@ pub fn list_add(
32} 32}
33 33
34pub fn list_change(config: Cfg, id: String) -> MLE<()> { 34pub fn list_change(config: Cfg, id: String) -> MLE<()> {
35 //TODO check if list exists 35 if lists_get_all_ids(config.clone())?.into_iter().find(|l| l == &id).is_none() {
36 return Err(MLError::new(ErrorType::ArgumentError, "List not found"));
37 };
36 println!("Change default list to: {}", id); 38 println!("Change default list to: {}", id);
37 config_change_current_list(config, id) 39 config_change_current_list(config, id)
38} 40}
@@ -68,3 +70,12 @@ pub async fn list_version(
68 let list = lists_get(config.clone(), id)?; 70 let list = lists_get(config.clone(), id)?;
69 update(config, vec![list], true, download, delete).await 71 update(config, vec![list], true, download, delete).await
70} 72}
73
74pub fn list_list(config: Cfg) -> MLE<()> {
75 let lists = lists_get_all_ids(config.clone())?;
76 for list in lists {
77 let l = lists_get(config.clone(), list)?;
78 println!("{}: | {} | {}", l.id, l.mc_version, l.modloader)
79 }
80 Ok(())
81}
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 216a06e..9a1a651 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,4 +1,4 @@
1use std::io::Write; 1use std::{io::Write, collections::HashMap};
2 2
3use crate::{ 3use crate::{
4 config::Cfg, 4 config::Cfg,
@@ -12,6 +12,12 @@ use crate::{
12 List, 12 List,
13}; 13};
14 14
15#[derive(Debug, Clone)]
16pub struct AddMod {
17 pub id: IDSelector,
18 pub set_version: bool
19}
20
15#[derive(Debug, Clone, PartialEq, Eq)] 21#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum IDSelector { 22pub enum IDSelector {
17 ModificationID(String), 23 ModificationID(String),
@@ -26,26 +32,26 @@ pub struct ProjectInfo {
26 pub current_version: Option<Version>, 32 pub current_version: Option<Version>,
27 pub applicable_versions: Vec<String>, 33 pub applicable_versions: Vec<String>,
28 pub download_link: String, 34 pub download_link: String,
35 pub set_version: bool,
29} 36}
30 37
31pub async fn mod_add( 38pub async fn mod_add(
32 config: Cfg, 39 config: Cfg,
33 ids: Vec<IDSelector>, 40 mods: Vec<AddMod>,
34 list: List, 41 list: List,
35 direct_download: bool, 42 direct_download: bool,
36 set_version: bool,
37) -> MLE<()> { 43) -> MLE<()> {
38 println!("Add mods to {}", list.id); 44 println!("Add mods to {}", list.id);
39 println!(" └Add mods:"); 45 println!(" └Add mods:");
40 46
41 let mut mod_ids: Vec<String> = Vec::new(); 47 let mut mod_ids: Vec<(String, bool)> = Vec::new();
42 let mut ver_ids: Vec<String> = Vec::new(); 48 let mut ver_ids: Vec<(String, bool)> = Vec::new();
43 49
44 //"Sort" project ids from version ids to be able to handle them differently but in a batch 50 //"Sort" project ids from version ids to be able to handle them differently but in a batch
45 for id in ids { 51 for m in mods {
46 match id { 52 match m.id {
47 IDSelector::ModificationID(pid) => mod_ids.push(pid), 53 IDSelector::ModificationID(pid) => mod_ids.push((pid, m.set_version)),
48 IDSelector::VersionID(vid) => ver_ids.push(vid), 54 IDSelector::VersionID(vid) => ver_ids.push((vid, m.set_version)),
49 } 55 }
50 } 56 }
51 57
@@ -83,7 +89,7 @@ pub async fn mod_add(
83 &current_version_id, 89 &current_version_id,
84 project.clone().applicable_versions, 90 project.clone().applicable_versions,
85 &project.download_link, 91 &project.download_link,
86 set_version, 92 project.set_version,
87 ) { 93 ) {
88 Err(e) => { 94 Err(e) => {
89 let expected_err = format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id); 95 let expected_err = format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id);
@@ -128,13 +134,23 @@ pub async fn mod_add(
128 Ok(()) 134 Ok(())
129} 135}
130 136
131async fn get_mod_infos(config: Cfg, mod_ids: Vec<String>, list: List) -> MLE<Vec<ProjectInfo>> { 137async fn get_mod_infos(config: Cfg, mod_ids: Vec<(String, bool)>, list: List) -> MLE<Vec<ProjectInfo>> {
138
139 let mut setmap: HashMap<String, bool> = HashMap::new();
140
141 let mut ids = vec![];
142
143 for id in mod_ids {
144 setmap.insert(id.0.to_string(), id.1);
145 ids.push(id.0);
146 }
147
132 let mut projectinfo: Vec<ProjectInfo> = Vec::new(); 148 let mut projectinfo: Vec<ProjectInfo> = Vec::new();
133 149
134 //Get required information from mod_ids 150 //Get required information from mod_ids
135 let m_projects = match mod_ids.len() { 151 let m_projects = match ids.len() {
136 1 => vec![project(&config.apis.modrinth, &mod_ids[0]).await], 152 1 => vec![project(&config.apis.modrinth, &ids[0]).await],
137 2.. => projects(&config.apis.modrinth, mod_ids).await, 153 2.. => projects(&config.apis.modrinth, ids).await,
138 _ => panic!("PANIC"), 154 _ => panic!("PANIC"),
139 }; 155 };
140 for project in m_projects { 156 for project in m_projects {
@@ -180,12 +196,13 @@ async fn get_mod_infos(config: Cfg, mod_ids: Vec<String>, list: List) -> MLE<Vec
180 } 196 }
181 197
182 projectinfo.push(ProjectInfo { 198 projectinfo.push(ProjectInfo {
183 mod_id: project.id, 199 mod_id: String::from(&project.id),
184 slug: project.slug, 200 slug: project.slug,
185 title: project.title, 201 title: project.title,
186 current_version, 202 current_version,
187 applicable_versions: available_versions_vec, 203 applicable_versions: available_versions_vec,
188 download_link: file, 204 download_link: file,
205 set_version: setmap.get(&project.id).unwrap().clone(),
189 }) 206 })
190 } else { 207 } else {
191 println!("\t └There's currently no mod version for your specified target"); 208 println!("\t └There's currently no mod version for your specified target");
@@ -193,12 +210,13 @@ async fn get_mod_infos(config: Cfg, mod_ids: Vec<String>, list: List) -> MLE<Vec
193 file = String::from("NONE"); 210 file = String::from("NONE");
194 available_versions_vec.push(String::from("NONE")); 211 available_versions_vec.push(String::from("NONE"));
195 projectinfo.push(ProjectInfo { 212 projectinfo.push(ProjectInfo {
196 mod_id: project.id, 213 mod_id: String::from(&project.id),
197 slug: project.slug, 214 slug: project.slug,
198 title: project.title, 215 title: project.title,
199 current_version, 216 current_version,
200 applicable_versions: available_versions_vec, 217 applicable_versions: available_versions_vec,
201 download_link: file, 218 download_link: file,
219 set_version: setmap.get(&project.id).unwrap().clone(),
202 }) 220 })
203 } 221 }
204 } 222 }
@@ -206,11 +224,20 @@ async fn get_mod_infos(config: Cfg, mod_ids: Vec<String>, list: List) -> MLE<Vec
206 Ok(projectinfo) 224 Ok(projectinfo)
207} 225}
208 226
209async fn get_ver_info(config: Cfg, ver_ids: Vec<String>) -> MLE<Vec<ProjectInfo>> { 227async fn get_ver_info(config: Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<ProjectInfo>> {
228
229 let mut setmap: HashMap<String, bool> = HashMap::new();
230
231 let mut ids = vec![];
232
233 for id in ver_ids {
234 setmap.insert(id.0.to_string(), id.1);
235 ids.push(id.0);
236 }
210 let mut projectinfo: Vec<ProjectInfo> = Vec::new(); 237 let mut projectinfo: Vec<ProjectInfo> = Vec::new();
211 238
212 //Get required information from ver_ids 239 //Get required information from ver_ids
213 let mut v_versions = get_raw_versions(&config.apis.modrinth, ver_ids).await; 240 let mut v_versions = get_raw_versions(&config.apis.modrinth, ids).await;
214 let mut v_mod_ids: Vec<String> = Vec::new(); 241 let mut v_mod_ids: Vec<String> = Vec::new();
215 for ver in v_versions.clone() { 242 for ver in v_versions.clone() {
216 v_mod_ids.push(ver.project_id); 243 v_mod_ids.push(ver.project_id);
@@ -230,12 +257,13 @@ async fn get_ver_info(config: Cfg, ver_ids: Vec<String>) -> MLE<Vec<ProjectInfo>
230 .unwrap() 257 .unwrap()
231 .url; 258 .url;
232 projectinfo.push(ProjectInfo { 259 projectinfo.push(ProjectInfo {
233 mod_id: project.id, 260 mod_id: String::from(&project.id),
234 slug: project.slug, 261 slug: project.slug,
235 title: project.title, 262 title: project.title,
236 current_version: Some(version.clone()), 263 current_version: Some(version.clone()),
237 applicable_versions: vec![String::from(&version.id)], 264 applicable_versions: vec![String::from(&version.id)],
238 download_link: file, 265 download_link: file,
266 set_version: setmap.get(&version.id).unwrap().clone(),
239 }) 267 })
240 } 268 }
241 Ok(projectinfo) 269 Ok(projectinfo)
@@ -281,7 +309,7 @@ pub fn mod_remove(config: Cfg, id: &str, list: List) -> MLE<()> {
281 // Remove mod from main list if not used elsewhere 309 // Remove mod from main list if not used elsewhere
282 let mut mod_used = false; 310 let mut mod_used = false;
283 for id in list_ids { 311 for id in list_ids {
284 let mods = match userlist_get_all_ids(config.clone(), id) { 312 let mods = match userlist_get_all_ids(config.clone(), &id) {
285 Ok(m) => m, 313 Ok(m) => m,
286 Err(err) => { 314 Err(err) => {
287 if err.to_string() == "Database: NO_MODS_USERLIST" { 315 if err.to_string() == "Database: NO_MODS_USERLIST" {
diff --git a/src/commands/update.rs b/src/commands/update.rs
index d76ba4b..d3a282b 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -19,7 +19,7 @@ pub async fn update(
19) -> MLE<()> { 19) -> MLE<()> {
20 for current_list in liststack { 20 for current_list in liststack {
21 println!("Update mods in {}", current_list.id); 21 println!("Update mods in {}", current_list.id);
22 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; 22 let mods = userlist_get_all_ids(config.clone(), &current_list.id)?;
23 23
24 let mut current_versions: Vec<(String, String)> = vec![]; 24 let mut current_versions: Vec<(String, String)> = vec![];
25 25
@@ -27,10 +27,10 @@ pub async fn update(
27 27
28 for id in mods { 28 for id in mods {
29 let info = mods_get_info(config.clone(), &id)?; 29 let info = mods_get_info(config.clone(), &id)?;
30 println!(" �{}", info.title); 30 println!(" �{}", info.title);
31 31
32 if userlist_get_set_version(config.clone(), &current_list.id, &id)? { 32 if userlist_get_set_version(config.clone(), &current_list.id, &id)? {
33 println!(" └Set version, skipping update"); 33 println!(" └Set version, skipping update");
34 continue; 34 continue;
35 } 35 }
36 36
@@ -54,7 +54,7 @@ pub async fn update(
54 Err(e) => { 54 Err(e) => {
55 if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { 55 if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" {
56 println!( 56 println!(
57 " └No new version found for the specified minecraft version" 57 " └No new version found for the specified minecraft version"
58 ); 58 );
59 } else { 59 } else {
60 return Err(e); 60 return Err(e);
@@ -105,7 +105,6 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML
105 } 105 }
106 106
107 let mut current: Vec<Version> = vec![]; 107 let mut current: Vec<Version> = vec![];
108 //TODO Split clean and no match
109 if clean 108 if clean
110 || (versions.join("|") 109 || (versions.join("|")
111 != userlist_get_applicable_versions( 110 != userlist_get_applicable_versions(
@@ -134,7 +133,6 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML
134 }?; 133 }?;
135 current.push(current_ver.clone()); 134 current.push(current_ver.clone());
136 135
137 //TODO implement version selection if no primary
138 let link = match current_ver 136 let link = match current_ver
139 .files 137 .files
140 .into_iter() 138 .into_iter()
diff --git a/src/db.rs b/src/db.rs
index 9ffbfe5..8fd21b1 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -220,7 +220,7 @@ pub fn userlist_insert(
220 Ok(()) 220 Ok(())
221} 221}
222 222
223pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> { 223pub fn userlist_get_all_ids(config: Cfg, list_id: &str) -> MLE<Vec<String>> {
224 let data = format!("{}/data.db", config.data); 224 let data = format!("{}/data.db", config.data);
225 let connection = Connection::open(data).unwrap(); 225 let connection = Connection::open(data).unwrap();
226 226
@@ -329,7 +329,7 @@ pub fn userlist_get_current_version(config: Cfg, list_id: &str, mod_id: &str) ->
329pub fn userlist_get_all_current_version_ids( 329pub fn userlist_get_all_current_version_ids(
330 config: Cfg, 330 config: Cfg,
331 list_id: String, 331 list_id: String,
332) -> Result<Vec<String>, Box<dyn std::error::Error>> { 332) -> MLE<Vec<String>> {
333 let data = format!("{}/data.db", config.data); 333 let data = format!("{}/data.db", config.data);
334 let connection = Connection::open(data)?; 334 let connection = Connection::open(data)?;
335 335
@@ -343,10 +343,10 @@ pub fn userlist_get_all_current_version_ids(
343 } 343 }
344 344
345 if versions.is_empty() { 345 if versions.is_empty() {
346 return Err(Box::new(std::io::Error::new( 346 return Err(MLError::new(
347 ErrorKind::Other, 347 ErrorType::DBError,
348 "NO_MODS_ON_LIST", 348 "NO_MODS_ON_LIST",
349 ))); 349 ));
350 }; 350 };
351 351
352 Ok(versions) 352 Ok(versions)
diff --git a/src/lib.rs b/src/lib.rs
index f18bdfb..1c40ceb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,6 +29,7 @@ impl Modloader {
29 match string { 29 match string {
30 "forge" => Ok(Modloader::Forge), 30 "forge" => Ok(Modloader::Forge),
31 "fabric" => Ok(Modloader::Fabric), 31 "fabric" => Ok(Modloader::Fabric),
32 "quilt" => Ok(Modloader::Quilt),
32 _ => Err(MLError::new(ErrorType::ArgumentError, "UNKNOWN_MODLOADER")), 33 _ => Err(MLError::new(ErrorType::ArgumentError, "UNKNOWN_MODLOADER")),
33 } 34 }
34 } 35 }
diff --git a/src/main.rs b/src/main.rs
index 2db304b..31a320b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,10 +3,9 @@ use modlist::{
3 config::Cfg, 3 config::Cfg,
4 db::{config_get_current_list, lists_get, lists_get_all_ids}, 4 db::{config_get_current_list, lists_get, lists_get_all_ids},
5 download, export, get_current_list, import, list_add, list_change, list_remove, list_version, 5 download, export, get_current_list, import, list_add, list_change, list_remove, list_version,
6 mod_add, mod_remove, update, IDSelector, List, Modloader, VersionLevel, 6 mod_add, mod_remove, update, IDSelector, List, Modloader, VersionLevel, list_list, AddMod,
7}; 7};
8 8
9//TODO make default list optional
10#[derive(Parser)] 9#[derive(Parser)]
11#[command(author, version, about)] 10#[command(author, version, about)]
12struct Cli { 11struct Cli {
@@ -185,7 +184,9 @@ async fn main() {
185 false => IDSelector::ModificationID(id), 184 false => IDSelector::ModificationID(id),
186 }; 185 };
187 186
188 mod_add(config, vec![marked_id], listf, download, lock).await 187 let add_id = AddMod { id: marked_id, set_version: lock };
188
189 mod_add(config, vec![add_id], listf, download).await
189 } 190 }
190 ModCommands::Remove { id, list } => { 191 ModCommands::Remove { id, list } => {
191 let listf = match list { 192 let listf = match list {
@@ -223,7 +224,7 @@ async fn main() {
223 } 224 }
224 ListCommands::Remove { id } => list_remove(config, id), 225 ListCommands::Remove { id } => list_remove(config, id),
225 ListCommands::List => { 226 ListCommands::List => {
226 todo!() 227 list_list(config)
227 } 228 }
228 ListCommands::Change { id } => list_change(config, id), 229 ListCommands::Change { id } => list_change(config, id),
229 ListCommands::Version { 230 ListCommands::Version {