From ff23a11e632812b685f594324e6004c6da81cd4d Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Sun, 5 Feb 2023 09:23:29 +0100 Subject: Fixed update shit not correctly updating --- .gitignore | 4 +- Cargo.lock | 149 +++++++++++++++----------- Cargo.toml | 4 +- planmodlist.xopp | Bin 342232 -> 342159 bytes src/apis/modrinth.rs | 6 +- src/commands/io.rs | 20 ++-- src/commands/list.rs | 1 + src/commands/mod.rs | 4 +- src/commands/modification.rs | 73 ++++++------- src/commands/setup.rs | 86 ++++++++------- src/commands/update.rs | 90 +++++++--------- src/db.rs | 101 ++++++++++++------ src/error.rs | 2 +- src/files.rs | 10 +- src/input.rs | 19 ++-- src/main.rs | 14 ++- tests/db.rs | 249 ------------------------------------------- 17 files changed, 321 insertions(+), 511 deletions(-) delete mode 100644 tests/db.rs diff --git a/.gitignore b/.gitignore index 8713145..390e3b2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ /dl /dl2 /test_tmp +/downloads .planmodlist.autosave.xopp data.db.cp export.toml config.toml /dev -/.fleet \ No newline at end of file +/.fleet +/.vscode \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index cf7495b..e1b7443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "bitflags" @@ -72,9 +72,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytes" @@ -84,9 +84,9 @@ checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -137,9 +137,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cxx" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" +checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8" dependencies = [ "cc", "cxxbridge-flags", @@ -149,9 +149,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" +checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8" dependencies = [ "cc", "codespan-reporting", @@ -164,15 +164,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" +checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971" [[package]] name = "cxxbridge-macro" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" +checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e" dependencies = [ "proc-macro2", "quote", @@ -271,24 +271,30 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" + +[[package]] +name = "futures-io" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", @@ -297,25 +303,28 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -334,9 +343,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" [[package]] name = "h2" @@ -615,7 +624,7 @@ dependencies = [ [[package]] name = "modlist" -version = "0.9.0" +version = "0.10.0" dependencies = [ "chrono", "dirs", @@ -678,9 +687,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -748,9 +757,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" dependencies = [ "cfg-if", "libc", @@ -785,9 +794,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -832,9 +841,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ "base64", "bytes", @@ -864,6 +873,7 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", "winreg", ] @@ -917,9 +927,9 @@ checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -930,9 +940,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -1042,9 +1052,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -1097,9 +1107,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.24.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ "autocfg", "bytes", @@ -1152,9 +1162,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -1193,9 +1203,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -1329,6 +1339,19 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.60" @@ -1387,45 +1410,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" diff --git a/Cargo.toml b/Cargo.toml index da48762..0b6ffa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "modlist" -version = "0.9.0" +version = "0.10.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,4 +15,4 @@ futures-util = "0.3.14" chrono = "0.4.22" toml = "0.5.10" error-chain = "0.12.4" -dirs = "4.0.0" \ No newline at end of file +dirs = "4.0.0" diff --git a/planmodlist.xopp b/planmodlist.xopp index b3a54d3..a73d324 100644 Binary files a/planmodlist.xopp and b/planmodlist.xopp differ diff --git a/src/apis/modrinth.rs b/src/apis/modrinth.rs index 36ab5df..f3f89a7 100644 --- a/src/apis/modrinth.rs +++ b/src/apis/modrinth.rs @@ -63,9 +63,7 @@ pub enum Type { pub enum Status { approved, rejected, - draft, - unlisted, - archived, + draft, unlisted, archived, processing, unknown } @@ -141,7 +139,6 @@ pub async fn project(api: String, name: &str) -> Project { } pub async fn projects(api: String, ids: Vec) -> Vec { - println!("\tGet versions from modrinth\n"); let all = ids.join(r#"",""#); let url = format!(r#"projects?ids=["{}"]"#, all); @@ -187,7 +184,6 @@ pub fn extract_current_version(versions: Vec) -> MLE { } times.sort_by_key(|t| t.1); times.reverse(); - println!("\t └New current version: {}", times[0].0); Ok(times[0].0.to_string()) }, _ => panic!("available_versions should never be negative"), diff --git a/src/commands/io.rs b/src/commands/io.rs index 4835e3d..44604d1 100644 --- a/src/commands/io.rs +++ b/src/commands/io.rs @@ -2,7 +2,7 @@ use std::fs::File; use std::io::prelude::*; use serde::{Serialize, Deserialize}; -use crate::{input::{Input, IoOptions}, db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, /*mod_add,*/ List, devdir, error::MLE}; +use crate::{input::{Input, IoOptions}, db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mods_add}; #[derive(Debug, Serialize, Deserialize)] struct Export { @@ -24,7 +24,7 @@ impl ExportList { let list = lists_get(config.clone(), String::from(&list_id))?; let mut dl_folder = None; - if download == true { dl_folder = Some(list.download_folder) }; + if download{ dl_folder = Some(list.download_folder) }; let mods = userlist_get_all_ids(config, list_id)?.join("|"); @@ -51,7 +51,7 @@ fn export(config: Cfg, input: Input) -> MLE<()> { } let mut lists: Vec = vec![]; for list_id in list_ids { - lists.push(ExportList::from(config.clone(), String::from(list_id), true)?); + lists.push(ExportList::from(config.clone(), list_id, true)?); } let toml = toml::to_string( &Export { lists } )?; @@ -59,7 +59,7 @@ fn export(config: Cfg, input: Input) -> MLE<()> { let filestr = dirs::home_dir().unwrap().join("mlexport.toml"); let mut file = File::create(devdir(filestr.into_os_string().into_string().unwrap().as_str()))?; - file.write_all(&toml.as_bytes())?; + file.write_all(toml.as_bytes())?; Ok(()) } @@ -67,8 +67,8 @@ fn export(config: Cfg, input: Input) -> MLE<()> { async fn import(config: Cfg, input: Input) -> MLE<()> { let filestr: String = match input.file { - Some(args) => String::from(args), - None => String::from(devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str())), + Some(args) => args, + None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()), }; let mut file = File::open(filestr)?; @@ -76,17 +76,17 @@ async fn import(config: Cfg, input: Input) -> MLE<()> { file.read_to_string(&mut content)?; let export: Export = toml::from_str(&content)?; - println!("{:#?}", export); - for exportlist in export.lists { let list = List { id: exportlist.id, mc_version: exportlist.mc_version, modloader: Modloader::from(&exportlist.launcher)?, download_folder: exportlist.download_folder.ok_or("NO_DL").unwrap() }; lists_insert(config.clone(), list.id.clone(), list.mc_version.clone(), list.modloader.clone(), String::from(&list.download_folder))?; - let mods: Vec<&str> = exportlist.mods.split("|").collect(); + let mods: Vec<&str> = exportlist.mods.split('|').collect(); let mut mod_ids = vec![]; for mod_id in mods { mod_ids.push(String::from(mod_id)); }; - //mod_add(config.clone(), mod_ids, list.clone(), false).await?; + //TODO impl set_version and good direct download + //TODO impl all at once, dafuck + mods_add(config.clone(), mod_ids, list, input.direct_download, false).await?; } Ok(()) } diff --git a/src/commands/list.rs b/src/commands/list.rs index eaf6fa1..8e86973 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -49,6 +49,7 @@ fn remove(config: Cfg, input: Input) -> MLE<()> { } ///Changing the current lists version and updating it +/// /// #Arguments /// /// * `config` - The current config diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 38139f9..0d5bd00 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,13 +1,13 @@ pub mod modification; pub mod list; pub mod update; -//pub mod setup; +pub mod setup; pub mod download; pub mod io; pub use modification::*; pub use list::*; pub use update::*; -//pub use setup::*; +pub use setup::*; pub use download::*; pub use io::*; diff --git a/src/commands/modification.rs b/src/commands/modification.rs index c82d6b5..12a635f 100644 --- a/src/commands/modification.rs +++ b/src/commands/modification.rs @@ -1,4 +1,9 @@ -use crate::{modrinth::{project, versions, extract_current_version, Version, projects}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, mods_get_all_ids, userlist_get_all_ids, userlist_get_current_version, lists_get_all_ids, mods_remove}, input::{Input, ModOptions}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}}; +use crate::{modrinth::{project, versions, extract_current_version, Version, projects}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, userlist_get_all_ids, userlist_get_current_version, lists_get_all_ids, mods_remove}, input::{Input, ModOptions}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}}; + +//TODO DO IT +pub struct ModVer { + +} pub async fn modification(config: Cfg, input: Input) -> MLE<()> { match input.clone().mod_options.ok_or("").unwrap() { @@ -13,22 +18,26 @@ pub async fn modification(config: Cfg, input: Input) -> MLE<()> { async fn add(config: Cfg, input: Input) -> MLE<()> { - mod_add(config, vec![String::from(input.mod_id.unwrap())], input.list.unwrap(), input.direct_download).await?; + mods_add(config, vec![input.mod_id.unwrap()], input.list.unwrap(), input.direct_download, input.set_version).await?; Ok(()) } - -pub async fn mod_add(config: Cfg, mod_id: Vec, list: List, direct_download: bool) -> MLE<()> { +//TODO impl specific version +pub async fn mods_add(config: Cfg, mod_id: Vec, list: List, direct_download: bool, set_version: bool) -> MLE<()> { - //Fix printing (its horrible) - println!("Adding mod(s) {:?}", mod_id); + println!("Add mods to {}", list.id); + println!(" └Add mods:"); let projects = if mod_id.len() == 1 { vec![project(String::from(&config.apis.modrinth), &mod_id[0]).await] } else { projects(String::from(&config.apis.modrinth), mod_id).await }; + + let mut downloadstack: Vec = Vec::new(); for project in projects { + println!("\t└{}", project.title); + println!("\t └Get versions"); let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; let mut available_versions_vec: Vec = Vec::new(); @@ -37,64 +46,56 @@ pub async fn mod_add(config: Cfg, mod_id: Vec, list: List, direct_downlo let file: String; if !available_versions.is_empty() { let current_id = extract_current_version(available_versions.clone())?; + println!("\t └Current version: {}", current_id); current_version = Some(available_versions.clone().into_iter().find(|v| v.id == current_id).unwrap()); current_version_id = current_version.clone().unwrap().id; file = current_version.clone().ok_or("").unwrap().files.into_iter().find(|f| f.primary).unwrap().url; - for ver in available_versions { available_versions_vec.push(ver.id); }; } else { - println!("There's currently no mod version for your specified target"); + println!("\t └There's currently no mod version for your specified target"); current_version = None; current_version_id = String::from("NONE"); file = String::from("NONE"); available_versions_vec.push(String::from("NONE")); } - //add to current list and mod table - match userlist_get_all_ids(config.clone(), list.clone().id) { - Ok(mods) => { - if mods.contains(&project.id) { - return Err(MLError::new(ErrorType::ModError, "MOD_ALREADY_ON_LIST")); } - else { - userlist_insert(config.clone(), String::from(&list.id), String::from(&project.id), String::from(¤t_version_id), available_versions_vec, file)?; - } + match userlist_insert(config.clone(), &list.id, &project.id, ¤t_version_id, available_versions_vec, &file, set_version) { + Err(e) => { + let expected_err = format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id); + if e.to_string() == expected_err { Err(MLError::new(ErrorType::ModError, "MOD_ALREADY_ON_SELECTED_LIST")) } else { Err(e) } }, - Err(..) => userlist_insert(config.clone(), String::from(&list.id), String::from(&project.id), String::from(¤t_version_id), available_versions_vec, file)?, - }; + Ok(..) => { Ok(..) }, + }?; - match mods_get_all_ids(config.clone()) { - Ok(mods) => { - if mods.contains(&project.id) { - //return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_IN_DATABASE"))) - } else { - mods_insert(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?; - } - }, - Err(..) => { - mods_insert(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?; + match mods_insert(config.clone(), &project.id, &project.slug, &project.title) { + Err(e) => { + if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" { Ok(..) } else { Err(e) } }, - }; + Ok(..) => Ok(..), + }?; - if direct_download && current_version.is_some() { download_versions(list.clone(), config.clone(), vec![current_version.unwrap()]).await?; }; - - } + downloadstack.push(current_version.unwrap()); + }; + + //Download all the added mods + if direct_download { + download_versions(list.clone(), config.clone(), downloadstack).await?; + }; Ok(()) } fn remove(config: Cfg, input: Input) -> MLE<()> { - - //TODO inplement deletion by slug or title - let mod_id = mods_get_id(config.clone(), input.clone().mod_id.unwrap())?; + + let mod_id = mods_get_id(&config.data, input.mod_id.as_ref().unwrap())?; let version = userlist_get_current_version(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; - //TODO implement remove from modlist if not in any other lists && config clean is true userlist_remove(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; delete_version(input.list.unwrap(), version)?; diff --git a/src/commands/setup.rs b/src/commands/setup.rs index cc7472c..0161bd7 100644 --- a/src/commands/setup.rs +++ b/src/commands/setup.rs @@ -1,66 +1,72 @@ -use std::{fs::File, path::Path, io::{Error, ErrorKind}}; +use std::{fs::File, path::Path}; -use 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, devdir}; +use crate::{config::Cfg, db::db_setup, error::MLE, devdir}; -pub async fn setup(config: Cfg) -> Result<(), Box> { +pub async fn setup(config: Cfg) -> MLE<()> { let db_file = devdir(format!("{}/data.db", config.data).as_str()); if !Path::new(&db_file).exists() { - return create(config, db_file); + create(config, db_file)?; } + /* match s_config_get_version(config.clone()) { Ok(ver) => { match ver.as_str() { "0.2" => to_03(config)?, "0.3" => to_04(config)?, - _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION"))) + _ => return Err(MLError::new(ErrorType::Other, "UNKNOWN_VERSION")) } }, Err(..) => to_02(config).await? }; + */ Ok(()) } -fn create(config: Cfg, db_file: String) -> Result<(), Box> { - File::create(db_file)?; - db_setup(config)?; - Ok(()) -} - -async fn to_02(config: Cfg) -> Result<(), Box> { - let lists = lists_get_all_ids(config.clone())?; - - for list in lists { - println!("Updating {}", list); - s_insert_column(config.clone(), String::from(&list), String::from("current_download"), String::from("TEXT"), None)?; - - let full_list = lists_get(config.clone(), String::from(&list))?; +fn create(config: Cfg, db_file: String) -> MLE<()> { - let versions = userlist_get_all_current_version_ids(config.clone(), full_list.clone().id)?; - - let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await; - - for ver in raw_versions { - println!("Adding link for {}", ver.project_id); - let file = ver.files.into_iter().find(|f| f.primary).unwrap(); - s_userlist_update_download(config.clone(), String::from(&full_list.id), ver.project_id, file.url)?; - } - }; - s_config_create_version(config)?; + println!("Create database"); + File::create(db_file)?; + db_setup(config)?; Ok(()) } -fn to_03(config: Cfg) -> Result<(), Box> { - s_insert_column(config.clone(), String::from("lists"), String::from("download_folder"), String::from("TEXT"), None)?; - s_config_update_version(config, String::from("0.3")) -} +//async fn to_02(config: Cfg) -> Result<(), Box> { +// let lists = lists_get_all_ids(config.clone())?; +// +// for list in lists { +// println!("Updating {}", list); +// s_insert_column(config.clone(), String::from(&list), String::from("current_download"), String::from("TEXT"), None)?; +// +// let full_list = lists_get(config.clone(), String::from(&list))?; +// +// let versions = userlist_get_all_current_version_ids(config.clone(), full_list.clone().id)?; +// +// let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await; +// +// for ver in raw_versions { +// println!("Adding link for {}", ver.project_id); +// let file = ver.files.into_iter().find(|f| f.primary).unwrap(); +// s_userlist_update_download(config.clone(), String::from(&full_list.id), ver.project_id, file.url)?; +// } +// }; +// s_config_create_version(config)?; +// +// Ok(()) +//} +// +//fn to_03(config: Cfg) -> Result<(), Box> { +// s_insert_column(config.clone(), String::from("lists"), String::from("download_folder"), String::from("TEXT"), None)?; +// s_config_update_version(config, String::from("0.3")) +//} +// +//fn to_04(config: Cfg) -> Result<(), Box> { +// for list_id in lists_get_all_ids(config.clone())? { +// s_insert_column(config.clone(), list_id, String::from("disabled_versions"), String::from("TEXT"), Some(String::from("NONE")))?; +// } +// s_config_update_version(config, String::from("0.4")) +//} -fn to_04(config: Cfg) -> Result<(), Box> { - for list_id in lists_get_all_ids(config.clone())? { - s_insert_column(config.clone(), list_id, String::from("disabled_versions"), String::from("TEXT"), Some(String::from("NONE")))?; - } - s_config_update_version(config, String::from("0.4")) -} \ No newline at end of file diff --git a/src/commands/update.rs b/src/commands/update.rs index d400a24..bc5b316 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs @@ -1,4 +1,4 @@ -use 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, lists_get_all_ids, lists_get, userlist_get_current_version, mods_change_versions}, List, input::Input, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; +use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, mods_get_title, userlist_get_set_version}, List, input::Input, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; pub async fn update(config: Cfg, input: Input) -> MLE<()> { let mut liststack: Vec = vec![]; @@ -9,7 +9,7 @@ pub async fn update(config: Cfg, input: Input) -> MLE<()> { } } else { let current = get_current_list(config.clone())?; - println!("Check for updates of mods in list {}", current.id); + println!("Update list {}:", current.id); liststack.push(current) } cmd_update(config, liststack, input.clean, input.direct_download, input.delete_old).await @@ -20,59 +20,41 @@ pub async fn cmd_update(config: Cfg, liststack: Vec, clean: bool, direct_d let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; let mut current_versions: Vec<(String, String)> = vec![]; + + println!(" └Update mods:"); + let mut updatestack: Vec = vec![]; + + for id in mods { + let title = mods_get_title(config.clone(), &id)?; + println!("\t└{}", title); - let mut versions = mods_get_versions(config.clone(), mods.clone())?; - versions.sort_by_key(|ver| ver.mod_id.clone()); - - let mut projects = projects(String::from(&config.apis.modrinth), mods).await; - projects.sort_by_key(|pro| pro.id.clone()); + if userlist_get_set_version(config.clone(), ¤t_list.id, &id)? { + println!("\t └Set version, skipping update"); + continue; + } - println!("Comparing mod versions:"); - let mut updatestack: Vec = vec![]; - for (index, project) in projects.into_iter().enumerate() { - //Get versions for project and check if they match up - let current_version = &versions[index]; - let p_id = String::from(&project.id); - let v_id = ¤t_version.mod_id; - if &p_id != v_id { return Err(MLError::new(ErrorType::Other, "SORTING_ERROR")) }; - - println!("\t({}) Check for update", project.title); - //Getting current installed version for disable or delete - let disable_version = userlist_get_current_version(config.clone(), String::from(¤t_list.id), String::from(&project.id))?; - - let version_db_string = project.versions.join("|"); + let disable_version = userlist_get_current_version(config.clone(), String::from(¤t_list.id), String::from(&id))?; - //Adding to stack if not the same versions in the list OR if clean == true - if clean || (version_db_string != current_version.versions) { - updatestack.push(match specific_update(config.clone(), clean, current_list.clone(), project.clone()).await { + updatestack.push( + match specific_update(config.clone(), clean, current_list.clone(), String::from(&id)).await { Ok(ver) => { - current_versions.push((disable_version, p_id)); + current_versions.push((disable_version, id)); ver }, Err(e) => { - //Catch no update available if e.to_string() == "Mod: NO_UPDATE_AVAILABLE" { - mods_change_versions(config.clone(), version_db_string, project.id)?; - println!("\t └No new version found for the specified minecraft version"); + println!("\t └No new version found for the specified minecraft version"); } else { return Err(e); }; continue; - }, - }); - } else { - println!("\t └No new version found"); - }; + } + } + ) }; - - //Linebreak readability - println!(""); - if clean { clean_list_dir(¤t_list)? }; - - //Linebreak readability - println!(""); + if clean { clean_list_dir(¤t_list)?; }; if direct_download && !updatestack.is_empty() { download_versions(current_list.clone(), config.clone(), updatestack).await?; @@ -81,10 +63,10 @@ pub async fn cmd_update(config: Cfg, liststack: Vec, clean: bool, direct_d if !clean { for ver in current_versions { if delete_old { - println!("Deleting version {} for mod {}", ver.0, ver.1); + println!("\t └Delete version {}", ver.0); delete_version(current_list.clone(), ver.0)?; } else if ver.0 != "NONE" { - println!("Disabling version {} for mod {}", ver.0, ver.1); + println!("\t └Disable version {}", ver.0); disable_version(config.clone(), current_list.clone(), ver.0, ver.1)?; }; } @@ -95,8 +77,8 @@ pub async fn cmd_update(config: Cfg, liststack: Vec, clean: bool, direct_d Ok(()) } -async fn specific_update(config: Cfg, clean: bool, list: List, project: Project) -> MLE { - let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; +async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> MLE { + let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&id), list.clone()).await; let mut versions: Vec = vec![]; @@ -108,12 +90,20 @@ async fn specific_update(config: Cfg, clean: bool, list: List, project: Project) versions.push(String::from("NONE")); } - let mut current: Vec = vec![]; - if clean || (versions.join("|") != userlist_get_applicable_versions(config.clone(), String::from(&list.id), String::from(&project.id))?) { - //get new versions - println!("\t └Get versions for specified minecraft versions"); + //TODO Split clean and no match + if clean || (versions.join("|") != userlist_get_applicable_versions(config.clone(), String::from(&list.id), String::from(&id))?) { + let current_str = extract_current_version(applicable_versions.clone())?; + + if clean { + println!("\t └Add version to downloadstack"); + } else { + println!("\t └Get versions for specified minecraft versions"); + println!("\t └New current version: {}", current_str); + }; + + //get new versions let current_ver = match applicable_versions.into_iter().find(|ver| ver.id == current_str).ok_or("!no current version in applicable_versions") { Ok(v) => Ok(v), Err(e) => Err(MLError::new(ErrorType::Other, e)), @@ -124,7 +114,7 @@ async fn specific_update(config: Cfg, clean: bool, list: List, project: Project) Ok(p) => Ok(p), Err(e) => Err(MLError::new(ErrorType::Other, e)), }?.url; - userlist_change_versions(config, list.id, current_str, versions.join("|"), link, project.id)?; + userlist_change_versions(config, list.id, current_str, versions.join("|"), link, id)?; } if current.is_empty() { return Err(MLError::new(ErrorType::ModError, "NO_UPDATE_AVAILABLE")) }; @@ -139,7 +129,7 @@ async fn download_updates_test() { use crate::{modrinth::{Version, VersionFile, Hash, VersionType}, Modloader, List}; let config = Cfg::init("modlist.toml").unwrap(); - let current_list = List { id: String::from("..."), mc_version: String::from("..."), modloader: Modloader::Forge, download_folder: String::from("./dl") }; + let current_list = List { id: String::from("..."), mc_version: String::from("..."), modloader: Modloader::Fabric, download_folder: String::from("./dev/tests/dl") }; let versions = vec![Version { id: "dEqtGnT9".to_string(), diff --git a/src/db.rs b/src/db.rs index f47bda6..ecc6854 100644 --- a/src/db.rs +++ b/src/db.rs @@ -4,17 +4,17 @@ use rusqlite::Connection; use crate::{Modloader, config::Cfg, List, devdir, error::{MLE, MLError, ErrorType}}; -//mods -pub fn mods_insert(config: Cfg, id: String, name: String, versions: Vec) -> MLE<()> { +//MODS +pub fn mods_insert(config: Cfg, id: &str, slug: &str, name: &str) -> MLE<()> { - println!("Inserting mod {}({}) into database", name, id); + println!("\t └Save mod info"); let data = devdir(format!("{}/data.db", config.data).as_str()); let connection = Connection::open(data)?; connection.execute( - "INSERT INTO mods (id, name, versions) VALUES (?1, ?2, ?3)", - [id, name.replace('\'', ""), versions.join("|")] + "INSERT INTO mods (id, slug, title) VALUES (?1, ?2, ?3)", + [id, slug, name.replace('\'', "").as_str()] )?; Ok(()) @@ -41,32 +41,53 @@ pub fn mods_get_all_ids(config: Cfg) -> Result, Box MLE { - let data = devdir(format!("{}/data.db", config.data).as_str()); +///Get mod id based on the slug or name +///# Arguments +/// +///* `data` - file directory of the database +///* `slug` - Slug or Name of a mod +/// +///# Failure +/// +///Will return `MLError` when no mod id is found +pub fn mods_get_id(data: &str, slug: &str) -> MLE { + let data = devdir(format!("{}/data.db", data).as_str()); let connection = Connection::open(data)?; let mut mod_id = String::new(); - let mut stmt = connection.prepare("SELECT id FROM mods WHERE name = ?")?; - let id_iter = stmt.query_map([name], |row| { + + //get from slug + let mut stmt = connection.prepare("SELECT id FROM mods WHERE slug = ?")?; + let id_iter = stmt.query_map([slug], |row| { row.get::(0) })?; for id in id_iter { mod_id = id?; }; - - match mod_id.is_empty() { - true => Err(MLError::new(ErrorType::DBError, "GI_MOD_NOT_FOUND")), - false => Ok(mod_id), + //get from title if no id found from slug + if mod_id.is_empty() { + let mut stmt = connection.prepare("SELECT id FROM mods WHERE title = ?")?; + let id_iter = stmt.query_map([slug], |row| { + row.get::(0) + })?; + + for id in id_iter { + mod_id = id?; + }; } + + if mod_id.is_empty() { return Err(MLError::new(ErrorType::DBError, "GI_MOD_NOT_FOUND")) }; + + Ok(mod_id) } -pub fn mods_get_name(config: Cfg, id: &str) -> MLE { +pub fn mods_get_title(config: Cfg, id: &str) -> MLE { let data = devdir(format!("{}/data.db", config.data).as_str()); let connection = Connection::open(data)?; let mut mod_name = String::new(); - let mut stmt = connection.prepare("SELECT name FROM mods WHERE id = ?")?; + let mut stmt = connection.prepare("SELECT title FROM mods WHERE id = ?")?; let name_iter = stmt.query_map([id], |row| { row.get::(0) })?; @@ -81,17 +102,6 @@ pub fn mods_get_name(config: Cfg, id: &str) -> MLE { } } -pub fn mods_change_versions(config: Cfg, versions: String, mod_id: String) -> MLE<()> { - - //println!("Updating versions for {} with \n {}", mod_id, versions); - - let data = devdir(format!("{}/data.db", config.data).as_str()); - let connection = Connection::open(data)?; - - connection.execute("UPDATE mods SET versions = ?1 WHERE id = ?2", [versions, mod_id])?; - Ok(()) -} - pub fn mods_remove(config: Cfg, id: String) -> MLE<()> { println!("Removing mod {} from database", id); @@ -124,7 +134,7 @@ pub fn mods_get_versions(config: Cfg, mods: Vec) -> MLE = Vec::new(); - let mut stmt = connection.prepare(format!("SELECT id, versions, name FROM mods {}", wherestr).as_str())?; + let mut stmt = connection.prepare(format!("SELECT id, versions, title FROM mods {}", wherestr).as_str())?; let id_iter = stmt.query_map([], |row| { Ok(vec![row.get::(0)?, row.get::(1)?, row.get::(2)?]) })?; @@ -143,14 +153,18 @@ pub fn mods_get_versions(config: Cfg, mods: Vec) -> MLE, current_link: String) -> MLE<()> { - println!("Inserting {} into current list({})", mod_id, list_id); +pub fn userlist_insert(config: Cfg, list_id: &str, mod_id: &str, current_version: &str, applicable_versions: Vec, current_link: &str, set_version: bool) -> MLE<()> { + println!("\t └Insert in list"); let data = devdir(format!("{}/data.db", config.data).as_str()); let connection = Connection::open(data)?; - - connection.execute(format!("INSERT INTO {} VALUES (?1, ?2, ?3, ?4, 'NONE')", list_id).as_str(), [mod_id, current_version, applicable_versions.join("|"), current_link])?; + let sv = match set_version { + true => "1", + false => "0", + }; + + connection.execute(format!("INSERT INTO {} VALUES (?1, ?2, ?3, ?4, 'NONE', ?5)", list_id).as_str(), [mod_id, current_version, applicable_versions.join("|").as_str(), current_link, sv])?; Ok(()) } @@ -285,6 +299,23 @@ pub fn userlist_get_all_current_versions_with_mods(config: Cfg, list_id: String) Ok(versions) } +pub fn userlist_get_set_version(config:Cfg, list_id: &str, mod_id: &str) -> MLE { + let data = devdir(format!("{}/data.db", config.data).as_str()); + let connection = Connection::open(data).unwrap(); + + let mut set_version: bool = false; + let mut stmt = connection.prepare(format!("SELECT set_version FROM {} WHERE mod_id = ?", list_id).as_str())?; + let ver_iter = stmt.query_map([&mod_id], |row| { + row.get::(0) + })?; + + for ver in ver_iter { + set_version = ver?; + }; + + Ok(set_version) +} + pub fn userlist_change_versions(config: Cfg, list_id: String, current_version: String, versions: String, link: String, mod_id: String) -> MLE<()> { let data = devdir(format!("{}/data.db", config.data).as_str()); let connection = Connection::open(data)?; @@ -357,7 +388,7 @@ pub fn lists_insert(config: Cfg, id: String, mc_version: String, mod_loader: Mod let connection = Connection::open(data)?; connection.execute("INSERT INTO lists VALUES (?1, ?2, ?3, ?4)", [id.clone(), mc_version, mod_loader.to_string(), download_folder])?; - connection.execute(format!("CREATE TABLE {}( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'current_download' TEXT, 'disabled_versions' TEXT DEFAULT 'NONE' )", id).as_str(), [])?; + connection.execute(format!("CREATE TABLE {}( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'current_download' TEXT, 'disabled_versions' TEXT DEFAULT 'NONE', 'set_version' INTEGER, CONSTRAINT {}_PK PRIMARY KEY (mod_id) )", id, id).as_str(), [])?; Ok(()) } @@ -505,7 +536,7 @@ pub fn s_insert_column(config: Cfg, table: String, column: String, c_type: Strin Ok(()) } -pub fn db_setup(config: Cfg) -> Result<(), Box> { +pub fn db_setup(config: Cfg) -> MLE<()> { println!("Initiating database"); @@ -514,9 +545,9 @@ pub fn db_setup(config: Cfg) -> Result<(), Box> { connection.execute_batch( "CREATE TABLE 'user_config' ( 'id' TEXT, 'value' TEXT ); - CREATE TABLE 'mods' ( 'id' TEXT, 'name' TEXT, 'versions' TEXT ); + CREATE TABLE 'mods' ( 'id' TEXT, 'slug' TEXT, 'title' TEXT, CONSTRAINT mods_PK PRIMARY KEY (id) ); CREATE TABLE 'lists' ( 'id' TEXT, 'mc_version' TEXT, 'modloader' TEXT, 'download_folder' TEXT ); - INSERT INTO 'user_config' VALUES ( 'db_version', '0.4' ); + INSERT INTO 'user_config' VALUES ( 'db_version', '0.5' ); INSERT INTO 'user_config' VALUES ( 'current_list', '...' )", )?; diff --git a/src/error.rs b/src/error.rs index 612a2e2..794a919 100644 --- a/src/error.rs +++ b/src/error.rs @@ -39,7 +39,7 @@ impl fmt::Display for MLError { ErrorType::DBError => write!(f, "Database: {}", self.message), ErrorType::ModError => write!(f, "Mod: {}", self.message), ErrorType::LibToml => write!(f, "TOML"), - ErrorType::LibSql => write!(f, "SQL"), + ErrorType::LibSql => write!(f, "SQL: {}", self.message), ErrorType::LibReq => write!(f, "REQWEST"), ErrorType::LibChrono => write!(f, "Chrono error: {}", self.message), ErrorType::IoError => write!(f, "IO"), diff --git a/src/files.rs b/src/files.rs index 8c822b2..b9325ea 100644 --- a/src/files.rs +++ b/src/files.rs @@ -2,17 +2,17 @@ use std::{fs::{File, read_dir, remove_file, rename}, io::Write, collections::Has use futures_util::StreamExt; use reqwest::Client; -use crate::{List, modrinth::Version, db::{userlist_add_disabled_versions, mods_get_name}, config::Cfg, error::{MLE, MLError, ErrorType}}; +use crate::{List, modrinth::Version, db::{userlist_add_disabled_versions, mods_get_title}, config::Cfg, error::{MLE, MLError, ErrorType}}; pub async fn download_versions(list: List, config: Cfg, versions: Vec) -> MLE { let dl_path = String::from(&list.download_folder); - println!("Download to directory from: {} ({})", list.id, dl_path); + println!(" └Download mods to {}", dl_path); for ver in versions { - let project_name = mods_get_name(config.clone(), &ver.project_id)?; - print!("\t({})Download version {}", project_name, ver.id); + let project_name = mods_get_title(config.clone(), &ver.project_id)?; + print!("\t└({})Download version {}", project_name, ver.id); //Force flush of stdout, else print! doesn't print instantly std::io::stdout().flush().unwrap(); let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); @@ -107,7 +107,7 @@ pub fn get_downloaded_versions(list: List) -> MLE> { pub fn clean_list_dir(list: &List) -> MLE<()> { let dl_path = &list.download_folder; - println!("Clean directory for: {}", list.id); + println!(" └Clean directory for: {}", list.id); for entry in std::fs::read_dir(dl_path)? { let entry = entry?; std::fs::remove_file(entry.path())?; diff --git a/src/input.rs b/src/input.rs index 144f22a..17fc773 100644 --- a/src/input.rs +++ b/src/input.rs @@ -29,6 +29,7 @@ pub enum Cmd { Download, Io, Version, + Setup, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -58,7 +59,7 @@ impl Input { args[0] = args[0].split_at(1).1; let mut command: Option = None; - + let mut mod_options: Option = None; let mut mod_id: Option = None; let mut mod_version: Option = None; @@ -77,7 +78,7 @@ impl Input { let mut file: Option = None; for arg in args { - let arg_split: Vec<&str> = arg.trim().split(" ").collect(); + let arg_split: Vec<&str> = arg.trim().split(' ').collect(); match arg_split[0] { "v" | "version" => { command = Some(Cmd::Version); @@ -97,9 +98,8 @@ impl Input { return Err(MLError::new(ErrorType::ArgumentError, "Please specify a list mod slug or id")); } }, + //TODO impl this "mv" => { - command = Some(Cmd::Mod); - mod_options = Some(ModOptions::Add); if arg_split.len() == 2 { mod_version = Some(String::from(arg_split[1])); } else { @@ -195,6 +195,9 @@ impl Input { "f" => { file = Some(String::from(arg_split[1])); }, + "setup" => { + command = Some(Cmd::Setup); + } _ => return Err(MLError::new(ErrorType::ArgumentError, format!("Unknown Argument ({})", arg_split[0]).as_str())), } } @@ -240,11 +243,12 @@ fn check_mod(mut input: Input, config: Cfg) -> MLE { match input.clone().mod_options.unwrap() { ModOptions::Add => { if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "No mod id/slug or version id")); }; - if input.list_id.is_none() { input.list = Some(get_current_list(config.clone())?); }; + if input.list_id.is_none() { input.list = Some(get_current_list(config)?); }; Ok(input) }, ModOptions::Remove => { if input.mod_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID")); }; + if input.list_id.is_none() { input.list = Some(get_current_list(config)?); }; Ok(input) }, } @@ -274,7 +278,6 @@ async fn check_list(mut input: Input, config: Cfg) -> MLE { Ok(input) }, ListOptions::Change => { - //TODO check if no change if input.list.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "NO_LIST_SPECIFIED")); }; Ok(input) }, @@ -292,7 +295,7 @@ async fn check_list(mut input: Input, config: Cfg) -> MLE { fn input_from() { let config = Cfg::init("modlist.toml").unwrap(); assert_eq!( - Input::from(config.clone(), vec![String::from("-la test -lv 1.19.3")]).unwrap(), + Input::from(config, vec![String::from("-la test -lv 1.19.3")]).unwrap(), Input { command: Some(Cmd::List), mod_options: None, @@ -310,7 +313,7 @@ fn input_from() { modloader: None, directory: None, io_options: None, - file: None + file: None, } ); diff --git a/src/main.rs b/src/main.rs index d177c3e..32727c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,20 @@ use std::{env, process}; -use modlist::{config::Cfg, input::{get_input, Cmd}, update, download, list, io, modification}; +use modlist::{config::Cfg, input::{get_input, Cmd}, update, download, list, io, modification, setup}; #[tokio::main] async fn main() { let config = Cfg::init("modlist.toml").unwrap(); - + let mut args: Vec = env::args().collect(); args.reverse(); args.pop(); args.reverse(); + + if args.is_empty() { + println!("Please enter an argument"); + process::exit(1); + }; let input = match get_input(config.clone(), args).await { Ok(i) => i, @@ -19,8 +24,6 @@ async fn main() { } }; - //dbg!(&input); - match input.clone().command.unwrap() { Cmd::Mod => { modification(config, input).await @@ -41,6 +44,9 @@ async fn main() { show_version(); Ok(()) }, + Cmd::Setup => { + setup(config).await + }, }.unwrap() } diff --git a/tests/db.rs b/tests/db.rs deleted file mode 100644 index 992899f..0000000 --- a/tests/db.rs +++ /dev/null @@ -1,249 +0,0 @@ -use std::{fs::{File, create_dir_all, remove_dir_all}, path::Path, sync::Once}; - -use modlist::{config::{Cfg, Apis}, db::{mods_insert, db_setup, mods_get_all_ids, mods_get_id, mods_remove, userlist_insert, lists_insert, userlist_get_all_ids, userlist_remove, mods_get_versions, userlist_get_applicable_versions, lists_remove, lists_get, lists_get_all_ids, userlist_get_all_current_version_ids, userlist_change_versions, s_userlist_update_download, userlist_get_all_downloads, config_change_current_list, config_get_current_list, s_config_update_version, s_config_create_version, s_config_get_version}, Modloader, List}; - -static INIT: Once = Once::new(); - -fn setup() -> Cfg { - let db_pathstr = "./test_tmp/db"; - - let config = Cfg { data: String::from(db_pathstr), apis: Apis { modrinth: String::from("-") } }; - - INIT.call_once(|| { - let db_path = Path::new(db_pathstr); - if db_path.exists() { remove_dir_all(db_pathstr).unwrap(); }; - create_dir_all(db_path).unwrap(); - let db_filestr = format!("{}/data.db", db_pathstr); - File::create(db_filestr).unwrap(); - println!("INIT TEST DB"); - db_setup(config.clone()).unwrap(); - }); - config -} - -#[test] -fn test_mods_insert() { - let config = setup(); - - mods_insert(config.clone(), String::from("I"), String::from("INSERT_TEST"), vec![String::from("INSERT_VER1"), String::from("INSERT_VER2")]).unwrap(); - let ids = mods_get_all_ids(config).unwrap(); - - assert!(ids.contains(&String::from("I"))); -} - -#[test] -fn test_mods_get_all_ids() { - let config = setup(); - - mods_insert(config.clone(), String::from("GAI1"), String::from("GETALLIDS_TEST1"), vec![String::from("GAI1_VER1"), String::from("GAI1_VER2")]).unwrap(); - mods_insert(config.clone(), String::from("GAI2"), String::from("GETALLIDS_TEST2"), vec![String::from("GAI2_VER1"), String::from("GAI2_VER2")]).unwrap(); - let ids = mods_get_all_ids(config).unwrap(); - - assert!(ids.contains(&String::from("GAI1"))); - assert!(ids.contains(&String::from("GAI2"))); -} - -#[test] -fn test_mods_get_id() { - let config = setup(); - - mods_insert(config, String::from("GI"), String::from("GETID_TEST"), vec![String::from("GI_VER1"), String::from("GI_VER2")]).unwrap(); -} - -#[test] -fn test_mods_remove() { - let config = setup(); - - mods_insert(config.clone(), String::from("R"), String::from("REMOVE_TEST"), vec![String::from("R_VER1"), String::from("R_VER2")]).unwrap(); - let ids = mods_get_all_ids(config.clone()).unwrap(); - assert!(ids.contains(&String::from("R"))); - mods_remove(config.clone(), String::from("R")).unwrap(); - assert!(mods_get_id(config, String::from("REMOVE_TEST")).is_err()); -} - -#[test] -fn test_mods_get_versions() { - let config = setup(); - - mods_insert(config.clone(), String::from("M_GVs1"), String::from("M_GVs_TEST1"), vec![String::from("M_GVs1_VER1"), String::from("M_GVs1_VER2")]).unwrap(); - mods_insert(config.clone(), String::from("M_GVs2"), String::from("M_GVs_TEST2"), vec![String::from("M_GVs2_VER1"), String::from("M_GVs2_VER2")]).unwrap(); - let versions = mods_get_versions(config, vec![String::from("M_GVs1"), String::from("M_GVs2")]).unwrap(); - - assert!(versions.contains(&modlist::db::DBModlistVersions { mod_id: String::from("M_GVs1"), versions: String::from("M_GVs1_VER1|M_GVs1_VER2") })); - assert!(versions.contains(&modlist::db::DBModlistVersions { mod_id: String::from("M_GVs2"), versions: String::from("M_GVs2_VER1|M_GVs2_VER2") })); -} - -//user_list -#[test] -fn test_userlist_insert() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_I_LIST"), String::from("UL_I_MC"), Modloader::Fabric, String::from("UL_I_FOLDER")).unwrap(); - userlist_insert(config, String::from("UL_I_LIST"), String::from("UL_I"), String::from("UL_I_VER1"), vec![String::from("UL_I_VER1"), String::from("UL_I_VER2")], String::from("localhost:8080/dl/UL_I_VER1.test")).unwrap(); -} - -#[test] -fn test_userlist_get_all_ids() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI_MC"), Modloader::Fabric, String::from("UL_GAI_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI1"), String::from("UL_GAI1_VER1"), vec![String::from("UL_GAI2_VER1"), String::from("UL_GAI1_VER2")], String::from("localhost:8080/dl/UL_GAI1_VER1.test")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI2"), String::from("UL_GAI2_VER1"), vec![String::from("UL_GAI2_VER1"), String::from("UL_GAI2_VER2")], String::from("localhost:8080/dl/UL_GAI2_VER1.test")).unwrap(); - let ids = userlist_get_all_ids(config, String::from("UL_GAI_LIST")).unwrap(); - - assert!(ids.contains(&String::from("UL_GAI1"))); - assert!(ids.contains(&String::from("UL_GAI2"))); -} - -#[test] -fn test_userlist_remove() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_R_LIST"), String::from("UL_R_MC"), Modloader::Fabric, String::from("UL_R_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_R_LIST"), String::from("UL_R"), String::from("UL_R_VER1"), vec![String::from("UL_R_VER1"), String::from("UL_R_VER2")], String::from("localhost:8080/dl/UL_R_VER1.test")).unwrap(); - let ids = userlist_get_all_ids(config.clone(), String::from("UL_R_LIST")).unwrap(); - assert!(ids.contains(&String::from("UL_R"))); - userlist_remove(config.clone(), String::from("UL_R_LIST"), String::from("UL_R")).unwrap(); - assert!(userlist_get_all_ids(config, String::from("UL_R_LIST")).is_err()) -} - -#[test] -fn test_userlist_get_applicable_versions() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_GAV_LIST"), String::from("UL_GAV_MC"), Modloader::Fabric, String::from("UL_GAV_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GAV_LIST"), String::from("UL_GAV"), String::from("UL_GAV_VER1"), vec![String::from("UL_GAV_VER1"), String::from("UL_GAV_VER2")], String::from("localhost:8080/dl/UL_GAV_VER1.test")).unwrap(); - assert_eq!(userlist_get_applicable_versions(config, String::from("UL_GAV_LIST"), String::from("UL_GAV")).unwrap(), String::from("UL_GAV_VER1|UL_GAV_VER2")); -} - -#[test] -fn test_userlist_get_all_current_version_ids() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI_MC"), Modloader::Fabric, String::from("UL_GACVI_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI1"), String::from("UL_GACVI1_VER1"), vec![String::from("UL_GACVI2_VER1"), String::from("UL_GACVI1_VER2")], String::from("localhost:8080/dl/UL_GACVI1_VER1.test")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI2"), String::from("UL_GACVI2_VER1"), vec![String::from("UL_GACVI2_VER1"), String::from("UL_GACVI2_VER2")], String::from("localhost:8080/dl/UL_GACVI2_VER1.test")).unwrap(); - - let ids = userlist_get_all_current_version_ids(config, String::from("UL_GACVI_LIST")).unwrap(); - - assert!(ids.contains(&String::from("UL_GACVI1_VER1"))); - assert!(ids.contains(&String::from("UL_GACVI2_VER1"))); -} - -#[test] -fn test_userlist_change_versions() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV_MC"), Modloader::Fabric, String::from("UL_CV_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV"), String::from("UL_CV_VER1"), vec![String::from("UL_CV_VER1"), String::from("UL_CV_VER2")], String::from("localhost:8080/dl/UL_CV_VER1.test")).unwrap(); - let versions = userlist_get_all_current_version_ids(config.clone(), String::from("UL_CV_LIST")).unwrap(); - assert!(versions.contains(&String::from("UL_CV_VER1"))); - - userlist_change_versions(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV_VER3"), String::from("UL_CV_VER1|UL_CV_VER2|UL_CV_VER3"), String::from("localhost:8080/dl/UL_CV_VER3.test"), String::from("UL_CV")).unwrap(); - let versions = userlist_get_all_current_version_ids(config, String::from("UL_CV_LIST")).unwrap(); - assert!(!versions.contains(&String::from("UL_CV_VER1"))); - assert!(versions.contains(&String::from("UL_CV_VER3"))); -} - -#[test] -fn test_userlist_get_all_downloads() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD_MC"), Modloader::Fabric, String::from("UL_GAD_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD1"), String::from("UL_GAD1_VER1"), vec![String::from("UL_GAD1_VER1"), String::from("UL_GAD1_VER1")], String::from("localhost:8080/dl/UL_GAD1_VER1.test")).unwrap(); - userlist_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD2"), String::from("UL_GAD2_VER1"), vec![String::from("UL_GAD2_VER1"), String::from("UL_GAD2_VER1")], String::from("localhost:8080/dl/UL_GAD2_VER1.test")).unwrap(); - let links = userlist_get_all_downloads(config, String::from("UL_GAD_LIST")).unwrap(); - - assert!(links.contains(&String::from("localhost:8080/dl/UL_GAD1_VER1.test"))); - assert!(links.contains(&String::from("localhost:8080/dl/UL_GAD2_VER1.test"))); -} - - -//lists -#[test] -fn test_lists_insert() { - let config = setup(); - - lists_insert(config, String::from("L_I_LIST"), String::from("L_I_MC"), Modloader::Fabric, String::from("L_I_FOLDER")).unwrap(); -} - -#[test] -fn test_lists_remove() { - let config = setup(); - - lists_insert(config.clone(), String::from("L_R_LIST"), String::from("L_R_MC"), Modloader::Fabric, String::from("L_R_FOLDER")).unwrap(); - lists_remove(config, String::from("L_R_LIST")).unwrap(); -} - -#[test] -fn test_lists_get() { - let config = setup(); - - lists_insert(config.clone(), String::from("L_G_LIST"), String::from("L_G_MC"), Modloader::Fabric, String::from("L_G_FOLDER")).unwrap(); - - assert_eq!(lists_get(config, String::from("L_G_LIST")).unwrap(), List { id: String::from("L_G_LIST"), mc_version: String::from("L_G_MC"), modloader: Modloader::Fabric, download_folder: String::from("L_G_FOLDER") }); -} - -#[test] -fn test_lists_get_all_ids() { - let config = setup(); - - lists_insert(config.clone(), String::from("L_GAI1_LIST"), String::from("L_GAI1_MC"), Modloader::Fabric, String::from("L_GAI1_FOLDER")).unwrap(); - lists_insert(config.clone(), String::from("L_GAI2_LIST"), String::from("L_GAI2_MC"), Modloader::Fabric, String::from("L_GAI2_FOLDER")).unwrap(); - let ids = lists_get_all_ids(config).unwrap(); - - assert!(ids.contains(&String::from("L_GAI1_LIST"))); - assert!(ids.contains(&String::from("L_GAI2_LIST"))); -} - -//config -#[test] -fn test_config_change_current_list() { - let config = setup(); - - config_change_current_list(config, String::from("C_CCL_LIST")).unwrap(); -} - -#[test] -fn test_config_get_current_list() { - let config = setup(); - - config_change_current_list(config.clone(), String::from("C_GCL_LIST")).unwrap(); - assert_eq!(config_get_current_list(config).unwrap(), String::from("C_GCL_LIST")); -} - -//setup -#[test] -fn test_s_userlist_update_download() { - let config = setup(); - - lists_insert(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD_MC"), Modloader::Fabric, String::from("UL_UD_FOLDER")).unwrap(); - userlist_insert(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD"), String::from("UL_UD_VER1"), vec![String::from("UL_UD_VER1"), String::from("UL_UD_VER1")], String::from("localhost:8080/dl/UL_UD_VER1.test")).unwrap(); - s_userlist_update_download(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD"), String::from("localhost:8080/dl/UL_UD_VER1X.test")).unwrap(); - let links = userlist_get_all_downloads(config, String::from("UL_UD_LIST")).unwrap(); - - assert!(links.contains(&String::from("localhost:8080/dl/UL_UD_VER1X.test"))); - assert!(!links.contains(&String::from("localhost:8080/dl/UL_UD_VER1.test"))); -} - -#[test] -fn test_s_config_create_version() { - let config = setup(); - - s_config_create_version(config).unwrap(); -} - -#[test] -fn test_s_config_update_version() { - let config = setup(); - - s_config_update_version(config, String::from("S_C_UV")).unwrap(); -} - -#[test] -fn test_s_config_get_version() { - let config = setup(); - - s_config_update_version(config.clone(), String::from("S_C_GV")).unwrap(); - assert_eq!(s_config_get_version(config).unwrap(), String::from("S_C_GV")); -} -- cgit v1.2.3