summaryrefslogtreecommitdiff
path: root/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/list.rs58
-rw-r--r--src/commands/modification.rs31
-rw-r--r--src/commands/setup.rs11
-rw-r--r--src/commands/update.rs35
4 files changed, 58 insertions, 77 deletions
diff --git a/src/commands/list.rs b/src/commands/list.rs
index 6c80e4e..76965df 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -1,38 +1,27 @@
1use std::io::{Error, ErrorKind}; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{db::{lists_insert, lists_remove, config_change_current_list, lists_get_all_ids, config_get_current_list, lists_get}, Modloader, config::Cfg, input::Input}; 3use crate::{db::{lists_insert, lists_remove, config_change_current_list, lists_get_all_ids, config_get_current_list, lists_get}, Modloader, config::Cfg, input::{Input, Subcmd}};
4 4
5#[derive(Debug, Clone, PartialEq, Eq)] 5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct List { 6pub struct List {
7 pub id: String, 7 pub id: String,
8 pub mc_version: String, 8 pub mc_version: String,
9 pub modloader: Modloader, 9 pub modloader: Modloader,
10 pub download_folder: String,
10} 11}
11 12
12pub fn list(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> { 13pub fn list(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
13 14
14 if args.is_none() { 15 match input.subcommand.ok_or("")? {
15 let lists = lists_get_all_ids(config.clone())?; 16 Subcmd::Add => {
16 let current_list = config_get_current_list(config)?; 17 add(config, input.args.ok_or("")?)
17 println!("Your lists:\n{}\n-----\nCurrently selected list: \"{}\"", lists.join(",\n"), current_list);
18 return Ok(());
19 }
20
21 let arguments = Input::from(args.unwrap().join(" "))?;
22
23 if arguments.args.is_none() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); };
24
25 match arguments.command.as_str() {
26 "add" => {
27 add(config, arguments.args.unwrap())
28 }, 18 },
29 "change" => { 19 Subcmd::Change => {
30 change(config, arguments.args.unwrap()) 20 change(config, input.args.ok_or("")?)
31 }, 21 },
32 "remove" => { 22 Subcmd::Remove => {
33 remove(config, arguments.args.unwrap()) 23 remove(config, input.args.ok_or("")?)
34 }, 24 }
35 _ => Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_SUBCOMMAND")))
36 } 25 }
37} 26}
38 27
@@ -43,16 +32,13 @@ pub fn get_current_list(config: Cfg) -> Result<List, Box<dyn std::error::Error>>
43 32
44fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 33fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
45 match args.len() { 34 match args.len() {
46 1 | 2 => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))), 35 1 | 2 | 3 => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))),
47 3 => { 36 4 => {
48 let id = String::from(&args[0]); 37 let id = String::from(&args[0]);
49 let mc_version = String::from(&args[1]); 38 let mc_version = String::from(&args[1]);
50 let mod_loader = match args[2].as_str() { 39 let mod_loader = Modloader::from(&args[2])?;
51 "forge" => Modloader::Forge, 40 let download_folder = String::from(&args[3]);
52 "fabric" => Modloader::Fabric, 41 lists_insert(config, id, mc_version, mod_loader, download_folder)
53 _ => return Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_MODLOADER")))
54 };
55 lists_insert(config, id, mc_version, mod_loader)
56 }, 42 },
57 5.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))), 43 5.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))),
58 _ => panic!("list arguments should never be zero or lower"), 44 _ => panic!("list arguments should never be zero or lower"),
@@ -65,10 +51,7 @@ fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
65 1 => { 51 1 => {
66 let list = String::from(&args[0]); 52 let list = String::from(&args[0]);
67 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); }; 53 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); };
68 match config_change_current_list(config, list) { 54 config_change_current_list(config, list)
69 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "72"))) },
70 Ok(()) => Ok(()),
71 }
72 }, 55 },
73 2.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))), 56 2.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))),
74 _ => panic!("list arguments should never be zero or lower"), 57 _ => panic!("list arguments should never be zero or lower"),
@@ -77,12 +60,7 @@ fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
77 60
78fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 61fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
79 match args.len() { 62 match args.len() {
80 1 => { 63 1 => lists_remove(config, String::from(&args[0])),
81 match lists_remove(config, String::from(&args[0])) {
82 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "85"))) },
83 Ok(()) => Ok(()),
84 }
85 },
86 2.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))), 64 2.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))),
87 _ => panic!("list arguments should never be zero or lower"), 65 _ => panic!("list arguments should never be zero or lower"),
88 } 66 }
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 595b677..519a0cb 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,23 +1,17 @@
1use std::io::{Error, ErrorKind}; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{modrinth::{project, versions, extract_current_version}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, mods_get_all_ids, userlist_get_all_ids}, input::Input, get_current_list}; 3use crate::{modrinth::{project, versions, extract_current_version}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, mods_get_all_ids, userlist_get_all_ids}, input::{Input, Subcmd}, get_current_list};
4 4
5pub async fn modification(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn modification(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
6 6
7 if args.is_none() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))) } 7 match input.subcommand.ok_or("")? {
8 8 Subcmd::Add => {
9 let arguments = Input::from(args.unwrap().join(" "))?; 9 add(config, input.args.ok_or("")?).await
10
11 if arguments.args.is_none() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); };
12
13 match arguments.command.as_str() {
14 "add" => {
15 add(config, arguments.args.unwrap()).await
16 }, 10 },
17 "remove" => { 11 Subcmd::Remove => {
18 remove(config, arguments.args.unwrap()) 12 remove(config, input.args.ok_or("")?)
19 }, 13 },
20 _ => Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_SUBCOMMAND"))) 14 _ => Err(Box::new(Error::new(ErrorKind::InvalidInput, "SUBCOMMAND_NOT_AVAILABLE")))
21 } 15 }
22} 16}
23 17
@@ -29,8 +23,6 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E
29 23
30 let project = project(String::from(&config.apis.modrinth), &args[0]).await; 24 let project = project(String::from(&config.apis.modrinth), &args[0]).await;
31 25
32 dbg!(&project);
33
34 if project.versions.is_empty() { panic!("This should never happen"); }; 26 if project.versions.is_empty() { panic!("This should never happen"); };
35 27
36 let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), current_list.clone()).await; 28 let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), current_list.clone()).await;
@@ -48,7 +40,6 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E
48 //add to current list and mod table 40 //add to current list and mod table
49 match userlist_get_all_ids(config.clone(), current_list.clone().id) { 41 match userlist_get_all_ids(config.clone(), current_list.clone().id) {
50 Ok(mods) => { 42 Ok(mods) => {
51 dbg!(&mods);
52 if mods.contains(&project.id) { 43 if mods.contains(&project.id) {
53 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); } 44 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); }
54 else { 45 else {
@@ -60,7 +51,6 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E
60 51
61 match mods_get_all_ids(config.clone()) { 52 match mods_get_all_ids(config.clone()) {
62 Ok(mods) => { 53 Ok(mods) => {
63 dbg!(&mods);
64 if mods.contains(&project.id) { 54 if mods.contains(&project.id) {
65 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_IN_DATABASE"))) 55 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_IN_DATABASE")))
66 } else { 56 } else {
@@ -81,8 +71,5 @@ fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
81 let mod_id = mods_get_id(config.clone(), String::from(&args[0]))?; 71 let mod_id = mods_get_id(config.clone(), String::from(&args[0]))?;
82 72
83 //TODO implement remove from modlist if not in any other lists && config clean is true 73 //TODO implement remove from modlist if not in any other lists && config clean is true
84 match userlist_remove(config, current_list.id, mod_id) { 74 userlist_remove(config, current_list.id, mod_id)
85 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
86 Ok(()) => Ok(()),
87 }
88} 75}
diff --git a/src/commands/setup.rs b/src/commands/setup.rs
index 8c0fcfd..be06040 100644
--- a/src/commands/setup.rs
+++ b/src/commands/setup.rs
@@ -1,9 +1,8 @@
1use std::{fs::File, path::Path, io::{Error, ErrorKind}}; 1use std::{fs::File, path::Path, io::{Error, ErrorKind}};
2 2
3use crate::{config::Cfg, db::{db_setup, s_config_get_version, s_config_create_version, s_insert_column, lists_get_all_ids, lists_get, userlist_get_all_current_version_ids, s_userlist_update_download}, modrinth::get_raw_versions}; 3use crate::{config::Cfg, db::{db_setup, s_config_get_version, s_config_create_version, s_insert_column, lists_get_all_ids, lists_get, userlist_get_all_current_version_ids, s_userlist_update_download, s_config_update_version}, modrinth::get_raw_versions};
4 4
5pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
6
7 let db_file = format!("{}/data.db", String::from(&config.data)); 6 let db_file = format!("{}/data.db", String::from(&config.data));
8 7
9 if !Path::new(&db_file).exists() { 8 if !Path::new(&db_file).exists() {
@@ -13,6 +12,7 @@ pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
13 match s_config_get_version(config.clone()) { 12 match s_config_get_version(config.clone()) {
14 Ok(ver) => { 13 Ok(ver) => {
15 match ver.as_str() { 14 match ver.as_str() {
15 "0.2" => to_03(config)?,
16 _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION"))) 16 _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION")))
17 } 17 }
18 }, 18 },
@@ -33,7 +33,7 @@ async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
33 33
34 for list in lists { 34 for list in lists {
35 println!("Updating {}", list); 35 println!("Updating {}", list);
36 s_insert_column(config.clone(), String::from(&list), String::from("current_download"), String::new())?; 36 s_insert_column(config.clone(), String::from(&list), String::from("current_download"), String::from("TEXT"))?;
37 37
38 let full_list = lists_get(config.clone(), String::from(&list))?; 38 let full_list = lists_get(config.clone(), String::from(&list))?;
39 39
@@ -51,3 +51,8 @@ async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
51 51
52 Ok(()) 52 Ok(())
53} 53}
54
55fn to_03(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
56 s_insert_column(config.clone(), String::from("lists"), String::from("download_folder"), String::from("TEXT"))?;
57 s_config_update_version(config, String::from("0.3"))
58}
diff --git a/src/commands/update.rs b/src/commands/update.rs
index e383eae..85630f5 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -4,9 +4,9 @@ use reqwest::Client;
4 4
5use futures_util::StreamExt; 5use futures_util::StreamExt;
6 6
7use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions}, List}; 7use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, mods_get_versions, userlist_get_applicable_versions, userlist_change_versions}, List, input::Input};
8 8
9pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 9pub async fn update(config: Cfg, input: Input) -> Result<(), Box<dyn std::error::Error>> {
10 10
11 let current_list = get_current_list(config.clone())?; 11 let current_list = get_current_list(config.clone())?;
12 12
@@ -20,15 +20,16 @@ pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
20 20
21 let mut updatestack: Vec<Version> = vec![]; 21 let mut updatestack: Vec<Version> = vec![];
22 for (index, project) in projects.into_iter().enumerate() { 22 for (index, project) in projects.into_iter().enumerate() {
23 //Get versions for project and check if they match up
23 let current_version = &versions[index]; 24 let current_version = &versions[index];
24
25 let p_id = String::from(&project.id); 25 let p_id = String::from(&project.id);
26 let v_id = &current_version.mod_id; 26 let v_id = &current_version.mod_id;
27
28 if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) }; 27 if &p_id != v_id { return Err(Box::new(Error::new(ErrorKind::Other, "SORTING_ERROR"))) };
29 28
30 if project.versions.join("|") != current_version.versions { 29
31 updatestack.push(match specific_update(config.clone(), current_list.clone(), project).await { 30 //Adding to stack if not the same versions in the list OR if clean == true
31 if input.clone().clean || (project.versions.join("|") != current_version.versions) {
32 updatestack.push(match specific_update(config.clone(), input.clone(), current_list.clone(), project).await {
32 Ok(ver) => ver, 33 Ok(ver) => ver,
33 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE") 34 //TODO handle errors (only continue on "NO_UPDATE_AVAILABLE")
34 Err(_) => { continue; }, 35 Err(_) => { continue; },
@@ -36,13 +37,23 @@ pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
36 }; 37 };
37 }; 38 };
38 //println!("{:?}", updatestack); 39 //println!("{:?}", updatestack);
40
41
42 if input.clean {
43 let dl_path = &current_list.download_folder;
44 println!("Cleaning {}", dl_path);
45 for entry in std::fs::read_dir(dl_path)? {
46 let entry = entry?;
47 std::fs::remove_file(entry.path())?;
48 }
49 }
39 50
40 download_updates(config, updatestack).await?; 51 download_updates(config, current_list, updatestack).await?;
41 52
42 Ok(()) 53 Ok(())
43} 54}
44 55
45async fn specific_update(config: Cfg, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> { 56async fn specific_update(config: Cfg, input: Input, list: List, project: Project) -> Result<Version, Box<dyn std::error::Error>> {
46 print!("Checking update for '{}' in {}", project.title, list.id); 57 print!("Checking update for '{}' in {}", project.title, list.id);
47 58
48 let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; 59 let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await;
@@ -54,7 +65,7 @@ async fn specific_update(config: Cfg, list: List, project: Project) -> Result<Ve
54 } 65 }
55 66
56 let mut current: Vec<Version> = vec![]; 67 let mut current: Vec<Version> = vec![];
57 if versions.join("|") != userlist_get_applicable_versions(config.clone(), String::from(&list.id), String::from(&project.id))? { 68 if input.clean || (versions.join("|") != userlist_get_applicable_versions(config.clone(), String::from(&list.id), String::from(&project.id))?) {
58 //get new versions 69 //get new versions
59 print!(" | getting new version"); 70 print!(" | getting new version");
60 let current_str = extract_current_version(applicable_versions.clone())?; 71 let current_str = extract_current_version(applicable_versions.clone())?;
@@ -71,9 +82,9 @@ async fn specific_update(config: Cfg, list: List, project: Project) -> Result<Ve
71 Ok(current[0].clone()) 82 Ok(current[0].clone())
72} 83}
73 84
74async fn download_updates(config: Cfg, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { 85async fn download_updates(config: Cfg, current_list: List, versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> {
75 86
76 let dl_path = String::from(&config.downloads); 87 let dl_path = String::from(&current_list.download_folder);
77 88
78 for ver in versions { 89 for ver in versions {
79 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); 90 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap();