diff --git a/.gitignore b/.gitignore
index e7c395b..415cc8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
.envrc
/.direnv
/.vscode
+/build
/result
/src/config.rs
/target
-/src/resources.gresource
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index c19b7b6..d43f468 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,15 +2,6 @@
# It is not intended for manual editing.
version = 3
-[[package]]
-name = "addr2line"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
-dependencies = [
- "gimli",
-]
-
[[package]]
name = "adler"
version = "1.0.2"
@@ -66,10 +57,19 @@ dependencies = [
]
[[package]]
-name = "anyhow"
-version = "1.0.65"
+name = "ansi_term"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "async-broadcast"
@@ -83,12 +83,25 @@ dependencies = [
]
[[package]]
-name = "async-oneshot"
-version = "0.5.0"
+name = "async-compression"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ec7c75bcbcb0139e9177f30692fd617405ca4e0c27802e128d53171f7042e2c"
+checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
dependencies = [
- "futures-micro",
+ "brotli",
+ "futures-core",
+ "memchr",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "atoi"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
+dependencies = [
+ "num-traits",
]
[[package]]
@@ -108,26 +121,11 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-[[package]]
-name = "backtrace"
-version = "0.3.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
-dependencies = [
- "addr2line",
- "cc",
- "cfg-if",
- "libc",
- "miniz_oxide",
- "object",
- "rustc-demangle",
-]
-
[[package]]
name = "base64"
-version = "0.13.0"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bit_field"
@@ -150,6 +148,15 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "block-buffer"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "brotli"
version = "3.3.4"
@@ -172,10 +179,22 @@ dependencies = [
]
[[package]]
-name = "bumpalo"
-version = "3.11.0"
+name = "bstr"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
+checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
+dependencies = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "bytemuck"
@@ -197,8 +216,9 @@ checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
[[package]]
name = "cairo-rs"
-version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f9ee4a4ca9239c9a839453dce04b7ddee2f859ec4cd7acd1f5703b68db549c"
dependencies = [
"bitflags",
"cairo-sys-rs",
@@ -211,7 +231,8 @@ dependencies = [
[[package]]
name = "cairo-sys-rs"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5119ea655ec777b523f0b57279e70f8a4542f61b0e98a48f892b4ef043fd4c5d"
dependencies = [
"glib-sys",
"libc",
@@ -235,13 +256,19 @@ checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-expr"
-version = "0.10.3"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db"
+checksum = "b0357a6402b295ca3a86bc148e84df46c02e41f41fef186bda662557ef6328aa"
dependencies = [
"smallvec",
]
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -250,19 +277,49 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "3.2.22"
+version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "bitflags",
+ "strsim 0.8.0",
+ "textwrap 0.11.0",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
+name = "clap"
+version = "3.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
dependencies = [
"atty",
"bitflags",
- "clap_derive",
- "clap_lex",
+ "clap_derive 3.2.18",
+ "clap_lex 0.2.4",
"indexmap",
"once_cell",
- "strsim",
+ "strsim 0.10.0",
+ "termcolor",
+ "textwrap 0.16.0",
+]
+
+[[package]]
+name = "clap"
+version = "4.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_derive 4.0.18",
+ "clap_lex 0.3.0",
+ "once_cell",
+ "strsim 0.10.0",
"termcolor",
- "textwrap",
]
[[package]]
@@ -278,6 +335,19 @@ dependencies = [
"syn",
]
+[[package]]
+name = "clap_derive"
+version = "4.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "clap_lex"
version = "0.2.4"
@@ -287,6 +357,15 @@ dependencies = [
"os_str_bytes",
]
+[[package]]
+name = "clap_lex"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
+dependencies = [
+ "os_str_bytes",
+]
+
[[package]]
name = "color_quant"
version = "1.1.0"
@@ -324,13 +403,38 @@ dependencies = [
"libc",
]
+[[package]]
+name = "crc"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff"
+
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
+dependencies = [
+ "crossbeam-utils 0.7.2",
+ "maybe-uninit",
]
[[package]]
@@ -339,8 +443,8 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
- "cfg-if",
- "crossbeam-utils",
+ "cfg-if 1.0.0",
+ "crossbeam-utils 0.8.12",
]
[[package]]
@@ -349,33 +453,90 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"crossbeam-epoch",
- "crossbeam-utils",
+ "crossbeam-utils 0.8.12",
]
[[package]]
name = "crossbeam-epoch"
-version = "0.9.10"
+version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
+checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
dependencies = [
"autocfg",
- "cfg-if",
- "crossbeam-utils",
+ "cfg-if 1.0.0",
+ "crossbeam-utils 0.8.12",
"memoffset",
- "once_cell",
"scopeguard",
]
[[package]]
-name = "crossbeam-utils"
-version = "0.8.11"
+name = "crossbeam-queue"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
+checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
dependencies = [
- "cfg-if",
- "once_cell",
+ "cfg-if 1.0.0",
+ "crossbeam-utils 0.8.12",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
+dependencies = [
+ "autocfg",
+ "cfg-if 0.1.10",
+ "lazy_static",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "csv"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
+dependencies = [
+ "bstr",
+ "csv-core",
+ "itoa 0.4.8",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+dependencies = [
+ "memchr",
]
[[package]]
@@ -384,7 +545,7 @@ version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"num_cpus",
]
@@ -398,10 +559,20 @@ dependencies = [
]
[[package]]
-name = "edit-distance"
-version = "2.1.0"
+name = "digest"
+version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbbaaaf38131deb9ca518a274a45bfdb8771f139517b073b16c2d3d32ae5037b"
+checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+dependencies = [
+ "block-buffer 0.10.3",
+ "crypto-common",
+]
+
+[[package]]
+name = "dotenvy"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
[[package]]
name = "either"
@@ -415,7 +586,7 @@ version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
]
[[package]]
@@ -439,41 +610,19 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "exr"
-version = "1.5.1"
+version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9a7880199e74c6d3fe45579df2f436c5913a71405494cb89d59234d86b47dc5"
+checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded"
dependencies = [
"bit_field",
"flume",
"half",
"lebe",
- "miniz_oxide",
+ "miniz_oxide 0.6.2",
"smallvec",
"threadpool",
]
-[[package]]
-name = "failure"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
-dependencies = [
- "backtrace",
- "failure_derive",
-]
-
-[[package]]
-name = "failure_derive"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "synstructure",
-]
-
[[package]]
name = "fastrand"
version = "1.8.0"
@@ -500,16 +649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
"crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "float-cmp"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
-dependencies = [
- "num-traits",
+ "miniz_oxide 0.5.4",
]
[[package]]
@@ -555,6 +695,12 @@ dependencies = [
"percent-encoding",
]
+[[package]]
+name = "fragile"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
+
[[package]]
name = "futf"
version = "0.1.5"
@@ -567,9 +713,9 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c"
+checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
dependencies = [
"futures-channel",
"futures-core",
@@ -582,9 +728,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
+checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
dependencies = [
"futures-core",
"futures-sink",
@@ -592,15 +738,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
+checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
[[package]]
name = "futures-executor"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab"
+checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
dependencies = [
"futures-core",
"futures-task",
@@ -608,48 +754,50 @@ dependencies = [
]
[[package]]
-name = "futures-io"
-version = "0.3.24"
+name = "futures-intrusive"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
+checksum = "1b6bdbb8c5a42b2bb5ee8dd9dc2c7d73ce3e15d26dfe100fb347ffa3f58c672b"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
[[package]]
name = "futures-macro"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
+checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
-[[package]]
-name = "futures-micro"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b460264b3593d68b16a7bc35f7bc226ddfebdf9a1c8db1ed95d5cc6b7168c826"
-dependencies = [
- "pin-project-lite",
-]
-
[[package]]
name = "futures-sink"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
+checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
[[package]]
name = "futures-task"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
+checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
[[package]]
name = "futures-util"
-version = "0.3.24"
+version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
+checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
dependencies = [
"futures-channel",
"futures-core",
@@ -666,7 +814,8 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0fb526c8c3a075eda15f961820edf3e15fe18576ac4fbabbb324e4cc6c421e6"
dependencies = [
"bitflags",
"gdk-pixbuf-sys",
@@ -678,7 +827,8 @@ dependencies = [
[[package]]
name = "gdk-pixbuf-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7df12d15c10c3c5a84d9fb4ba0e27659f6a2bdee4f27f8b17126da15d5ddd3f2"
dependencies = [
"gio-sys",
"glib-sys",
@@ -690,7 +840,8 @@ dependencies = [
[[package]]
name = "gdk4"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66fe07f362c977c4684d1136a29f097208b3ccb2013ab6f441a3c60a046fd358"
dependencies = [
"bitflags",
"cairo-rs",
@@ -705,7 +856,8 @@ dependencies = [
[[package]]
name = "gdk4-sys"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddcf9e3ab5f237bb641e7f2fccc4b26d5b86f111f0d62e27d452dc24964541c2"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -730,11 +882,11 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"js-sys",
"libc",
"wasi",
@@ -751,16 +903,11 @@ dependencies = [
"weezl",
]
-[[package]]
-name = "gimli"
-version = "0.26.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
-
[[package]]
name = "gio"
-version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33c1debf8d0315d69be0153aa76249db3c858ef69b7778ad3cc669e6d370c485"
dependencies = [
"bitflags",
"futures-channel",
@@ -771,13 +918,16 @@ dependencies = [
"glib",
"libc",
"once_cell",
+ "pin-project-lite",
+ "smallvec",
"thiserror",
]
[[package]]
name = "gio-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6da1bba9d3f2ab13a6e9932c40f240dc99ebc9f0bdc35cfb130d1a3df36f374c"
dependencies = [
"glib-sys",
"gobject-sys",
@@ -788,8 +938,9 @@ dependencies = [
[[package]]
name = "glib"
-version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5abffa711471e015eb93d65d6ea20e7e9f6f7951fc0a1042280439319b2de06"
dependencies = [
"bitflags",
"futures-channel",
@@ -797,6 +948,7 @@ dependencies = [
"futures-executor",
"futures-task",
"futures-util",
+ "gio-sys",
"glib-macros",
"glib-sys",
"gobject-sys",
@@ -809,7 +961,8 @@ dependencies = [
[[package]]
name = "glib-macros"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e195c1311fa6b04d7b896ea39385f6bd60ef5d25bf74a7c11c8c3f94f6c1a572"
dependencies = [
"anyhow",
"heck",
@@ -823,16 +976,31 @@ dependencies = [
[[package]]
name = "glib-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b33357bb421a77bd849f6a0bfcaf3b4b256a2577802971bb5dd522d530f27021"
dependencies = [
"libc",
"system-deps",
]
+[[package]]
+name = "globset"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "fnv",
+ "log",
+ "regex",
+]
+
[[package]]
name = "gobject-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63ca11a57400f3d4fda594e002844be47900c9fb8b29e2155c6e37a1f24e51b3"
dependencies = [
"glib-sys",
"libc",
@@ -842,7 +1010,8 @@ dependencies = [
[[package]]
name = "graphene-rs"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95a8de4506a64776d90fedf9c28fdca5a7127f8cc9c78976e8184ac6f42685d8"
dependencies = [
"glib",
"graphene-sys",
@@ -852,7 +1021,8 @@ dependencies = [
[[package]]
name = "graphene-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2c952f764f02f8546fcc5d014bc78aa704c6d453c828c8b429121f704349163"
dependencies = [
"glib-sys",
"libc",
@@ -863,7 +1033,8 @@ dependencies = [
[[package]]
name = "gsk4"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fc2b86c751a7fe9aad0fdba85937a6aace3a8453e0e2a08d2a31ce4bb8ae55"
dependencies = [
"bitflags",
"cairo-rs",
@@ -878,7 +1049,8 @@ dependencies = [
[[package]]
name = "gsk4-sys"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2cb53e25cbbe3fa8e3e9db7c06d65085086fadbec4cd0aa567b2e2a4917db83d"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
@@ -892,8 +1064,9 @@ dependencies = [
[[package]]
name = "gtk4"
-version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47223ddb27033731b71ea841d1b878bd87a275a865f1df60b41505f9e4933d64"
dependencies = [
"bitflags",
"cairo-rs",
@@ -915,7 +1088,8 @@ dependencies = [
[[package]]
name = "gtk4-macros"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce5eb86364b216ee8c497b1121831168fb25130d3378495a135f8e5c1972db7b"
dependencies = [
"anyhow",
"proc-macro-crate",
@@ -928,7 +1102,8 @@ dependencies = [
[[package]]
name = "gtk4-sys"
version = "0.5.0"
-source = "git+https://github.com/gtk-rs/gtk4-rs#58c7187169ae74fac6a68d9454c33ad15da761b7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f04bd0b63d999a36ae53a916ee4b20ea64a3ef4732ca8a98b1fde4a22c1476c"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -945,9 +1120,9 @@ dependencies = [
[[package]]
name = "h2"
-version = "0.3.14"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be"
+checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
dependencies = [
"bytes",
"fnv",
@@ -964,18 +1139,11 @@ dependencies = [
[[package]]
name = "half"
-version = "1.8.2"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
-
-[[package]]
-name = "halfbrown"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce69ed202df415a3d4a01e6f3341320ca88b9bd4f0bf37be6fa239cdea06d9bf"
+checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554"
dependencies = [
- "hashbrown 0.12.3",
- "serde",
+ "crunchy",
]
[[package]]
@@ -993,11 +1161,23 @@ dependencies = [
"ahash",
]
+[[package]]
+name = "hashlink"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
+dependencies = [
+ "hashbrown 0.12.3",
+]
+
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+dependencies = [
+ "unicode-segmentation",
+]
[[package]]
name = "hermit-abi"
@@ -1052,7 +1232,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes",
"fnv",
- "itoa",
+ "itoa 1.0.4",
]
[[package]]
@@ -1102,7 +1282,7 @@ dependencies = [
"http-body",
"httparse",
"httpdate",
- "itoa",
+ "itoa 1.0.4",
"pin-project-lite",
"socket2",
"tokio",
@@ -1134,6 +1314,24 @@ dependencies = [
"unicode-normalization",
]
+[[package]]
+name = "ignore"
+version = "0.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
+dependencies = [
+ "crossbeam-utils 0.8.12",
+ "globset",
+ "lazy_static",
+ "log",
+ "memchr",
+ "regex",
+ "same-file",
+ "thread_local",
+ "walkdir",
+ "winapi-util",
+]
+
[[package]]
name = "ijson"
version = "0.1.3"
@@ -1181,7 +1379,7 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
]
[[package]]
@@ -1191,10 +1389,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
[[package]]
-name = "itoa"
-version = "1.0.3"
+name = "itertools"
+version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]]
name = "jpeg-decoder"
@@ -1229,7 +1442,8 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libadwaita"
version = "0.2.0"
-source = "git+https://gitlab.gnome.org/World/Rust/libadwaita-rs#2161931a19f43a6764c7006da87914cddb6429c8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed92f031cf7f3d501b84f41e4d05aed6ebfd8eed59a8fc0cccbf51359e92c8e3"
dependencies = [
"bitflags",
"futures-channel",
@@ -1247,7 +1461,8 @@ dependencies = [
[[package]]
name = "libadwaita-sys"
version = "0.2.0"
-source = "git+https://gitlab.gnome.org/World/Rust/libadwaita-rs#2161931a19f43a6764c7006da87914cddb6429c8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ec4243e86fb53d06df2461d543529a640c9a0fba2d4cc850b70e11a85f9d952"
dependencies = [
"gdk4-sys",
"gio-sys",
@@ -1261,9 +1476,20 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.133"
+version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
+]
[[package]]
name = "linkify"
@@ -1290,7 +1516,7 @@ version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
]
[[package]]
@@ -1331,6 +1557,12 @@ dependencies = [
"xml5ever",
]
+[[package]]
+name = "maybe-uninit"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
+
[[package]]
name = "memchr"
version = "2.5.0"
@@ -1352,6 +1584,12 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
[[package]]
name = "miniz_oxide"
version = "0.5.4"
@@ -1362,15 +1600,24 @@ dependencies = [
]
[[package]]
-name = "mio"
-version = "0.8.4"
+name = "miniz_oxide"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
+checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
dependencies = [
"libc",
"log",
"wasi",
- "windows-sys",
+ "windows-sys 0.42.0",
]
[[package]]
@@ -1407,30 +1654,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
-name = "nix-editor"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cf248c2a02080d305cf67a51b989755e29a4256e896ed091cbb5fad578cf032"
+name = "nix-data"
+version = "0.0.2"
+source = "git+https://github.com/snowflakelinux/nix-data?rev=a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95#a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95"
dependencies = [
- "clap",
- "failure",
+ "anyhow",
+ "csv",
+ "ijson",
+ "lazy_static",
+ "log",
+ "nix-editor",
+ "pretty_env_logger",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "tokio",
+]
+
+[[package]]
+name = "nix-editor"
+version = "0.3.0-beta.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54cc1d93deb37efb27faaf8ffbdf9d0a536a371fb0c1e9dae2bffe01ba55f65a"
+dependencies = [
+ "clap 4.0.18",
+ "nixpkgs-fmt",
"owo-colors",
"rnix",
+ "thiserror",
]
[[package]]
name = "nix-software-center"
-version = "0.0.3"
+version = "0.1.0"
dependencies = [
- "brotli",
- "edit-distance",
+ "anyhow",
"flate2",
"gtk4",
"html2pango",
- "ijson",
"image",
"libadwaita",
"log",
+ "nix-data",
"nix-editor",
"pretty_env_logger",
"quick-xml",
@@ -1442,20 +1708,43 @@ dependencies = [
"serde_json",
"serde_yaml",
"sha256",
- "simd-json",
"spdx",
- "strum",
- "strum_macros",
+ "sqlx",
"tokio",
"tracker",
- "which",
+]
+
+[[package]]
+name = "nixpkgs-fmt"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f1bdfcb88bb9dc3ae8a6ef55cda89eb33d7c69a98411b4cdb845adf391a7587"
+dependencies = [
+ "clap 2.34.0",
+ "crossbeam-channel 0.4.4",
+ "ignore",
+ "libc",
+ "rnix",
+ "rowan",
+ "serde_json",
+ "smol_str",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
]
[[package]]
name = "nsc-helper"
version = "0.1.0"
dependencies = [
- "clap",
+ "clap 3.2.23",
"users",
]
@@ -1499,15 +1788,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "object"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
-dependencies = [
- "memchr",
-]
-
[[package]]
name = "once_cell"
version = "1.15.0"
@@ -1527,7 +1807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13"
dependencies = [
"bitflags",
- "cfg-if",
+ "cfg-if 1.0.0",
"foreign-types",
"libc",
"once_cell",
@@ -1554,9 +1834,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
-version = "0.9.76"
+version = "0.9.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce"
+checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a"
dependencies = [
"autocfg",
"cc",
@@ -1580,7 +1860,8 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "pango"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7208c60f224cf6e44c551df5ee2ef38f9da0fd29d7c5a0402000b8ab0520e798"
dependencies = [
"bitflags",
"gio",
@@ -1593,7 +1874,8 @@ dependencies = [
[[package]]
name = "pango-sys"
version = "0.16.0"
-source = "git+https://github.com/gtk-rs/gtk-rs-core#61a082e6fb3cb50af8c936dc8858b7a67db4ac9a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "922441c228366ed98d3534b87bc7c987c50564094c3abbc3513717786419252d"
dependencies = [
"glib-sys",
"gobject-sys",
@@ -1613,17 +1895,23 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.3"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"libc",
"redox_syscall",
"smallvec",
- "windows-sys",
+ "windows-sys 0.42.0",
]
+[[package]]
+name = "paste"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
+
[[package]]
name = "percent-encoding"
version = "2.2.0"
@@ -1632,9 +1920,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "pest"
-version = "2.3.1"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb779fcf4bb850fbbb0edc96ff6cf34fd90c4b1a112ce042653280d9a7364048"
+checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
dependencies = [
"thiserror",
"ucd-trie",
@@ -1712,9 +2000,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
+checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "png"
@@ -1725,7 +2013,7 @@ dependencies = [
"bitflags",
"crc32fast",
"flate2",
- "miniz_oxide",
+ "miniz_oxide 0.5.4",
]
[[package]]
@@ -1787,9 +2075,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.44"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
@@ -1867,9 +2155,9 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
dependencies = [
- "crossbeam-channel",
+ "crossbeam-channel 0.5.6",
"crossbeam-deque",
- "crossbeam-utils",
+ "crossbeam-utils 0.8.12",
"num_cpus",
]
@@ -1893,6 +2181,12 @@ dependencies = [
"regex-syntax",
]
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
[[package]]
name = "regex-syntax"
version = "0.6.27"
@@ -1901,16 +2195,16 @@ checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "relm4"
-version = "0.5.0-beta.2"
-source = "git+https://github.com/Relm4/Relm4?tag=v0.5.0-beta.2#7b0a9387833e6a1d6bf6afbba323451b06b0fb08"
+version = "0.5.0-beta.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "691f7e54e0e008aed42522887fa634d5699cfaa11873d2090420717a76173613"
dependencies = [
"async-broadcast",
- "async-oneshot",
"flume",
+ "fragile",
"futures",
"gtk4",
"libadwaita",
- "log",
"once_cell",
"relm4-macros",
"tokio",
@@ -1919,8 +2213,9 @@ dependencies = [
[[package]]
name = "relm4-components"
-version = "0.5.0-beta.2"
-source = "git+https://github.com/Relm4/Relm4?tag=v0.5.0-beta.2#7b0a9387833e6a1d6bf6afbba323451b06b0fb08"
+version = "0.5.0-beta.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7dbc38bb6813a2ce81a8d5156a08db234cf7c367fda31b6ff99fc3386ec0bb2"
dependencies = [
"log",
"once_cell",
@@ -1930,8 +2225,9 @@ dependencies = [
[[package]]
name = "relm4-macros"
-version = "0.5.0-beta.2"
-source = "git+https://github.com/Relm4/Relm4?tag=v0.5.0-beta.2#7b0a9387833e6a1d6bf6afbba323451b06b0fb08"
+version = "0.5.0-beta.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c710756302235fd02a26b45ddb4db2ec5b4d6e10c3d687911b465ececf979d1f"
dependencies = [
"proc-macro2",
"quote",
@@ -1953,6 +2249,7 @@ version = "0.11.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc"
dependencies = [
+ "async-compression",
"base64",
"bytes",
"encoding_rs",
@@ -1976,6 +2273,7 @@ dependencies = [
"serde_urlencoded",
"tokio",
"tokio-native-tls",
+ "tokio-util",
"tower-service",
"url",
"wasm-bindgen",
@@ -2005,15 +2303,10 @@ dependencies = [
"hashbrown 0.9.1",
"memoffset",
"rustc-hash",
+ "serde",
"text-size",
]
-[[package]]
-name = "rustc-demangle"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
-
[[package]]
name = "rustc-hash"
version = "1.1.0"
@@ -2029,18 +2322,21 @@ dependencies = [
"semver",
]
-[[package]]
-name = "rustversion"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
-
[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "schannel"
version = "0.1.20"
@@ -2048,7 +2344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
dependencies = [
"lazy_static",
- "windows-sys",
+ "windows-sys 0.36.1",
]
[[package]]
@@ -2106,18 +2402,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.145"
+version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.145"
+version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
+checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
@@ -2126,11 +2422,11 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.85"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
dependencies = [
- "itoa",
+ "itoa 1.0.4",
"ryu",
"serde",
]
@@ -2142,19 +2438,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
- "itoa",
+ "itoa 1.0.4",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
-version = "0.9.13"
+version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8613d593412a0deb7bbd8de9d908efff5a0cb9ccd8f62c641e7b2ed2f57291d1"
+checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da"
dependencies = [
"indexmap",
- "itoa",
+ "itoa 1.0.4",
"ryu",
"serde",
"unsafe-libyaml",
@@ -2166,21 +2462,32 @@ version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
- "block-buffer",
- "cfg-if",
+ "block-buffer 0.9.0",
+ "cfg-if 1.0.0",
"cpufeatures",
- "digest",
+ "digest 0.9.0",
"opaque-debug",
]
[[package]]
-name = "sha256"
-version = "1.0.3"
+name = "sha2"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e84a7f596c081d359de5e06a83877138bc3c4483591e1af1916e1472e6e146e"
+checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest 0.10.5",
+]
+
+[[package]]
+name = "sha256"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e334db67871c14c18fc066ad14af13f9fdf5f9a91c61af432d1e3a39c8c6a141"
dependencies = [
"hex",
- "sha2",
+ "sha2 0.9.9",
]
[[package]]
@@ -2192,25 +2499,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "simd-json"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bd78b840b9de64fa3f7d72909b76343849f68e8c3d32608db8d38e4e5481f84"
-dependencies = [
- "halfbrown",
- "serde",
- "serde_json",
- "simdutf8",
- "value-trait",
-]
-
-[[package]]
-name = "simdutf8"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
-
[[package]]
name = "siphasher"
version = "0.3.10"
@@ -2228,9 +2516,9 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "smol_str"
@@ -2269,6 +2557,101 @@ dependencies = [
"lock_api",
]
+[[package]]
+name = "sqlformat"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
+dependencies = [
+ "itertools",
+ "nom",
+ "unicode_categories",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105"
+dependencies = [
+ "ahash",
+ "atoi",
+ "bitflags",
+ "byteorder",
+ "bytes",
+ "crc",
+ "crossbeam-queue",
+ "dotenvy",
+ "either",
+ "event-listener",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "hashlink",
+ "hex",
+ "indexmap",
+ "itoa 1.0.4",
+ "libc",
+ "libsqlite3-sys",
+ "log",
+ "memchr",
+ "once_cell",
+ "paste",
+ "percent-encoding",
+ "sha2 0.10.6",
+ "smallvec",
+ "sqlformat",
+ "sqlx-rt",
+ "stringprep",
+ "thiserror",
+ "tokio-stream",
+ "url",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9"
+dependencies = [
+ "dotenvy",
+ "either",
+ "heck",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "sha2 0.10.6",
+ "sqlx-core",
+ "sqlx-rt",
+ "syn",
+ "url",
+]
+
+[[package]]
+name = "sqlx-rt"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396"
+dependencies = [
+ "native-tls",
+ "once_cell",
+ "tokio",
+ "tokio-native-tls",
+]
+
[[package]]
name = "string_cache"
version = "0.8.4"
@@ -2295,59 +2678,44 @@ dependencies = [
"quote",
]
+[[package]]
+name = "stringprep"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "strsim"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-[[package]]
-name = "strum"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
-
-[[package]]
-name = "strum_macros"
-version = "0.24.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "rustversion",
- "syn",
-]
-
[[package]]
name = "syn"
-version = "1.0.101"
+version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
-[[package]]
-name = "synstructure"
-version = "0.12.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "unicode-xid",
-]
-
[[package]]
name = "system-deps"
-version = "6.0.2"
+version = "6.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709"
+checksum = "2955b1fe31e1fa2fbd1976b71cc69a606d7d4da16f6de3333d0c92d51419aeff"
dependencies = [
"cfg-expr",
"heck",
@@ -2362,7 +2730,7 @@ version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"fastrand",
"libc",
"redox_syscall",
@@ -2395,33 +2763,54 @@ name = "text-size"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"
+dependencies = [
+ "serde",
+]
[[package]]
name = "textwrap"
-version = "0.15.1"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
-version = "1.0.36"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a99cb8c4b9a8ef0e7907cd3b617cc8dc04d571c4e73c8ae403d80ac160bb122"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.36"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a891860d3c8d66fec8e73ddb3765f90082374dbaaa833407b904a94f1a7eb43"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
+[[package]]
+name = "thread_local"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+dependencies = [
+ "once_cell",
+]
+
[[package]]
name = "threadpool"
version = "1.8.1"
@@ -2469,6 +2858,7 @@ dependencies = [
"memchr",
"mio",
"num_cpus",
+ "parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@@ -2497,6 +2887,17 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "tokio-stream"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
[[package]]
name = "tokio-util"
version = "0.7.4"
@@ -2528,12 +2929,11 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
-version = "0.1.36"
+version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
- "cfg-if",
- "log",
+ "cfg-if 1.0.0",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -2541,9 +2941,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.22"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
+checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
@@ -2552,9 +2952,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.29"
+version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
]
@@ -2605,9 +3005,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-normalization"
@@ -2619,10 +3019,22 @@ dependencies = [
]
[[package]]
-name = "unicode-xid"
-version = "0.2.4"
+name = "unicode-segmentation"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "unicode_categories"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unsafe-libyaml"
@@ -2657,24 +3069,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-[[package]]
-name = "value-trait"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0a635407649b66e125e4d2ffd208153210179f8c7c8b71c030aa2ad3eeb4c8f"
-dependencies = [
- "float-cmp",
- "halfbrown",
- "itoa",
- "ryu",
-]
-
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
[[package]]
name = "version-compare"
version = "0.1.0"
@@ -2687,6 +3093,17 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
[[package]]
name = "want"
version = "0.3.0"
@@ -2709,7 +3126,7 @@ version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"wasm-bindgen-macro",
]
@@ -2734,7 +3151,7 @@ version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
"js-sys",
"wasm-bindgen",
"web-sys",
@@ -2785,17 +3202,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
-[[package]]
-name = "which"
-version = "4.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
-dependencies = [
- "either",
- "libc",
- "once_cell",
-]
-
[[package]]
name = "winapi"
version = "0.3.9"
@@ -2833,43 +3239,100 @@ version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_msvc",
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
]
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
[[package]]
name = "winreg"
version = "0.10.1"
diff --git a/Cargo.toml b/Cargo.toml
index 8c33182..12b6149 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,26 +1,27 @@
[package]
name = "nix-software-center"
-version = "0.0.3"
+version = "0.1.0"
edition = "2021"
default-run = "nix-software-center"
[dependencies]
-relm4 = { git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.2", features = ["all"] }
-relm4-components = { package = "relm4-components", git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.2"}
-adw = { package = "libadwaita", git = "https://gitlab.gnome.org/World/Rust/libadwaita-rs", features = ["v1_2", "gtk_v4_6"] }
-gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs", features = ["v4_6"] }
+relm4 = { version = "0.5.0-beta.4", features = ["all"] }
+relm4-components = { package = "relm4-components", version = "0.5.0-beta.4"}
+adw = { package = "libadwaita", version = "0.2", features = ["v1_2", "gtk_v4_6"] }
+gtk = { package = "gtk4", version = "0.5", features = ["v4_6"] }
tokio = { version = "1.21", features = ["rt", "macros", "time", "rt-multi-thread", "sync", "process"] }
tracker = "0.1"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
-simd-json = { version = "0.6", features = ["allow-non-simd"] }
-nix-editor = "0.2.12"
+nix-editor = "0.3.0-beta.1"
+nix-data = { git = "https://github.com/snowflakelinux/nix-data", rev = "a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95" }
+
+sqlx = { version = "0.6", features = [ "runtime-tokio-native-tls" , "sqlite" ] }
html2pango = "0.5"
-brotli = "3.3"
log = "0.4"
pretty_env_logger = "0.4"
flate2 = "1.0"
@@ -30,11 +31,8 @@ reqwest = { version = "0.11", features = ["blocking"] }
sha256 = "1.0"
image = "0.24"
spdx = "0.9"
-edit-distance = "2.1"
-ijson = "0.1"
-strum = "0.24"
-strum_macros = "0.24"
-which = "4.3"
+
+anyhow = "1.0"
[workspace]
members = [".", "nsc-helper"]
diff --git a/data/icons/nsc-audio.svg b/data/icons/nsc-audio.svg
new file mode 100644
index 0000000..666597c
--- /dev/null
+++ b/data/icons/nsc-audio.svg
@@ -0,0 +1,528 @@
+
+
diff --git a/data/icons/nsc-development.svg b/data/icons/nsc-development.svg
new file mode 100644
index 0000000..78792bb
--- /dev/null
+++ b/data/icons/nsc-development.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/data/icons/nsc-gaming.svg b/data/icons/nsc-gaming.svg
new file mode 100644
index 0000000..d5a3a30
--- /dev/null
+++ b/data/icons/nsc-gaming.svg
@@ -0,0 +1,1135 @@
+
+
diff --git a/data/icons/nsc-graphics.svg b/data/icons/nsc-graphics.svg
new file mode 100644
index 0000000..234a6f7
--- /dev/null
+++ b/data/icons/nsc-graphics.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/data/icons/compass-symbolic.svg b/data/icons/nsc-home-symbolic.svg
similarity index 100%
rename from data/icons/compass-symbolic.svg
rename to data/icons/nsc-home-symbolic.svg
diff --git a/data/icons/selection-mode-symbolic.svg b/data/icons/nsc-installed-symbolic.svg
similarity index 100%
rename from data/icons/selection-mode-symbolic.svg
rename to data/icons/nsc-installed-symbolic.svg
diff --git a/data/icons/nsc-update-symbolic.svg b/data/icons/nsc-update-symbolic.svg
new file mode 100644
index 0000000..7981d78
--- /dev/null
+++ b/data/icons/nsc-update-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/data/icons/nsc-video.svg b/data/icons/nsc-video.svg
new file mode 100644
index 0000000..0d203e9
--- /dev/null
+++ b/data/icons/nsc-video.svg
@@ -0,0 +1,86 @@
+
+
diff --git a/data/icons/nsc-web.svg b/data/icons/nsc-web.svg
new file mode 100644
index 0000000..2a221ef
--- /dev/null
+++ b/data/icons/nsc-web.svg
@@ -0,0 +1,64 @@
+
+
diff --git a/data/meson.build b/data/meson.build
index 7bdcad9..850af7a 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,4 +1,5 @@
subdir('icons')
+subdir('resources')
# Desktop file
desktop_conf = configuration_data()
desktop_conf.set('icon', application_id)
diff --git a/data/resources/meson.build b/data/resources/meson.build
new file mode 100644
index 0000000..7e81bd5
--- /dev/null
+++ b/data/resources/meson.build
@@ -0,0 +1,8 @@
+resources = gnome.compile_resources(
+ 'resources',
+ 'resources.gresource.xml',
+ gresource_bundle: true,
+ source_dir: meson.current_build_dir(),
+ install: true,
+ install_dir: pkgdatadir,
+)
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
new file mode 100644
index 0000000..6fb68ca
--- /dev/null
+++ b/data/resources/resources.gresource.xml
@@ -0,0 +1,14 @@
+
+
+
+ ../icons/nsc-home-symbolic.svg
+ ../icons/nsc-installed-symbolic.svg
+ ../icons/nsc-update-symbolic.svg
+ ../icons/nsc-audio.svg
+ ../icons/nsc-development.svg
+ ../icons/nsc-gaming.svg
+ ../icons/nsc-graphics.svg
+ ../icons/nsc-video.svg
+ ../icons/nsc-web.svg
+
+
diff --git a/default.nix b/default.nix
index ec2bce7..fe8b025 100644
--- a/default.nix
+++ b/default.nix
@@ -2,16 +2,6 @@
, lib ? import
}:
let
- libadwaita-git = pkgs.libadwaita.overrideAttrs (oldAttrs: rec {
- version = "1.2.0";
- src = pkgs.fetchFromGitLab {
- domain = "gitlab.gnome.org";
- owner = "GNOME";
- repo = "libadwaita";
- rev = version;
- hash = "sha256-3lH7Vi9M8k+GSrCpvruRpLrIpMoOakKbcJlaAc/FK+U=";
- };
- });
nixos-appstream-data = (import
(pkgs.fetchFromGitHub {
owner = "vlinkz";
@@ -19,18 +9,18 @@ let
rev = "66b3399e6d81017c10265611a151d1109ff1af1b";
hash = "sha256-oiEZD4sMpb2djxReg99GUo0RHWAehxSyQBbiz8Z4DJk=";
})
- { stdenv = pkgs.stdenv; lib = pkgs.lib; pkgs = pkgs; });
+ { set = "all"; stdenv = pkgs.stdenv; lib = pkgs.lib; pkgs = pkgs; });
in
pkgs.stdenv.mkDerivation rec {
pname = "nix-software-center";
- version = "0.0.3";
+ version = "0.1.0";
src = [ ./. ];
cargoDeps = pkgs.rustPlatform.fetchCargoTarball {
inherit src;
name = "${pname}-${version}";
- hash = "sha256-8eUFl3N1tVZ2j+S6iIIpFSH5F5fXAl5+Yz3xS/NxF2I=";
+ hash = "sha256-yZKhtc5Rnkk3QdASnIxHFAYKPbG0RWySXLBjhraFPuc=";
};
nativeBuildInputs = with pkgs; [
@@ -54,7 +44,8 @@ pkgs.stdenv.mkDerivation rec {
glib
gtk4
gtksourceview5
- libadwaita-git
+ libadwaita
+ libxml2
openssl
wayland
gnome.adwaita-icon-theme
diff --git a/flake.lock b/flake.lock
index ca6be2f..4f8cfb3 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1664195620,
- "narHash": "sha256-/0V1a1gAR+QbiQe4aCxBoivhkxss0xyt2mBD6yDrgjw=",
+ "lastModified": 1666703756,
+ "narHash": "sha256-GwpMJ1hT+z1fMAUkaGtvbvofJQwdVFDEGVhfE82+AUk=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "62228ccc672ed000f35b1e5c82e4183e46767e52",
+ "rev": "f994293d1eb8812f032e8919e10a594567cf6ef7",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 2fdf9ff..79982bb 100644
--- a/flake.nix
+++ b/flake.nix
@@ -10,16 +10,6 @@
pkgs = import nixpkgs {
inherit system;
};
- libadwaita-git = pkgs.libadwaita.overrideAttrs (oldAttrs: rec {
- version = "1.2.0";
- src = pkgs.fetchFromGitLab {
- domain = "gitlab.gnome.org";
- owner = "GNOME";
- repo = "libadwaita";
- rev = version;
- hash = "sha256-3lH7Vi9M8k+GSrCpvruRpLrIpMoOakKbcJlaAc/FK+U=";
- };
- });
nixos-appstream-data = pkgs.fetchFromGitHub {
owner = "vlinkz";
repo = "nixos-appstream-data";
@@ -58,7 +48,8 @@
graphene
gtk4
gtksourceview5
- libadwaita-git
+ libadwaita
+ libxml2
meson
ninja
openssl
diff --git a/meson.build b/meson.build
index 103573f..bc8ab73 100644
--- a/meson.build
+++ b/meson.build
@@ -1,7 +1,7 @@
project(
'nix-software-center',
'rust',
- version: '0.0.3',
+ version: '0.1.0',
meson_version: '>= 0.59',
license: 'GPL-3.0-only',
)
diff --git a/nsc-helper/src/meson.build b/nsc-helper/src/meson.build
index 977fe4e..12cacfb 100644
--- a/nsc-helper/src/meson.build
+++ b/nsc-helper/src/meson.build
@@ -27,6 +27,6 @@ cargo_build = custom_target(
cargo, 'build',
cargo_options,
'&&',
- 'cp', 'src' / rust_target / 'nsc-helper', '@OUTPUT@',
+ 'cp', 'nsc-helper' / 'src' / rust_target / 'nsc-helper', '@OUTPUT@',
]
)
diff --git a/src/main.rs b/src/main.rs
index b4d168b..8e3e73e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,13 +1,21 @@
use adw::gio;
-use nix_software_center::ui::window::AppModel;
+use gtk::{prelude::ApplicationExt, glib};
+use log::{error, info};
+use nix_software_center::{ui::window::AppModel, config::RESOURCES_FILE};
use relm4::*;
-use nix_software_center::config::PKGDATADIR;
fn main() {
+ gtk::init().unwrap();
pretty_env_logger::init();
- if let Ok(res) = gio::Resource::load(PKGDATADIR.to_string() + "/resources.gresource") {
+ glib::set_application_name("Software Center");
+ if let Ok(res) = gio::Resource::load(RESOURCES_FILE) {
+ info!("Resource loaded: {}", RESOURCES_FILE);
gio::resources_register(&res);
+ } else {
+ error!("Failed to load resources");
}
- let app = RelmApp::new(nix_software_center::config::APP_ID);
- let application = app.app.clone();
- app.run::(application);
+ gtk::Window::set_default_icon_name(nix_software_center::config::APP_ID);
+ let app = adw::Application::new(Some(nix_software_center::config::APP_ID), gio::ApplicationFlags::empty());
+ app.set_resource_base_path(Some("/dev/vlinkz/NixSoftwareCenter"));
+ let app = RelmApp::with_app(app);
+ app.run::(());
}
diff --git a/src/meson.build b/src/meson.build
index 59ef8b0..d99036d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,17 +5,6 @@ global_conf.set_quoted('PROFILE', profile)
global_conf.set_quoted('VERSION', version + version_suffix)
global_conf.set_quoted('GETTEXT_PACKAGE', gettext_package)
global_conf.set_quoted('LOCALEDIR', localedir)
-
-gnome = import('gnome')
-resources = gnome.compile_resources(
- 'resources',
- 'resources.gresource.xml',
- gresource_bundle: true,
- source_dir: meson.current_build_dir(),
- install: true,
- install_dir: pkgdatadir,
-)
-
config = configure_file(
input: 'config.rs.in',
output: 'config.rs',
@@ -51,6 +40,7 @@ cargo_build = custom_target(
console: true,
install: true,
install_dir: bindir,
+ depends: resources,
command: [
'env',
cargo_env,
diff --git a/src/parse/config.rs b/src/parse/config.rs
index 87ae87a..a4e6f59 100644
--- a/src/parse/config.rs
+++ b/src/parse/config.rs
@@ -1,56 +1,15 @@
-use std::{
- env,
- error::Error,
- fs::{self, File},
- io::Write,
- path::Path,
-};
+use anyhow::Result;
+use nix_data::config::configfile::NixDataConfig;
-use serde::{Deserialize, Serialize};
-
-#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
-pub struct NscConfig {
- pub systemconfig: Option,
- pub flake: Option,
- pub flakearg: Option,
-}
-
-pub fn getconfig() -> Option {
- if let Ok(c) = getconfigval() {
+pub fn getconfig() -> Option {
+ if let Ok(c) = nix_data::config::configfile::getconfig() {
Some(c)
} else {
None
}
}
-fn getconfigval() -> Result> {
- let configfile = checkconfig()?;
- let config: NscConfig =
- serde_json::from_reader(File::open(format!("{}/config.json", configfile))?)?;
- Ok(config)
-}
-
-fn checkconfig() -> Result> {
- let cfgdir = format!("{}/.config/nix-software-center", env::var("HOME")?);
- if !Path::is_file(Path::new(&format!("{}/config.json", &cfgdir))) {
- if !Path::is_file(Path::new("/etc/nix-software-center/config.json")) {
- Err(Box::new(std::io::Error::new(
- std::io::ErrorKind::InvalidData,
- "No config file found",
- )))
- } else {
- Ok("/etc/nix-software-center/".to_string())
- }
- } else {
- Ok(cfgdir)
- }
-}
-
-pub fn editconfig(config: NscConfig) -> Result<(), Box> {
- let cfgdir = format!("{}/.config/nix-software-center", env::var("HOME")?);
- fs::create_dir_all(&cfgdir)?;
- let json = serde_json::to_string_pretty(&config)?;
- let mut file = File::create(format!("{}/config.json", cfgdir))?;
- file.write_all(json.as_bytes())?;
+pub fn editconfig(config: NixDataConfig) -> Result<()> {
+ nix_data::config::configfile::setuserconfig(config)?;
Ok(())
-}
\ No newline at end of file
+}
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 199c472..d06be6d 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -1,3 +1,3 @@
-pub mod cache;
+// pub mod cache;
pub mod packages;
pub mod config;
\ No newline at end of file
diff --git a/src/parse/packages.rs b/src/parse/packages.rs
index 0745c74..9f12d8d 100644
--- a/src/parse/packages.rs
+++ b/src/parse/packages.rs
@@ -1,91 +1,58 @@
use flate2::bufread::GzDecoder;
-use ijson::IString;
use serde::{Deserialize, Serialize};
-use std::fs;
-use std::io::Read;
-use std::{self, fs::File, collections::HashMap, error::Error, env, io::BufReader};
+use std::{self, fs::File, collections::HashMap, io::{BufReader, Read}};
use log::*;
+use anyhow::Result;
use crate::APPINFO;
-#[derive(Serialize, Deserialize, Debug)]
-pub struct PackageBase {
- packages: HashMap,
-}
-
-#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
-pub struct Package {
- pub system: IString,
- pub pname: IString,
- pub meta: Meta,
- pub version: IString,
- #[serde(skip_deserializing)]
- pub appdata: Option,
-}
-
-#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
-pub struct Meta {
- pub broken: Option,
- pub insecure: Option,
- pub unsupported: Option,
- pub unfree: Option,
- pub description: Option,
- #[serde(rename = "longDescription")]
- pub longdescription: Option,
- pub homepage: Option,
- pub maintainers: Option,
- pub position: Option,
- pub license: Option,
- pub platforms: Option
-}
-
-#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
#[serde(untagged)]
pub enum StrOrVec {
- Single(IString),
- List(Vec),
+ Single(String),
+ List(Vec),
}
-#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
#[serde(untagged)]
pub enum Platform {
- Single(IString),
- List(Vec),
- ListList(Vec>),
+ Single(String),
+ List(Vec),
+ ListList(Vec>),
}
-#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
#[serde(untagged)]
pub enum LicenseEnum {
Single(License),
List(Vec),
- SingleStr(IString),
- VecStr(Vec),
+ SingleStr(String),
+ VecStr(Vec),
Mixed(Vec)
}
-#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
pub struct License {
pub free: Option,
#[serde(rename = "fullName")]
- pub fullname: Option,
+ pub fullname: Option,
#[serde(rename = "spdxId")]
- pub spdxid: Option,
- pub url: Option,
+ pub spdxid: Option,
+ pub url: Option,
}
-#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
pub struct PkgMaintainer {
- pub email: Option,
- pub github: Option,
- pub matrix: Option,
- pub name: Option
+ pub email: Option,
+ pub github: Option,
+ pub matrix: Option,
+ pub name: Option
}
-#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct AppData {
#[serde(rename = "Type")]
- pub metatype: IString,
+ pub metatype: String,
#[serde(rename = "ID")]
pub id: String,
#[serde(rename = "Package")]
@@ -110,7 +77,7 @@ pub struct AppData {
pub categories: Option>,
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppUrl {
pub homepage: Option,
pub bugtracker: Option,
@@ -118,27 +85,27 @@ pub struct AppUrl {
pub donation: Option,
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppIconList {
pub cached: Option>,
pub stock: Option,
// TODO: add support for other icon types
}
-#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct AppIcon {
pub name: String,
pub width: u32,
pub height: u32,
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppLaunchable {
#[serde(rename = "desktop-id")]
pub desktopid: Vec
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppProvides {
pub binaries: Option>,
pub ids: Option>,
@@ -146,7 +113,7 @@ pub struct AppProvides {
pub libraries: Option>,
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppScreenshot {
pub default: Option,
pub thumbnails: Option>,
@@ -154,33 +121,12 @@ pub struct AppScreenshot {
pub sourceimage: Option,
}
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct AppScreenshotImage {
pub url: String,
}
-#[derive(Debug, Serialize, Deserialize)]
-struct FlakePkgs {
- packages: HashMap
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-struct FlakeJson {
- pname: IString,
- version: IString,
-}
-
-pub async fn readpkgs() -> Result, Box> {
- info!("Reading package list");
- let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
- let cachefile = format!("{}/packages.json", cachedir);
- let file = File::open(cachefile)?;
- let reader = BufReader::new(file);
- trace!("Reading packages.json");
- let pkgbase: PackageBase = simd_json::serde::from_reader(reader)?;
- trace!("Finished reading packages.json");
- let mut pkgs = pkgbase.packages;
- debug!("APPDATADIR {}", APPINFO);
+pub fn appsteamdata() -> Result> {
let appdata = File::open(&format!("{}/xmls/nixos_x86_64_linux.yml.gz", APPINFO))?;
let appreader = BufReader::new(appdata);
let mut d = GzDecoder::new(appreader);
@@ -188,61 +134,15 @@ pub async fn readpkgs() -> Result, Box>();
files.remove(0);
+
+ let mut out = HashMap::new();
+
for f in files {
if let Ok(appstream) = serde_yaml::from_str::(f) {
- if let Some(p) = pkgs.get_mut(&appstream.package.to_string()) {
- p.appdata = Some(appstream);
- }
+ out.insert(appstream.package.to_string(), appstream);
} else {
warn!("Failed to parse some appstream data");
}
}
- Ok(pkgs)
+ Ok(out)
}
-
-pub fn readlegacysyspkgs() -> Result, Box> {
- info!("Reading legacy system package list");
- let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
- let cachefile = format!("{}/syspackages.json", cachedir);
- if let Ok(f) = fs::read_to_string(&cachefile) {
- if f.trim().is_empty() {
- return Ok(HashMap::new());
- }
- }
- let file = File::open(cachefile)?;
- let reader = BufReader::new(file);
- let newpkgs: HashMap = simd_json::serde::from_reader(reader)?;
- Ok(newpkgs)
-}
-
-pub fn readflakesyspkgs() -> Result, Box> {
- info!("Reading flake system package list");
- let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
- let cachefile = format!("{}/syspackages.json", cachedir);
- if let Ok(f) = fs::read_to_string(&cachefile) {
- if f.trim().is_empty() {
- return Ok(HashMap::new());
- }
- }
- let file = File::open(cachefile)?;
- let reader = BufReader::new(file);
- let newpkgs: HashMap = simd_json::serde::from_reader(reader)?;
- let newpkgs = newpkgs.into_iter().filter_map(|(k, v)| if let Some(pkg) = k.strip_prefix("legacyPackages.x86_64-linux.") { Some((pkg.to_string(), v.version.to_string())) } else { None }).collect::>();
- Ok(newpkgs)
-}
-
-pub fn readprofilepkgs() -> Result, Box> {
- info!("Reading profile package list");
- let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
- let cachefile = format!("{}/profilepackages.json", cachedir);
- if let Ok(f) = fs::read_to_string(&cachefile) {
- if f.trim().is_empty() {
- return Ok(HashMap::new());
- }
- }
- let file = File::open(cachefile)?;
- let reader = BufReader::new(file);
- let profilepkgs: FlakePkgs = simd_json::serde::from_reader(reader)?;
- let profilepkgs = profilepkgs.packages.into_iter().map(|(pkg, v)| (pkg.to_string(), v.version.to_string())).collect::>();
- Ok(profilepkgs)
-}
\ No newline at end of file
diff --git a/src/resources.gresource.xml b/src/resources.gresource.xml
deleted file mode 100644
index 3cb266a..0000000
--- a/src/resources.gresource.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- ../data/icons/compass-symbolic.svg
- ../data/icons/selection-mode-symbolic.svg
-
-
\ No newline at end of file
diff --git a/src/ui/about.rs b/src/ui/about.rs
index 2e75ad6..c07066c 100644
--- a/src/ui/about.rs
+++ b/src/ui/about.rs
@@ -17,7 +17,7 @@ pub enum AboutPageMsg {
#[relm4::component(pub)]
impl SimpleComponent for AboutPageModel {
- type InitParams = gtk::Window;
+ type Init = gtk::Window;
type Input = AboutPageMsg;
type Output = AppMsg;
type Widgets = AboutPageWidgets;
@@ -40,7 +40,7 @@ impl SimpleComponent for AboutPageModel {
}
fn init(
- parent_window: Self::InitParams,
+ parent_window: Self::Init,
root: &Self::Root,
_sender: ComponentSender,
) -> ComponentParts {
diff --git a/src/ui/categories.rs b/src/ui/categories.rs
index 09ca47d..e41cf53 100644
--- a/src/ui/categories.rs
+++ b/src/ui/categories.rs
@@ -1,22 +1,21 @@
use relm4::adw::prelude::*;
use relm4::gtk::pango;
use relm4::{factory::*, *};
-use strum_macros::{EnumIter, Display};
use super::window::AppMsg;
-#[derive(Debug, PartialEq)]
+#[derive(Debug)]
pub struct PkgGroup {
pub category: PkgCategory,
}
-#[derive(Debug, Display, Hash, EnumIter, Eq, PartialEq, Clone)]
+#[derive(Debug, Hash, Eq, PartialEq, Clone)]
pub enum PkgCategory {
Audio,
Development,
Games,
Graphics,
- Network,
+ Web,
Video,
}
@@ -33,7 +32,7 @@ impl FactoryComponent for PkgGroup {
type Output = PkgCategoryMsg;
type Widgets = PkgGroupWidgets;
type ParentWidget = gtk::FlowBox;
- type ParentMsg = AppMsg;
+ type ParentInput = AppMsg;
view! {
gtk::FlowBoxChild {
@@ -51,14 +50,14 @@ impl FactoryComponent for PkgGroup {
gtk::Image {
add_css_class: "icon-dropshadow",
set_icon_name: match self.category {
- PkgCategory::Audio => Some("audio-x-generic"),
- PkgCategory::Development => Some("computer"),
- PkgCategory::Games => Some("input-gaming"),
- PkgCategory::Graphics => Some("image-x-generic"),
- PkgCategory::Network => Some("network-server"),
- PkgCategory::Video => Some("video-x-generic"),
+ PkgCategory::Audio => Some("nsc-audio"),
+ PkgCategory::Development => Some("nsc-development"),
+ PkgCategory::Games => Some("nsc-gaming"),
+ PkgCategory::Graphics => Some("nsc-graphics"),
+ PkgCategory::Web => Some("nsc-web"),
+ PkgCategory::Video => Some("nsc-video"),
},
- set_pixel_size: 32,
+ set_pixel_size: 40,
},
gtk::Label {
add_css_class: "title-2",
@@ -69,7 +68,7 @@ impl FactoryComponent for PkgGroup {
PkgCategory::Development => "Development",
PkgCategory::Games => "Games",
PkgCategory::Graphics => "Graphics",
- PkgCategory::Network => "Network",
+ PkgCategory::Web => "Web",
PkgCategory::Video => "Video",
},
set_ellipsize: pango::EllipsizeMode::End,
@@ -95,7 +94,7 @@ impl FactoryComponent for PkgGroup {
}
}
- fn output_to_parent_msg(output: Self::Output) -> Option {
+ fn output_to_parent_input(output: Self::Output) -> Option {
Some(match output {
PkgCategoryMsg::Open(x) => AppMsg::OpenCategoryPage(x),
})
diff --git a/src/ui/categorypage.rs b/src/ui/categorypage.rs
index 4e8bffc..9195f58 100644
--- a/src/ui/categorypage.rs
+++ b/src/ui/categorypage.rs
@@ -1,6 +1,7 @@
use super::{window::*, categories::PkgCategory, categorytile::CategoryTile};
use adw::prelude::*;
use relm4::{factory::*, *};
+use log::*;
#[tracker::track]
#[derive(Debug)]
@@ -22,12 +23,19 @@ pub enum CategoryPageMsg {
UpdateInstalled(Vec, Vec)
}
+#[derive(Debug)]
+pub enum CategoryPageAsyncMsg {
+ PushRec(CategoryTile),
+ Push(CategoryTile),
+}
+
#[relm4::component(pub)]
-impl SimpleComponent for CategoryPageModel {
- type InitParams = ();
+impl Component for CategoryPageModel {
+ type Init = ();
type Input = CategoryPageMsg;
type Output = AppMsg;
type Widgets = CategoryPageWidgets;
+ type CommandOutput = CategoryPageAsyncMsg;
view! {
gtk::Box {
@@ -45,7 +53,14 @@ impl SimpleComponent for CategoryPageModel {
#[wrap(Some)]
set_title_widget = >k::Label {
#[watch]
- set_label: &model.category.to_string(),
+ set_label: match model.category {
+ PkgCategory::Audio => "Audio",
+ PkgCategory::Development => "Development",
+ PkgCategory::Games => "Games",
+ PkgCategory::Graphics => "Graphics",
+ PkgCategory::Web => "Web",
+ PkgCategory::Video => "Video",
+ },
},
},
gtk::ScrolledWindow {
@@ -59,11 +74,14 @@ impl SimpleComponent for CategoryPageModel {
set_maximum_size: 1000,
set_tightening_threshold: 750,
if model.busy {
+ #[name(spinner)]
gtk::Spinner {
+ set_hexpand: true,
+ set_vexpand: true,
set_halign: gtk::Align::Center,
set_valign: gtk::Align::Center,
set_spinning: true,
- set_height_request: 32,
+ set_size_request: (64, 64),
}
} else {
gtk::Box {
@@ -115,14 +133,14 @@ impl SimpleComponent for CategoryPageModel {
}
fn init(
- (): Self::InitParams,
+ (): Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
let model = CategoryPageModel {
category: PkgCategory::Audio,
- recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
- apps: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
+ recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
+ apps: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
busy: true,
tracker: 0
};
@@ -139,30 +157,44 @@ impl SimpleComponent for CategoryPageModel {
self.reset();
match msg {
CategoryPageMsg::Close => {
- let mut recapps_guard = self.recommendedapps.guard();
- let mut apps_guard = self.apps.guard();
- recapps_guard.clear();
- apps_guard.clear();
sender.output(AppMsg::FrontFrontPage)
}
CategoryPageMsg::OpenPkg(pkg) => {
sender.output(AppMsg::OpenPkg(pkg))
}
CategoryPageMsg::Open(category, catrec, catall) => {
+ info!("CategoryPageMsg::Open");
self.set_category(category);
let mut recapps_guard = self.recommendedapps.guard();
recapps_guard.clear();
- for app in catrec {
- recapps_guard.push_back(app);
- }
+ recapps_guard.drop();
let mut apps_guard = self.apps.guard();
apps_guard.clear();
- for app in catall {
- apps_guard.push_back(app);
- }
+ apps_guard.drop();
+
+ sender.command(|out, shutdown| {
+ shutdown.register(async move {
+ for app in catrec {
+ out.send(CategoryPageAsyncMsg::PushRec(app));
+ tokio::time::sleep(tokio::time::Duration::from_millis(5)).await;
+ }
+ }).drop_on_shutdown()
+ });
+
+ sender.command(|out, shutdown| {
+ shutdown.register(async move {
+ for app in catall {
+ out.send(CategoryPageAsyncMsg::Push(app));
+ tokio::time::sleep(tokio::time::Duration::from_millis(5)).await;
+ }
+ }).drop_on_shutdown()
+ });
+
self.busy = false;
+ info!("DONE CategoryPageMsg::Open");
}
CategoryPageMsg::Loading(category) => {
+ info!("CategoryPageMsg::Loading");
self.set_category(category);
self.busy = true;
}
@@ -199,4 +231,19 @@ impl SimpleComponent for CategoryPageModel {
}
}
+ fn update_cmd(&mut self, msg: Self::CommandOutput, _sender: ComponentSender) {
+ match msg {
+ CategoryPageAsyncMsg::PushRec(tile) => {
+ let mut recapps_guard = self.recommendedapps.guard();
+ recapps_guard.push_back(tile);
+ recapps_guard.drop();
+ }
+ CategoryPageAsyncMsg::Push(tile) => {
+ let mut apps_guard = self.apps.guard();
+ apps_guard.push_back(tile);
+ apps_guard.drop();
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/ui/categorytile.rs b/src/ui/categorytile.rs
index 44f9c04..834bb0e 100644
--- a/src/ui/categorytile.rs
+++ b/src/ui/categorytile.rs
@@ -7,7 +7,7 @@ use relm4::adw::prelude::*;
use relm4::gtk::pango;
use relm4::{factory::*, *};
-#[derive(Default, Debug, PartialEq, Clone)]
+#[derive(Default, Debug, PartialEq, Eq, Clone)]
pub struct CategoryTile {
pub name: String,
pub pkg: String,
@@ -31,7 +31,7 @@ impl FactoryComponent for CategoryTile {
type Output = CategoryTileMsg;
type Widgets = CategoryTileWidgets;
type ParentWidget = gtk::FlowBox;
- type ParentMsg = CategoryPageMsg;
+ type ParentInput = CategoryPageMsg;
view! {
gtk::FlowBoxChild {
@@ -176,7 +176,7 @@ impl FactoryComponent for CategoryTile {
}
}
- fn output_to_parent_msg(output: Self::Output) -> Option {
+ fn output_to_parent_input(output: Self::Output) -> Option {
Some(match output {
CategoryTileMsg::Open(x) => CategoryPageMsg::OpenPkg(x),
})
diff --git a/src/ui/installedpage.rs b/src/ui/installedpage.rs
index edbdaa0..e9dcff7 100644
--- a/src/ui/installedpage.rs
+++ b/src/ui/installedpage.rs
@@ -28,7 +28,7 @@ pub enum InstalledPageMsg {
#[relm4::component(pub)]
impl SimpleComponent for InstalledPageModel {
- type InitParams = (SystemPkgs, UserPkgs);
+ type Init = (SystemPkgs, UserPkgs);
type Input = InstalledPageMsg;
type Output = AppMsg;
type Widgets = InstalledPageWidgets;
@@ -93,13 +93,13 @@ impl SimpleComponent for InstalledPageModel {
}
fn init(
- (systempkgtype, userpkgtype): Self::InitParams,
+ (systempkgtype, userpkgtype): Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
let model = InstalledPageModel {
- installeduserlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
- installedsystemlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
+ installeduserlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
+ installedsystemlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
updatetracker: 0,
userpkgtype,
systempkgtype,
@@ -196,7 +196,7 @@ impl SimpleComponent for InstalledPageModel {
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InstalledItem {
pub name: String,
pub pkg: Option,
@@ -207,7 +207,7 @@ pub struct InstalledItem {
pub busy: bool,
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub struct InstalledItemModel {
pub item: InstalledItem,
}
@@ -230,7 +230,7 @@ impl FactoryComponent for InstalledItemModel {
type Output = InstalledItemMsg;
type Widgets = InstalledItemWidgets;
type ParentWidget = adw::gtk::ListBox;
- type ParentMsg = InstalledPageMsg;
+ type ParentInput = InstalledPageMsg;
view! {
adw::PreferencesRow {
@@ -363,7 +363,7 @@ impl FactoryComponent for InstalledItemModel {
}
}
- fn output_to_parent_msg(output: Self::Output) -> Option {
+ fn output_to_parent_input(output: Self::Output) -> Option {
Some(match output {
InstalledItemMsg::Delete(item) => InstalledPageMsg::Remove(item),
})
diff --git a/src/ui/installworker.rs b/src/ui/installworker.rs
index ac7b018..d8a191f 100644
--- a/src/ui/installworker.rs
+++ b/src/ui/installworker.rs
@@ -1,8 +1,7 @@
-use crate::parse::config::NscConfig;
-
use super::pkgpage::{InstallType, PkgAction, PkgMsg, WorkPkg};
use super::window::{SystemPkgs, UserPkgs};
use log::*;
+use nix_data::config::configfile::NixDataConfig;
use relm4::*;
use std::error::Error;
use std::path::Path;
@@ -25,7 +24,7 @@ pub struct InstallAsyncHandler {
#[derive(Debug)]
pub enum InstallAsyncHandlerMsg {
- SetConfig(NscConfig),
+ SetConfig(NixDataConfig),
SetPkgTypes(SystemPkgs, UserPkgs),
Process(WorkPkg),
CancelProcess,
@@ -39,11 +38,11 @@ pub struct InstallAsyncHandlerInit {
}
impl Worker for InstallAsyncHandler {
- type InitParams = InstallAsyncHandlerInit;
+ type Init = InstallAsyncHandlerInit;
type Input = InstallAsyncHandlerMsg;
type Output = PkgMsg;
- fn init(params: Self::InitParams, _sender: relm4::ComponentSender) -> Self {
+ fn init(params: Self::Init, _sender: relm4::ComponentSender) -> Self {
Self {
process: None,
work: None,
diff --git a/src/ui/pkgpage.rs b/src/ui/pkgpage.rs
index 8efebcd..bc3157c 100644
--- a/src/ui/pkgpage.rs
+++ b/src/ui/pkgpage.rs
@@ -2,6 +2,7 @@ use adw::gio;
use adw::prelude::*;
use html2pango;
use image::{imageops::FilterType, ImageFormat};
+use nix_data::config::configfile::NixDataConfig;
use relm4::actions::RelmAction;
use relm4::actions::RelmActionGroup;
use relm4::gtk::pango;
@@ -22,9 +23,7 @@ use std::{
};
use log::*;
-use crate::parse::config::NscConfig;
use crate::parse::packages::PkgMaintainer;
-use crate::parse::packages::StrOrVec;
use crate::ui::installworker::InstallAsyncHandlerMsg;
use super::installworker::InstallAsyncHandler;
@@ -36,7 +35,7 @@ use super::{screenshotfactory::ScreenshotItem, window::AppMsg};
#[tracker::track]
#[derive(Debug)]
pub struct PkgModel {
- config: NscConfig,
+ config: NixDataConfig,
name: String,
pkg: String,
pname: String,
@@ -63,6 +62,7 @@ pub struct PkgModel {
installedsystempkgs: HashSet,
workqueue: HashSet,
+ visible: bool,
}
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
@@ -87,13 +87,13 @@ pub enum PkgAction {
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub enum Launch {
GtkApp(String),
TerminalApp(String),
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub enum CarouselPage {
First,
Middle,
@@ -107,7 +107,7 @@ pub enum InstallType {
System,
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub struct License {
pub free: Option,
pub fullname: String,
@@ -126,7 +126,7 @@ pub struct PkgInitModel {
pub description: Option,
pub icon: Option,
pub screenshots: Vec,
- pub homepage: Option,
+ pub homepage: Option,
pub licenses: Vec,
pub platforms: Vec,
pub maintainers: Vec,
@@ -135,7 +135,7 @@ pub struct PkgInitModel {
#[derive(Debug)]
pub enum PkgMsg {
- UpdateConfig(NscConfig),
+ UpdateConfig(NixDataConfig),
UpdatePkgTypes(SystemPkgs, UserPkgs),
Open(Box),
LoadScreenshot(String, usize, String),
@@ -168,7 +168,7 @@ pub enum PkgAsyncMsg {
pub struct PkgPageInit {
pub syspkgs: SystemPkgs,
pub userpkgs: UserPkgs,
- pub config: NscConfig,
+ pub config: NixDataConfig,
}
#[relm4::component(pub)]
@@ -231,6 +231,8 @@ impl Component for PkgModel {
set_hexpand: true,
set_hscrollbar_policy: gtk::PolicyType::Never,
set_vscrollbar_policy: gtk::PolicyType::Automatic,
+ #[track(model.changed(PkgModel::visible()) && !self.visible)]
+ set_vadjustment: gtk::Adjustment::NONE,
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
adw::Clamp {
@@ -617,7 +619,6 @@ impl Component for PkgModel {
set_homogeneous: true,
set_row_spacing: 5,
set_column_spacing: 4,
- // set_margin_all: 15,
set_selection_mode: gtk::SelectionMode::None,
set_max_children_per_line: 2,
append = >k::FlowBoxChild {
@@ -960,13 +961,11 @@ impl Component for PkgModel {
maintainers: vec![],
installeduserpkgs: HashSet::new(),
installedsystempkgs: HashSet::new(),
- // installinguserpkgs: HashSet::new(),
- // installingsystempkgs: HashSet::new(),
- // removinguserpkgs: HashSet::new(),
syspkgtype: initparams.syspkgs,
userpkgtype: initparams.userpkgs,
workqueue: HashSet::new(),
launchable: None,
+ visible: false,
tracker: 0,
};
@@ -1003,9 +1002,9 @@ impl Component for PkgModel {
})
};
- group.add_action(nixenv);
- group.add_action(nixprofile);
- group.add_action(nixsystem);
+ group.add_action(&nixenv);
+ group.add_action(&nixprofile);
+ group.add_action(&nixsystem);
let actions = group.into_action_group();
widgets
@@ -1027,8 +1026,8 @@ impl Component for PkgModel {
})
};
- rungroup.add_action(launchaction);
- rungroup.add_action(termaction);
+ rungroup.add_action(&launchaction);
+ rungroup.add_action(&termaction);
let runactions = rungroup.into_action_group();
widgets
@@ -1051,6 +1050,7 @@ impl Component for PkgModel {
self.installworker.emit(InstallAsyncHandlerMsg::SetPkgTypes(syspkgs, userpkgs));
}
PkgMsg::Open(pkgmodel) => {
+ self.set_visible(true);
self.set_pkg(pkgmodel.pkg);
self.set_name(pkgmodel.name);
self.set_icon(pkgmodel.icon);
@@ -1123,22 +1123,7 @@ impl Component for PkgModel {
self.description = Some(pango.strip_prefix('\n').unwrap_or(&pango).to_string());
}
- if let Some(h) = pkgmodel.homepage {
- match h {
- StrOrVec::Single(h) => {
- self.homepage = Some(h.to_string());
- }
- StrOrVec::List(h) => {
- if let Some(first) = h.get(0) {
- self.homepage = Some(first.to_string());
- } else {
- self.homepage = None;
- }
- }
- }
- } else {
- self.homepage = None;
- }
+ self.homepage = pkgmodel.homepage;
if pkgmodel.screenshots.len() <= 1 {
self.carpage = CarouselPage::Single;
@@ -1150,14 +1135,14 @@ impl Component for PkgModel {
let mut scrn_guard = self.screenshots.guard();
scrn_guard.clear();
for _i in 0..pkgmodel.screenshots.len() {
- scrn_guard.push_back(())
+ scrn_guard.push_back(());
}
}
for (i, url) in pkgmodel.screenshots.into_iter().enumerate() {
if let Ok(home) = env::var("HOME") {
let cachedir = format!("{}/.cache/nix-software-center", home);
- let sha = digest(&url);
+ let sha = digest(url.to_string());
let scrnpath = format!("{}/screenshots/{}", cachedir, sha);
let pkg = self.pkg.clone();
@@ -1197,7 +1182,6 @@ impl Component for PkgModel {
let mut content = Cursor::new(b);
if std::io::copy(&mut content, &mut file).is_ok() {
fn openimg(scrnpath: &str) -> Result<(), Box> {
- // let mut reader = Reader::new(Cursor::new(imgdata.buffer())).with_guessed_format().expect("Cursor io never fails");
let img = if let Ok(x) = image::load(BufReader::new(File::open(scrnpath)?), image::ImageFormat::Png) {
x
} else if let Ok(x) = image::load(BufReader::new(File::open(scrnpath)?), image::ImageFormat::Jpeg) {
@@ -1289,13 +1273,14 @@ impl Component for PkgModel {
}
}
PkgMsg::Close => {
- self.pkg = String::default();
- self.name = String::default();
- self.summary = None;
- self.description = None;
- self.icon = None;
- let mut scrn_guard = self.screenshots.guard();
- scrn_guard.clear();
+ // self.pkg = String::default();
+ // self.name = String::default();
+ // self.summary = None;
+ // self.description = None;
+ // self.icon = None;
+ // let mut scrn_guard = self.screenshots.guard();
+ // scrn_guard.clear();
+ self.set_visible(false);
sender.output(AppMsg::FrontPage)
}
PkgMsg::InstallUser => {
@@ -1390,11 +1375,10 @@ impl Component for PkgModel {
PkgAction::Remove => {
self.installedsystempkgs.remove(&work.pkg);
}
- };
- sender.output(AppMsg::UpdateUpdatePkgs);
+ }
}
}
- sender.output(AppMsg::UpdatePkgs(None));
+ sender.output(AppMsg::UpdateInstalledPkgs);
if let Some(n) = &work.notify {
match n {
NotifyPage::Installed => {
@@ -1556,29 +1540,7 @@ impl Component for PkgModel {
}
fn launchterm(cmd: &str) {
- if which::which("kgx").is_ok() {
- let _ = Command::new("kgx").arg("-e").arg(&cmd).spawn();
- } else if which::which("gnome-terminal").is_ok() {
- let _ = Command::new("gnome-terminal").arg("--").arg(&cmd).spawn();
- } else if which::which("konsole").is_ok() {
- let _ = Command::new("konsole").arg("-e").arg(&cmd).spawn();
- } else if which::which("mate-terminal").is_ok() {
- let _ = Command::new("mate-terminal").arg("-e").arg(&cmd).spawn();
- } else if which::which("xfce4-terminal").is_ok() {
- let _ = Command::new("xfce4-terminal").arg("-e").arg(&cmd).spawn();
- } else if which::which("tilix").is_ok() {
- let _ = Command::new("tilix").arg("-e").arg(&cmd).spawn();
- } else if which::which("terminology").is_ok() {
- let _ = Command::new("terminology").arg("-e").arg(&cmd).spawn();
- } else if which::which("alacritty").is_ok() {
- let _ = Command::new("alacritty").arg("-e").arg(&cmd).spawn();
- } else if which::which("urxvt").is_ok() {
- let _ = Command::new("urxvt").arg("-e").arg(&cmd).spawn();
- } else if which::which("xterm").is_ok() {
- let _ = Command::new("xterm").arg("-e").arg(&cmd).spawn();
- } else {
- error!("No terminal detected!")
- }
+ let _ = Command::new("kgx").arg("-e").arg(&cmd).spawn();
}
relm4::new_action_group!(ModeActionGroup, "mode");
diff --git a/src/ui/pkgtile.rs b/src/ui/pkgtile.rs
index ef3e80d..bfed941 100644
--- a/src/ui/pkgtile.rs
+++ b/src/ui/pkgtile.rs
@@ -8,7 +8,7 @@ use crate::APPINFO;
use super::window::AppMsg;
-#[derive(Default, Debug, PartialEq)]
+#[derive(Default, Debug, PartialEq, Eq)]
pub struct PkgTile {
pub name: String,
pub pkg: String,
@@ -32,7 +32,7 @@ impl FactoryComponent for PkgTile {
type Output = PkgTileMsg;
type Widgets = PkgTileWidgets;
type ParentWidget = gtk::FlowBox;
- type ParentMsg = AppMsg;
+ type ParentInput = AppMsg;
view! {
gtk::FlowBoxChild {
@@ -171,7 +171,7 @@ impl FactoryComponent for PkgTile {
}
}
- fn output_to_parent_msg(output: Self::Output) -> Option {
+ fn output_to_parent_input(output: Self::Output) -> Option {
Some(match output {
PkgTileMsg::Open(x) => AppMsg::OpenPkg(x),
})
diff --git a/src/ui/preferencespage.rs b/src/ui/preferencespage.rs
index c78215a..f95ddd6 100644
--- a/src/ui/preferencespage.rs
+++ b/src/ui/preferencespage.rs
@@ -1,9 +1,7 @@
use std::path::PathBuf;
-
-use crate::parse::config::NscConfig;
-
use super::window::AppMsg;
use adw::prelude::*;
+use nix_data::config::configfile::NixDataConfig;
use relm4::*;
use relm4_components::open_dialog::*;
@@ -22,7 +20,7 @@ pub struct PreferencesPageModel {
#[derive(Debug)]
pub enum PreferencesPageMsg {
- Show(NscConfig),
+ Show(NixDataConfig),
Open,
OpenFlake,
SetConfigPath(Option),
@@ -34,7 +32,7 @@ pub enum PreferencesPageMsg {
#[relm4::component(pub)]
impl SimpleComponent for PreferencesPageModel {
- type InitParams = gtk::Window;
+ type Init = gtk::Window;
type Input = PreferencesPageMsg;
type Output = AppMsg;
type Widgets = PreferencesPageWidgets;
@@ -165,7 +163,7 @@ impl SimpleComponent for PreferencesPageModel {
} @flakeentry,
#[track(model.changed(PreferencesPageModel::flake()))]
#[block_signal(flakeentry)]
- set_text: &model.flakearg.as_ref().unwrap_or(&String::new())
+ set_text: model.flakearg.as_ref().unwrap_or(&String::new())
}
}
@@ -174,21 +172,21 @@ impl SimpleComponent for PreferencesPageModel {
}
fn init(
- parent_window: Self::InitParams,
+ parent_window: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
let open_dialog = OpenDialog::builder()
.transient_for_native(root)
.launch(OpenDialogSettings::default())
- .forward(&sender.input, |response| match response {
+ .forward(sender.input_sender(), |response| match response {
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetConfigPath(Some(path)),
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
});
let flake_file_dialog = OpenDialog::builder()
.transient_for_native(root)
.launch(OpenDialogSettings::default())
- .forward(&sender.input, |response| match response {
+ .forward(sender.input_sender(), |response| match response {
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetFlakePath(Some(path)),
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
});
@@ -211,9 +209,9 @@ impl SimpleComponent for PreferencesPageModel {
self.reset();
match msg {
PreferencesPageMsg::Show(config) => {
- self.configpath = config.systemconfig.as_ref().map(|x| PathBuf::from(x));
- self.set_flake(config.flake.as_ref().map(|x| PathBuf::from(x)));
- self.set_flakearg(config.flakearg.clone());
+ self.configpath = config.systemconfig.as_ref().map(PathBuf::from);
+ self.set_flake(config.flake.as_ref().map(PathBuf::from));
+ self.set_flakearg(config.flakearg);
self.hidden = false;
}
PreferencesPageMsg::Open => self.open_dialog.emit(OpenDialogMsg::Open),
diff --git a/src/ui/screenshotfactory.rs b/src/ui/screenshotfactory.rs
index 5f791a3..f653a30 100644
--- a/src/ui/screenshotfactory.rs
+++ b/src/ui/screenshotfactory.rs
@@ -3,7 +3,7 @@ use relm4::{factory::*, *};
use super::pkgpage::PkgMsg;
-#[derive(Default, Debug, PartialEq)]
+#[derive(Default, Debug, PartialEq, Eq)]
pub struct ScreenshotItem {
pub path: Option,
pub error: bool,
@@ -20,7 +20,7 @@ impl FactoryComponent for ScreenshotItem {
type Output = ScreenshotItemMsg;
type Widgets = PkgTileWidgets;
type ParentWidget = adw::Carousel;
- type ParentMsg = PkgMsg;
+ type ParentInput = PkgMsg;
view! {
gtk::Box {
diff --git a/src/ui/searchpage.rs b/src/ui/searchpage.rs
index 17de67f..b154af4 100644
--- a/src/ui/searchpage.rs
+++ b/src/ui/searchpage.rs
@@ -16,16 +16,14 @@ pub struct SearchPageModel {
#[derive(Debug)]
pub enum SearchPageMsg {
- Open,
Search(Vec),
UpdateInstalled(HashSet, HashSet),
- Close,
OpenRow(gtk::ListBoxRow)
}
#[relm4::component(pub)]
impl SimpleComponent for SearchPageModel {
- type InitParams = ();
+ type Init = ();
type Input = SearchPageMsg;
type Output = AppMsg;
type Widgets = SearchPageWidgets;
@@ -53,12 +51,12 @@ impl SimpleComponent for SearchPageModel {
}
fn init(
- (): Self::InitParams,
+ (): Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
let model = SearchPageModel {
- searchitems: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
+ searchitems: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
searchitemtracker: 0,
tracker: 0,
};
@@ -82,8 +80,6 @@ impl SimpleComponent for SearchPageModel {
searchitem_guard.drop();
self.update_searchitemtracker(|_| ());
}
- SearchPageMsg::Open => {}
- SearchPageMsg::Close => {}
SearchPageMsg::OpenRow(row) => {
let searchitem_guard = self.searchitems.guard();
for (i, child) in searchitem_guard.widget().iter_children().enumerate() {
@@ -110,7 +106,7 @@ impl SimpleComponent for SearchPageModel {
}
}
-#[derive(Default, Debug, PartialEq)]
+#[derive(Default, Debug, PartialEq, Eq)]
pub struct SearchItem {
pub name: String,
pub pkg: String,
@@ -122,7 +118,7 @@ pub struct SearchItem {
}
#[tracker::track]
-#[derive(Default, Debug, PartialEq)]
+#[derive(Default, Debug, PartialEq, Eq)]
pub struct SearchItemModel {
pub item: SearchItem,
}
@@ -138,7 +134,7 @@ impl FactoryComponent for SearchItemModel {
type Output = SearchItemMsg;
type Widgets = SearchItemWidgets;
type ParentWidget = adw::gtk::ListBox;
- type ParentMsg = SearchPageMsg;
+ type ParentInput = SearchPageMsg;
view! {
adw::PreferencesRow {
diff --git a/src/ui/updatedialog.rs b/src/ui/updatedialog.rs
index 301ba5d..33639e8 100644
--- a/src/ui/updatedialog.rs
+++ b/src/ui/updatedialog.rs
@@ -21,7 +21,7 @@ pub enum UpdateDialogMsg {
#[relm4::component(pub)]
impl SimpleComponent for UpdateDialogModel {
- type InitParams = gtk::Window;
+ type Init = gtk::Window;
type Input = UpdateDialogMsg;
type Output = UpdatePageMsg;
type Widgets = UpdateDialogWidgets;
@@ -99,7 +99,7 @@ impl SimpleComponent for UpdateDialogModel {
}
fn init(
- parent_window: Self::InitParams,
+ parent_window: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
diff --git a/src/ui/updatepage.rs b/src/ui/updatepage.rs
index 35f420f..34c7b71 100644
--- a/src/ui/updatepage.rs
+++ b/src/ui/updatepage.rs
@@ -1,7 +1,8 @@
-use crate::{parse::{cache::channelver, config::NscConfig}, APPINFO};
+use crate::APPINFO;
use super::{pkgpage::InstallType, window::*, updatedialog::{UpdateDialogModel, UpdateDialogMsg}, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}};
use adw::prelude::*;
+use nix_data::config::configfile::NixDataConfig;
use relm4::{factory::*, gtk::pango, *};
use std::{path::Path, convert::identity};
use log::*;
@@ -18,7 +19,7 @@ pub struct UpdatePageModel {
updatedialog: Controller,
#[tracker::no_eq]
updateworker: WorkerController,
- config: NscConfig,
+ config: NixDataConfig,
systype: SystemPkgs,
usertype: UserPkgs,
updatetracker: u8,
@@ -26,7 +27,7 @@ pub struct UpdatePageModel {
#[derive(Debug)]
pub enum UpdatePageMsg {
- UpdateConfig(NscConfig),
+ UpdateConfig(NixDataConfig),
UpdatePkgTypes(SystemPkgs, UserPkgs),
Update(Vec, Vec),
OpenRow(usize, InstallType),
@@ -45,12 +46,12 @@ pub struct UpdatePageInit {
pub window: gtk::Window,
pub systype: SystemPkgs,
pub usertype: UserPkgs,
- pub config: NscConfig,
+ pub config: NixDataConfig,
}
#[relm4::component(pub)]
impl SimpleComponent for UpdatePageModel {
- type InitParams = UpdatePageInit;
+ type Init = UpdatePageInit;
type Input = UpdatePageMsg;
type Output = AppMsg;
type Widgets = UpdatePageWidgets;
@@ -277,7 +278,7 @@ impl SimpleComponent for UpdatePageModel {
}
fn init(
- initparams: Self::InitParams,
+ initparams: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
@@ -292,8 +293,8 @@ impl SimpleComponent for UpdatePageModel {
updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(config.clone()));
let model = UpdatePageModel {
- updateuserlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
- updatesystemlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
+ updateuserlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
+ updatesystemlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
channelupdate: None,
updatetracker: 0,
updatedialog,
@@ -320,15 +321,21 @@ impl SimpleComponent for UpdatePageModel {
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(self.config.clone()));
}
UpdatePageMsg::UpdatePkgTypes(systype, usertype) => {
- self.systype = systype.clone();
- self.usertype = usertype.clone();
+ self.systype = systype;
+ self.usertype = usertype;
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdatePkgTypes(self.systype.clone(), self.usertype.clone()));
}
UpdatePageMsg::Update(updateuserlist, updatesystemlist) => {
info!("UpdatePageMsg::Update");
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
- self.channelupdate = channelver().unwrap_or(None);
+ self.channelupdate = match nix_data::cache::channel::uptodate() {
+ Ok(x) => {
+ x
+ },
+ Err(_) => None,
+ };
+ debug!("CHANNELUPDATE: {:?}", self.channelupdate);
self.update_updatetracker(|_| ());
let mut updateuserlist_guard = self.updateuserlist.guard();
updateuserlist_guard.clear();
@@ -384,7 +391,7 @@ impl SimpleComponent for UpdatePageModel {
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAll);
}
UpdatePageMsg::DoneWorking => {
- sender.output(AppMsg::ReloadUpdate);
+ sender.output(AppMsg::UpdateInstalledPkgs);
}
UpdatePageMsg::DoneLoading => {
self.updatedialog.emit(UpdateDialogMsg::Done);
@@ -396,7 +403,7 @@ impl SimpleComponent for UpdatePageModel {
}
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub struct UpdateItem {
pub name: String,
pub pkg: Option,
@@ -408,7 +415,7 @@ pub struct UpdateItem {
pub verto: Option,
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
pub struct UpdateItemModel {
item: UpdateItem,
}
@@ -424,7 +431,7 @@ impl FactoryComponent for UpdateItemModel {
type Output = UpdateItemMsg;
type Widgets = UpdateItemWidgets;
type ParentWidget = adw::gtk::ListBox;
- type ParentMsg = UpdatePageMsg;
+ type ParentInput = UpdatePageMsg;
view! {
adw::PreferencesRow {
diff --git a/src/ui/updateworker.rs b/src/ui/updateworker.rs
index f90b347..5dc7f1b 100644
--- a/src/ui/updateworker.rs
+++ b/src/ui/updateworker.rs
@@ -1,10 +1,9 @@
+use nix_data::config::configfile::NixDataConfig;
use relm4::*;
use std::{error::Error, path::Path, process::Stdio};
use tokio::io::AsyncBufReadExt;
use log::*;
-use crate::parse::config::NscConfig;
-
use super::{
updatepage::UpdatePageMsg,
window::{SystemPkgs, UserPkgs},
@@ -23,7 +22,7 @@ pub struct UpdateAsyncHandler {
#[derive(Debug)]
pub enum UpdateAsyncHandlerMsg {
- UpdateConfig(NscConfig),
+ UpdateConfig(NixDataConfig),
UpdatePkgTypes(SystemPkgs, UserPkgs),
UpdateChannels,
@@ -47,11 +46,11 @@ pub struct UpdateAsyncHandlerInit {
}
impl Worker for UpdateAsyncHandler {
- type InitParams = UpdateAsyncHandlerInit;
+ type Init = UpdateAsyncHandlerInit;
type Input = UpdateAsyncHandlerMsg;
type Output = UpdatePageMsg;
- fn init(params: Self::InitParams, _sender: relm4::ComponentSender) -> Self {
+ fn init(params: Self::Init, _sender: relm4::ComponentSender) -> Self {
Self {
process: None,
systemconfig: None,
diff --git a/src/ui/welcome.rs b/src/ui/welcome.rs
index 19ec4e0..9cd0904 100644
--- a/src/ui/welcome.rs
+++ b/src/ui/welcome.rs
@@ -2,11 +2,10 @@ use std::path::{PathBuf, Path};
use adw::prelude::*;
use log::info;
+use nix_data::config::configfile::NixDataConfig;
use relm4::*;
use relm4_components::open_dialog::*;
-use crate::parse::config::NscConfig;
-
use super::window::AppMsg;
#[tracker::track]
@@ -36,7 +35,7 @@ pub enum WelcomeMsg {
#[relm4::component(pub)]
impl SimpleComponent for WelcomeModel {
- type InitParams = gtk::Window;
+ type Init = gtk::Window;
type Input = WelcomeMsg;
type Output = AppMsg;
type Widgets = WelcomeWidgets;
@@ -176,7 +175,7 @@ impl SimpleComponent for WelcomeModel {
}
fn init(
- parent_window: Self::InitParams,
+ parent_window: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
@@ -184,7 +183,7 @@ impl SimpleComponent for WelcomeModel {
let conf_dialog = OpenDialog::builder()
.transient_for_native(root)
.launch(OpenDialogSettings::default())
- .forward(&sender.input, |response| match response {
+ .forward(sender.input_sender(), |response| match response {
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateConfPath(path),
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
});
@@ -193,7 +192,7 @@ impl SimpleComponent for WelcomeModel {
let flake_dialog = OpenDialog::builder()
.transient_for_native(root)
.launch(OpenDialogSettings::default())
- .forward(&sender.input, |response| match response {
+ .forward(sender.input_sender(), |response| match response {
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateFlakePath(path),
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
});
@@ -222,7 +221,7 @@ impl SimpleComponent for WelcomeModel {
self.hidden = false;
}
WelcomeMsg::Close => {
- let config = NscConfig {
+ let config = NixDataConfig {
systemconfig: self.confpath.as_ref().map(|x| x.to_string_lossy().to_string()),
flake: self.flakepath.as_ref().map(|x| x.to_string_lossy().to_string()),
flakearg: None,
diff --git a/src/ui/window.rs b/src/ui/window.rs
index 2f4b0a1..0334185 100644
--- a/src/ui/window.rs
+++ b/src/ui/window.rs
@@ -1,18 +1,38 @@
-use std::{collections::{HashMap, HashSet}, convert::identity, error::Error, process::Command, fs, io, path::{PathBuf, Path}};
-use ijson::IValue;
-use relm4::{actions::*, factory::*, *};
+use crate::{
+ config,
+ parse::{
+ config::{editconfig, getconfig},
+ packages::{AppData, LicenseEnum, PkgMaintainer, Platform},
+ },
+ ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg},
+ APPINFO,
+};
use adw::prelude::*;
-use edit_distance;
-use serde_json::Value;
-use spdx::Expression;
-use crate::{parse::{packages::{Package, LicenseEnum, Platform, PkgMaintainer}, cache::{uptodatelegacy, uptodateflake}, config::{NscConfig, getconfig, editconfig}}, ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg}, APPINFO, config};
use log::*;
+use nix_data::config::configfile::NixDataConfig;
+use relm4::{actions::*, factory::*, *};
+use spdx::Expression;
+use sqlx::{QueryBuilder, Sqlite, SqlitePool};
+use std::{
+ collections::{HashMap, HashSet},
+ convert::identity,
+ fs,
+ path::Path,
+};
use super::{
- categories::{PkgGroup, PkgCategory},
+ about::{AboutPageModel, AboutPageMsg},
+ categories::{PkgCategory, PkgGroup},
+ categorypage::{CategoryPageModel, CategoryPageMsg},
+ categorytile::CategoryTile,
+ installedpage::{InstalledPageModel, InstalledPageMsg},
+ pkgpage::{self, InstallType, PkgInitModel, PkgModel, PkgMsg, WorkPkg},
pkgtile::PkgTile,
- pkgpage::{PkgModel, PkgMsg, PkgInitModel, self, InstallType, WorkPkg},
- windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg, CacheReturn}, searchpage::{SearchPageModel, SearchPageMsg, SearchItem}, installedpage::{InstalledPageModel, InstalledPageMsg}, updatepage::{UpdatePageModel, UpdatePageMsg, UpdateItem, UpdatePageInit}, about::{AboutPageModel, AboutPageMsg}, preferencespage::{PreferencesPageModel, PreferencesPageMsg}, categorypage::{CategoryPageModel, CategoryPageMsg}, categorytile::CategoryTile, welcome::WelcomeModel,
+ preferencespage::{PreferencesPageModel, PreferencesPageMsg},
+ searchpage::{SearchItem, SearchPageModel, SearchPageMsg},
+ updatepage::{UpdateItem, UpdatePageInit, UpdatePageModel, UpdatePageMsg},
+ welcome::WelcomeModel,
+ windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg},
};
#[derive(PartialEq)]
@@ -27,25 +47,23 @@ enum MainPage {
CategoryPage,
}
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone)]
pub enum SystemPkgs {
Legacy,
Flake,
None,
}
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone)]
pub enum UserPkgs {
Env,
Profile,
}
-
#[tracker::track]
pub struct AppModel {
- application: adw::Application,
mainwindow: adw::ApplicationWindow,
- config: NscConfig,
+ config: NixDataConfig,
#[tracker::no_eq]
windowloading: WorkerController,
#[tracker::no_eq]
@@ -53,11 +71,18 @@ pub struct AppModel {
busy: bool,
page: Page,
mainpage: MainPage,
+ // #[tracker::no_eq]
+ // pkgs: HashMap,
+ // syspkgs: HashMap,
+ // profilepkgs: Option>,
+ // pkgitems: HashMap,
#[tracker::no_eq]
- pkgs: HashMap,
- syspkgs: HashMap,
- profilepkgs: Option>,
- pkgitems: HashMap,
+ pkgdb: String,
+ #[tracker::no_eq]
+ nixpkgsdb: Option,
+ #[tracker::no_eq]
+ systemdb: Option,
+ appdata: HashMap,
installeduserpkgs: HashMap,
installedsystempkgs: HashSet,
syspkgtype: SystemPkgs,
@@ -91,18 +116,25 @@ pub enum AppMsg {
UpdateSysconfig(Option),
UpdateFlake(Option, Option),
TryLoad,
- ReloadUpdate,
- LoadConfig(NscConfig),
+ LoadConfig(NixDataConfig),
Close,
LoadError(String, String),
- Initialize(HashMap, Vec, HashMap, HashMap>, HashMap>, Option> /* profile pkgs */),
- ReloadUpdateItems(HashMap, HashMap),
+ Initialize(
+ String,
+ Option,
+ Option,
+ HashMap,
+ Vec,
+ HashMap>,
+ HashMap>,
+ ),
OpenPkg(String),
FrontPage,
FrontFrontPage,
- UpdatePkgs(Option>),
+ // UpdatePkgs(Option>),
UpdateInstalledPkgs,
- UpdateUpdatePkgs,
+ UpdateInstalledPage,
+ // UpdateUpdatePkgs,
UpdateCategoryPkgs,
SetSearch(bool),
SetVsBar(bool),
@@ -113,10 +145,12 @@ pub enum AppMsg {
AddInstalledToWorkQueue(WorkPkg),
RemoveInstalledBusy(WorkPkg),
OpenCategoryPage(PkgCategory),
- LoadCategory(PkgCategory)
+ LoadCategory(PkgCategory),
+
+ UpdateRecPkgs(Vec),
}
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PkgItem {
pkg: String,
pname: String,
@@ -128,12 +162,15 @@ pub struct PkgItem {
#[derive(Debug)]
pub enum AppAsyncMsg {
- Search(String, Vec)
+ Search(String, Vec),
+ UpdateRecPkgs(Vec),
+ UpdateInstalledPkgs(HashSet, HashMap),
+ LoadCategory(PkgCategory, Vec, Vec),
}
#[relm4::component(pub)]
impl Component for AppModel {
- type Init = adw::Application;
+ type Init = ();
type Input = AppMsg;
type Output = ();
type Widgets = AppWidgets;
@@ -202,7 +239,7 @@ impl Component for AppModel {
connect_toggled[sender] => move |x| {
sender.input(AppMsg::SetSearch(x.is_active()))
} @searchtoggle
-
+
},
#[name(viewswitchertitle)]
#[wrap(Some)]
@@ -344,12 +381,12 @@ impl Component for AppModel {
}
}
- fn init(
- application: Self::Init,
+ #[tokio::main]
+ async fn init(
+ _application: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {
-
let (config, welcome) = if let Some(config) = getconfig() {
debug!("Got config: {:?}", config);
let mut out = false;
@@ -363,33 +400,31 @@ impl Component for AppModel {
if !Path::new(&flakepath).exists() {
warn!("Invalid flake path: {}", flakepath);
out = true
- } else {
- out = false
}
- } else {
- out = false
}
(config, out)
} else {
// Show welcome page
debug!("No config found");
- (NscConfig {
- systemconfig: None,
- flake: None,
- flakearg: None,
- }, true)
+ (
+ NixDataConfig {
+ systemconfig: None,
+ flake: None,
+ flakearg: None,
+ },
+ true,
+ )
};
let userpkgtype = if let Ok(h) = std::env::var("HOME") {
-
if Path::new(&format!("{}/.nix-profile/manifest.json", h)).exists()
- || !Path::new("/nix/var/nix/profiles/per-user/root/channels/nixos").exists()
- || !Path::new(&format!("{}/.nix-profile/manifest.nix", h)).exists()
- || if let Ok(m) = fs::read_to_string(&format!("{}/.nix-profile/manifest.nix", h)) {
- m == "[ ]"
- } else {
- false
- }
+ || !Path::new("/nix/var/nix/profiles/per-user/root/channels/nixos").exists()
+ || !Path::new(&format!("{}/.nix-profile/manifest.nix", h)).exists()
+ || if let Ok(m) = fs::read_to_string(&format!("{}/.nix-profile/manifest.nix", h)) {
+ m == "[ ]"
+ } else {
+ false
+ }
{
UserPkgs::Profile
} else {
@@ -404,7 +439,9 @@ impl Component for AppModel {
} else {
match fs::read_to_string("/run/current-system/nixos-version") {
Ok(s) => {
- if !Path::new("/nix/var/nix/profiles/per-user/root/channels/nixos").exists() || config.flake.is_some() {
+ if !Path::new("/nix/var/nix/profiles/per-user/root/channels/nixos").exists()
+ || config.flake.is_some()
+ {
SystemPkgs::Flake
} else if let Some(last) = s.split('.').last() {
if last.len() == 7 || last == "dirty" || last == "git" {
@@ -423,8 +460,6 @@ impl Component for AppModel {
debug!("userpkgtype: {:?}", userpkgtype);
debug!("syspkgtype: {:?}", syspkgtype);
-
-
let windowloading = WindowAsyncHandler::builder()
.detach_worker(())
.forward(sender.input_sender(), identity);
@@ -448,12 +483,16 @@ impl Component for AppModel {
.launch((syspkgtype.clone(), userpkgtype.clone()))
.forward(sender.input_sender(), identity);
let updatepage = UpdatePageModel::builder()
- .launch(UpdatePageInit { window: root.clone().upcast(), systype: syspkgtype.clone(), usertype: userpkgtype.clone(), config: config.clone() })
+ .launch(UpdatePageInit {
+ window: root.clone().upcast(),
+ systype: syspkgtype.clone(),
+ usertype: userpkgtype.clone(),
+ config: config.clone(),
+ })
.forward(sender.input_sender(), identity);
let viewstack = adw::ViewStack::new();
let model = AppModel {
- application,
mainwindow: root.clone(),
config,
windowloading,
@@ -461,18 +500,18 @@ impl Component for AppModel {
busy: true,
page: Page::FrontPage,
mainpage: MainPage::FrontPage,
- pkgs: HashMap::new(),
- syspkgs: HashMap::new(),
- pkgitems: HashMap::new(),
+ pkgdb: String::new(),
+ nixpkgsdb: None,
+ systemdb: None,
+ appdata: HashMap::new(),
installeduserpkgs: HashMap::new(),
installedsystempkgs: HashSet::new(),
- profilepkgs: None,
syspkgtype,
userpkgtype,
categoryrec: HashMap::new(),
categoryall: HashMap::new(),
- recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
- categories: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
+ recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
+ categories: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
pkgpage,
searchpage,
categorypage,
@@ -493,7 +532,11 @@ impl Component for AppModel {
.forward(sender.input_sender(), identity);
welcomepage.emit(WelcomeMsg::Show);
} else {
- model.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(CacheReturn::Init, model.syspkgtype.clone(), model.userpkgtype.clone(), model.config.clone()));
+ model.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(
+ model.syspkgtype.clone(),
+ model.userpkgtype.clone(),
+ model.config.clone(),
+ ));
}
let recbox = model.recommendedapps.widget();
let categorybox = model.categories.widget();
@@ -516,8 +559,8 @@ impl Component for AppModel {
})
};
- group.add_action(aboutpage);
- group.add_action(prefernecespage);
+ group.add_action(&aboutpage);
+ group.add_action(&prefernecespage);
let actions = group.into_action_group();
widgets
.main_window
@@ -536,40 +579,80 @@ impl Component for AppModel {
installedvs.set_name(Some("installed"));
searchvs.set_name(Some("search"));
updatesvs.set_name(Some("updates"));
- frontvs.set_icon_name(Some("compass"));
- installedvs.set_icon_name(Some("selection-mode"));
- updatesvs.set_icon_name(Some("emblem-synchronizing-symbolic"));
+ frontvs.set_icon_name(Some("nsc-home-symbolic"));
+ installedvs.set_icon_name(Some("nsc-installed-symbolic"));
+ updatesvs.set_icon_name(Some("nsc-update-symbolic"));
ComponentParts { model, widgets }
}
- fn update(&mut self, msg: Self::Input, sender: ComponentSender) {
+ #[tokio::main]
+ async fn update(&mut self, msg: Self::Input, sender: ComponentSender) {
self.reset();
match msg {
AppMsg::TryLoad => {
self.busy = true;
- self.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(CacheReturn::Init, self.syspkgtype.clone(), self.userpkgtype.clone(), self.config.clone()));
- }
- AppMsg::ReloadUpdate => {
- self.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(CacheReturn::Update, self.syspkgtype.clone(), self.userpkgtype.clone(), self.config.clone()));
+ self.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ self.config.clone(),
+ ));
}
AppMsg::LoadConfig(config) => {
+ info!("AppMsg::LoadConfig");
self.config = config;
if let Err(e) = editconfig(self.config.clone()) {
warn!("Error editing config: {}", e);
}
+
+ self.syspkgtype = if self.config.systemconfig.is_none() {
+ SystemPkgs::None
+ } else {
+ match fs::read_to_string("/run/current-system/nixos-version") {
+ Ok(s) => {
+ if !Path::new("/nix/var/nix/profiles/per-user/root/channels/nixos")
+ .exists()
+ || self.config.flake.is_some()
+ {
+ SystemPkgs::Flake
+ } else if let Some(last) = s.split('.').last() {
+ if last.len() == 7 || last == "dirty" || last == "git" {
+ SystemPkgs::Flake
+ } else {
+ SystemPkgs::Legacy
+ }
+ } else {
+ SystemPkgs::Legacy
+ }
+ }
+ Err(_) => SystemPkgs::None,
+ }
+ };
+ self.pkgpage.emit(PkgMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
self.pkgpage.emit(PkgMsg::UpdateConfig(self.config.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
- self.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(CacheReturn::Init, self.syspkgtype.clone(), self.userpkgtype.clone(), self.config.clone()));
+ self.updatepage.emit(UpdatePageMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
+ self.updatepage
+ .emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
+ self.windowloading.emit(WindowAsyncHandlerMsg::CheckCache(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ self.config.clone(),
+ ));
}
AppMsg::Close => {
- self.application.quit();
+ relm4::main_application().quit();
}
AppMsg::LoadError(msg, msg2) => {
self.busy = false;
self.loaderrordialog.emit(LoadErrorMsg::Show(msg, msg2));
}
AppMsg::UpdateSysconfig(systemconfig) => {
- self.config = NscConfig {
+ self.config = NixDataConfig {
systemconfig: systemconfig.clone(),
flake: self.config.flake.clone(),
flakearg: self.config.flakearg.clone(),
@@ -591,15 +674,23 @@ impl Component for AppModel {
}
self.pkgpage.emit(PkgMsg::UpdateConfig(self.config.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
- self.pkgpage.emit(PkgMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
- self.installedpage.emit(InstalledPageMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
- sender.input(AppMsg::UpdatePkgs(None));
-
+ self.updatepage
+ .emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
+ self.pkgpage.emit(PkgMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
+ self.updatepage.emit(UpdatePageMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
+ self.installedpage.emit(InstalledPageMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
}
AppMsg::UpdateFlake(flake, flakearg) => {
- self.config = NscConfig {
+ self.config = NixDataConfig {
systemconfig: self.config.systemconfig.clone(),
flake: flake.clone(),
flakearg,
@@ -615,60 +706,50 @@ impl Component for AppModel {
}
self.pkgpage.emit(PkgMsg::UpdateConfig(self.config.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
- self.pkgpage.emit(PkgMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
- self.installedpage.emit(InstalledPageMsg::UpdatePkgTypes(self.syspkgtype.clone(), self.userpkgtype.clone()));
+ self.updatepage
+ .emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
+ self.pkgpage.emit(PkgMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
+ self.updatepage.emit(UpdatePageMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
+ self.installedpage.emit(InstalledPageMsg::UpdatePkgTypes(
+ self.syspkgtype.clone(),
+ self.userpkgtype.clone(),
+ ));
}
- AppMsg::Initialize(pkgs, recommendedapps, syspkgs, categoryrec, categoryall, profilepkgs) => {
- self.syspkgs = syspkgs;
- self.profilepkgs = profilepkgs;
+ AppMsg::Initialize(
+ pkgdb,
+ nixpkgsdb,
+ systemdb,
+ appdata,
+ recommendedapps,
+ categoryrec,
+ categoryall,
+ ) => {
+ info!("AppMsg::Initialize");
+ self.pkgdb = pkgdb;
+ self.nixpkgsdb = nixpkgsdb;
+ self.systemdb = systemdb;
+ self.appdata = appdata;
self.categoryrec = categoryrec;
self.categoryall = categoryall;
- let mut pkgitems = HashMap::new();
- for (pkg, pkgdata) in &pkgs {
- let pname = pkgdata.pname.to_string();
- let mut name = pkgdata.pname.to_string();
- let version = pkgdata.version.to_string();
- let mut icon = None;
- let mut summary = pkgdata.meta.description.as_ref().map(|x| x.to_string());
- if let Some(appdata) = &pkgdata.appdata {
- if let Some(i) = &appdata.icon {
- if let Some(mut iconvec) = i.cached.clone() {
- iconvec.sort_by(|a, b| a.height.cmp(&b.height));
- icon = Some(iconvec[0].name.clone());
- }
- }
- if let Some(s) = &appdata.summary {
- summary = Some(s.get("C").unwrap_or(&summary.unwrap_or_default()).to_string());
- }
- if let Some(n) = &appdata.name {
- name = n.get("C").unwrap_or(&name).to_string();
- }
- }
- pkgitems.insert(pkg.to_string(), PkgItem {
- pkg: pkg.to_string(),
- pname,
- name,
- version,
- icon,
- summary,
- });
- }
- self.pkgitems = pkgitems;
+
self.page = Page::FrontPage;
self.pkgpage.emit(PkgMsg::UpdateConfig(self.config.clone()));
- self.updatepage.emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
- self.pkgs = pkgs;
- sender.input(AppMsg::UpdatePkgs(Some(recommendedapps)));
-
+ self.updatepage
+ .emit(UpdatePageMsg::UpdateConfig(self.config.clone()));
+ sender.input(AppMsg::UpdateRecPkgs(recommendedapps));
let mut cat_guard = self.categories.guard();
for c in vec![
PkgCategory::Audio,
PkgCategory::Development,
PkgCategory::Games,
PkgCategory::Graphics,
- PkgCategory::Network,
+ PkgCategory::Web,
PkgCategory::Video,
] {
cat_guard.push_back(c);
@@ -676,233 +757,356 @@ impl Component for AppModel {
cat_guard.drop();
self.busy = false;
}
- AppMsg::ReloadUpdateItems(pkgs, syspkgs) => {
- self.syspkgs = syspkgs;
- let mut pkgitems = HashMap::new();
- for (pkg, pkgdata) in &pkgs {
- let pname = pkgdata.pname.to_string();
- let mut name = pkgdata.pname.to_string();
- let version = pkgdata.version.to_string();
- let mut icon = None;
- let mut summary = pkgdata.meta.description.as_ref().map(|x| x.to_string());
- if let Some(appdata) = &pkgdata.appdata {
- if let Some(i) = &appdata.icon {
- if let Some(mut iconvec) = i.cached.clone() {
- iconvec.sort_by(|a, b| a.height.cmp(&b.height));
- icon = Some(iconvec[0].name.clone());
+ AppMsg::UpdateRecPkgs(pkgs) => {
+ info!("AppMsg::UpdateRecPkgs");
+ let appdata: HashMap = self
+ .appdata
+ .iter()
+ .filter_map(|(k, v)| {
+ if pkgs.contains(k) {
+ Some((k.to_string(), v.clone()))
+ } else {
+ None
+ }
+ })
+ .collect();
+ let installeduser = self.installeduserpkgs.clone();
+ let installedsystem = self.installedsystempkgs.clone();
+ let poolref = self.pkgdb.clone();
+ sender.oneshot_command(async move {
+ let mut pkgtiles = vec![];
+ if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", poolref)).await {
+ for pkg in pkgs {
+ if let Some(data) = appdata.get(&pkg) {
+ let pname: (String,) =
+ sqlx::query_as("SELECT pname FROM pkgs WHERE attribute = $1")
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ pkgtiles.push(PkgTile {
+ pkg: pkg.to_string(),
+ name: if let Some(name) = &data.name {
+ name.get("C").unwrap_or(&pname.0).to_string()
+ } else {
+ pname.0.to_string()
+ },
+ pname: pname.0,
+ icon: data
+ .icon
+ .as_ref()
+ .and_then(|x| x.cached.as_ref())
+ .map(|x| x[0].name.clone()),
+ summary: data
+ .summary
+ .as_ref()
+ .and_then(|x| x.get("C"))
+ .map(|x| x.to_string())
+ .unwrap_or_default(),
+ installeduser: installeduser.contains_key(&pkg),
+ installedsystem: installedsystem.contains(&pkg),
+ })
}
}
- if let Some(s) = &appdata.summary {
- summary = Some(s.get("C").unwrap_or(&summary.unwrap_or_default()).to_string());
- }
- if let Some(n) = &appdata.name {
- name = n.get("C").unwrap_or(&name).to_string();
- }
}
- pkgitems.insert(pkg.to_string(), PkgItem {
- pkg: pkg.to_string(),
- pname,
- name,
- version,
- icon,
- summary,
- });
- }
- self.pkgitems = pkgitems;
- sender.input(AppMsg::UpdatePkgs(None));
- self.updatepage.emit(UpdatePageMsg::DoneLoading);
+ AppAsyncMsg::UpdateRecPkgs(pkgtiles)
+ });
}
AppMsg::OpenPkg(pkg) => {
- if let Some(input) = self.pkgs.get(&pkg) {
- let mut name = input.pname.to_string();
- let mut summary = input.meta.description.as_ref().map(|x| x.to_string());
- let mut description = input.meta.longdescription.as_ref().map(|x| x.to_string());
- let mut icon = None;
- let mut screenshots = vec![];
- let mut licenses = vec![];
- let mut platforms = vec![];
- let mut maintainers = vec![];
- let mut launchable = None;
+ info!("AppMsg::OpenPkg {}", pkg);
+ if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", self.pkgdb)).await {
+ let pkgdata: Result<
+ (
+ String,
+ String,
+ String,
+ String,
+ String,
+ String,
+ String,
+ String,
+ ),
+ _,
+ > = sqlx::query_as(
+ r#"
+SELECT pname, system, description, longdescription, homepage, license, platforms, maintainers
+FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = $1
+ "#,
+ )
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await;
- fn addlicense(pkglicense: &LicenseEnum, licenses: &mut Vec) {
- match pkglicense {
- LicenseEnum::Single(l) => {
- if let Some(n) = &l.fullname {
- let parsed = if let Some(id) = &l.spdxid {
- if let Ok(Some(license)) = Expression::parse(id).map(|p| p.requirements().map(|er| er.req.license.id()).collect::>()[0]) {
+ if let Ok((
+ pname,
+ system,
+ description,
+ longdescription,
+ homepage,
+ licensejson,
+ platformsjson,
+ maintainersjson,
+ )) = pkgdata
+ {
+ let mut name = pname.to_string();
+ let mut summary = if description.is_empty() {
+ None
+ } else {
+ Some(description)
+ };
+ let mut description = if longdescription.is_empty() {
+ None
+ } else {
+ Some(longdescription)
+ };
+ let mut icon = None;
+ let mut screenshots = vec![];
+ let mut licenses = vec![];
+ let mut platforms = vec![];
+ let mut maintainers = vec![];
+ let mut launchable = None;
+
+ if let Some(data) = self.appdata.get(&pkg) {
+ if let Some(n) = &data.name {
+ if let Some(n) = n.get("C") {
+ name = n.to_string();
+ }
+ }
+ if let Some(s) = &data.summary {
+ if let Some(s) = s.get("C") {
+ summary = Some(s.to_string());
+ }
+ }
+ if let Some(d) = &data.description {
+ if let Some(d) = d.get("C") {
+ description = Some(d.to_string());
+ }
+ }
+ if let Some(i) = &data.icon {
+ if let Some(mut i) = i.cached.clone() {
+ i.sort_by(|x, y| x.height.cmp(&y.height));
+ if let Some(i) = i.last() {
+ icon = Some(format!(
+ "{}/icons/nixos/{}x{}/{}",
+ APPINFO, i.width, i.height, i.name
+ ));
+ }
+ }
+ }
+ if let Some(s) = &data.screenshots {
+ for s in s {
+ if let Some(u) = &s.sourceimage {
+ if !screenshots.contains(&u.url) {
+ if s.default == Some(true) {
+ screenshots.insert(0, u.url.clone());
+ } else {
+ screenshots.push(u.url.clone());
+ }
+ } else if s.default == Some(true) {
+ if let Some(index) =
+ screenshots.iter().position(|x| *x == u.url)
+ {
+ screenshots.remove(index);
+ screenshots.insert(0, u.url.clone());
+ }
+ }
+ }
+ }
+ }
+ if let Some(l) = &data.launchable {
+ if let Some(d) = l.desktopid.get(0) {
+ launchable = Some(d.to_string());
+ }
+ }
+ }
+
+ fn addlicense(
+ pkglicense: &LicenseEnum,
+ licenses: &mut Vec,
+ ) {
+ match pkglicense {
+ LicenseEnum::Single(l) => {
+ if let Some(n) = &l.fullname {
+ let parsed = if let Some(id) = &l.spdxid {
+ if let Ok(Some(license)) =
+ Expression::parse(id).map(|p| {
+ p.requirements()
+ .map(|er| er.req.license.id())
+ .collect::>()[0]
+ })
+ {
+ Some(license)
+ } else {
+ None
+ }
+ } else if let Ok(Some(license)) =
+ Expression::parse(n).map(|p| {
+ p.requirements()
+ .map(|er| er.req.license.id())
+ .collect::>()[0]
+ })
+ {
Some(license)
} else {
None
- }
- } else if let Ok(Some(license)) = Expression::parse(n).map(|p| p.requirements().map(|er| er.req.license.id()).collect::>()[0]) {
- Some(license)
- } else {
- None
- };
- licenses.push(pkgpage::License {
- free: if let Some(f) = l.free { Some(f) } else { parsed.map(|p| p.is_osi_approved() || p.is_fsf_free_libre() )},
- fullname: n.to_string(),
- spdxid: l.spdxid.clone().map(|x| x.to_string()),
- url: if let Some(u) = &l.url { Some(u.to_string()) } else { parsed.map(|p| format!("https://spdx.org/licenses/{}.html", p.name))},
- })
- } else if let Some(s) = &l.spdxid {
- if let Ok(Some(license)) = Expression::parse(s).map(|p| p.requirements().map(|er| er.req.license.id()).collect::>()[0]) {
+ };
licenses.push(pkgpage::License {
- free: Some(license.is_osi_approved() || license.is_fsf_free_libre() || l.free.unwrap_or(false)),
+ free: if let Some(f) = l.free {
+ Some(f)
+ } else {
+ parsed.map(|p| {
+ p.is_osi_approved() || p.is_fsf_free_libre()
+ })
+ },
+ fullname: n.to_string(),
+ spdxid: l.spdxid.clone(),
+ url: if let Some(u) = &l.url {
+ Some(u.to_string())
+ } else {
+ parsed.map(|p| {
+ format!(
+ "https://spdx.org/licenses/{}.html",
+ p.name
+ )
+ })
+ },
+ })
+ } else if let Some(s) = &l.spdxid {
+ if let Ok(Some(license)) = Expression::parse(s).map(|p| {
+ p.requirements()
+ .map(|er| er.req.license.id())
+ .collect::>()[0]
+ }) {
+ licenses.push(pkgpage::License {
+ free: Some(
+ license.is_osi_approved()
+ || license.is_fsf_free_libre()
+ || l.free.unwrap_or(false),
+ ),
+ fullname: license.full_name.to_string(),
+ spdxid: Some(license.name.to_string()),
+ url: if l.url.is_some() {
+ l.url.clone()
+ } else {
+ Some(format!(
+ "https://spdx.org/licenses/{}.html",
+ license.name
+ ))
+ },
+ })
+ }
+ }
+ }
+ LicenseEnum::List(lst) => {
+ for l in lst {
+ addlicense(&LicenseEnum::Single(l.clone()), licenses);
+ }
+ }
+ LicenseEnum::SingleStr(s) => {
+ if let Ok(Some(license)) = Expression::parse(s).map(|p| {
+ p.requirements()
+ .map(|er| er.req.license.id())
+ .collect::>()[0]
+ }) {
+ licenses.push(pkgpage::License {
+ free: Some(
+ license.is_osi_approved()
+ || license.is_fsf_free_libre(),
+ ),
fullname: license.full_name.to_string(),
spdxid: Some(license.name.to_string()),
- url: if l.url.is_some() {
- l.url.clone().map(|x| x.to_string())
- } else {
- Some(format!("https://spdx.org/licenses/{}.html", license.name))
- },
+ url: Some(format!(
+ "https://spdx.org/licenses/{}.html",
+ license.name
+ )),
})
}
}
- },
- LicenseEnum::List(lst) => {
- for l in lst {
- addlicense(&LicenseEnum::Single(l.clone()), licenses);
+ LicenseEnum::VecStr(lst) => {
+ for s in lst {
+ addlicense(&LicenseEnum::SingleStr(s.clone()), licenses);
+ }
}
- },
- LicenseEnum::SingleStr(s) => {
- if let Ok(Some(license)) = Expression::parse(s).map(|p| p.requirements().map(|er| er.req.license.id()).collect::>()[0]) {
- licenses.push(pkgpage::License {
- free: Some(license.is_osi_approved() || license.is_fsf_free_libre()),
- fullname: license.full_name.to_string(),
- spdxid: Some(license.name.to_string()),
- url: Some(format!("https://spdx.org/licenses/{}.html", license.name)),
- })
- }
- },
- LicenseEnum::VecStr(lst) => {
- for s in lst {
- addlicense(&LicenseEnum::SingleStr(s.clone()), licenses);
- }
- },
- LicenseEnum::Mixed(v) => {
- for l in v {
- addlicense(l, licenses);
- }
- }
- }
- }
-
- if let Some(pkglicense) = &input.meta.license {
- addlicense(pkglicense, &mut licenses);
- }
-
- if let Some(data) = &input.appdata {
- if let Some(n) = &data.name {
- if let Some(n) = n.get("C") {
- name = n.to_string();
- }
- }
- if let Some(s) = &data.summary {
- if let Some(s) = s.get("C") {
- summary = Some(s.to_string());
- }
- }
- if let Some(d) = &data.description {
- if let Some(d) = d.get("C") {
- description = Some(d.to_string());
- }
- }
- if let Some(i) = &data.icon {
- if let Some(mut i) = i.cached.clone() {
- i.sort_by(|x, y| x.height.cmp(&y.height));
- if let Some(i) = i.last() {
- icon = Some(format!(
- "{}/icons/nixos/{}x{}/{}",
- APPINFO, i.width, i.height, i.name
- ));
- }
- }
- }
- if let Some(s) = &data.screenshots {
- for s in s {
- if let Some(u) = &s.sourceimage {
- if !screenshots.contains(&u.url) {
- if s.default == Some(true) {
- screenshots.insert(0, u.url.clone());
- } else {
- screenshots.push(u.url.clone());
- }
- } else if s.default == Some(true) {
- if let Some(index) = screenshots.iter().position(|x| *x == u.url) {
- screenshots.remove(index);
- screenshots.insert(0, u.url.clone());
- }
+ LicenseEnum::Mixed(v) => {
+ for l in v {
+ addlicense(l, licenses);
}
}
}
}
- if let Some(l) = &data.launchable {
- if let Some(d) = l.desktopid.get(0) {
- launchable = Some(d.to_string());
- }
- }
- }
- if let Some(p) = &input.meta.platforms {
- match p {
- Platform::Single(p) => {
- if !platforms.contains(&p.to_string()) && p != &input.system {
- platforms.push(p.to_string());
- }
- },
- Platform::List(v) => {
- for p in v {
- if !platforms.contains(&p.to_string()) && p != &input.system {
- platforms.push(p.to_string());
+ if let Ok(pkglicense) = serde_json::from_str::(&licensejson) {
+ addlicense(&pkglicense, &mut licenses);
+ }
+
+ let platformslst = serde_json::from_str::(&platformsjson);
+ if let Ok(p) = platformslst {
+ match p {
+ Platform::Single(p) => {
+ if !platforms.contains(&p) && p != system {
+ platforms.push(p);
}
}
- },
- Platform::ListList(vv) => {
- for v in vv {
+ Platform::List(v) => {
for p in v {
- if !platforms.contains(&p.to_string()) && p != &input.system {
+ if !platforms.contains(&p.to_string()) && p != system {
platforms.push(p.to_string());
}
}
}
+ Platform::ListList(vv) => {
+ for v in vv {
+ for p in v {
+ if !platforms.contains(&p.to_string()) && p != system {
+ platforms.push(p.to_string());
+ }
+ }
+ }
+ }
}
}
- }
- platforms.sort();
- platforms.insert(0, input.system.to_string());
+ platforms.sort();
+ platforms.insert(0, system);
- if let Some(m) = input.meta.maintainers.clone() {
- if let Ok(m) = ijson::from_value::>(&m) {
+ if let Ok(m) = serde_json::from_str::>(&maintainersjson)
+ {
for m in m {
maintainers.push(m);
}
}
- }
- let out = PkgInitModel {
- name,
- pname: input.pname.to_string(),
- summary,
- description,
- icon,
- pkg,
- screenshots,
- homepage: input.meta.homepage.clone(),
- platforms,
- licenses,
- maintainers,
- installeduserpkgs: self.installeduserpkgs.keys().cloned().collect(),
- installedsystempkgs: self.installedsystempkgs.clone(),
- launchable
- };
- self.page = Page::PkgPage;
- if self.viewstack.visible_child_name() != Some(gtk::glib::GString::from("search")) {
- self.searching = false;
+ let out = PkgInitModel {
+ name,
+ pname,
+ summary,
+ description,
+ icon,
+ pkg,
+ screenshots,
+ homepage: if homepage.is_empty() {
+ None
+ } else {
+ Some(homepage)
+ },
+ platforms,
+ licenses,
+ maintainers,
+ installeduserpkgs: self.installeduserpkgs.keys().cloned().collect(),
+ installedsystempkgs: self.installedsystempkgs.clone(),
+ launchable,
+ };
+ self.page = Page::PkgPage;
+ if self.viewstack.visible_child_name()
+ != Some(gtk::glib::GString::from("search"))
+ {
+ self.searching = false;
+ }
+ self.busy = false;
+ self.pkgpage.emit(PkgMsg::Open(Box::new(out)));
}
- self.busy = false;
- self.pkgpage.emit(PkgMsg::Open(Box::new(out)));
- }
+ } else {
+ eprintln!("No pkgdb!!!!!!!!!!!!!!!!!!");
+ }
}
AppMsg::FrontPage => {
self.page = Page::FrontPage;
@@ -911,369 +1115,403 @@ impl Component for AppModel {
self.page = Page::FrontPage;
self.mainpage = MainPage::FrontPage;
}
- AppMsg::UpdatePkgs(rec) => {
- info!("AppMsg::UpdatePkgs");
- fn getsystempkgs(config: &str) -> Result, Box> {
- let f = fs::read_to_string(config)?;
- match nix_editor::read::getarrvals(&f, "environment.systemPackages") {
- Ok(x) => Ok(HashSet::from_iter(x.into_iter())),
- Err(_) => Err(Box::new(io::Error::new(
- io::ErrorKind::InvalidData,
- "Failed to read value from configuration",
- )))
- }
- }
-
- fn getuserenvpkgs() -> Result, Box> {
- let out = Command::new("nix-env").arg("-q").arg("--json").output()?;
- let data: IValue = serde_json::from_str(&String::from_utf8_lossy(&out.stdout))?;
- let mut pcurrpkgs = HashMap::new();
- for (_, pkg) in data.as_object().unwrap() {
- pcurrpkgs.insert(
- pkg.as_object().unwrap()["pname"]
- .as_string()
- .unwrap()
- .to_string(),
- pkg.as_object().unwrap()["version"]
- .as_string()
- .unwrap()
- .to_string()
- );
- }
- Ok(pcurrpkgs)
- }
-
- fn getuserprofilepkgs() -> Result, Box> {
- let data: IValue = serde_json::from_str(&fs::read_to_string(Path::new(&format!("{}/.nix-profile/manifest.json", std::env::var("HOME")?)))?)?;
- let mut pcurrpkgs = HashMap::new();
- for pkg in data.as_object().unwrap()["elements"].as_array().unwrap().iter() {
- if let Some(p) = pkg.get("attrPath") {
- if let Some(pkgname) = p.as_string()
- .unwrap()
- // Change to current platform
- .strip_prefix("legacyPackages.x86_64-linux.") {
- if let Some(sp) = pkg.get("storePaths") {
- if let Some(sp) = sp.as_array().unwrap().get(0) {
- let storepath = sp.as_string().unwrap().to_string();
- let output = Command::new("nix")
- .arg("show-derivation")
- .arg(&storepath)
- .output()?;
- if let Ok(data) = serde_json::from_str::(&String::from_utf8_lossy(&output.stdout)) {
- if let Some(version) = data.as_object().unwrap().values().next().unwrap()["env"].get("version") {
- let version = version.as_str().unwrap().to_string();
- pcurrpkgs.insert(
- pkgname.to_string(),
- version,
- );
- } else {
- pcurrpkgs.insert(
- pkgname.to_string(),
- String::default(),
- );
- }
- }
- }
+ AppMsg::UpdateInstalledPkgs => {
+ info!("AppMsg::UpdateInstalledPkgs");
+ let systemconfig = self.config.systemconfig.clone();
+ let syspkgtype = self.syspkgtype.clone();
+ let userpkgtype = self.userpkgtype.clone();
+ sender.oneshot_command(async move {
+ let installedsystempkgs = if let Some(config) = &systemconfig {
+ match syspkgtype {
+ SystemPkgs::Flake => {
+ let pkgs = nix_data::cache::flakes::getflakepkgs(&[config]).await;
+ if let Ok(pkgs) = pkgs {
+ pkgs.keys().cloned().collect::>()
+ } else {
+ HashSet::new()
}
}
+ SystemPkgs::Legacy => {
+ let pkgs = nix_data::cache::channel::getlegacypkgs(&[config]).await;
+ if let Ok(pkgs) = pkgs {
+ pkgs.keys().cloned().collect::>()
+ } else {
+ HashSet::new()
+ }
+ }
+ _ => HashSet::new(),
}
- }
- Ok(pcurrpkgs)
- }
+ } else {
+ HashSet::new()
+ };
- let systempkgs = if let Some(sysconfig) = &self.config.systemconfig {
- match getsystempkgs(sysconfig) {
- Ok(x) => x,
- Err(_) => {
- self.installedsystempkgs.clone()
- }
- }
- } else {
- HashSet::new()
- };
-
- let userpkgs = match self.userpkgtype {
- UserPkgs::Env => {
- match getuserenvpkgs() {
- Ok(out) => out,
- Err(_) => {
- self.installeduserpkgs.clone()
+ let installeduserpkgs = match userpkgtype {
+ UserPkgs::Profile => {
+ let pkgs = nix_data::cache::profile::getprofilepkgs_versioned().await;
+ if let Ok(pkgs) = pkgs {
+ pkgs
+ } else {
+ HashMap::new()
}
}
- },
- UserPkgs::Profile => {
- match getuserprofilepkgs() {
- Ok(out) => out,
- Err(_) => {
- self.installeduserpkgs.clone()
+ UserPkgs::Env => {
+ let pkgs = nix_data::cache::channel::getenvpkgs();
+ if let Ok(pkgs) = pkgs {
+ pkgs
+ } else {
+ HashMap::new()
}
}
- }
- };
-
- self.installedsystempkgs = systempkgs;
- self.installeduserpkgs = userpkgs;
-
- if let Some(recommendedapps) = rec {
- let mut recapps_guard = self.recommendedapps.guard();
- for app in recommendedapps {
- if let Some(x) = self.pkgs.get(&app) {
- if let Some(data) = &x.appdata {
- if let Some(icon) = &data.icon {
- if let Some(summary) = &data.summary {
- if let Some(name) = &data.name {
- let name = name.get("C").unwrap().to_string();
- let mut iconvec = icon.cached.as_ref().unwrap().to_vec();
- iconvec.sort_by(|a, b| a.height.cmp(&b.height));
- let summary =
- summary.get("C").unwrap_or(&String::new()).to_string();
- recapps_guard.push_back(PkgTile {
- pkg: app,
+ };
+ AppAsyncMsg::UpdateInstalledPkgs(installedsystempkgs, installeduserpkgs)
+ });
+ }
+ AppMsg::UpdateInstalledPage => {
+ info!("AppMsg::UpdateInstalledPage");
+ let mut installeduseritems = vec![];
+ let mut updateuseritems = vec![];
+ // let pool = SqlitePool::connect(&self.pkgdb).await.unwrap();
+ println!("Installed user pkgs: {:?}", self.installeduserpkgs);
+ println!("Installed system pkgs: {:?}", self.installedsystempkgs);
+ if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", self.pkgdb)).await {
+ match self.userpkgtype {
+ UserPkgs::Env => {
+ for (installedpname, installedver) in &self.installeduserpkgs {
+ let possibleitems: Vec<(String,)> =
+ sqlx::query_as("SELECT attribute FROM pkgs WHERE pname = $1")
+ .bind(installedpname)
+ .fetch_all(pool)
+ .await
+ .unwrap();
+ match possibleitems.len() {
+ 1 => {
+ let (pkg,) = &possibleitems[0];
+ let (description,): (String,) = sqlx::query_as(
+ "SELECT description FROM meta WHERE attribute = $1",
+ )
+ .bind(pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let (newver,): (String,) = sqlx::query_as(
+ "SELECT version FROM pkgs WHERE attribute = $1",
+ )
+ .bind(pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let mut name = installedpname.to_string();
+ let mut summary = if description.is_empty() {
+ None
+ } else {
+ Some(description.to_string())
+ };
+ let mut icon = None;
+ if let Some(data) = self.appdata.get(pkg) {
+ if let Some(n) = &data.name {
+ if let Some(n) = n.get("C") {
+ name = n.to_string();
+ }
+ }
+ if let Some(s) = &data.summary {
+ if let Some(s) = s.get("C") {
+ summary = Some(s.to_string());
+ }
+ }
+ if let Some(i) = &data.icon {
+ if let Some(i) = &i.cached {
+ icon = Some(i[0].name.clone());
+ }
+ }
+ }
+ installeduseritems.push(InstalledItem {
+ name: name.clone(),
+ pname: installedpname.to_string(),
+ pkg: Some(pkg.clone()),
+ summary: summary.clone(),
+ icon: icon.clone(),
+ pkgtype: InstallType::User,
+ busy: self.installedpagebusy.contains(&(
+ installedpname.to_string(),
+ InstallType::User,
+ )),
+ });
+ if !installedver.eq(&newver) {
+ updateuseritems.push(UpdateItem {
name,
- pname: x.pname.to_string(),
- icon: Some(iconvec[0].name.clone()),
+ pname: installedpname.to_string(),
+ pkg: Some(pkg.clone()),
summary,
- installeduser: self.installeduserpkgs.contains_key(&x.pname.to_string()),
- installedsystem: self.installedsystempkgs.contains(&x.pname.to_string()),
+ icon,
+ pkgtype: InstallType::User,
+ verfrom: Some(installedver.to_string()),
+ verto: Some(newver),
});
}
}
- }
- }
- }
- }
- recapps_guard.drop();
- } else {
- let mut pkgtile_guard = self.recommendedapps.guard();
- for i in 0..pkgtile_guard.len() {
- if let Some(pkgtile) = &mut pkgtile_guard.get_mut(i) {
- pkgtile.installedsystem = self.installedsystempkgs.contains(&pkgtile.pkg);
- pkgtile.installeduser = self.installeduserpkgs.contains_key(&pkgtile.pname);
- }
- }
- pkgtile_guard.drop();
- }
-
- sender.input(AppMsg::UpdateInstalledPkgs);
- sender.input(AppMsg::UpdateUpdatePkgs);
- sender.input(AppMsg::UpdateCategoryPkgs);
-
- if self.searching {
- self.update_searching(|_| ());
- self.searchpage.emit(SearchPageMsg::UpdateInstalled(self.installeduserpkgs.keys().cloned().collect(), self.installedsystempkgs.clone()));
- }
- }
- AppMsg::UpdateInstalledPkgs => {
- let mut installeduseritems = vec![];
- match self.userpkgtype {
- UserPkgs::Env => {
- for installedpname in self.installeduserpkgs.keys() {
- let possibleitems = self.pkgitems.iter().filter(|(_, x)| &x.pname == installedpname);
- let count = possibleitems.clone().count();
- match count {
- 1 => {
- let (pkg, data) = possibleitems.collect::>()[0];
- installeduseritems.push(InstalledItem {
- name: data.name.clone(),
- pname: data.pname.clone(),
- pkg: Some(pkg.clone()),
- summary: data.summary.clone(),
- icon: data.icon.clone(),
- pkgtype: InstallType::User,
- busy: self.installedpagebusy.contains(&(data.pname.clone(), InstallType::User)),
- })
- }
- 2.. => {
- installeduseritems.push(InstalledItem {
- name: installedpname.clone(),
- pname: installedpname.clone(),
- pkg: None,
- summary: None, //data.summary.clone(),
- icon: None, //data.icon.clone(),
- pkgtype: InstallType::User,
- busy: self.installedpagebusy.contains(&(installedpname.clone(), InstallType::User)),
- })
- }
- _ => {}
- }
- }
- }
- UserPkgs::Profile => {
- for installedpkg in self.installeduserpkgs.keys() {
- if let Some(item) = self.pkgitems.get(installedpkg) {
- installeduseritems.push(InstalledItem {
- name: item.name.clone(),
- pname: item.pname.clone(),
- pkg: Some(item.pkg.clone()),
- summary: item.summary.clone(),
- icon: item.icon.clone(),
- pkgtype: InstallType::User,
- busy: self.installedpagebusy.contains(&(item.pkg.clone(), InstallType::User)),
- })
- }
- }
- }
- }
-
- installeduseritems.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
- let mut installedsystemitems = vec![];
- for installedpkg in &self.installedsystempkgs {
- if let Some(item) = self.pkgitems.get(installedpkg) {
- installedsystemitems.push(InstalledItem {
- name: item.name.clone(),
- pname: item.pname.clone(),
- pkg: Some(item.pkg.clone()),
- summary: item.summary.clone(),
- icon: item.icon.clone(),
- pkgtype: InstallType::System,
- busy: self.installedpagebusy.contains(&(item.pkg.clone(), InstallType::System)),
- })
- }
- }
- installedsystemitems.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
- self.installedpage.emit(InstalledPageMsg::Update(installeduseritems, installedsystemitems));
- }
- AppMsg::UpdateUpdatePkgs => {
- info!("AppMsg::UpdateUpdatePkgs");
- debug!("InstalledUserPkgs: {:?}", self.installeduserpkgs);
- debug!("InstalledSystemPkgs: {:?}", self.installedsystempkgs);
- let mut updateuseritems = vec![];
- match self.userpkgtype {
- UserPkgs::Env => {
- for (installedpname, version) in self.installeduserpkgs.iter() {
- let possibleitems = self.pkgitems.iter().filter(|(_, x)| &x.pname == installedpname);
- let count = possibleitems.clone().count();
- match count {
- 1 => {
- let (pkg, data) = possibleitems.collect::>()[0];
- if &data.version != version {
- updateuseritems.push(UpdateItem {
- name: data.name.clone(),
- pname: data.pname.clone(),
- pkg: Some(pkg.clone()),
- summary: data.summary.clone(),
- icon: data.icon.clone(),
- pkgtype: InstallType::User,
- verfrom: Some(version.clone()),
- verto: Some(data.version.clone()),
- })
- } else {
- trace!("Pkg {} is up to date", pkg);
- }
- }
- 2.. => {
- let mut update = true;
- for (pkg, _) in possibleitems {
- if let Some(ver) = self.syspkgs.get(pkg) {
- if version == ver {
- update = false;
- }
-
- }
- }
- if update {
- updateuseritems.push(UpdateItem {
+ 2.. => {
+ installeduseritems.push(InstalledItem {
name: installedpname.clone(),
pname: installedpname.clone(),
pkg: None,
- summary: None, //data.summary.clone(),
- icon: None, //data.icon.clone(),
+ summary: None,
+ icon: None,
pkgtype: InstallType::User,
- verfrom: Some(version.clone()),
- verto: None,
- })
- } else {
- trace!("Pkg {} is up to date", installedpname);
+ busy: self.installedpagebusy.contains(&(
+ installedpname.clone(),
+ InstallType::User,
+ )),
+ });
+ let possibleversions: Vec<(String,)> = sqlx::query_as(
+ "SELECT version FROM pkgs WHERE pname = $1",
+ )
+ .bind(installedpname)
+ .fetch_all(pool)
+ .await
+ .unwrap();
+ if !possibleversions.contains(&(installedver.to_string(),))
+ {
+ updateuseritems.push(UpdateItem {
+ name: installedpname.clone(),
+ pname: installedpname.clone(),
+ pkg: None,
+ summary: None,
+ icon: None,
+ pkgtype: InstallType::User,
+ verfrom: Some(installedver.to_string()),
+ verto: None,
+ });
+ }
}
+ _ => {}
}
- _ => {}
}
}
- }
- UserPkgs::Profile => {
- for (installedpkg, version) in &self.installeduserpkgs {
- if let Some(item) = self.pkgitems.get(installedpkg) {
- if let Some(profilepkgs) = &self.profilepkgs {
- if let Some(newver) = profilepkgs.get(installedpkg) {
+ UserPkgs::Profile => {
+ for installedpkg in self.installeduserpkgs.keys() {
+ println!("Checking package {}", installedpkg);
+ let (pname, version): (String, String) = sqlx::query_as(
+ "SELECT pname, version FROM pkgs WHERE attribute = $1",
+ )
+ .bind(installedpkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let (description,): (String,) = sqlx::query_as(
+ "SELECT description FROM meta WHERE attribute = $1",
+ )
+ .bind(installedpkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let mut name = pname.to_string();
+ let mut summary = if description.is_empty() {
+ None
+ } else {
+ Some(description)
+ };
+ let mut icon = None;
+ if let Some(data) = self.appdata.get(installedpkg) {
+ if let Some(n) = &data.name {
+ if let Some(n) = n.get("C") {
+ name = n.to_string();
+ }
+ }
+ if let Some(s) = &data.summary {
+ if let Some(s) = s.get("C") {
+ summary = Some(s.to_string());
+ }
+ }
+ if let Some(i) = &data.icon {
+ if let Some(i) = &i.cached {
+ icon = Some(i[0].name.clone());
+ }
+ }
+ }
+ installeduseritems.push(InstalledItem {
+ name: name.to_string(),
+ pname: pname.to_string(),
+ pkg: Some(installedpkg.clone()),
+ summary: summary.clone(),
+ icon: icon.clone(),
+ pkgtype: InstallType::User,
+ busy: self
+ .installedpagebusy
+ .contains(&(installedpkg.clone(), InstallType::User)),
+ });
+ if let Some(latest) = &self.nixpkgsdb {
+ if let Ok(latestpool) =
+ &SqlitePool::connect(&format!("sqlite://{}", latest)).await
+ {
+ let (newver,): (String,) = sqlx::query_as(
+ "SELECT version FROM pkgs WHERE attribute = $1",
+ )
+ .bind(installedpkg)
+ .fetch_one(latestpool)
+ .await
+ .unwrap();
+ println!(
+ "PROFILE: {} {} {}",
+ installedpkg, version, newver
+ );
if version != newver {
updateuseritems.push(UpdateItem {
- name: item.name.clone(),
- pname: item.pname.clone(),
- pkg: Some(item.pkg.clone()),
- summary: item.summary.clone(),
- icon: item.icon.clone(),
- pkgtype: InstallType::User,
+ name,
+ pname,
+ pkg: Some(installedpkg.clone()),
+ summary,
+ icon,
+ pkgtype: InstallType::System,
verfrom: Some(version.clone()),
verto: Some(newver.clone()),
})
- } else {
- trace!("Pkg {} is up to date. Ver: {}", item.pname, version);
}
}
}
}
}
}
- }
- updateuseritems.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
- let mut updatesystemitems = vec![];
- for installedpkg in &self.installedsystempkgs {
- if let Some(item) = self.pkgitems.get(installedpkg) {
- if let Some(sysver) = self.syspkgs.get(installedpkg) {
- if &item.version != sysver {
- updatesystemitems.push(UpdateItem {
- name: item.name.clone(),
- pname: item.pname.clone(),
- pkg: Some(item.pkg.clone()),
- summary: item.summary.clone(),
- icon: item.icon.clone(),
- pkgtype: InstallType::System,
- verfrom: Some(sysver.clone()),
- verto: Some(item.version.clone()),
- })
- } else {
- trace!("Pkg {} is up to date", item.pkg);
+ installeduseritems
+ .sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
+ let mut installedsystemitems = vec![];
+ let mut updatesystemitems = vec![];
+ for installedpkg in &self.installedsystempkgs {
+ let (pname, version): (String, String) =
+ sqlx::query_as("SELECT pname, version FROM pkgs where attribute = $1")
+ .bind(installedpkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let (description,): (String,) =
+ sqlx::query_as("SELECT description FROM meta WHERE attribute = $1")
+ .bind(installedpkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ let mut name = pname.to_string();
+ let mut summary = if description.is_empty() {
+ None
+ } else {
+ Some(description)
+ };
+ let mut icon = None;
+ if let Some(data) = self.appdata.get(installedpkg) {
+ if let Some(n) = &data.name {
+ if let Some(n) = n.get("C") {
+ name = n.to_string();
+ }
+ }
+ if let Some(s) = &data.summary {
+ if let Some(s) = s.get("C") {
+ summary = Some(s.to_string());
+ }
+ }
+ if let Some(i) = &data.icon {
+ if let Some(i) = &i.cached {
+ icon = Some(i[0].name.clone());
+ }
+ }
+ }
+ // if let Some(item) = self.pkgitems.get(installedpkg) {
+ installedsystemitems.push(InstalledItem {
+ name: name.to_string(),
+ pname: pname.to_string(),
+ pkg: Some(installedpkg.clone()),
+ summary: summary.clone(),
+ icon: icon.clone(),
+ pkgtype: InstallType::System,
+ busy: self
+ .installedpagebusy
+ .contains(&(installedpkg.clone(), InstallType::System)),
+ });
+ if let Some(current) = &self.systemdb {
+ if let Ok(currentpool) =
+ &SqlitePool::connect(&format!("sqlite://{}", current)).await
+ {
+ let (currver,): (String,) =
+ sqlx::query_as("SELECT version FROM pkgs WHERE attribute = $1")
+ .bind(installedpkg)
+ .fetch_one(currentpool)
+ .await
+ .unwrap();
+ println!("SYSTEM: {} {} {}", installedpkg, currver, version);
+ if version != currver {
+ updatesystemitems.push(UpdateItem {
+ name,
+ pname,
+ pkg: Some(installedpkg.clone()),
+ summary,
+ icon,
+ pkgtype: InstallType::System,
+ verfrom: Some(currver.clone()),
+ verto: Some(version.clone()),
+ })
+ }
}
}
}
- }
- updatesystemitems.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
- match self.syspkgtype {
- SystemPkgs::Legacy => {
- if let Ok(Some((old, new))) = uptodatelegacy() {
- updatesystemitems.insert(0, UpdateItem {
- name: String::from("NixOS System"),
- pname: String::new(),
- pkg: None,
- summary: Some(String::from("NixOS internal packages and modules")),
- icon: None,
- pkgtype: InstallType::System,
- verfrom: Some(old),
- verto: Some(new),
- })
+
+ // Add NixOS system to update list
+ match self.syspkgtype {
+ SystemPkgs::Legacy => {
+ if let Ok(Some((old, new))) = nix_data::cache::channel::uptodate() {
+ updatesystemitems.insert(
+ 0,
+ UpdateItem {
+ name: String::from("NixOS System"),
+ pname: String::new(),
+ pkg: None,
+ summary: Some(String::from(
+ "NixOS internal packages and modules",
+ )),
+ icon: None,
+ pkgtype: InstallType::System,
+ verfrom: Some(old),
+ verto: Some(new),
+ },
+ )
+ }
}
- }
- SystemPkgs::Flake => {
- if let Ok(Some((old, new))) = uptodateflake() {
- updatesystemitems.insert(0, UpdateItem {
- name: String::from("NixOS System"),
- pname: String::new(),
- pkg: None,
- summary: Some(String::from("NixOS internal packages and modules")),
- icon: None,
- pkgtype: InstallType::System,
- verfrom: Some(old),
- verto: Some(new),
- })
+ SystemPkgs::Flake => {
+ if let Ok(Some((old, new))) = nix_data::cache::flakes::uptodate() {
+ updatesystemitems.insert(
+ 0,
+ UpdateItem {
+ name: String::from("NixOS System"),
+ pname: String::new(),
+ pkg: None,
+ summary: Some(String::from(
+ "NixOS internal packages and modules",
+ )),
+ icon: None,
+ pkgtype: InstallType::System,
+ verfrom: Some(old),
+ verto: Some(new),
+ },
+ )
+ }
}
+ SystemPkgs::None => {}
}
- SystemPkgs::None => {}
+
+ installedsystemitems
+ .sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
+ self.installedpage.emit(InstalledPageMsg::Update(
+ installeduseritems,
+ installedsystemitems,
+ ));
+ self.updatepage
+ .emit(UpdatePageMsg::Update(updateuseritems, updatesystemitems));
+ } else {
+ error!("Could not connect to pkgdb");
}
- self.updatepage.emit(UpdatePageMsg::Update(updateuseritems, updatesystemitems));
}
AppMsg::UpdateCategoryPkgs => {
- self.categorypage.emit(CategoryPageMsg::UpdateInstalled(self.installeduserpkgs.keys().cloned().collect::>(), self.installedsystempkgs.iter().cloned().collect::>()));
+ self.categorypage.emit(CategoryPageMsg::UpdateInstalled(
+ self.installeduserpkgs.keys().cloned().collect::>(),
+ self.installedsystempkgs.iter().cloned().collect::>(),
+ ));
}
AppMsg::SetSearch(show) => {
self.set_searching(show);
@@ -1300,67 +1538,117 @@ impl Component for AppModel {
info!("AppMsg::Search");
debug!("Searching for: {}", search);
self.viewstack.set_visible_child_name("search");
- self.searchpage.emit(SearchPageMsg::Open);
self.set_searchquery(search.to_string());
- let pkgitems: Vec = self.pkgitems.values().cloned().collect();
let installeduserpkgs = self.installeduserpkgs.clone();
let installedsystempkgs = self.installedsystempkgs.clone();
let userpkgtype = self.userpkgtype.clone();
+ let pkgdb = self.pkgdb.clone();
+ let appdata = self.appdata.clone();
sender.command(move |out, shutdown| {
- let pkgs = pkgitems.clone();
let search = search.clone();
let installeduserpkgs = installeduserpkgs.clone();
let installedsystempkgs = installedsystempkgs;
let userpkgtype = userpkgtype.clone();
shutdown.register(async move {
let searchsplit: Vec = search.split(' ').filter(|x| x.len() > 1).map(|x| x.to_string()).collect();
- let mut namepkgs = pkgs.iter().filter(|x| searchsplit.iter().any(|s| x.name.to_lowercase().contains(&s.to_lowercase()))).collect::>();
- let mut pnamepkgs = pkgs.iter().filter(|x| searchsplit.iter().any(|s| x.pname.to_lowercase().contains(&s.to_lowercase())) && !namepkgs.contains(x)).collect::>();
- let mut pkgpkgs = pkgs.iter().filter(|x| searchsplit.iter().any(|s| x.pkg.to_lowercase().contains(&s.to_lowercase())) && !namepkgs.contains(x) && !pnamepkgs.contains(x)).collect::>();
- let mut sumpkgs = pkgs.iter().filter(|x| if let Some(sum) = &x.summary { searchsplit.iter().any(|s| sum.to_lowercase().contains(&s.to_lowercase())) } else { false } && !namepkgs.contains(x) && !pnamepkgs.contains(x) && !pkgpkgs.contains(x)).collect::>();
- namepkgs.sort_by(|a, b| edit_distance::edit_distance(&a.name.to_lowercase(), &search.to_lowercase()).cmp(&edit_distance::edit_distance(&b.name.to_lowercase(), &search.to_lowercase())));
- pnamepkgs.sort_by(|a, b| edit_distance::edit_distance(&a.pname.to_lowercase(), &search.to_lowercase()).cmp(&edit_distance::edit_distance(&b.pname.to_lowercase(), &search.to_lowercase())));
- pkgpkgs.sort_by(|a, b| edit_distance::edit_distance(&a.pkg.to_lowercase(), &search.to_lowercase()).cmp(&edit_distance::edit_distance(&b.pkg.to_lowercase(), &search.to_lowercase())));
- sumpkgs.sort_by(|a, b| {
- let mut x = 0;
- for s in &searchsplit {
- x += a.summary.as_ref().unwrap_or(&String::new()).to_lowercase().matches(&s.to_lowercase()).count()
+ warn!("Searchsplit: {:?}", searchsplit);
+ if let Ok(pkgpool) = &SqlitePool::connect(&format!("sqlite://{}", pkgdb)).await {
+ let mut queryb: QueryBuilder = QueryBuilder::new(
+ "SELECT pkgs.attribute, pkgs.pname, description, version FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE (",
+ );
+ for (i, q) in searchsplit.iter().enumerate() {
+ if i == searchsplit.len() - 1 {
+ queryb
+ .push(r#"pkgs.attribute LIKE "#)
+ .push_bind(format!("%{}%", q))
+ .push(r#" OR description LIKE "#)
+ .push_bind(format!("%{}%", q))
+ .push(")");
+ } else {
+ queryb
+ .push(r#"pkgs.attribute LIKE "#)
+ .push_bind(format!("%{}%", q))
+ .push(r#" OR description LIKE "#)
+ .push_bind(format!("%{}%", q))
+ .push(r#") AND ("#);
+ }
}
- let mut y = 0;
- for s in &searchsplit {
- y += b.summary.as_ref().unwrap_or(&String::new()).to_lowercase().matches(&s.to_lowercase()).count()
+ queryb.push("ORDER BY LENGTH(pkgs.attribute) ASC");
+ let q: Vec<(String, String, String, String)> =
+ queryb.build_query_as().fetch_all(pkgpool).await.unwrap();
+ let mut outpkgs = Vec::new();
+ for (i, (attr, pname, desc, _version)) in q.into_iter().enumerate() {
+ if let Some(data) = appdata.get(&attr) {
+ outpkgs.push(SearchItem {
+ pkg: attr.to_string(),
+ pname: pname.to_string(),
+ name: if let Some(name) = &data.name { name.get("C").unwrap_or(&attr).to_string() } else { attr.to_string() },
+ summary: if desc.is_empty() { None } else { Some(desc) },
+ icon: data
+ .icon
+ .as_ref()
+ .and_then(|x| x.cached.as_ref())
+ .map(|x| x[0].name.clone()),
+ installeduser: match userpkgtype {
+ UserPkgs::Env => installeduserpkgs.contains_key(&pname),
+ UserPkgs::Profile => installeduserpkgs.contains_key(&attr)
+ },
+ installedsystem: installedsystempkgs.contains(&attr),
+ })
+ } else {
+ outpkgs.push(SearchItem {
+ pkg: attr.to_string(),
+ pname: pname.to_string(),
+ name: pname.to_string(),
+ summary: if desc.is_empty() { None } else { Some(desc) },
+ icon: None,
+ installeduser: match userpkgtype {
+ UserPkgs::Env => installeduserpkgs.contains_key(&pname),
+ UserPkgs::Profile => installeduserpkgs.contains_key(&attr)
+ },
+ installedsystem: installedsystempkgs.contains(&attr),
+ });
+ }
+ if i >= 200 {
+ break;
+ }
}
- x.cmp(&y)
- });
-
-
- let mut combpkgs = namepkgs;
- combpkgs.append(&mut pnamepkgs);
- combpkgs.append(&mut pkgpkgs);
- combpkgs.append(&mut sumpkgs);
-
- combpkgs.sort_by(|a, b| {
- b.icon.is_some().cmp(&a.icon.is_some())
- });
- let mut outpkgs: Vec = vec![];
- for (i, p) in combpkgs.iter().enumerate() {
- outpkgs.push(SearchItem {
- pkg: p.pkg.to_string(),
- pname: p.pname.to_string(),
- name: p.name.to_string(),
- summary: p.summary.clone(),
- icon: p.icon.clone(),
- installeduser: match userpkgtype {
- UserPkgs::Env => installeduserpkgs.contains_key(&p.pname),
- UserPkgs::Profile => installeduserpkgs.contains_key(&p.pkg)
- },
- installedsystem: installedsystempkgs.contains(&p.pkg),
+ outpkgs.sort_by(|a, b| {
+ let mut aleft = a.name.to_lowercase() + &a.pkg.to_lowercase();
+ let mut bleft = b.name.to_lowercase() + &b.pkg.to_lowercase();
+ for q in searchsplit.iter() {
+ let q = &q.to_lowercase();
+ if aleft.contains(q) {
+ aleft = aleft.replace(q, "");
+ } else {
+ aleft.push_str(q);
+ }
+ if bleft.contains(q) {
+ bleft = bleft.replace(q, "");
+ } else {
+ bleft.push_str(q);
+ }
+ }
+ let mut apoints = aleft.len() + 5;
+ let mut bpoints = bleft.len() + 5;
+ // for q in searchsplit.iter() {
+ // if a.name.contains(q) {
+ // apoints -= 1;
+ // }
+ // if b.name.contains(q) {
+ // bpoints -= 1;
+ // }
+ // }
+ if appdata.get(&a.pkg).is_some() {
+ apoints -= 5;
+ }
+ if appdata.get(&b.pkg).is_some() {
+ bpoints -= 5;
+ }
+ apoints.cmp(&bpoints)
});
- if i > 100 {
- break;
- }
+ out.send(AppAsyncMsg::Search(search.to_string(), outpkgs))
}
- out.send(AppAsyncMsg::Search(search.to_string(), outpkgs))
}).drop_on_shutdown()
})
}
@@ -1389,95 +1677,183 @@ impl Component for AppModel {
InstallType::User => work.pname.to_string(),
InstallType::System => work.pkg.to_string(),
};
- self.installedpagebusy.retain(|(x, y)| x != &p && y != &work.pkgtype);
+ self.installedpagebusy
+ .retain(|(x, y)| x != &p && y != &work.pkgtype);
self.installedpage.emit(InstalledPageMsg::UnsetBusy(work));
}
AppMsg::OpenCategoryPage(category) => {
- info!("AppMsg::OpenCategoryPage({})", category);
+ info!("AppMsg::OpenCategoryPage({:?})", category);
self.page = Page::FrontPage;
self.mainpage = MainPage::CategoryPage;
+ self.categorypage
+ .emit(CategoryPageMsg::Loading(category.clone()));
sender.input(AppMsg::LoadCategory(category));
}
AppMsg::LoadCategory(category) => {
- let mut catrec = vec![];
- for app in self.categoryrec.get(&category).unwrap_or(&vec![]) {
- if let Some(x) = self.pkgs.get(app) {
- let mut name = x.pname.to_string();
- let mut icon = None;
- let mut summary = x.meta.description.clone().map(|x| x.to_string());
- if let Some(data) = &x.appdata {
- if let Some(i) = &data.icon {
- let mut iconvec = i.cached.as_ref().unwrap().to_vec();
- iconvec.sort_by(|a, b| a.height.cmp(&b.height));
- icon = Some(iconvec[0].name.clone());
- }
- if let Some(s) = &data.summary {
- summary =
- s.get("C").map(|x| x.to_string());
-
- }
- if let Some(n) = &data.name {
- name = n.get("C").unwrap().to_string();
+ info!("AppMsg::LoadCategory({:?})", category);
+ let pkgdb = self.pkgdb.clone();
+ let categoryrec = self.categoryrec.get(&category).unwrap_or(&vec![]).to_vec();
+ let categoryall = self.categoryall.get(&category).unwrap_or(&vec![]).to_vec();
+ let appdata = self.appdata.clone();
+ let installeduser = self.installeduserpkgs.clone();
+ let installedsystem = self.installedsystempkgs.clone();
+ let category = category;
+ sender.oneshot_command(async move {
+ let mut catrec = vec![];
+ let mut catall = vec![];
+ if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", pkgdb)).await {
+ for pkg in categoryrec {
+ if let Some(data) = appdata.get(&pkg) {
+ let pname: (String,) =
+ sqlx::query_as("SELECT pname FROM pkgs WHERE attribute = $1")
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ catrec.push(CategoryTile {
+ pkg: pkg.to_string(),
+ name: if let Some(name) = &data.name {
+ name.get("C").unwrap_or(&pname.0).to_string()
+ } else {
+ pname.0.to_string()
+ },
+ pname: pname.0,
+ icon: data
+ .icon
+ .as_ref()
+ .and_then(|x| x.cached.as_ref())
+ .map(|x| x[0].name.clone()),
+ summary: data
+ .summary
+ .as_ref()
+ .and_then(|x| x.get("C"))
+ .map(|x| x.to_string()),
+ installeduser: installeduser.contains_key(&pkg),
+ installedsystem: installedsystem.contains(&pkg),
+ })
+ } else {
+ let (pname, description): (String, String) =
+ sqlx::query_as("SELECT pname, description FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = $1")
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ catrec.push(CategoryTile {
+ pkg: pkg.to_string(),
+ name: pname.to_string(),
+ pname: pname.to_string(),
+ icon: None,
+ summary: if description.is_empty() { None } else { Some(description) },
+ installeduser: installeduser.contains_key(&pkg),
+ installedsystem: installedsystem.contains(&pkg),
+ })
}
}
- catrec.push(CategoryTile {
- pkg: app.to_string(),
- name,
- pname: x.pname.to_string(),
- icon,
- summary,
- installeduser: self.installeduserpkgs.contains_key(&x.pname.to_string()),
- installedsystem: self.installedsystempkgs.contains(&x.pname.to_string()),
- });
- }
- }
-
- let mut catall = vec![];
- for app in self.categoryall.get(&category).unwrap_or(&vec![]) {
- if let Some(x) = self.pkgs.get(app) {
- let mut name = x.pname.to_string();
- let mut icon = None;
- let mut summary = x.meta.description.clone().map(|x| x.to_string());
- if let Some(data) = &x.appdata {
- if let Some(i) = &data.icon {
- let mut iconvec = i.cached.as_ref().unwrap().to_vec();
- iconvec.sort_by(|a, b| a.height.cmp(&b.height));
- icon = Some(iconvec[0].name.clone());
- }
- if let Some(s) = &data.summary {
- summary =
- s.get("C").map(|x| x.to_string());
-
- }
- if let Some(n) = &data.name {
- name = n.get("C").unwrap().to_string();
+ for pkg in categoryall {
+ if let Some(data) = appdata.get(&pkg) {
+ let pname: (String,) =
+ sqlx::query_as("SELECT pname FROM pkgs WHERE attribute = $1")
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ catall.push(CategoryTile {
+ pkg: pkg.to_string(),
+ name: if let Some(name) = &data.name {
+ name.get("C").unwrap_or(&pname.0).to_string()
+ } else {
+ pname.0.to_string()
+ },
+ pname: pname.0,
+ icon: data
+ .icon
+ .as_ref()
+ .and_then(|x| x.cached.as_ref())
+ .map(|x| x[0].name.clone()),
+ summary: data
+ .summary
+ .as_ref()
+ .and_then(|x| x.get("C"))
+ .map(|x| x.to_string()),
+ installeduser: installeduser.contains_key(&pkg),
+ installedsystem: installedsystem.contains(&pkg),
+ })
+ } else {
+ let (pname, description): (String, String) =
+ sqlx::query_as("SELECT pname, description FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = $1")
+ .bind(&pkg)
+ .fetch_one(pool)
+ .await
+ .unwrap();
+ catall.push(CategoryTile {
+ pkg: pkg.to_string(),
+ name: pname.to_string(),
+ pname: pname.to_string(),
+ icon: None,
+ summary: if description.is_empty() { None } else { Some(description) },
+ installeduser: installeduser.contains_key(&pkg),
+ installedsystem: installedsystem.contains(&pkg),
+ })
}
}
- catall.push(CategoryTile {
- pkg: app.to_string(),
- name,
- pname: x.pname.to_string(),
- icon,
- summary,
- installeduser: self.installeduserpkgs.contains_key(&x.pname.to_string()),
- installedsystem: self.installedsystempkgs.contains(&x.pname.to_string()),
- });
+ } else {
+ error!("Failed to connect to pkgdb")
}
- }
-
- self.categorypage.emit(CategoryPageMsg::Open(category, catrec, catall));
-
+ AppAsyncMsg::LoadCategory(category, catrec, catall)
+ });
}
}
}
- fn update_cmd(&mut self, msg: Self::CommandOutput, _sender: ComponentSender) {
+ fn update_cmd(&mut self, msg: Self::CommandOutput, sender: ComponentSender) {
match msg {
AppAsyncMsg::Search(search, pkgitems) => {
if search == self.searchquery {
self.searchpage.emit(SearchPageMsg::Search(pkgitems))
}
}
+ AppAsyncMsg::UpdateRecPkgs(pkgtiles) => {
+ info!("AppAsyncMsg::UpdateRecPkgs");
+ let mut recapps_guard = self.recommendedapps.guard();
+ recapps_guard.clear();
+ for tile in pkgtiles {
+ recapps_guard.push_back(tile);
+ }
+ recapps_guard.drop();
+ sender.input(AppMsg::UpdateInstalledPkgs);
+ info!("DONE AppAsyncMsg::UpdateRecPkgs");
+ }
+ AppAsyncMsg::UpdateInstalledPkgs(installedsystempkgs, installeduserpkgs) => {
+ info!("AppAsyncMsg::UpdateInstalledPkgs");
+ if installedsystempkgs != self.installedsystempkgs
+ || installeduserpkgs != self.installeduserpkgs
+ {
+ warn!("Changes needed!");
+ self.installedsystempkgs = installedsystempkgs;
+ self.installeduserpkgs = installeduserpkgs;
+ sender.input(AppMsg::UpdateInstalledPage);
+ debug!("Getting recommended apps guard");
+ let mut recommendedapps_guard = self.recommendedapps.guard();
+ debug!("Got recommended apps guard");
+ for item in recommendedapps_guard.iter_mut() {
+ debug!("Got item {}", item.pkg);
+ item.installeduser = self.installeduserpkgs.contains_key(&item.pname);
+ item.installedsystem = self.installedsystempkgs.contains(&item.pname);
+ }
+ if self.searching {
+ // self.update_searching(|_| ());
+ self.searchpage.emit(SearchPageMsg::UpdateInstalled(
+ self.installeduserpkgs.keys().cloned().collect(),
+ self.installedsystempkgs.clone(),
+ ));
+ }
+ }
+ info!("DONE AppAsyncMsg::UpdateInstalledPkgs");
+ }
+ AppAsyncMsg::LoadCategory(category, catrec, catall) => {
+ self.categorypage
+ .emit(CategoryPageMsg::Open(category, catrec, catall));
+ }
}
}
}
diff --git a/src/ui/windowloading.rs b/src/ui/windowloading.rs
index 4f3466e..fd70b5f 100644
--- a/src/ui/windowloading.rs
+++ b/src/ui/windowloading.rs
@@ -1,423 +1,381 @@
use super::window::AppMsg;
use super::window::SystemPkgs;
-use crate::parse::cache::checkcache;
-use crate::parse::config::NscConfig;
-use crate::parse::packages::readflakesyspkgs;
-use crate::parse::packages::readpkgs;
-use crate::parse::packages::readlegacysyspkgs;
-use crate::parse::packages::Package;
-use crate::parse::packages::readprofilepkgs;
+use crate::parse::packages::appsteamdata;
+use crate::parse::packages::AppData;
use crate::ui::categories::PkgCategory;
use crate::ui::window::UserPkgs;
+use log::*;
+use nix_data::config::configfile::NixDataConfig;
use rand::prelude::SliceRandom;
use rand::thread_rng;
use relm4::adw::prelude::*;
use relm4::*;
+use sqlx::SqlitePool;
use std::{collections::HashMap, env};
-use strum::IntoEnumIterator;
-use log::*;
pub struct WindowAsyncHandler;
#[derive(Debug)]
pub enum WindowAsyncHandlerMsg {
- CheckCache(CacheReturn, SystemPkgs, UserPkgs, NscConfig),
-}
-
-#[derive(Debug, PartialEq)]
-pub enum CacheReturn {
- Init,
- Update,
+ CheckCache(SystemPkgs, UserPkgs, NixDataConfig),
}
impl Worker for WindowAsyncHandler {
- type InitParams = ();
+ type Init = ();
type Input = WindowAsyncHandlerMsg;
type Output = AppMsg;
- fn init(_params: Self::InitParams, _sender: relm4::ComponentSender) -> Self {
+ fn init(_params: Self::Init, _sender: relm4::ComponentSender) -> Self {
Self
}
fn update(&mut self, msg: Self::Input, sender: ComponentSender) {
match msg {
- WindowAsyncHandlerMsg::CheckCache(cr, syspkgs, userpkgs, config) => {
+ WindowAsyncHandlerMsg::CheckCache(syspkgs, userpkgs, _config) => {
info!("WindowAsyncHandlerMsg::CheckCache");
- let syspkgs2 = syspkgs.clone();
- let userpkgs2 = userpkgs.clone();
- let config = config.clone();
relm4::spawn(async move {
- match checkcache(syspkgs2, userpkgs2, config) {
- Ok(_) => {}
- Err(e) => {
- warn!("FAILED TO CHECK CACHE");
- warn!("{}", e);
- sender.output(AppMsg::LoadError(
- String::from("Could not load cache"),
- String::from(
- "Try connecting to the internet or launching the application again",
- ),
- ));
- return;
- }
- }
- let pkgs = match readpkgs().await {
- Ok(pkgs) => pkgs,
- Err(e) => {
- warn!("FAILED TO LOAD PKGS");
- warn!("{}", e);
- sender.output(AppMsg::LoadError(
- String::from("Could not load packages"),
- String::from(
- "Try connecting to the internet or launching the application again",
- ),
- ));
- return;
- }
- };
-
- let newpkgs = match syspkgs {
- SystemPkgs::Legacy => {
- match readlegacysyspkgs() {
- Ok(newpkgs) => newpkgs,
- Err(e) => {
- warn!("FAILED TO LOAD NEW PKGS");
- warn!("{}", e);
- sender.output(AppMsg::LoadError(
- String::from("Could not load new packages"),
- String::from(
- "Try connecting to the internet or launching the application again",
- ),
- ));
- return;
- }
- }
- }
- SystemPkgs::Flake => {
- match readflakesyspkgs() {
- Ok(newpkgs) => newpkgs,
- Err(e) => {
- warn!("FAILED TO LOAD NEW PKGS");
- warn!("{}", e);
- sender.output(AppMsg::LoadError(
- String::from("Could not load new packages"),
- String::from(
- "Try connecting to the internet or launching the application again",
- ),
- ));
- return;
- }
- }
- }
- SystemPkgs::None => {
- HashMap::new()
- }
- };
-
- let profilepkgs = match userpkgs {
- UserPkgs::Env => None,
- UserPkgs::Profile => if let Ok(r) = readprofilepkgs() { Some(r) } else { None },
- };
-
let mut recpicks = vec![];
let mut catpicks: HashMap> = HashMap::new();
let mut catpkgs: HashMap> = HashMap::new();
+ println!("Connecting to DB");
+ let pkgdb = nix_data::cache::nixos::nixospkgs().await.unwrap();
+ let pool = SqlitePool::connect(&format!("sqlite://{}", pkgdb))
+ .await
+ .unwrap();
- if cr == CacheReturn::Init {
- let desktopenv = env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
- let appdatapkgs = pkgs
- .iter()
- .filter(|(x, _)| {
- if let Some(p) = pkgs.get(*x) {
- if let Some(data) = &p.appdata {
- (if let Some(i) = &data.icon {
- i.cached.is_some()
- } else {
- false
- }) && data.description.is_some()
- && data.name.is_some()
- && data.launchable.is_some()
- && data.screenshots.is_some()
- && (!x.starts_with("gnome.") || desktopenv == "GNOME")
- && (!x.starts_with("xfce.") || desktopenv == "XFCE")
- && (!x.starts_with("mate.") || desktopenv == "MATE")
- && (!x.starts_with("cinnamon.")
- || desktopenv == "X-Cinnamon")
- && (!x.starts_with("libsForQt5") || desktopenv == "KDE")
- && (!x.starts_with("pantheon.")
- || desktopenv == "Pantheon")
- } else {
- false
- }
- } else {
- false
- }
- })
- .collect::>();
-
- let mut recommendedpkgs = appdatapkgs
- .keys()
- .map(|x| x.to_string())
- .collect::>();
- let mut rng = thread_rng();
- recommendedpkgs.shuffle(&mut rng);
-
- let mut desktoppicks = recommendedpkgs
- .iter()
- .filter(|x| {
- if desktopenv == "GNOME" {
- x.starts_with("gnome.") || x.starts_with("gnome-")
- } else if desktopenv == "XFCE" {
- x.starts_with("xfce.")
- } else if desktopenv == "MATE" {
- x.starts_with("mate.")
- } else if desktopenv == "X-Cinnamon" {
- x.starts_with("cinnamon.")
- } else if desktopenv == "KDE" {
- x.starts_with("libsForQt5")
- } else if desktopenv == "Pantheon" {
- x.starts_with("pantheon.")
- } else {
- false
- }
- })
- .collect::>();
-
- for p in desktoppicks.iter().take(3) {
- recpicks.push(p.to_string());
+ let nixpkgsdb = match userpkgs {
+ UserPkgs::Profile => {
+ if let Ok(x) = nix_data::cache::profile::nixpkgslatest().await {
+ Some(x)
+ } else {
+ None
+ }
}
- for category in PkgCategory::iter() {
- desktoppicks.shuffle(&mut rng);
- let mut cvec = vec![];
- let mut allvec = vec![];
- let mut rpkgs = recommendedpkgs.clone();
- fn checkpkgs(
- pkg: String,
- pkgs: &HashMap<&String, &Package>,
- category: PkgCategory,
- ) -> bool {
- match category {
- PkgCategory::Audio => {
- // Audio:
- // - pkgs/applications/audio
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/applications/audio") {
+ UserPkgs::Env => None,
+ };
+
+ let systemdb = match syspkgs {
+ SystemPkgs::None => None,
+ SystemPkgs::Legacy => {
+ if let Ok(x) = nix_data::cache::channel::legacypkgs().await {
+ Some(x)
+ } else {
+ None
+ }
+ }
+ SystemPkgs::Flake => {
+ if let Ok(x) = nix_data::cache::flakes::flakespkgs().await {
+ Some(x)
+ } else {
+ None
+ }
+ }
+ };
+
+ let pkglist: Vec<(String,)> = sqlx::query_as("SELECT attribute FROM pkgs")
+ .fetch_all(&pool)
+ .await
+ .unwrap();
+ let pkglist = pkglist.iter().map(|x| x.0.clone()).collect::>();
+
+ let posvec: Vec<(String, String)> =
+ sqlx::query_as("SELECT attribute, position FROM meta")
+ .fetch_all(&pool)
+ .await
+ .unwrap();
+ println!("Got DB data");
+ let appdata = appsteamdata().unwrap();
+
+ let desktopenv = env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
+
+ let mut recpkgs = pkglist
+ .iter()
+ .filter(|x| {
+ if let Some(data) = appdata.get(&x.to_string()) {
+ (if let Some(i) = &data.icon {
+ i.cached.is_some()
+ } else {
+ false
+ }) && data.description.is_some()
+ && data.name.is_some()
+ && data.launchable.is_some()
+ && data.screenshots.is_some()
+ && (!x.starts_with("gnome.") || desktopenv == "GNOME")
+ && (!x.starts_with("xfce.") || desktopenv == "XFCE")
+ && (!x.starts_with("mate.") || desktopenv == "MATE")
+ && (!x.starts_with("cinnamon.") || desktopenv == "X-Cinnamon")
+ && (!x.starts_with("libsForQt5") || desktopenv == "KDE")
+ && (!x.starts_with("pantheon.") || desktopenv == "Pantheon")
+ } else {
+ false
+ }
+ })
+ .collect::>();
+
+ let mut rng = thread_rng();
+ recpkgs.shuffle(&mut rng);
+
+ let mut desktoppicks = recpkgs
+ .iter()
+ .filter(|x| {
+ if desktopenv == "GNOME" {
+ x.starts_with("gnome.") || x.starts_with("gnome-")
+ } else if desktopenv == "XFCE" {
+ x.starts_with("xfce.")
+ } else if desktopenv == "MATE" {
+ x.starts_with("mate.")
+ } else if desktopenv == "X-Cinnamon" {
+ x.starts_with("cinnamon.")
+ } else if desktopenv == "KDE" {
+ x.starts_with("libsForQt5")
+ } else if desktopenv == "Pantheon" {
+ x.starts_with("pantheon.")
+ } else {
+ false
+ }
+ })
+ .collect::>();
+
+ for p in desktoppicks.iter().take(3) {
+ recpicks.push(p.to_string());
+ }
+
+ let pospkgs = posvec
+ .into_iter()
+ .map(|(x, y)| (x, if y.is_empty() { None } else { Some(y) }))
+ .collect::>>();
+
+ println!("Starting category");
+ for category in vec![
+ PkgCategory::Audio,
+ PkgCategory::Development,
+ PkgCategory::Games,
+ PkgCategory::Graphics,
+ PkgCategory::Web,
+ PkgCategory::Video,
+ ] {
+ desktoppicks.shuffle(&mut rng);
+ let mut cvec = vec![];
+ let mut allvec = vec![];
+ let mut rpkgs = recpkgs.clone();
+ fn checkpkgs(
+ pkg: String,
+ pospkgs: &HashMap>,
+ appdata: &HashMap,
+ category: PkgCategory,
+ ) -> bool {
+ match category {
+ PkgCategory::Audio => {
+ // Audio:
+ // - pkgs/applications/audio
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/applications/audio") {
+ return true;
+ }
+ if let Some(data) = appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Audio")) {
return true;
}
}
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories.contains(&String::from("Audio")) {
- return true;
- }
- }
- }
}
- false
}
- PkgCategory::Development => {
- // Development:
- // - pkgs/development
- // - pkgs/applications/terminal-emulators
- // - xdg: Development
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/development")
- || pos.starts_with(
- "pkgs/applications/terminal-emulators",
- )
+ false
+ }
+ PkgCategory::Development => {
+ // Development:
+ // - pkgs/development
+ // - pkgs/applications/terminal-emulators
+ // - xdg: Development
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/development")
+ || pos
+ .starts_with("pkgs/applications/terminal-emulators")
+ {
+ return true;
+ }
+ if let Some(data) = appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Development"))
{
return true;
}
}
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories
- .contains(&String::from("Development"))
- {
- return true;
- }
- }
- }
}
- false
}
- PkgCategory::Games => {
- // Games:
- // - pkgs/games
- // - pkgs/applications/emulators
- // - pkgs/tools/games
- // - xdg::Games
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/games")
- || pos.starts_with(
- "pkgs/applications/emulators",
- )
- || pos.starts_with("pkgs/tools/games")
- {
+ false
+ }
+ PkgCategory::Games => {
+ // Games:
+ // - pkgs/games
+ // - pkgs/applications/emulators
+ // - pkgs/tools/games
+ // - xdg::Games
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/games")
+ || pos.starts_with("pkgs/applications/emulators")
+ || pos.starts_with("pkgs/tools/games")
+ {
+ return true;
+ }
+ if let Some(data) = &appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Games")) {
return true;
}
}
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories.contains(&String::from("Games")) {
- return true;
- }
- }
- }
}
- false
}
- PkgCategory::Graphics => {
- // Graphics:
- // - pkgs/applications/graphics
- // - xdg: Graphics
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/applications/graphics")
- || pos.starts_with("xdg:Graphics")
- {
+ false
+ }
+ PkgCategory::Graphics => {
+ // Graphics:
+ // - pkgs/applications/graphics
+ // - xdg: Graphics
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/applications/graphics")
+ || pos.starts_with("xdg:Graphics")
+ {
+ return true;
+ }
+ if let Some(data) = &appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Graphics")) {
return true;
}
}
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories.contains(&String::from("Graphics")) {
- return true;
- }
- }
- }
- }
- false
- }
- PkgCategory::Network => {
- // Network:
- // - pkgs/applications/networking
- // - xdg: Network
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/applications/networking")
- || pos.starts_with("xdg:Network")
- {
- return true;
- }
- }
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories.contains(&String::from("Network")) {
- return true;
- }
- }
- }
- }
- false
- }
- PkgCategory::Video => {
- // Video:
- // - pkgs/applications/video
- // - xdg: Video
- if let Some(p) = pkgs.get(&pkg) {
- if let Some(pos) = &p.meta.position {
- if pos.starts_with("pkgs/applications/video")
- || pos.starts_with("xdg:Video")
- {
- return true;
- }
- }
- if let Some(data) = &p.appdata {
- if let Some(categories) = &data.categories {
- if categories.contains(&String::from("Video")) {
- return true;
- }
- }
- }
}
- false
}
+ false
+ }
+ PkgCategory::Web => {
+ // Web:
+ // - pkgs/applications/networking
+ // - xdg: Network
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/applications/networking")
+ || pos.starts_with("xdg:Network")
+ {
+ return true;
+ }
+ if let Some(data) = &appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Network")) {
+ return true;
+ }
+ }
+ }
+ }
+ false
+ }
+ PkgCategory::Video => {
+ // Video:
+ // - pkgs/applications/video
+ // - xdg: Video
+ if let Some(Some(pos)) = pospkgs.get(&pkg) {
+ if pos.starts_with("pkgs/applications/video")
+ || pos.starts_with("xdg:Video")
+ {
+ return true;
+ }
+ if let Some(data) = &appdata.get(&pkg) {
+ if let Some(categories) = &data.categories {
+ if categories.contains(&String::from("Video")) {
+ return true;
+ }
+ }
+ }
+ }
+ false
}
}
+ }
- for pkg in desktoppicks.iter().take(3) {
- if checkpkgs(pkg.to_string(), &appdatapkgs, category.clone()) {
+ for pkg in desktoppicks.iter().take(3) {
+ if checkpkgs(pkg.to_string(), &pospkgs, &appdata, category.clone()) {
+ cvec.push(pkg.to_string());
+ }
+ }
+
+ while cvec.len() < 12 {
+ if let Some(pkg) = rpkgs.pop() {
+ if !cvec.contains(&pkg.to_string())
+ && checkpkgs(
+ pkg.to_string(),
+ &pospkgs,
+ &appdata,
+ category.clone(),
+ )
+ {
cvec.push(pkg.to_string());
}
- }
-
- while cvec.len() < 12 {
- if let Some(pkg) = rpkgs.pop() {
- if !cvec.contains(&pkg.to_string())
- && checkpkgs(
- pkg.to_string(),
- &appdatapkgs,
- category.clone(),
- )
- {
- cvec.push(pkg.to_string());
- }
- } else {
- break;
- }
- }
-
- let catagortypkgs = pkgs
- .iter()
- .filter(|(x, _)| {
- if let Some(p) = appdatapkgs.get(*x) {
- if let Some(position) = &p.meta.position {
- (position.starts_with("pkgs/applications/audio") && category == PkgCategory::Audio)
- || (position.starts_with("pkgs/applications/terminal-emulators") && category == PkgCategory::Development)
- || (position.starts_with("pkgs/applications/emulators") && category == PkgCategory::Games)
- || (position.starts_with("pkgs/applications/graphics") && category == PkgCategory::Graphics)
- || (position.starts_with("pkgs/applications/networking") && category == PkgCategory::Network)
- || (position.starts_with("pkgs/applications/video") && category == PkgCategory::Video)
- || (position.starts_with("pkgs/tools/games") && category == PkgCategory::Games)
- || (position.starts_with("pkgs/games") && category == PkgCategory::Games)
- || (position.starts_with("pkgs/development") && category == PkgCategory::Development)
- || appdatapkgs.contains_key(x)
- } else {
- false
- }
- } else {
- false
- }
- })
- .collect::>();
-
- for pkg in catagortypkgs.keys() {
- if checkpkgs(pkg.to_string(), &catagortypkgs, category.clone()) {
- allvec.push(pkg.to_string());
- }
- }
-
- cvec.shuffle(&mut rng);
- allvec.sort_by_key(|x| x.to_lowercase());
- catpicks.insert(category.clone(), cvec);
- catpkgs.insert(category.clone(), allvec);
- }
-
- while recpicks.len() < 12 {
- if let Some(p) = recommendedpkgs.pop() {
- if !recpicks.contains(&p.to_string()) {
- recpicks.push(p);
- }
} else {
break;
}
}
- recpicks.shuffle(&mut rng);
+
+ let catagortypkgs = pkglist
+ .iter()
+ .filter(|x| {
+ if appdata.get(*x).is_some() {
+ if let Some(Some(position)) = &pospkgs.get(*x) {
+ (position.starts_with("pkgs/applications/audio")
+ && category == PkgCategory::Audio)
+ || (position.starts_with(
+ "pkgs/applications/terminal-emulators",
+ ) && category == PkgCategory::Development)
+ || (position.starts_with("pkgs/applications/emulators")
+ && category == PkgCategory::Games)
+ || (position.starts_with("pkgs/applications/graphics")
+ && category == PkgCategory::Graphics)
+ || (position
+ .starts_with("pkgs/applications/networking")
+ && category == PkgCategory::Web)
+ || (position.starts_with("pkgs/applications/video")
+ && category == PkgCategory::Video)
+ || (position.starts_with("pkgs/tools/games")
+ && category == PkgCategory::Games)
+ || (position.starts_with("pkgs/games")
+ && category == PkgCategory::Games)
+ || (position.starts_with("pkgs/development")
+ && category == PkgCategory::Development)
+ || recpkgs.contains(x)
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ })
+ .collect::>();
+
+ for pkg in catagortypkgs {
+ if checkpkgs(pkg.to_string(), &pospkgs, &appdata, category.clone()) {
+ allvec.push(pkg.to_string());
+ }
+ }
+
+ cvec.shuffle(&mut rng);
+ allvec.sort_by_key(|x| x.to_lowercase());
+ catpicks.insert(category.clone(), cvec);
+ catpkgs.insert(category.clone(), allvec);
}
- match cr {
- CacheReturn::Init => {
- sender.output(AppMsg::Initialize(pkgs, recpicks, newpkgs, catpicks, catpkgs, profilepkgs));
- }
- CacheReturn::Update => {
- sender.output(AppMsg::ReloadUpdateItems(pkgs, newpkgs));
+ while recpicks.len() < 12 {
+ if let Some(p) = recpkgs.pop() {
+ if !recpicks.contains(&p.to_string()) {
+ recpicks.push(p.to_string());
+ }
+ } else {
+ break;
}
}
+ recpicks.shuffle(&mut rng);
+
+ sender.output(AppMsg::Initialize(
+ pkgdb, nixpkgsdb, systemdb, appdata, recpicks, catpicks, catpkgs,
+ ));
});
}
}
@@ -435,12 +393,11 @@ pub enum LoadErrorMsg {
Show(String, String),
Retry,
Close,
- // Preferences,
}
#[relm4::component(pub)]
impl SimpleComponent for LoadErrorModel {
- type InitParams = gtk::Window;
+ type Init = gtk::Window;
type Input = LoadErrorMsg;
type Output = AppMsg;
type Widgets = LoadErrorWidgets;
@@ -472,7 +429,7 @@ impl SimpleComponent for LoadErrorModel {
}
fn init(
- parent_window: Self::InitParams,
+ parent_window: Self::Init,
root: &Self::Root,
sender: ComponentSender,
) -> ComponentParts {