summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Cargo.lock139
-rw-r--r--Cargo.toml2
-rw-r--r--src/cache.rs37
-rw-r--r--src/commands/download.rs2
-rw-r--r--src/commands/io.rs5
-rw-r--r--src/commands/mod.rs2
-rw-r--r--src/commands/setup.rs70
-rw-r--r--src/commands/update.rs98
-rw-r--r--src/config.rs84
-rw-r--r--src/db.rs70
-rw-r--r--src/files.rs72
-rw-r--r--src/lib.rs17
-rw-r--r--src/main.rs26
14 files changed, 327 insertions, 301 deletions
diff --git a/.gitignore b/.gitignore
index 390e3b2..343357f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@
7.planmodlist.autosave.xopp 7.planmodlist.autosave.xopp
8data.db.cp 8data.db.cp
9export.toml 9export.toml
10config.toml 10modlist.toml
11/dev 11/dev
12/.fleet 12/.fleet
13/.vscode \ No newline at end of file 13/.vscode
diff --git a/Cargo.lock b/Cargo.lock
index f99cd87..f25b161 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,9 +39,9 @@ dependencies = [
39 39
40[[package]] 40[[package]]
41name = "anstream" 41name = "anstream"
42version = "0.3.0" 42version = "0.3.1"
43source = "registry+https://github.com/rust-lang/crates.io-index" 43source = "registry+https://github.com/rust-lang/crates.io-index"
44checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" 44checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450"
45dependencies = [ 45dependencies = [
46 "anstyle", 46 "anstyle",
47 "anstyle-parse", 47 "anstyle-parse",
@@ -78,9 +78,9 @@ dependencies = [
78 78
79[[package]] 79[[package]]
80name = "anstyle-wincon" 80name = "anstyle-wincon"
81version = "1.0.0" 81version = "1.0.1"
82source = "registry+https://github.com/rust-lang/crates.io-index" 82source = "registry+https://github.com/rust-lang/crates.io-index"
83checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" 83checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
84dependencies = [ 84dependencies = [
85 "anstyle", 85 "anstyle",
86 "windows-sys 0.48.0", 86 "windows-sys 0.48.0",
@@ -121,15 +121,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
121 121
122[[package]] 122[[package]]
123name = "bitflags" 123name = "bitflags"
124version = "2.0.2" 124version = "2.2.1"
125source = "registry+https://github.com/rust-lang/crates.io-index" 125source = "registry+https://github.com/rust-lang/crates.io-index"
126checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" 126checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
127 127
128[[package]] 128[[package]]
129name = "bumpalo" 129name = "bumpalo"
130version = "3.12.0" 130version = "3.12.1"
131source = "registry+https://github.com/rust-lang/crates.io-index" 131source = "registry+https://github.com/rust-lang/crates.io-index"
132checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" 132checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8"
133 133
134[[package]] 134[[package]]
135name = "bytes" 135name = "bytes"
@@ -166,9 +166,9 @@ dependencies = [
166 166
167[[package]] 167[[package]]
168name = "clap" 168name = "clap"
169version = "4.2.2" 169version = "4.2.4"
170source = "registry+https://github.com/rust-lang/crates.io-index" 170source = "registry+https://github.com/rust-lang/crates.io-index"
171checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a" 171checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62"
172dependencies = [ 172dependencies = [
173 "clap_builder", 173 "clap_builder",
174 "clap_derive", 174 "clap_derive",
@@ -177,9 +177,9 @@ dependencies = [
177 177
178[[package]] 178[[package]]
179name = "clap_builder" 179name = "clap_builder"
180version = "4.2.2" 180version = "4.2.4"
181source = "registry+https://github.com/rust-lang/crates.io-index" 181source = "registry+https://github.com/rust-lang/crates.io-index"
182checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6" 182checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749"
183dependencies = [ 183dependencies = [
184 "anstream", 184 "anstream",
185 "anstyle", 185 "anstyle",
@@ -190,9 +190,9 @@ dependencies = [
190 190
191[[package]] 191[[package]]
192name = "clap_complete" 192name = "clap_complete"
193version = "4.2.0" 193version = "4.2.1"
194source = "registry+https://github.com/rust-lang/crates.io-index" 194source = "registry+https://github.com/rust-lang/crates.io-index"
195checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" 195checksum = "1a19591b2ab0e3c04b588a0e04ddde7b9eaa423646d1b4a8092879216bf47473"
196dependencies = [ 196dependencies = [
197 "clap", 197 "clap",
198] 198]
@@ -206,7 +206,7 @@ dependencies = [
206 "heck", 206 "heck",
207 "proc-macro2", 207 "proc-macro2",
208 "quote", 208 "quote",
209 "syn 2.0.13", 209 "syn 2.0.15",
210] 210]
211 211
212[[package]] 212[[package]]
@@ -271,7 +271,7 @@ dependencies = [
271 "proc-macro2", 271 "proc-macro2",
272 "quote", 272 "quote",
273 "scratch", 273 "scratch",
274 "syn 2.0.13", 274 "syn 2.0.15",
275] 275]
276 276
277[[package]] 277[[package]]
@@ -288,7 +288,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
288dependencies = [ 288dependencies = [
289 "proc-macro2", 289 "proc-macro2",
290 "quote", 290 "quote",
291 "syn 2.0.13", 291 "syn 2.0.15",
292] 292]
293 293
294[[package]] 294[[package]]
@@ -322,13 +322,13 @@ dependencies = [
322 322
323[[package]] 323[[package]]
324name = "errno" 324name = "errno"
325version = "0.3.0" 325version = "0.3.1"
326source = "registry+https://github.com/rust-lang/crates.io-index" 326source = "registry+https://github.com/rust-lang/crates.io-index"
327checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" 327checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
328dependencies = [ 328dependencies = [
329 "errno-dragonfly", 329 "errno-dragonfly",
330 "libc", 330 "libc",
331 "windows-sys 0.45.0", 331 "windows-sys 0.48.0",
332] 332]
333 333
334[[package]] 334[[package]]
@@ -431,7 +431,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
431dependencies = [ 431dependencies = [
432 "proc-macro2", 432 "proc-macro2",
433 "quote", 433 "quote",
434 "syn 2.0.13", 434 "syn 2.0.15",
435] 435]
436 436
437[[package]] 437[[package]]
@@ -465,9 +465,9 @@ dependencies = [
465 465
466[[package]] 466[[package]]
467name = "getrandom" 467name = "getrandom"
468version = "0.2.8" 468version = "0.2.9"
469source = "registry+https://github.com/rust-lang/crates.io-index" 469source = "registry+https://github.com/rust-lang/crates.io-index"
470checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 470checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
471dependencies = [ 471dependencies = [
472 "cfg-if", 472 "cfg-if",
473 "libc", 473 "libc",
@@ -482,9 +482,9 @@ checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
482 482
483[[package]] 483[[package]]
484name = "h2" 484name = "h2"
485version = "0.3.16" 485version = "0.3.18"
486source = "registry+https://github.com/rust-lang/crates.io-index" 486source = "registry+https://github.com/rust-lang/crates.io-index"
487checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" 487checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
488dependencies = [ 488dependencies = [
489 "bytes", 489 "bytes",
490 "fnv", 490 "fnv",
@@ -574,9 +574,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
574 574
575[[package]] 575[[package]]
576name = "hyper" 576name = "hyper"
577version = "0.14.25" 577version = "0.14.26"
578source = "registry+https://github.com/rust-lang/crates.io-index" 578source = "registry+https://github.com/rust-lang/crates.io-index"
579checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" 579checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
580dependencies = [ 580dependencies = [
581 "bytes", 581 "bytes",
582 "futures-channel", 582 "futures-channel",
@@ -664,13 +664,13 @@ dependencies = [
664 664
665[[package]] 665[[package]]
666name = "io-lifetimes" 666name = "io-lifetimes"
667version = "1.0.9" 667version = "1.0.10"
668source = "registry+https://github.com/rust-lang/crates.io-index" 668source = "registry+https://github.com/rust-lang/crates.io-index"
669checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" 669checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
670dependencies = [ 670dependencies = [
671 "hermit-abi 0.3.1", 671 "hermit-abi 0.3.1",
672 "libc", 672 "libc",
673 "windows-sys 0.45.0", 673 "windows-sys 0.48.0",
674] 674]
675 675
676[[package]] 676[[package]]
@@ -681,14 +681,14 @@ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
681 681
682[[package]] 682[[package]]
683name = "is-terminal" 683name = "is-terminal"
684version = "0.4.6" 684version = "0.4.7"
685source = "registry+https://github.com/rust-lang/crates.io-index" 685source = "registry+https://github.com/rust-lang/crates.io-index"
686checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" 686checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
687dependencies = [ 687dependencies = [
688 "hermit-abi 0.3.1", 688 "hermit-abi 0.3.1",
689 "io-lifetimes", 689 "io-lifetimes",
690 "rustix", 690 "rustix",
691 "windows-sys 0.45.0", 691 "windows-sys 0.48.0",
692] 692]
693 693
694[[package]] 694[[package]]
@@ -714,9 +714,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
714 714
715[[package]] 715[[package]]
716name = "libc" 716name = "libc"
717version = "0.2.141" 717version = "0.2.142"
718source = "registry+https://github.com/rust-lang/crates.io-index" 718source = "registry+https://github.com/rust-lang/crates.io-index"
719checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" 719checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
720 720
721[[package]] 721[[package]]
722name = "libsqlite3-sys" 722name = "libsqlite3-sys"
@@ -740,9 +740,9 @@ dependencies = [
740 740
741[[package]] 741[[package]]
742name = "linux-raw-sys" 742name = "linux-raw-sys"
743version = "0.3.1" 743version = "0.3.4"
744source = "registry+https://github.com/rust-lang/crates.io-index" 744source = "registry+https://github.com/rust-lang/crates.io-index"
745checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" 745checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf"
746 746
747[[package]] 747[[package]]
748name = "lock_api" 748name = "lock_api"
@@ -798,7 +798,7 @@ dependencies = [
798 798
799[[package]] 799[[package]]
800name = "modlist" 800name = "modlist"
801version = "0.12.0" 801version = "0.13.1"
802dependencies = [ 802dependencies = [
803 "chrono", 803 "chrono",
804 "clap", 804 "clap",
@@ -878,9 +878,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
878 878
879[[package]] 879[[package]]
880name = "openssl" 880name = "openssl"
881version = "0.10.49" 881version = "0.10.52"
882source = "registry+https://github.com/rust-lang/crates.io-index" 882source = "registry+https://github.com/rust-lang/crates.io-index"
883checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" 883checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56"
884dependencies = [ 884dependencies = [
885 "bitflags 1.3.2", 885 "bitflags 1.3.2",
886 "cfg-if", 886 "cfg-if",
@@ -899,7 +899,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
899dependencies = [ 899dependencies = [
900 "proc-macro2", 900 "proc-macro2",
901 "quote", 901 "quote",
902 "syn 2.0.13", 902 "syn 2.0.15",
903] 903]
904 904
905[[package]] 905[[package]]
@@ -910,9 +910,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
910 910
911[[package]] 911[[package]]
912name = "openssl-sys" 912name = "openssl-sys"
913version = "0.9.84" 913version = "0.9.87"
914source = "registry+https://github.com/rust-lang/crates.io-index" 914source = "registry+https://github.com/rust-lang/crates.io-index"
915checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" 915checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
916dependencies = [ 916dependencies = [
917 "cc", 917 "cc",
918 "libc", 918 "libc",
@@ -1059,7 +1059,7 @@ version = "0.29.0"
1059source = "registry+https://github.com/rust-lang/crates.io-index" 1059source = "registry+https://github.com/rust-lang/crates.io-index"
1060checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" 1060checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
1061dependencies = [ 1061dependencies = [
1062 "bitflags 2.0.2", 1062 "bitflags 2.2.1",
1063 "fallible-iterator", 1063 "fallible-iterator",
1064 "fallible-streaming-iterator", 1064 "fallible-streaming-iterator",
1065 "hashlink", 1065 "hashlink",
@@ -1069,22 +1069,22 @@ dependencies = [
1069 1069
1070[[package]] 1070[[package]]
1071name = "rustc-demangle" 1071name = "rustc-demangle"
1072version = "0.1.22" 1072version = "0.1.23"
1073source = "registry+https://github.com/rust-lang/crates.io-index" 1073source = "registry+https://github.com/rust-lang/crates.io-index"
1074checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" 1074checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
1075 1075
1076[[package]] 1076[[package]]
1077name = "rustix" 1077name = "rustix"
1078version = "0.37.7" 1078version = "0.37.15"
1079source = "registry+https://github.com/rust-lang/crates.io-index" 1079source = "registry+https://github.com/rust-lang/crates.io-index"
1080checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" 1080checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece"
1081dependencies = [ 1081dependencies = [
1082 "bitflags 1.3.2", 1082 "bitflags 1.3.2",
1083 "errno", 1083 "errno",
1084 "io-lifetimes", 1084 "io-lifetimes",
1085 "libc", 1085 "libc",
1086 "linux-raw-sys", 1086 "linux-raw-sys",
1087 "windows-sys 0.45.0", 1087 "windows-sys 0.48.0",
1088] 1088]
1089 1089
1090[[package]] 1090[[package]]
@@ -1139,29 +1139,29 @@ dependencies = [
1139 1139
1140[[package]] 1140[[package]]
1141name = "serde" 1141name = "serde"
1142version = "1.0.159" 1142version = "1.0.160"
1143source = "registry+https://github.com/rust-lang/crates.io-index" 1143source = "registry+https://github.com/rust-lang/crates.io-index"
1144checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" 1144checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
1145dependencies = [ 1145dependencies = [
1146 "serde_derive", 1146 "serde_derive",
1147] 1147]
1148 1148
1149[[package]] 1149[[package]]
1150name = "serde_derive" 1150name = "serde_derive"
1151version = "1.0.159" 1151version = "1.0.160"
1152source = "registry+https://github.com/rust-lang/crates.io-index" 1152source = "registry+https://github.com/rust-lang/crates.io-index"
1153checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" 1153checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
1154dependencies = [ 1154dependencies = [
1155 "proc-macro2", 1155 "proc-macro2",
1156 "quote", 1156 "quote",
1157 "syn 2.0.13", 1157 "syn 2.0.15",
1158] 1158]
1159 1159
1160[[package]] 1160[[package]]
1161name = "serde_json" 1161name = "serde_json"
1162version = "1.0.95" 1162version = "1.0.96"
1163source = "registry+https://github.com/rust-lang/crates.io-index" 1163source = "registry+https://github.com/rust-lang/crates.io-index"
1164checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" 1164checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
1165dependencies = [ 1165dependencies = [
1166 "itoa", 1166 "itoa",
1167 "ryu", 1167 "ryu",
@@ -1242,9 +1242,9 @@ dependencies = [
1242 1242
1243[[package]] 1243[[package]]
1244name = "syn" 1244name = "syn"
1245version = "2.0.13" 1245version = "2.0.15"
1246source = "registry+https://github.com/rust-lang/crates.io-index" 1246source = "registry+https://github.com/rust-lang/crates.io-index"
1247checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" 1247checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
1248dependencies = [ 1248dependencies = [
1249 "proc-macro2", 1249 "proc-macro2",
1250 "quote", 1250 "quote",
@@ -1290,7 +1290,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
1290dependencies = [ 1290dependencies = [
1291 "proc-macro2", 1291 "proc-macro2",
1292 "quote", 1292 "quote",
1293 "syn 2.0.13", 1293 "syn 2.0.15",
1294] 1294]
1295 1295
1296[[package]] 1296[[package]]
@@ -1321,9 +1321,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1321 1321
1322[[package]] 1322[[package]]
1323name = "tokio" 1323name = "tokio"
1324version = "1.27.0" 1324version = "1.28.0"
1325source = "registry+https://github.com/rust-lang/crates.io-index" 1325source = "registry+https://github.com/rust-lang/crates.io-index"
1326checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" 1326checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f"
1327dependencies = [ 1327dependencies = [
1328 "autocfg", 1328 "autocfg",
1329 "bytes", 1329 "bytes",
@@ -1335,18 +1335,18 @@ dependencies = [
1335 "signal-hook-registry", 1335 "signal-hook-registry",
1336 "socket2", 1336 "socket2",
1337 "tokio-macros", 1337 "tokio-macros",
1338 "windows-sys 0.45.0", 1338 "windows-sys 0.48.0",
1339] 1339]
1340 1340
1341[[package]] 1341[[package]]
1342name = "tokio-macros" 1342name = "tokio-macros"
1343version = "2.0.0" 1343version = "2.1.0"
1344source = "registry+https://github.com/rust-lang/crates.io-index" 1344source = "registry+https://github.com/rust-lang/crates.io-index"
1345checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" 1345checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
1346dependencies = [ 1346dependencies = [
1347 "proc-macro2", 1347 "proc-macro2",
1348 "quote", 1348 "quote",
1349 "syn 2.0.13", 1349 "syn 2.0.15",
1350] 1350]
1351 1351
1352[[package]] 1352[[package]]
@@ -1361,9 +1361,9 @@ dependencies = [
1361 1361
1362[[package]] 1362[[package]]
1363name = "tokio-util" 1363name = "tokio-util"
1364version = "0.7.7" 1364version = "0.7.8"
1365source = "registry+https://github.com/rust-lang/crates.io-index" 1365source = "registry+https://github.com/rust-lang/crates.io-index"
1366checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" 1366checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
1367dependencies = [ 1367dependencies = [
1368 "bytes", 1368 "bytes",
1369 "futures-core", 1369 "futures-core",
@@ -1415,11 +1415,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
1415 1415
1416[[package]] 1416[[package]]
1417name = "tracing" 1417name = "tracing"
1418version = "0.1.37" 1418version = "0.1.38"
1419source = "registry+https://github.com/rust-lang/crates.io-index" 1419source = "registry+https://github.com/rust-lang/crates.io-index"
1420checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1420checksum = "cf9cf6a813d3f40c88b0b6b6f29a5c95c6cdbf97c1f9cc53fb820200f5ad814d"
1421dependencies = [ 1421dependencies = [
1422 "cfg-if",
1423 "pin-project-lite", 1422 "pin-project-lite",
1424 "tracing-core", 1423 "tracing-core",
1425] 1424]
diff --git a/Cargo.toml b/Cargo.toml
index 51652f3..7b6466f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
1[package] 1[package]
2name = "modlist" 2name = "modlist"
3version = "0.12.0" 3version = "0.13.1"
4edition = "2021" 4edition = "2021"
5 5
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/src/cache.rs b/src/cache.rs
new file mode 100644
index 0000000..11645d1
--- /dev/null
+++ b/src/cache.rs
@@ -0,0 +1,37 @@
1use std::{
2 collections::HashMap,
3 fs::{copy, read_dir},
4};
5
6/// .
7///
8/// # Panics
9///
10/// Panics if .
11pub fn get_cached_versions(path: &str) -> HashMap<String, String> {
12 let mut versions: HashMap<String, String> = HashMap::new();
13 for file in read_dir(path).unwrap() {
14 let path = file.unwrap().path();
15 if path.is_file() && path.extension().ok_or("BAH").unwrap() == "jar" {
16 let pathstr = path.to_str().ok_or("BAH").unwrap();
17 let namesplit: Vec<&str> = pathstr.split('.').collect();
18 versions.insert(
19 String::from(namesplit[namesplit.len() - 2]),
20 String::from(pathstr),
21 );
22 }
23 }
24 versions
25}
26
27/// .
28///
29/// # Panics
30///
31/// Panics if .
32pub fn copy_cached_version(version_path: &str, download_path: &str) {
33 let versplit: Vec<&str> = version_path.split('/').collect();
34 let download = format!("{}{}", download_path, versplit[versplit.len() - 1]);
35 // println!("{:#?}", download);
36 copy(version_path, download).unwrap();
37}
diff --git a/src/commands/download.rs b/src/commands/download.rs
index 9434591..1a8eb8f 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -23,7 +23,7 @@ pub async fn download(config: Cfg, all_lists: bool, clean: bool, delete_old: boo
23 23
24 for current_list in liststack { 24 for current_list in liststack {
25 let downloaded_versions = get_downloaded_versions(current_list.clone())?; 25 let downloaded_versions = get_downloaded_versions(current_list.clone())?;
26 println!("To download: {:#?}", downloaded_versions); 26 // println!("To download: {:#?}", downloaded_versions);
27 let current_version_ids = match userlist_get_all_current_versions_with_mods( 27 let current_version_ids = match userlist_get_all_current_versions_with_mods(
28 config.clone(), 28 config.clone(),
29 String::from(&current_list.id), 29 String::from(&current_list.id),
diff --git a/src/commands/io.rs b/src/commands/io.rs
index 7f03eec..82b30ce 100644
--- a/src/commands/io.rs
+++ b/src/commands/io.rs
@@ -5,7 +5,6 @@ use std::io::prelude::*;
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_all_ids},
8 devdir,
9 error::MLE, 8 error::MLE,
10 mod_add, IDSelector, List, Modloader, 9 mod_add, IDSelector, List, Modloader,
11}; 10};
@@ -61,9 +60,7 @@ pub fn export(config: Cfg, list: Option<String>) -> MLE<()> {
61 60
62 let filestr = dirs::home_dir().unwrap().join("mlexport.toml"); 61 let filestr = dirs::home_dir().unwrap().join("mlexport.toml");
63 62
64 let mut file = File::create(devdir( 63 let mut file = File::create(filestr.into_os_string().into_string().unwrap().as_str())?;
65 filestr.into_os_string().into_string().unwrap().as_str(),
66 ))?;
67 file.write_all(toml.as_bytes())?; 64 file.write_all(toml.as_bytes())?;
68 65
69 Ok(()) 66 Ok(())
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 1c7c012..0f13056 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -2,12 +2,10 @@ pub mod download;
2pub mod io; 2pub mod io;
3pub mod list; 3pub mod list;
4pub mod modification; 4pub mod modification;
5pub mod setup;
6pub mod update; 5pub mod update;
7 6
8pub use download::*; 7pub use download::*;
9pub use io::*; 8pub use io::*;
10pub use list::*; 9pub use list::*;
11pub use modification::*; 10pub use modification::*;
12pub use setup::*;
13pub use update::*; 11pub use update::*;
diff --git a/src/commands/setup.rs b/src/commands/setup.rs
deleted file mode 100644
index 40e8c0a..0000000
--- a/src/commands/setup.rs
+++ /dev/null
@@ -1,70 +0,0 @@
1use std::{fs::File, path::Path};
2
3use crate::{config::Cfg, db::db_setup, devdir, error::MLE};
4
5pub async fn setup(config: Cfg) -> MLE<()> {
6 let db_file = devdir(format!("{}/data.db", config.data).as_str());
7
8 if !Path::new(&db_file).exists() {
9 create(config, db_file)?;
10 }
11
12 /*
13 match s_config_get_version(config.clone()) {
14 Ok(ver) => {
15 match ver.as_str() {
16 "0.2" => to_03(config)?,
17 "0.3" => to_04(config)?,
18 _ => return Err(MLError::new(ErrorType::Other, "UNKNOWN_VERSION"))
19 }
20 },
21 Err(..) => to_02(config).await?
22 };
23 */
24
25 Ok(())
26}
27
28fn create(config: Cfg, db_file: String) -> MLE<()> {
29 println!("Create database");
30
31 File::create(db_file)?;
32 db_setup(config)?;
33 Ok(())
34}
35
36//async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
37// let lists = lists_get_all_ids(config.clone())?;
38//
39// for list in lists {
40// println!("Updating {}", list);
41// s_insert_column(config.clone(), String::from(&list), String::from("current_download"), String::from("TEXT"), None)?;
42//
43// let full_list = lists_get(config.clone(), String::from(&list))?;
44//
45// let versions = userlist_get_all_current_version_ids(config.clone(), full_list.clone().id)?;
46//
47// let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await;
48//
49// for ver in raw_versions {
50// println!("Adding link for {}", ver.project_id);
51// let file = ver.files.into_iter().find(|f| f.primary).unwrap();
52// s_userlist_update_download(config.clone(), String::from(&full_list.id), ver.project_id, file.url)?;
53// }
54// };
55// s_config_create_version(config)?;
56//
57// Ok(())
58//}
59//
60//fn to_03(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
61// s_insert_column(config.clone(), String::from("lists"), String::from("download_folder"), String::from("TEXT"), None)?;
62// s_config_update_version(config, String::from("0.3"))
63//}
64//
65//fn to_04(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
66// for list_id in lists_get_all_ids(config.clone())? {
67// s_insert_column(config.clone(), list_id, String::from("disabled_versions"), String::from("TEXT"), Some(String::from("NONE")))?;
68// }
69// s_config_update_version(config, String::from("0.4"))
70//}
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 3d9578b..4bc3ac0 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -156,52 +156,52 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML
156 Ok(current[0].clone()) 156 Ok(current[0].clone())
157} 157}
158 158
159#[tokio::test] 159// #[tokio::test]
160async fn download_updates_test() { 160// async fn download_updates_test() {
161 use crate::{ 161// use crate::{
162 modrinth::{Hash, Version, VersionFile, VersionType}, 162// modrinth::{Hash, Version, VersionFile, VersionType},
163 List, Modloader, 163// List, Modloader,
164 }; 164// };
165 165//
166 let config = Cfg::init("modlist.toml").unwrap(); 166// let config = Cfg::init().unwrap();
167 let current_list = List { 167// let current_list = List {
168 id: String::from("..."), 168// id: String::from("..."),
169 mc_version: String::from("..."), 169// mc_version: String::from("..."),
170 modloader: Modloader::Fabric, 170// modloader: Modloader::Fabric,
171 download_folder: String::from("./dev/tests/dl"), 171// download_folder: String::from("./dev/tests/dl"),
172 }; 172// };
173 173//
174 let versions = vec![Version { 174// let versions = vec![Version {
175 id: "dEqtGnT9".to_string(), 175// id: "dEqtGnT9".to_string(),
176 project_id: "kYuIpRLv".to_string(), 176// project_id: "kYuIpRLv".to_string(),
177 author_id: "Qnt13hO8".to_string(), 177// author_id: "Qnt13hO8".to_string(),
178 featured: true, 178// featured: true,
179 name: "1.2.2-1.19 - Fabric".to_string(), 179// name: "1.2.2-1.19 - Fabric".to_string(),
180 version_number: "1.2.2-1.19".to_string(), 180// version_number: "1.2.2-1.19".to_string(),
181 changelog: None, 181// changelog: None,
182 date_published: "2022-11-02T17:41:43.072267Z".to_string(), 182// date_published: "2022-11-02T17:41:43.072267Z".to_string(),
183 downloads: 58, 183// downloads: 58,
184 version_type: VersionType::release, 184// version_type: VersionType::release,
185 files: vec![VersionFile { 185// files: vec![VersionFile {
186 hashes: Hash { 186// hashes: Hash {
187 sha1: "fdc6dc39427fc92cc1d7ad8b275b5b83325e712b".to_string(), 187// sha1: "fdc6dc39427fc92cc1d7ad8b275b5b83325e712b".to_string(),
188 sha512: "5b372f00d6e5d6a5ef225c3897826b9f6a2be5506905f7f71b9e939779765b41be6f2a9b029cfc752ad0751d0d2d5f8bb4544408df1363eebdde15641e99a849".to_string() 188// sha512: "5b372f00d6e5d6a5ef225c3897826b9f6a2be5506905f7f71b9e939779765b41be6f2a9b029cfc752ad0751d0d2d5f8bb4544408df1363eebdde15641e99a849".to_string()
189 }, 189// },
190 url: "https://cdn.modrinth.com/data/kYuIpRLv/versions/dEqtGnT9/waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), 190// url: "https://cdn.modrinth.com/data/kYuIpRLv/versions/dEqtGnT9/waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(),
191 filename: "waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(), 191// filename: "waveycapes-fabric-1.2.2-mc1.19.2.jar".to_string(),
192 primary: true, 192// primary: true,
193 size: 323176 193// size: 323176
194 }], 194// }],
195 game_versions: vec![ 195// game_versions: vec![
196 "1.19".to_string(), 196// "1.19".to_string(),
197 "1.19.1".to_string(), 197// "1.19.1".to_string(),
198 "1.19.2".to_string() 198// "1.19.2".to_string()
199 ], 199// ],
200 loaders: vec![ 200// loaders: vec![
201 "fabric".to_string() 201// "fabric".to_string()
202 ] 202// ]
203 }]; 203// }];
204 assert!(download_versions(current_list, config, versions) 204// assert!(download_versions(current_list, config, versions)
205 .await 205// .await
206 .is_ok()) 206// .is_ok())
207} 207// }
diff --git a/src/config.rs b/src/config.rs
index 1b54d5f..61db1c7 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,15 +1,17 @@
1use std::{ 1use std::{
2 fs::File, 2 fs::{create_dir_all, File},
3 io::{Read, Write}, 3 io::{Read, Write},
4 path::Path,
4}; 5};
5 6
6use serde::{Deserialize, Serialize}; 7use serde::{Deserialize, Serialize};
7 8
8use crate::{devdir, error::MLE}; 9use crate::{db::db_setup, error::MLE};
9 10
10#[derive(Debug, Clone, Serialize, Deserialize)] 11#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct Cfg { 12pub struct Cfg {
12 pub data: String, 13 pub data: String,
14 pub cache: String,
13 pub apis: Apis, 15 pub apis: Apis,
14} 16}
15 17
@@ -19,24 +21,22 @@ pub struct Apis {
19} 21}
20 22
21impl Cfg { 23impl Cfg {
22 pub fn init(filename: &str) -> MLE<Self> { 24 pub fn init(path: Option<String>) -> MLE<Self> {
23 let configfile = dirs::config_dir().unwrap().join(filename); 25 let configfile = match path.clone() {
26 Some(p) => String::from(p),
27 None => dirs::config_dir()
28 .unwrap()
29 .join("modlist.toml")
30 .to_string_lossy()
31 .to_string(),
32 };
24 33
25 let mut file = match File::open(devdir(configfile.to_str().unwrap())) { 34 let mut file = match File::open(&configfile) {
26 Ok(file) => file, 35 Ok(file) => file,
27 Err(err) => { 36 Err(err) => {
28 if err.kind() == std::io::ErrorKind::NotFound { 37 if err.kind() == std::io::ErrorKind::NotFound && path.is_none() {
29 println!("No config file found, creating one"); 38 create_config(&configfile)?;
30 let default_cfg = Cfg { 39 File::open(&configfile)?
31 data: String::from("./"),
32 apis: Apis {
33 modrinth: String::from("https://api.modrinth.com/v2/"),
34 },
35 };
36 let mut file = File::create(devdir(configfile.to_str().unwrap()))?;
37 println!("Created config file");
38 file.write_all(toml::to_string(&default_cfg)?.as_bytes())?;
39 File::open(devdir(configfile.to_str().unwrap()))?
40 } else { 40 } else {
41 return Err(err.into()); 41 return Err(err.into());
42 } 42 }
@@ -45,6 +45,56 @@ impl Cfg {
45 let mut content = String::new(); 45 let mut content = String::new();
46 file.read_to_string(&mut content)?; 46 file.read_to_string(&mut content)?;
47 let config = toml::from_str::<Cfg>(&content)?; 47 let config = toml::from_str::<Cfg>(&content)?;
48 //Check cache
49 if !Path::new(&config.cache).exists() {
50 create_cache(&config.cache)?;
51 };
52 //Check database
53 //TODO check file
54 let datafile = format!("{}/data.db", config.data);
55 match File::open(&datafile) {
56 Ok(..) => (),
57 Err(..) => create_database(&datafile)?,
58 };
48 Ok(config) 59 Ok(config)
49 } 60 }
50} 61}
62
63fn create_config(path: &str) -> MLE<()> {
64 print!("No config file found, create default");
65 //Force flush of stdout, else print! doesn't print instantly
66 std::io::stdout().flush()?;
67 let default_cfg = Cfg {
68 //TODO get home dir
69 data: String::from("$HOME/.cache/modlist/"),
70 cache: String::from("$HOME/.cache/modlist/cache"),
71 apis: Apis {
72 modrinth: String::from("https://api.modrinth.com/v2/"),
73 },
74 };
75 let mut file = File::create(path)?;
76 file.write_all(toml::to_string(&default_cfg)?.as_bytes())?;
77 println!(" ✓");
78 Ok(())
79}
80
81fn create_database(path: &str) -> MLE<()> {
82 print!("No database found, create base");
83 //Force flush of stdout, else print! doesn't print instantly
84 std::io::stdout().flush()?;
85
86 File::create(path)?;
87 db_setup(path)?;
88 println!(" ✓");
89 Ok(())
90}
91
92fn create_cache(path: &str) -> MLE<()> {
93 print!("No cache direcory found, create one");
94 //Force flush of stdout, else print! doesn't print instantly
95 std::io::stdout().flush()?;
96
97 create_dir_all(path)?;
98 println!(" ✓");
99 Ok(())
100}
diff --git a/src/db.rs b/src/db.rs
index 09d54c2..abfe1dd 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -4,14 +4,13 @@ use rusqlite::Connection;
4 4
5use crate::{ 5use crate::{
6 config::Cfg, 6 config::Cfg,
7 devdir,
8 error::{ErrorType, MLError, MLE}, 7 error::{ErrorType, MLError, MLE},
9 List, Modloader, 8 List, Modloader,
10}; 9};
11 10
12//MODS 11//MODS
13pub fn mods_insert(config: Cfg, id: &str, slug: &str, name: &str) -> MLE<()> { 12pub fn mods_insert(config: Cfg, id: &str, slug: &str, name: &str) -> MLE<()> {
14 let data = devdir(format!("{}/data.db", config.data).as_str()); 13 let data = format!("{}/data.db", config.data);
15 let connection = Connection::open(data)?; 14 let connection = Connection::open(data)?;
16 15
17 connection.execute( 16 connection.execute(
@@ -23,7 +22,7 @@ pub fn mods_insert(config: Cfg, id: &str, slug: &str, name: &str) -> MLE<()> {
23} 22}
24 23
25pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { 24pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> {
26 let data = devdir(format!("{}/data.db", config.data).as_str()); 25 let data = format!("{}/data.db", config.data);
27 let connection = Connection::open(data).unwrap(); 26 let connection = Connection::open(data).unwrap();
28 27
29 let mut mods: Vec<String> = Vec::new(); 28 let mut mods: Vec<String> = Vec::new();
@@ -53,7 +52,7 @@ pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::
53pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> { 52pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> {
54 //TODO check if "slug" is id 53 //TODO check if "slug" is id
55 54
56 let data = devdir(format!("{}/data.db", data).as_str()); 55 let data = format!("{}/data.db", data);
57 let connection = Connection::open(data)?; 56 let connection = Connection::open(data)?;
58 57
59 let mut mod_id = String::new(); 58 let mut mod_id = String::new();
@@ -88,7 +87,7 @@ pub struct ModInfo {
88} 87}
89 88
90pub fn mods_get_info(config: Cfg, id: &str) -> MLE<ModInfo> { 89pub fn mods_get_info(config: Cfg, id: &str) -> MLE<ModInfo> {
91 let data = devdir(format!("{}/data.db", config.data).as_str()); 90 let data = format!("{}/data.db", config.data);
92 let connection = Connection::open(data)?; 91 let connection = Connection::open(data)?;
93 92
94 let mut mod_info: Option<ModInfo> = None; 93 let mut mod_info: Option<ModInfo> = None;
@@ -117,7 +116,7 @@ pub fn mods_get_info(config: Cfg, id: &str) -> MLE<ModInfo> {
117pub fn mods_remove(config: Cfg, id: String) -> MLE<()> { 116pub fn mods_remove(config: Cfg, id: String) -> MLE<()> {
118 println!("Removing mod {} from database", id); 117 println!("Removing mod {} from database", id);
119 118
120 let data = devdir(format!("{}/data.db", config.data).as_str()); 119 let data = format!("{}/data.db", config.data);
121 let connection = Connection::open(data)?; 120 let connection = Connection::open(data)?;
122 121
123 connection.execute("DELETE FROM mods WHERE id = ?", [id])?; 122 connection.execute("DELETE FROM mods WHERE id = ?", [id])?;
@@ -132,7 +131,7 @@ pub struct DBModlistVersions {
132} 131}
133 132
134pub fn mods_get_versions(config: Cfg, mods: Vec<String>) -> MLE<Vec<DBModlistVersions>> { 133pub fn mods_get_versions(config: Cfg, mods: Vec<String>) -> MLE<Vec<DBModlistVersions>> {
135 let data = devdir(format!("{}/data.db", config.data).as_str()); 134 let data = format!("{}/data.db", config.data);
136 let connection = Connection::open(data)?; 135 let connection = Connection::open(data)?;
137 136
138 if mods.is_empty() { 137 if mods.is_empty() {
@@ -188,7 +187,7 @@ pub fn userlist_insert(
188 current_link: &str, 187 current_link: &str,
189 set_version: bool, 188 set_version: bool,
190) -> MLE<()> { 189) -> MLE<()> {
191 let data = devdir(format!("{}/data.db", config.data).as_str()); 190 let data = format!("{}/data.db", config.data);
192 let connection = Connection::open(data)?; 191 let connection = Connection::open(data)?;
193 192
194 let sv = match set_version { 193 let sv = match set_version {
@@ -215,7 +214,7 @@ pub fn userlist_insert(
215} 214}
216 215
217pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> { 216pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> {
218 let data = devdir(format!("{}/data.db", config.data).as_str()); 217 let data = format!("{}/data.db", config.data);
219 let connection = Connection::open(data).unwrap(); 218 let connection = Connection::open(data).unwrap();
220 219
221 let mut mod_ids: Vec<String> = Vec::new(); 220 let mut mod_ids: Vec<String> = Vec::new();
@@ -234,7 +233,7 @@ pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> {
234} 233}
235 234
236pub fn userlist_remove(config: Cfg, list_id: &str, mod_id: &str) -> MLE<()> { 235pub fn userlist_remove(config: Cfg, list_id: &str, mod_id: &str) -> MLE<()> {
237 let data = devdir(format!("{}/data.db", config.data).as_str()); 236 let data = format!("{}/data.db", config.data);
238 let connection = Connection::open(data)?; 237 let connection = Connection::open(data)?;
239 238
240 connection.execute( 239 connection.execute(
@@ -249,7 +248,7 @@ pub fn userlist_get_applicable_versions(
249 list_id: String, 248 list_id: String,
250 mod_id: String, 249 mod_id: String,
251) -> MLE<String> { 250) -> MLE<String> {
252 let data = devdir(format!("{}/data.db", config.data).as_str()); 251 let data = format!("{}/data.db", config.data);
253 let connection = Connection::open(data).unwrap(); 252 let connection = Connection::open(data).unwrap();
254 253
255 let mut version: String = String::new(); 254 let mut version: String = String::new();
@@ -276,7 +275,7 @@ pub fn userlist_get_all_applicable_versions_with_mods(
276 config: Cfg, 275 config: Cfg,
277 list_id: String, 276 list_id: String,
278) -> MLE<Vec<(String, String)>> { 277) -> MLE<Vec<(String, String)>> {
279 let data = devdir(format!("{}/data.db", config.data).as_str()); 278 let data = format!("{}/data.db", config.data);
280 let connection = Connection::open(data)?; 279 let connection = Connection::open(data)?;
281 280
282 let mut versions: Vec<(String, String)> = Vec::new(); 281 let mut versions: Vec<(String, String)> = Vec::new();
@@ -302,7 +301,7 @@ pub fn userlist_get_all_applicable_versions_with_mods(
302} 301}
303 302
304pub fn userlist_get_current_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<String> { 303pub fn userlist_get_current_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<String> {
305 let data = devdir(format!("{}/data.db", config.data).as_str()); 304 let data = format!("{}/data.db", config.data);
306 let connection = Connection::open(data).unwrap(); 305 let connection = Connection::open(data).unwrap();
307 306
308 let mut version: String = String::new(); 307 let mut version: String = String::new();
@@ -324,7 +323,7 @@ pub fn userlist_get_all_current_version_ids(
324 config: Cfg, 323 config: Cfg,
325 list_id: String, 324 list_id: String,
326) -> Result<Vec<String>, Box<dyn std::error::Error>> { 325) -> Result<Vec<String>, Box<dyn std::error::Error>> {
327 let data = devdir(format!("{}/data.db", config.data).as_str()); 326 let data = format!("{}/data.db", config.data);
328 let connection = Connection::open(data)?; 327 let connection = Connection::open(data)?;
329 328
330 let mut versions: Vec<String> = Vec::new(); 329 let mut versions: Vec<String> = Vec::new();
@@ -350,7 +349,7 @@ pub fn userlist_get_all_current_versions_with_mods(
350 config: Cfg, 349 config: Cfg,
351 list_id: String, 350 list_id: String,
352) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> { 351) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> {
353 let data = devdir(format!("{}/data.db", config.data).as_str()); 352 let data = format!("{}/data.db", config.data);
354 let connection = Connection::open(data)?; 353 let connection = Connection::open(data)?;
355 354
356 let mut versions: Vec<(String, String)> = Vec::new(); 355 let mut versions: Vec<(String, String)> = Vec::new();
@@ -379,7 +378,7 @@ pub fn userlist_get_all_current_versions_with_mods(
379} 378}
380 379
381pub fn userlist_get_set_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<bool> { 380pub fn userlist_get_set_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<bool> {
382 let data = devdir(format!("{}/data.db", config.data).as_str()); 381 let data = format!("{}/data.db", config.data);
383 let connection = Connection::open(data).unwrap(); 382 let connection = Connection::open(data).unwrap();
384 383
385 let mut set_version: bool = false; 384 let mut set_version: bool = false;
@@ -402,7 +401,7 @@ pub fn userlist_change_versions(
402 link: String, 401 link: String,
403 mod_id: String, 402 mod_id: String,
404) -> MLE<()> { 403) -> MLE<()> {
405 let data = devdir(format!("{}/data.db", config.data).as_str()); 404 let data = format!("{}/data.db", config.data);
406 let connection = Connection::open(data)?; 405 let connection = Connection::open(data)?;
407 406
408 connection.execute(format!("UPDATE {} SET current_version = ?1, applicable_versions = ?2, current_download = ?3 WHERE mod_id = ?4", list_id).as_str(), [current_version, versions, link, mod_id])?; 407 connection.execute(format!("UPDATE {} SET current_version = ?1, applicable_versions = ?2, current_download = ?3 WHERE mod_id = ?4", list_id).as_str(), [current_version, versions, link, mod_id])?;
@@ -415,7 +414,7 @@ pub fn userlist_add_disabled_versions(
415 disabled_version: String, 414 disabled_version: String,
416 mod_id: String, 415 mod_id: String,
417) -> MLE<()> { 416) -> MLE<()> {
418 let data = devdir(format!("{}/data.db", config.data).as_str()); 417 let data = format!("{}/data.db", config.data);
419 let connection = Connection::open(data)?; 418 let connection = Connection::open(data)?;
420 419
421 let currently_disabled_versions = 420 let currently_disabled_versions =
@@ -437,7 +436,7 @@ pub fn userlist_add_disabled_versions(
437} 436}
438 437
439pub fn userlist_get_disabled_versions(config: Cfg, list_id: String, mod_id: String) -> MLE<String> { 438pub fn userlist_get_disabled_versions(config: Cfg, list_id: String, mod_id: String) -> MLE<String> {
440 let data = devdir(format!("{}/data.db", config.data).as_str()); 439 let data = format!("{}/data.db", config.data);
441 let connection = Connection::open(data).unwrap(); 440 let connection = Connection::open(data).unwrap();
442 441
443 let mut version: String = String::new(); 442 let mut version: String = String::new();
@@ -459,7 +458,7 @@ pub fn userlist_get_all_downloads(
459 config: Cfg, 458 config: Cfg,
460 list_id: String, 459 list_id: String,
461) -> Result<Vec<String>, Box<dyn std::error::Error>> { 460) -> Result<Vec<String>, Box<dyn std::error::Error>> {
462 let data = devdir(format!("{}/data.db", config.data).as_str()); 461 let data = format!("{}/data.db", config.data);
463 let connection = Connection::open(data).unwrap(); 462 let connection = Connection::open(data).unwrap();
464 463
465 let mut links: Vec<String> = Vec::new(); 464 let mut links: Vec<String> = Vec::new();
@@ -494,7 +493,7 @@ pub fn lists_insert(
494) -> MLE<()> { 493) -> MLE<()> {
495 println!("Creating list {}", id); 494 println!("Creating list {}", id);
496 495
497 let data = devdir(format!("{}/data.db", config.data).as_str()); 496 let data = format!("{}/data.db", config.data);
498 let connection = Connection::open(data)?; 497 let connection = Connection::open(data)?;
499 498
500 connection.execute( 499 connection.execute(
@@ -512,7 +511,7 @@ pub fn lists_insert(
512} 511}
513 512
514pub fn lists_remove(config: Cfg, id: String) -> MLE<()> { 513pub fn lists_remove(config: Cfg, id: String) -> MLE<()> {
515 let data = devdir(format!("{}/data.db", config.data).as_str()); 514 let data = format!("{}/data.db", config.data);
516 let connection = Connection::open(data)?; 515 let connection = Connection::open(data)?;
517 516
518 connection.execute("DELETE FROM lists WHERE id = ?", [&id])?; 517 connection.execute("DELETE FROM lists WHERE id = ?", [&id])?;
@@ -521,7 +520,7 @@ pub fn lists_remove(config: Cfg, id: String) -> MLE<()> {
521} 520}
522 521
523pub fn lists_get(config: Cfg, list_id: String) -> MLE<List> { 522pub fn lists_get(config: Cfg, list_id: String) -> MLE<List> {
524 let data = devdir(format!("{}/data.db", config.data).as_str()); 523 let data = format!("{}/data.db", config.data);
525 let connection = Connection::open(data).unwrap(); 524 let connection = Connection::open(data).unwrap();
526 525
527 let mut list = List { 526 let mut list = List {
@@ -559,7 +558,7 @@ pub fn lists_get(config: Cfg, list_id: String) -> MLE<List> {
559} 558}
560 559
561pub fn lists_version(config: Cfg, list_id: &str, version: &str) -> MLE<()> { 560pub fn lists_version(config: Cfg, list_id: &str, version: &str) -> MLE<()> {
562 let data = devdir(format!("{}/data.db", config.data).as_str()); 561 let data = format!("{}/data.db", config.data);
563 let connection = Connection::open(data).unwrap(); 562 let connection = Connection::open(data).unwrap();
564 563
565 connection.execute( 564 connection.execute(
@@ -570,7 +569,7 @@ pub fn lists_version(config: Cfg, list_id: &str, version: &str) -> MLE<()> {
570} 569}
571 570
572pub fn lists_get_all_ids(config: Cfg) -> MLE<Vec<String>> { 571pub fn lists_get_all_ids(config: Cfg) -> MLE<Vec<String>> {
573 let data = devdir(format!("{}/data.db", config.data).as_str()); 572 let data = format!("{}/data.db", config.data);
574 let connection = Connection::open(data).unwrap(); 573 let connection = Connection::open(data).unwrap();
575 574
576 let mut list_ids: Vec<String> = Vec::new(); 575 let mut list_ids: Vec<String> = Vec::new();
@@ -589,7 +588,7 @@ pub fn lists_get_all_ids(config: Cfg) -> MLE<Vec<String>> {
589 588
590//config 589//config
591pub fn config_change_current_list(config: Cfg, id: String) -> MLE<()> { 590pub fn config_change_current_list(config: Cfg, id: String) -> MLE<()> {
592 let data = devdir(format!("{}/data.db", config.data).as_str()); 591 let data = format!("{}/data.db", config.data);
593 let connection = Connection::open(data)?; 592 let connection = Connection::open(data)?;
594 593
595 connection.execute( 594 connection.execute(
@@ -600,7 +599,7 @@ pub fn config_change_current_list(config: Cfg, id: String) -> MLE<()> {
600} 599}
601 600
602pub fn config_get_current_list(config: Cfg) -> MLE<String> { 601pub fn config_get_current_list(config: Cfg) -> MLE<String> {
603 let data = devdir(format!("{}/data.db", config.data).as_str()); 602 let data = format!("{}/data.db", config.data);
604 let connection = Connection::open(data).unwrap(); 603 let connection = Connection::open(data).unwrap();
605 604
606 let mut list_id = String::new(); 605 let mut list_id = String::new();
@@ -625,7 +624,7 @@ pub fn s_userlist_update_download(
625 mod_id: String, 624 mod_id: String,
626 link: String, 625 link: String,
627) -> Result<(), Box<dyn std::error::Error>> { 626) -> Result<(), Box<dyn std::error::Error>> {
628 let data = devdir(format!("{}/data.db", config.data).as_str()); 627 let data = format!("{}/data.db", config.data);
629 let connection = Connection::open(data)?; 628 let connection = Connection::open(data)?;
630 629
631 connection.execute( 630 connection.execute(
@@ -640,7 +639,7 @@ pub fn s_userlist_update_download(
640} 639}
641 640
642pub fn s_config_create_version(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 641pub fn s_config_create_version(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
643 let data = devdir(format!("{}/data.db", config.data).as_str()); 642 let data = format!("{}/data.db", config.data);
644 let connection = Connection::open(data)?; 643 let connection = Connection::open(data)?;
645 644
646 connection.execute( 645 connection.execute(
@@ -651,7 +650,7 @@ pub fn s_config_create_version(config: Cfg) -> Result<(), Box<dyn std::error::Er
651} 650}
652 651
653pub fn s_config_update_version(config: Cfg, ver: String) -> Result<(), Box<dyn std::error::Error>> { 652pub fn s_config_update_version(config: Cfg, ver: String) -> Result<(), Box<dyn std::error::Error>> {
654 let data = devdir(format!("{}/data.db", config.data).as_str()); 653 let data = format!("{}/data.db", config.data);
655 let connection = Connection::open(data)?; 654 let connection = Connection::open(data)?;
656 655
657 connection.execute( 656 connection.execute(
@@ -662,7 +661,7 @@ pub fn s_config_update_version(config: Cfg, ver: String) -> Result<(), Box<dyn s
662} 661}
663 662
664pub fn s_config_get_version(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { 663pub fn s_config_get_version(config: Cfg) -> Result<String, Box<dyn std::error::Error>> {
665 let data = devdir(format!("{}/data.db", config.data).as_str()); 664 let data = format!("{}/data.db", config.data);
666 let connection = Connection::open(data)?; 665 let connection = Connection::open(data)?;
667 666
668 let mut version: String = String::new(); 667 let mut version: String = String::new();
@@ -689,7 +688,7 @@ pub fn s_insert_column(
689 c_type: String, 688 c_type: String,
690 default: Option<String>, 689 default: Option<String>,
691) -> Result<(), Box<dyn std::error::Error>> { 690) -> Result<(), Box<dyn std::error::Error>> {
692 let data = devdir(format!("{}/data.db", config.data).as_str()); 691 let data = format!("{}/data.db", config.data);
693 let connection = Connection::open(data)?; 692 let connection = Connection::open(data)?;
694 693
695 let mut sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, c_type); 694 let mut sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, c_type);
@@ -702,11 +701,8 @@ pub fn s_insert_column(
702 Ok(()) 701 Ok(())
703} 702}
704 703
705pub fn db_setup(config: Cfg) -> MLE<()> { 704pub fn db_setup(path: &str) -> MLE<()> {
706 println!("Initiating database"); 705 let connection = Connection::open(path)?;
707
708 let data = devdir(format!("{}/data.db", config.data).as_str());
709 let connection = Connection::open(data)?;
710 706
711 connection.execute_batch( 707 connection.execute_batch(
712 "CREATE TABLE 'user_config' ( 'id' TEXT, 'value' TEXT ); 708 "CREATE TABLE 'user_config' ( 'id' TEXT, 'value' TEXT );
diff --git a/src/files.rs b/src/files.rs
index 6160cb4..59fc7de 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -2,11 +2,12 @@ use futures_util::StreamExt;
2use reqwest::Client; 2use reqwest::Client;
3use std::{ 3use std::{
4 collections::HashMap, 4 collections::HashMap,
5 fs::{read_dir, remove_file, rename, File}, 5 fs::{copy, read_dir, remove_file, rename, File},
6 io::Write, 6 io::Write,
7}; 7};
8 8
9use crate::{ 9use crate::{
10 cache::{copy_cached_version, get_cached_versions},
10 config::Cfg, 11 config::Cfg,
11 db::{mods_get_info, userlist_add_disabled_versions}, 12 db::{mods_get_info, userlist_add_disabled_versions},
12 error::{ErrorType, MLError, MLE}, 13 error::{ErrorType, MLError, MLE},
@@ -15,31 +16,62 @@ use crate::{
15}; 16};
16 17
17pub async fn download_versions(list: List, config: Cfg, versions: Vec<Version>) -> MLE<String> { 18pub async fn download_versions(list: List, config: Cfg, versions: Vec<Version>) -> MLE<String> {
19 let mut cached = get_cached_versions(&config.cache);
20
21 println!("{:#?}", cached);
22
18 let dl_path = String::from(&list.download_folder); 23 let dl_path = String::from(&list.download_folder);
19 24
20 println!(" └Download mods to {}", dl_path); 25 println!(" └Download mods to {}", dl_path);
21 26
22 for ver in versions { 27 for ver in versions {
23 let project_info = mods_get_info(config.clone(), &ver.project_id)?; 28 let project_info = mods_get_info(config.clone(), &ver.project_id)?;
24 print!("\t└({})Download version {}", project_info.title, ver.id); 29
25 //Force flush of stdout, else print! doesn't print instantly 30 //Check cache if already downloaded
26 std::io::stdout().flush().unwrap(); 31 let c = cached.remove(&ver.id);
27 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); 32 if c.is_some() {
28 let mut splitname: Vec<&str> = primary_file.filename.split('.').collect(); 33 print!(
29 let extension = match splitname.pop().ok_or("") { 34 "\t└({})Get version {} from cache",
30 Ok(e) => e, 35 project_info.title, ver.id
31 Err(..) => return Err(MLError::new(ErrorType::Other, "NO_FILE_EXTENSION")), 36 );
32 }; 37 //Force flush of stdout, else print! doesn't print instantly
33 let filename = format!( 38 std::io::stdout().flush()?;
34 "{}.mr.{}.{}.{}", 39 copy_cached_version(&c.unwrap(), &dl_path);
35 splitname.join("."), 40 println!(" ✓");
36 ver.project_id, 41 } else {
37 ver.id, 42 print!("\t└({})Download version {}", project_info.title, ver.id);
38 extension 43 //Force flush of stdout, else print! doesn't print instantly
39 ); 44 std::io::stdout().flush().unwrap();
40 download_file(primary_file.url, list.clone().download_folder, filename).await?; 45 let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap();
41 //tokio::time::sleep(std::time::Duration::new(3, 0)).await; 46 let mut splitname: Vec<&str> = primary_file.filename.split('.').collect();
42 println!(" ✓"); 47 let extension = match splitname.pop().ok_or("") {
48 Ok(e) => e,
49 Err(..) => return Err(MLError::new(ErrorType::Other, "NO_FILE_EXTENSION")),
50 };
51 let filename = format!(
52 "{}.mr.{}.{}.{}",
53 splitname.join("."),
54 ver.project_id,
55 ver.id,
56 extension
57 );
58 download_file(
59 primary_file.url,
60 list.clone().download_folder,
61 filename.clone(),
62 )
63 .await?;
64 println!(" ✓");
65 //Copy file to cache
66 print!("\t └Copy to cache");
67 //Force flush of stdout, else print! doesn't print instantly
68 std::io::stdout().flush().unwrap();
69 let dl_path_file = format!("{}/{}", list.download_folder, filename);
70 let cache_path = format!("{}/{}", &config.clone().cache, filename);
71 // println!("{}:{}", dl_path_file, cache_path);
72 copy(dl_path_file, cache_path)?;
73 println!(" ✓");
74 }
43 } 75 }
44 76
45 Ok(dl_path) 77 Ok(dl_path)
diff --git a/src/lib.rs b/src/lib.rs
index 43f0fe7..185edd7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,11 +1,12 @@
1pub mod apis; 1pub mod apis;
2pub mod cache;
2pub mod commands; 3pub mod commands;
3pub mod config; 4pub mod config;
4pub mod db; 5pub mod db;
5pub mod error; 6pub mod error;
6pub mod files; 7pub mod files;
7 8
8use std::{fmt::Display, path::Path}; 9use std::fmt::Display;
9 10
10pub use apis::*; 11pub use apis::*;
11pub use commands::*; 12pub use commands::*;
@@ -35,17 +36,3 @@ impl Display for Modloader {
35 } 36 }
36 } 37 }
37} 38}
38
39pub fn devdir(path: &str) -> String {
40 let p = Path::new(path);
41 let dev = std::env::var("DEV");
42 let lvl = match dev {
43 Ok(dev) => dev.parse::<i32>().unwrap(),
44 Err(..) => 0,
45 };
46 if lvl >= 1 {
47 format!("./dev/{}", p.file_name().unwrap().to_str().unwrap())
48 } else {
49 String::from(path)
50 }
51}
diff --git a/src/main.rs b/src/main.rs
index 2006856..0ecb850 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,8 +2,8 @@ use clap::{Parser, Subcommand};
2use modlist::{ 2use 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 devdir, download, export, get_current_list, import, list_add, list_change, list_remove, 5 download, export, get_current_list, import, list_add, list_change, list_remove, list_version,
6 list_version, mod_add, mod_remove, update, IDSelector, List, Modloader, 6 mod_add, mod_remove, update, IDSelector, List, Modloader,
7}; 7};
8 8
9//TODO implement remote sql db 9//TODO implement remote sql db
@@ -14,6 +14,10 @@ use modlist::{
14struct Cli { 14struct Cli {
15 #[command(subcommand)] 15 #[command(subcommand)]
16 command: Commands, 16 command: Commands,
17
18 /// config file path
19 #[arg(short, long)]
20 config: Option<String>,
17} 21}
18 22
19#[derive(Subcommand)] 23#[derive(Subcommand)]
@@ -143,10 +147,9 @@ enum ListCommands {
143async fn main() { 147async fn main() {
144 let cli = Cli::parse(); 148 let cli = Cli::parse();
145 149
146 let config = Cfg::init("modlist.toml").unwrap(); 150 let config = Cfg::init(cli.config).unwrap();
147 println!("{:?}", config); 151 println!("{:?}", config);
148 152
149 //TODO setup? maybe setup on install
150 match cli.command { 153 match cli.command {
151 Commands::Mod { command } => { 154 Commands::Mod { command } => {
152 match command { 155 match command {
@@ -250,15 +253,12 @@ async fn main() {
250 Commands::Import { file, download } => { 253 Commands::Import { file, download } => {
251 let filestr: String = match file { 254 let filestr: String = match file {
252 Some(args) => args, 255 Some(args) => args,
253 None => devdir( 256 None => dirs::home_dir()
254 dirs::home_dir() 257 .unwrap()
255 .unwrap() 258 .join("mlexport.toml")
256 .join("mlexport.toml") 259 .into_os_string()
257 .into_os_string() 260 .into_string()
258 .into_string() 261 .unwrap(),
259 .unwrap()
260 .as_str(),
261 ),
262 }; 262 };
263 263
264 import(config, filestr, download).await 264 import(config, filestr, download).await