Add decky sorting query support
This commit is contained in:
parent
512e03d9c7
commit
cf2786242d
12 changed files with 537 additions and 19 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
/target
|
/target
|
||||||
|
**/target
|
||||||
/store
|
/store
|
||||||
not-decky-*
|
not-decky-*
|
||||||
|
/*.sh
|
||||||
|
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -435,6 +435,7 @@ dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"serde",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
@ -537,8 +538,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decky_api"
|
name = "decky_api"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -899,7 +901,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "not-decky-store"
|
name = "not-decky-store"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-cors",
|
"actix-cors",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -911,6 +913,7 @@ dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
"sha256",
|
"sha256",
|
||||||
"simplelog",
|
"simplelog",
|
||||||
"ureq",
|
"ureq",
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
[package]
|
[package]
|
||||||
name = "not-decky-store"
|
name = "not-decky-store"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
decky_api = { version = "0.1.0", path = "./decky_api" }
|
decky_api = { version = "0.2.0", path = "./decky_api" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { version = "1.0" }
|
serde_json = { version = "1.0" }
|
||||||
|
serde_urlencoded = "0.7"
|
||||||
bytes = "1.3"
|
bytes = "1.3"
|
||||||
sha256 = "1.1"
|
sha256 = "1.1"
|
||||||
|
|
||||||
|
|
365
decky_api/Cargo.lock
generated
Normal file
365
decky_api/Cargo.lock
generated
Normal file
|
@ -0,0 +1,365 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
|
||||||
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "decky_api"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.59"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.66"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a293318316cf6478ec1ad2a21c49390a8d5b5eae9fab736467d93fbc0edc29c5"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
|
"windows_aarch64_msvc 0.48.5",
|
||||||
|
"windows_i686_gnu 0.48.5",
|
||||||
|
"windows_i686_msvc 0.48.5",
|
||||||
|
"windows_x86_64_gnu 0.48.5",
|
||||||
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.0",
|
||||||
|
"windows_aarch64_msvc 0.52.0",
|
||||||
|
"windows_i686_gnu 0.52.0",
|
||||||
|
"windows_i686_msvc 0.52.0",
|
||||||
|
"windows_x86_64_gnu 0.52.0",
|
||||||
|
"windows_x86_64_gnullvm 0.52.0",
|
||||||
|
"windows_x86_64_msvc 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|
@ -1,9 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "decky_api"
|
name = "decky_api"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
mod store_plugin;
|
mod store_plugin;
|
||||||
|
|
||||||
pub use store_plugin::{StorePlugin, StorePluginVersion, StorePluginList};
|
pub use store_plugin::{StorePlugin, StorePluginVersion, StorePluginList, StorePluginQuery, StorePluginQuerySortColumn, StorePluginQuerySortDirection};
|
||||||
|
|
|
@ -11,6 +11,10 @@ pub struct StorePlugin {
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub tags: Vec<String>,
|
pub tags: Vec<String>,
|
||||||
pub image_url: String,
|
pub image_url: String,
|
||||||
|
pub downloads: Option<u64>,
|
||||||
|
pub updates: Option<u64>,
|
||||||
|
pub created: Option<chrono::DateTime<chrono::Utc>>,
|
||||||
|
pub updated: Option<chrono::DateTime<chrono::Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -18,4 +22,31 @@ pub struct StorePluginVersion {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
pub artifact: Option<String>,
|
pub artifact: Option<String>,
|
||||||
|
pub created: Option<chrono::DateTime<chrono::Utc>>,
|
||||||
|
pub downloads: Option<u64>,
|
||||||
|
pub updates: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct StorePluginQuery {
|
||||||
|
pub sort_by: Option<StorePluginQuerySortColumn>,
|
||||||
|
pub sort_direction: Option<StorePluginQuerySortDirection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub enum StorePluginQuerySortColumn {
|
||||||
|
#[serde(rename = "name")]
|
||||||
|
Name,
|
||||||
|
#[serde(rename = "date")]
|
||||||
|
Date,
|
||||||
|
#[serde(rename = "downloads")]
|
||||||
|
Downloads
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub enum StorePluginQuerySortDirection {
|
||||||
|
#[serde(rename = "asc")]
|
||||||
|
Ascending,
|
||||||
|
#[serde(rename = "desc")]
|
||||||
|
Descending,
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,12 @@ fn build_storage_box(storage: &cli::StorageArgs) -> Box<dyn storage::IStorage> {
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let args = cli::CliArgs::get();
|
let args = cli::CliArgs::get();
|
||||||
let log_filepath = std::path::Path::new("/tmp").join(format!("{}.log", consts::PACKAGE_NAME));
|
let log_filepath = std::path::Path::new("/tmp").join(format!("{}.log", consts::PACKAGE_NAME));
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let log_level = LevelFilter::Debug;
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let log_level = LevelFilter::Info;
|
||||||
WriteLogger::init(
|
WriteLogger::init(
|
||||||
LevelFilter::Debug,
|
log_level,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
std::fs::File::create(&log_filepath).unwrap(),
|
std::fs::File::create(&log_filepath).unwrap(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ use decky_api::{StorePlugin, StorePluginList, StorePluginVersion};
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use super::IStorage;
|
use super::{IStorage, IQueryHandler};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct PluginMetadata {
|
pub struct PluginMetadata {
|
||||||
|
@ -21,6 +21,10 @@ pub struct PluginMetadata {
|
||||||
|
|
||||||
impl PluginMetadata {
|
impl PluginMetadata {
|
||||||
fn complete(self, name: String, versions: Vec<StorePluginVersion>, image: String) -> StorePlugin {
|
fn complete(self, name: String, versions: Vec<StorePluginVersion>, image: String) -> StorePlugin {
|
||||||
|
let downloads = versions.iter().map(|v| v.downloads.unwrap_or(0)).sum();
|
||||||
|
let updates = versions.iter().map(|v| v.updates.unwrap_or(0)).sum();
|
||||||
|
let created_time = versions.iter().map(|v| v.created.unwrap_or_default()).min().unwrap_or_default();
|
||||||
|
let updated_time = versions.iter().map(|v| v.created.unwrap_or_default()).max().unwrap_or_default();
|
||||||
StorePlugin {
|
StorePlugin {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -29,6 +33,10 @@ impl PluginMetadata {
|
||||||
description: self.description,
|
description: self.description,
|
||||||
tags: self.tags,
|
tags: self.tags,
|
||||||
image_url: image,
|
image_url: image,
|
||||||
|
downloads: Some(downloads),
|
||||||
|
updates: Some(updates),
|
||||||
|
created: Some(created_time),
|
||||||
|
updated: Some(updated_time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +45,7 @@ pub struct FileStorage {
|
||||||
stats: Option<RwLock<HashMap<String, AtomicU64>>>, // TODO collect hit counts on actions
|
stats: Option<RwLock<HashMap<String, AtomicU64>>>, // TODO collect hit counts on actions
|
||||||
root: PathBuf,
|
root: PathBuf,
|
||||||
domain_root: String,
|
domain_root: String,
|
||||||
|
query_handler: Box<dyn IQueryHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileStorage {
|
impl FileStorage {
|
||||||
|
@ -45,6 +54,7 @@ impl FileStorage {
|
||||||
root: root,
|
root: root,
|
||||||
domain_root: domain_root,
|
domain_root: domain_root,
|
||||||
stats: if enable_stats { Some(RwLock::new(HashMap::new())) } else { None },
|
stats: if enable_stats { Some(RwLock::new(HashMap::new())) } else { None },
|
||||||
|
query_handler: Box::new(super::StandardPostRetrievalSort),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +80,7 @@ impl FileStorage {
|
||||||
.join(format!("image.png"))
|
.join(format!("image.png"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_all_plugins(&self) -> std::io::Result<StorePluginList> {
|
fn read_all_plugins(&self, query: Option<&str>) -> std::io::Result<StorePluginList> {
|
||||||
let plugins = self.plugins_path();
|
let plugins = self.plugins_path();
|
||||||
let dir_reader = plugins.read_dir()?;
|
let dir_reader = plugins.read_dir()?;
|
||||||
let mut results = Vec::with_capacity(dir_reader.size_hint().1.unwrap_or(32));
|
let mut results = Vec::with_capacity(dir_reader.size_hint().1.unwrap_or(32));
|
||||||
|
@ -91,9 +101,39 @@ impl FileStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(query) = query {
|
||||||
|
let relevant_params = self.query_handler.supported_params(query);
|
||||||
|
results = self.query_handler.filter(&relevant_params, results);
|
||||||
|
}
|
||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn version_stat_entry_name(plugin_name: &str, version_name: &str) -> String {
|
||||||
|
format!("{} {}", plugin_name, version_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn plugin_stat_entry_name(plugin_name: &str) -> String {
|
||||||
|
format!("{}", plugin_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn artifact_url(&self, plugin_name: &str, version_name: &str, hash_str: &str) -> String {
|
||||||
|
format!("{}/plugins/{}/{}/{}.zip", self.domain_root, plugin_name, version_name, hash_str)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn image_url(&self, plugin_name: &str) -> String {
|
||||||
|
format!("{}/plugins/{}.png", self.domain_root, plugin_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_single_version_stats(&self, plugin_name: &str, version_name: &str) -> Option<u64> {
|
||||||
|
let lock = self.stats.as_ref()?.read().expect("Couldn't acquire stats read lock");
|
||||||
|
let stat_entry = Self::version_stat_entry_name(plugin_name, version_name);
|
||||||
|
if let Some(stat_counter) = lock.get(&stat_entry) {
|
||||||
|
Some(stat_counter.load(Ordering::SeqCst))
|
||||||
|
} else {
|
||||||
|
Some(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn read_single_plugin(&self, path: &PathBuf) -> std::io::Result<StorePlugin> {
|
fn read_single_plugin(&self, path: &PathBuf) -> std::io::Result<StorePlugin> {
|
||||||
let plugin_name = path.file_name().unwrap().to_string_lossy().into_owned();
|
let plugin_name = path.file_name().unwrap().to_string_lossy().into_owned();
|
||||||
let json_path = self.plugin_json_path(path);
|
let json_path = self.plugin_json_path(path);
|
||||||
|
@ -115,17 +155,21 @@ impl FileStorage {
|
||||||
if extension == "zip" {
|
if extension == "zip" {
|
||||||
let version_name = entry_path.file_stem().unwrap().to_string_lossy().into_owned();
|
let version_name = entry_path.file_stem().unwrap().to_string_lossy().into_owned();
|
||||||
let hash_str = sha256::try_digest(&entry_path)?;
|
let hash_str = sha256::try_digest(&entry_path)?;
|
||||||
let artifact_url = format!("{}/plugins/{}/{}/{}.zip", self.domain_root, plugin_name, version_name, hash_str);
|
let artifact_url = self.artifact_url(&plugin_name, &version_name, &hash_str);
|
||||||
|
let downloads_stat = self.get_single_version_stats(&plugin_name, &version_name);
|
||||||
versions.push(StorePluginVersion {
|
versions.push(StorePluginVersion {
|
||||||
name: version_name,
|
name: version_name,
|
||||||
hash: hash_str,
|
hash: hash_str,
|
||||||
artifact: Some(artifact_url)
|
artifact: Some(artifact_url),
|
||||||
|
created: Some(entry.metadata()?.created()?.into()),
|
||||||
|
downloads: downloads_stat,
|
||||||
|
updates: None, // TODO what is this?
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
versions.sort_by(|a, b| b.name.cmp(&a.name)); // sort e.g. v2 before v1
|
versions.sort_by(|a, b| b.name.cmp(&a.name)); // sort e.g. v2 before v1
|
||||||
let image_url = format!("{}/plugins/{}.png", self.domain_root, plugin_name);
|
let image_url = self.image_url(&plugin_name);
|
||||||
Ok(
|
Ok(
|
||||||
plugin_info.complete(
|
plugin_info.complete(
|
||||||
plugin_name,
|
plugin_name,
|
||||||
|
@ -137,9 +181,8 @@ impl FileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IStorage for FileStorage {
|
impl IStorage for FileStorage {
|
||||||
fn plugins(&self, _query: &str) -> StorePluginList {
|
fn plugins(&self, query: &str) -> StorePluginList {
|
||||||
// TODO handle query string
|
match self.read_all_plugins(Some(query)) {
|
||||||
match self.read_all_plugins() {
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Plugins read error: {}", e);
|
log::error!("Plugins read error: {}", e);
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -174,7 +217,7 @@ impl IStorage for FileStorage {
|
||||||
|
|
||||||
fn get_statistics(&self) -> std::collections::HashMap<String, u64> {
|
fn get_statistics(&self) -> std::collections::HashMap<String, u64> {
|
||||||
if let Some(stats) = &self.stats {
|
if let Some(stats) = &self.stats {
|
||||||
if let Ok(plugins) = self.read_all_plugins() {
|
if let Ok(plugins) = self.read_all_plugins(None) {
|
||||||
let lock = stats.read().expect("Failed to acquire stats read lock");
|
let lock = stats.read().expect("Failed to acquire stats read lock");
|
||||||
let mut map = std::collections::HashMap::with_capacity(lock.len());
|
let mut map = std::collections::HashMap::with_capacity(lock.len());
|
||||||
for plugin in plugins {
|
for plugin in plugins {
|
||||||
|
@ -183,10 +226,10 @@ impl IStorage for FileStorage {
|
||||||
if let Some(count) = lock.get(&version.hash) {
|
if let Some(count) = lock.get(&version.hash) {
|
||||||
let count_val = count.load(Ordering::SeqCst);
|
let count_val = count.load(Ordering::SeqCst);
|
||||||
total += count_val;
|
total += count_val;
|
||||||
map.insert(format!("{} {}", plugin.name, version.name), count_val);
|
map.insert(Self::version_stat_entry_name(&plugin.name, &version.name), count_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map.insert(format!("{}", plugin.name), total);
|
map.insert(Self::plugin_stat_entry_name(&plugin.name), total);
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -21,3 +21,12 @@ impl IStorage for EmptyStorage {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IQueryHandler: Send + Sync {
|
||||||
|
fn filter(&self, query: &str, plugins: decky_api::StorePluginList) -> decky_api::StorePluginList;
|
||||||
|
|
||||||
|
/// Filter out recognized query parameters from query string, returning only those that the query handler can use in IQueryHandler::filter
|
||||||
|
fn supported_params(&self, query: &str) -> String {
|
||||||
|
query.to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ mod filesystem;
|
||||||
mod interface;
|
mod interface;
|
||||||
mod merge;
|
mod merge;
|
||||||
mod proxy;
|
mod proxy;
|
||||||
|
mod standard_sort;
|
||||||
|
|
||||||
pub use cache::CachedStorage;
|
pub use cache::CachedStorage;
|
||||||
pub use filesystem::FileStorage;
|
pub use filesystem::FileStorage;
|
||||||
pub use interface::{IStorage, EmptyStorage};
|
pub use interface::{IStorage, EmptyStorage, IQueryHandler};
|
||||||
pub use merge::MergedStorage;
|
pub use merge::MergedStorage;
|
||||||
pub use proxy::ProxiedStorage;
|
pub use proxy::ProxiedStorage;
|
||||||
|
pub use standard_sort::StandardPostRetrievalSort;
|
||||||
|
|
57
src/storage/standard_sort.rs
Normal file
57
src/storage/standard_sort.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use decky_api::{StorePluginQuery, StorePluginQuerySortColumn, StorePluginQuerySortDirection};
|
||||||
|
|
||||||
|
use super::IQueryHandler;
|
||||||
|
|
||||||
|
pub struct StandardPostRetrievalSort;
|
||||||
|
|
||||||
|
impl IQueryHandler for StandardPostRetrievalSort {
|
||||||
|
fn filter(&self, query: &str, mut plugins: decky_api::StorePluginList) -> decky_api::StorePluginList {
|
||||||
|
log::debug!("StandardPostRetrievalSort::filter got query string `{}`", query);
|
||||||
|
let query: StorePluginQuery = match serde_urlencoded::from_str(query) {
|
||||||
|
Ok(q) => q,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to parse query string {}: {}", query, e);
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match (query.sort_by, query.sort_direction) {
|
||||||
|
(None, _) => plugins,
|
||||||
|
(Some(StorePluginQuerySortColumn::Name), direction) => {
|
||||||
|
plugins.sort_by_key(|p| p.name.to_lowercase());
|
||||||
|
match direction {
|
||||||
|
None | Some(StorePluginQuerySortDirection::Ascending) => {},
|
||||||
|
Some(StorePluginQuerySortDirection::Descending) => plugins.reverse(),
|
||||||
|
}
|
||||||
|
plugins
|
||||||
|
},
|
||||||
|
(Some(StorePluginQuerySortColumn::Date), direction) => {
|
||||||
|
plugins.sort_by_key(
|
||||||
|
|p| p.versions.iter()
|
||||||
|
.max_by_key(
|
||||||
|
|v| v.created.unwrap_or_default())
|
||||||
|
.map(|v| v.created.unwrap_or_default())
|
||||||
|
);
|
||||||
|
match direction {
|
||||||
|
None | Some(StorePluginQuerySortDirection::Ascending) => {},
|
||||||
|
Some(StorePluginQuerySortDirection::Descending) => plugins.reverse(),
|
||||||
|
}
|
||||||
|
plugins
|
||||||
|
},
|
||||||
|
(Some(StorePluginQuerySortColumn::Downloads), direction) => {
|
||||||
|
plugins.sort_by_key(|p| p.versions.iter().map(|v| v.downloads.unwrap_or(0)).sum::<u64>());
|
||||||
|
match direction {
|
||||||
|
None | Some(StorePluginQuerySortDirection::Ascending) => {},
|
||||||
|
Some(StorePluginQuerySortDirection::Descending) => plugins.reverse(),
|
||||||
|
}
|
||||||
|
plugins
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn supported_params(&self, query: &str) -> String {
|
||||||
|
match serde_urlencoded::from_str::<StorePluginQuery>(query) {
|
||||||
|
Ok(q) => serde_urlencoded::to_string(&q).unwrap_or_default(),
|
||||||
|
Err(_) => "".to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue