From bcdf5132211a79098d72b72aec60989e224ec6e4 Mon Sep 17 00:00:00 2001 From: fengyc Date: Sun, 8 Dec 2024 16:54:47 +0800 Subject: [PATCH] refactor: v2.0, cmd refactor --- Cargo.lock | 485 ++++++++++++++++--- README.md | 2 + pisugar-core/Cargo.toml | 3 +- pisugar-core/src/lib.rs | 1 - pisugar-core/src/model.rs | 28 +- pisugar-poweroff/Cargo.toml | 2 +- pisugar-poweroff/src/main.rs | 3 +- pisugar-programmer/Cargo.toml | 2 +- pisugar-server/Cargo.toml | 9 +- pisugar-server/src/cmds.rs | 207 +++++++++ pisugar-server/src/main.rs | 766 +++++++++++-------------------- scripts/aur/PKGBUILD | 2 +- scripts/pisugar-power-manager.sh | 2 +- 13 files changed, 953 insertions(+), 559 deletions(-) create mode 100644 pisugar-server/src/cmds.rs diff --git a/Cargo.lock b/Cargo.lock index 6ba0c58..788b83e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,16 +1,65 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.63" @@ -110,13 +159,47 @@ checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83" dependencies = [ "atty", "bitflags", - "clap_lex", - "indexmap", - "strsim", + "clap_lex 0.2.4", + "indexmap 1.8.2", + "strsim 0.10.0", "termcolor", "textwrap", ] +[[package]] +name = "clap" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +dependencies = [ + "anstream", + "anstyle", + "clap_lex 0.7.4", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "clap_lex" version = "0.2.4" @@ -126,6 +209,18 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -244,6 +339,34 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "either_n" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c91ae510829160d5cfb19eb4ae7b6e01d44b767ca8f727c6cee936e53cc9ae5" + +[[package]] +name = "enum-variants-strings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf78b873650dcfe36b4f4b39cbad0615bfdda80b0dbd302bcc43f729e26d9cfc" +dependencies = [ + "enum-variants-strings-derive", +] + +[[package]] +name = "enum-variants-strings-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c219bbaeb0dfcf75ef2a911d080245affeb04ad8da4b53986a0e4bbe6b966a2" +dependencies = [ + "either_n", + "proc-macro2", + "quote", + "string-cases", + "syn 2.0.90", +] + [[package]] name = "env_logger" version = "0.9.0" @@ -270,6 +393,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.1" @@ -318,9 +447,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -333,9 +462,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -343,15 +472,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -360,38 +489,44 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -426,6 +561,12 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.3.13" @@ -438,7 +579,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.8.2", "slab", "tokio", "tokio-util", @@ -451,6 +592,18 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -603,7 +756,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", ] [[package]] @@ -629,6 +792,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.2" @@ -697,9 +866,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -860,7 +1029,7 @@ checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.96", ] [[package]] @@ -877,10 +1046,11 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pisugar-core" -version = "1.7.8" +version = "2.0.0" dependencies = [ "anyhow", "chrono", + "clap 4.5.23", "hyper", "log", "rppal", @@ -891,10 +1061,10 @@ dependencies = [ [[package]] name = "pisugar-poweroff" -version = "1.7.8" +version = "2.0.0" dependencies = [ "anyhow", - "clap", + "clap 3.2.8", "env_logger 0.9.0", "log", "pisugar-core", @@ -902,9 +1072,9 @@ dependencies = [ [[package]] name = "pisugar-programmer" -version = "1.7.8" +version = "2.0.0" dependencies = [ - "clap", + "clap 3.2.8", "env_logger 0.10.0", "log", "rppal", @@ -913,15 +1083,16 @@ dependencies = [ [[package]] name = "pisugar-server" -version = "1.7.8" +version = "2.0.0" dependencies = [ "anyhow", "base64", "bytes", "chrono", - "clap", + "clap 4.5.23", "ctrlc", "digest_auth", + "enum-variants-strings", "env_logger 0.9.0", "futures", "futures-channel", @@ -934,7 +1105,9 @@ dependencies = [ "log", "pisugar-core", "rand", + "rstest", "serde", + "shlex", "syslog", "tokio", "tokio-tungstenite", @@ -948,20 +1121,29 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1031,9 +1213,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1042,9 +1236,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "rppal" @@ -1066,6 +1266,45 @@ dependencies = [ "tokio", ] +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.90", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.37.13" @@ -1092,6 +1331,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.137" @@ -1109,7 +1354,7 @@ checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.96", ] [[package]] @@ -1162,6 +1407,12 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1193,12 +1444,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "string-cases" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31d23461f9e0fbe756cf9d5a36be93740fe12c8b094409a5f78f0f912ee2b6f" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "1.0.96" @@ -1210,6 +1473,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sysinfo" version = "0.23.13" @@ -1270,7 +1544,7 @@ checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.96", ] [[package]] @@ -1337,7 +1611,7 @@ checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.96", ] [[package]] @@ -1366,6 +1640,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.7.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.1" @@ -1440,9 +1731,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -1471,6 +1762,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "version_check" version = "0.9.4" @@ -1564,7 +1861,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1573,21 +1879,43 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", "windows_i686_gnu 0.48.0", "windows_i686_msvc 0.48.0", "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.48.0", "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -1600,6 +1928,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -1612,6 +1946,18 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -1624,6 +1970,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -1636,12 +1988,24 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -1653,3 +2017,18 @@ name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] diff --git a/README.md b/README.md index b5c5671..4156ba6 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,8 @@ Default ports: ws 0.0.0.0:8422 # standalone websocket api http 0.0.0.0:8421 # web UI and websocket (/ws) +To get the full command list, please send a `help xx` request. + | Command | Description | Response/Usage | | :- | :-: | :-: | | get firmware_version | firmware version | firmware_version: [string] | diff --git a/pisugar-core/Cargo.toml b/pisugar-core/Cargo.toml index eee3f69..04006a4 100644 --- a/pisugar-core/Cargo.toml +++ b/pisugar-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pisugar-core" -version = "1.7.8" +version = "2.0.0" authors = ["PiSugare"] edition = "2018" license = "gplv3" @@ -17,3 +17,4 @@ serde_json = "1.0" hyper = {version ="0.14.10", features = ["full"]} anyhow = "1" rsntp = "4.0.0" +clap = "4.5.23" diff --git a/pisugar-core/src/lib.rs b/pisugar-core/src/lib.rs index 200527a..180291d 100644 --- a/pisugar-core/src/lib.rs +++ b/pisugar-core/src/lib.rs @@ -3,7 +3,6 @@ use std::fmt; use std::fmt::{Display, Formatter}; use std::io; -use std::io::Write; use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus}; use std::thread; diff --git a/pisugar-core/src/model.rs b/pisugar-core/src/model.rs index 331fcfa..44f46e4 100644 --- a/pisugar-core/src/model.rs +++ b/pisugar-core/src/model.rs @@ -1,5 +1,8 @@ -use std::convert::TryFrom; use std::fmt; +use std::str::FromStr; + +use clap::builder::PossibleValue; +use clap::ValueEnum; use crate::ip5312::IP5312Battery; use crate::pisugar3::{PiSugar3Battery, PiSugar3RTC, I2C_ADDR_P3}; @@ -88,11 +91,11 @@ impl fmt::Display for Model { } } -impl TryFrom<&str> for Model { - type Error = (); +impl FromStr for Model { + type Err = (); - fn try_from(value: &str) -> std::result::Result { - match value { + fn from_str(s: &str) -> std::result::Result { + match s { PISUGAR_2_4LEDS => Ok(Model::PiSugar_2_4LEDs), PISUGAR_2_2LEDS => Ok(Model::PiSugar_2_2LEDs), PISUGAR_2_PRO => Ok(Model::PiSugar_2_Pro), @@ -101,3 +104,18 @@ impl TryFrom<&str> for Model { } } } + +impl ValueEnum for Model { + fn value_variants<'a>() -> &'a [Self] { + &[Model::PiSugar_2_4LEDs, Model::PiSugar_2_2LEDs, Model::PiSugar_2_Pro, Model::PiSugar_3] + } + + fn to_possible_value(&self) -> Option { + Some(match self { + Model::PiSugar_2_4LEDs => PossibleValue::new(PISUGAR_2_4LEDS), + Model::PiSugar_2_2LEDs => PossibleValue::new(PISUGAR_2_2LEDS), + Model::PiSugar_2_Pro => PossibleValue::new(PISUGAR_2_PRO), + Model::PiSugar_3 => PossibleValue::new(PISUGAR_3), + }) + } +} diff --git a/pisugar-poweroff/Cargo.toml b/pisugar-poweroff/Cargo.toml index 853272a..3c843ad 100644 --- a/pisugar-poweroff/Cargo.toml +++ b/pisugar-poweroff/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pisugar-poweroff" -version = "1.7.8" +version = "2.0.0" authors = ["PiSugar"] edition = "2018" description = "PiSugar Poweroff" diff --git a/pisugar-poweroff/src/main.rs b/pisugar-poweroff/src/main.rs index ae75798..da3e65d 100644 --- a/pisugar-poweroff/src/main.rs +++ b/pisugar-poweroff/src/main.rs @@ -5,7 +5,6 @@ use std::time::Duration; use clap::{Arg, Command}; use env_logger::Env; use pisugar_core::{Model, PiSugarConfig, PiSugarCore, Result}; -use std::convert::TryInto; fn shutdown(config: PiSugarConfig, model: Model, retries: u32) -> Result<()> { for _ in 0..retries { @@ -79,7 +78,7 @@ fn main() { ) .get_matches(); - let model: Model = matches.value_of("model").unwrap().try_into().unwrap(); + let model: Model = matches.value_of("model").unwrap().parse().unwrap(); let log_level = matches.value_of("log").unwrap(); let countdown: u64 = matches.value_of("countdown").unwrap().parse().unwrap(); let retries: u32 = matches.value_of("retries").unwrap().parse().unwrap(); diff --git a/pisugar-programmer/Cargo.toml b/pisugar-programmer/Cargo.toml index 500d332..309417e 100644 --- a/pisugar-programmer/Cargo.toml +++ b/pisugar-programmer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pisugar-programmer" -version = "1.7.8" +version = "2.0.0" authors = ["PiSugar"] edition = "2018" description = "PiSugar Firmware Programmer (for PiSugar 3)" diff --git a/pisugar-server/Cargo.toml b/pisugar-server/Cargo.toml index 4195ddb..ca2ff6c 100644 --- a/pisugar-server/Cargo.toml +++ b/pisugar-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pisugar-server" -version = "1.7.8" +version = "2.0.0" authors = ["PiSugar"] edition = "2018" description = "PiSugar Power Manager" @@ -16,7 +16,7 @@ syslog = "6" rand = "0.8" base64 = "0.13" libc = "0.2" -clap = "3" +clap = { version = "4", features = ["derive"] } bytes = "1" ctrlc = "3.1.4" lazy_static = "1.4" @@ -34,10 +34,15 @@ hyper-tungstenite = "0.8" websocket-codec = "0.5" digest_auth = "0.3.0" pisugar-core = { path = "../pisugar-core" } +shlex = "1.3.0" +enum-variants-strings = "0.3.0" [[bin]] name = "pisugar-server" +[dev-dependencies] +rstest = "0.23.0" + [package.metadata.deb] license-file = ["../LICENSE", "0"] copyright = "2020, PiSugar team" diff --git a/pisugar-server/src/cmds.rs b/pisugar-server/src/cmds.rs new file mode 100644 index 0000000..f046337 --- /dev/null +++ b/pisugar-server/src/cmds.rs @@ -0,0 +1,207 @@ +use std::str::FromStr; + +use anyhow::anyhow; +use anyhow::Error as AnyError; +use chrono::{DateTime, FixedOffset}; +use clap::{builder::PossibleValue, ArgAction, Args, Parser, Subcommand}; +use enum_variants_strings::EnumVariantsStrings; + +#[derive(Debug, Parser, PartialEq)] +#[command(multicall = true)] +#[clap(rename_all = "snake_case")] +pub enum Cmds { + #[command(subcommand)] + Get(GetCmds), + + SetBatteryChargingRange { + #[arg(value_delimiter = ',')] + range: Vec, + }, + + SetBatteryInputProtect(BoolArg), + + SetBatteryOutput(BoolArg), + + SetFullChargeDuration { + seconds: u64, + }, + + SetAllowCharging(BoolArg), + + RtcClearFlag, + + RtcPi2rtc, + + RtcRtc2pi, + + RtcWeb, + + RtcAlarmSet { + datetime: DateTime, + weekdays: u8, + }, + + RtcAlarmDisable, + + RtcAdjustPpm { + ppm: f64, + }, + + SetSafeShutdownLevel { + level: f64, + }, + + SetSafeShutdownDelay { + delay: f64, + }, + + RtcTestWake, + + SetButtonEnable { + mode: ButtonMode, + enable: bool, + }, + + SetButtonShell { + mode: ButtonMode, + shell: Vec, + }, + + SetAutoPowerOn(BoolArg), + + SetAuth { + username: Option, + password: Option, + }, + + ForceShutdown, + + SetAntiMistouch(BoolArg), + + SetSoftPoweroff(BoolArg), + + SetSoftPoweroffShell { + shell: Vec, + }, + + SetInputProtect(BoolArg), +} + +impl FromStr for Cmds { + type Err = AnyError; + + fn from_str(s: &str) -> Result { + let mut args = shlex::split(s).ok_or(anyhow!("Invalid args"))?; + if args.as_slice()[1..].iter().any(|a| a.starts_with("-")) { + args.insert(1, "--".to_string()); + } + Ok(Self::try_parse_from(args)?) + } +} + +#[derive(Debug, Subcommand, PartialEq, Eq)] +#[clap(rename_all = "snake_case")] +pub enum GetCmds { + Version, + Model, + FirmwareVersion, + Battery, + BatteryI, + BatteryV, + BatteryLedAmount, + BatteryPowerPlugged, + BatteryAllowCharging, + BatteryChargingRange, + BatteryCharging, + BatteryInputProtectEnabled, + BatteryOutputEnabled, + FullChargeDuration, + SystemTime, + RtcTime, + RtcTimeList, + RtcAlarmFlag, + RtcAlarmTime, + RtcAlarmTimeList, + RtcAlarmEnabled, + RtcAdjustPpm, + AlarmRepeat, + SafeShutdownLevel, + SafeShutdownDelay, + ButtonEnable { mode: ButtonMode }, + ButtonShell { mode: ButtonMode }, + AutoPowerOn, + AuthUsername, + AntiMistouch, + SoftPoweroff, + SoftPoweroffShell, + Temperature, + InputProtect, +} + +#[derive(Debug, EnumVariantsStrings, PartialEq, Eq, Clone, Copy)] +pub enum ButtonMode { + Single, + Double, + Long, +} + +impl clap::ValueEnum for ButtonMode { + fn value_variants<'a>() -> &'a [Self] { + &[Self::Single, Self::Double, Self::Long] + } + + fn to_possible_value(&self) -> Option { + Some(PossibleValue::new(self.to_str())) + } +} + +#[derive(Debug, Args, PartialEq)] +pub struct BatteryRangeArgs { + pub min: f32, + pub max: f32, +} + +#[derive(Debug, Args, PartialEq)] +pub struct BoolArg { + #[arg(action = ArgAction::Set)] + pub enable: bool, +} + +#[cfg(test)] +mod tests { + + use anyhow::Result; + use rstest::rstest; + + use super::*; + + #[rstest] + #[case("get version", Cmds::Get(GetCmds::Version))] + #[case("get model", Cmds::Get(GetCmds::Model))] + #[case("get firmware_version", Cmds::Get(GetCmds::FirmwareVersion))] + #[case("get button_enable single", Cmds::Get(GetCmds::ButtonEnable{ mode: ButtonMode::Single }))] + #[case("get button_shell long", Cmds::Get(GetCmds::ButtonShell { mode: ButtonMode::Long } ))] + #[case("set_battery_charging_range 30.0,80.0", Cmds::SetBatteryChargingRange{ range: vec![30.0, 80.0]})] + #[case("set_battery_output true", Cmds::SetBatteryOutput(BoolArg{ enable: true }))] + #[case("set_battery_output false", Cmds::SetBatteryOutput(BoolArg { enable: false }))] + #[case("set_button_shell single echo hello", Cmds::SetButtonShell { mode: ButtonMode::Single, shell: vec!["echo".to_string(), "hello".to_string()] })] + #[case("set_soft_poweroff_shell shutdown -a", Cmds::SetSoftPoweroffShell { shell: vec!["shutdown".to_string(), "-a".to_string()] })] + #[case("set_soft_poweroff_shell bash \"shutdown -a\"", Cmds::SetSoftPoweroffShell { shell: vec!["bash".to_string(), "shutdown -a".to_string()] })] + fn test_cmds(#[case] repl: &str, #[case] cmd: Cmds) -> Result<()> { + assert!(cmd == Cmds::from_str(repl)?); + Ok(()) + } + + #[rstest] + fn test_help() { + let h = Cmds::from_str("help"); + assert!(format!("{:?}", h).contains("help")); + } + + #[rstest] + fn test_help_get() { + let h = Cmds::from_str("help get"); + println!("{:?}", h); + assert!(format!("{:?}", h).contains("version")); + } +} diff --git a/pisugar-server/src/main.rs b/pisugar-server/src/main.rs index 4ed22e2..db93247 100644 --- a/pisugar-server/src/main.rs +++ b/pisugar-server/src/main.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; use std::env; use std::fs::remove_file; use std::io; @@ -10,9 +10,12 @@ use std::sync::{Arc, Mutex}; use std::thread::sleep; use std::time::{Instant, SystemTime}; +use std::str::FromStr; + use anyhow::{anyhow, bail, Result}; use chrono::prelude::*; -use clap::{Arg, Command}; +use clap::{Arg, ArgAction, Command}; +use cmds::{BoolArg, ButtonMode, Cmds}; use digest_auth::{AuthContext, AuthorizationHeader, Charset, Qop, WwwAuthenticateHeader}; use env_logger::Env; use futures::prelude::*; @@ -33,9 +36,12 @@ use tokio::time::Duration; use tokio_util::codec::{BytesCodec, Framed}; use pisugar_core::{ - execute_shell, get_ntp_datetime, notify_shutdown_soon, sys_write_time, Error, Model, PiSugarConfig, PiSugarCore, RTCRawTime, I2C_READ_INTERVAL + execute_shell, get_ntp_datetime, notify_shutdown_soon, sys_write_time, Error, Model, PiSugarConfig, PiSugarCore, + RTCRawTime, I2C_READ_INTERVAL, }; +mod cmds; + /// Websocket info const WS_JSON: &str = "_ws.json"; @@ -74,445 +80,246 @@ fn handle_request(core: Arc>, req: &str) -> String { log::debug!("Request: {}", req); } + if req.starts_with("help") { + let help = Cmds::from_str(req).expect_err(""); + return help.to_string(); + } + + let cmd = match Cmds::from_str(req) { + Ok(cmd) => cmd, + Err(e) => { + log::warn!("Invalid cmd: {}", e); + return err; + } + }; + let core_cloned = core.clone(); - if let Ok(mut core) = core.lock() { - if !parts.is_empty() { - match parts[0].as_str() { - "get" => { - if parts.len() > 1 { - let resp = match parts[1].as_str() { - "version" => Ok(env!("CARGO_PKG_VERSION").to_string()), - "model" => Ok(core.model()), - "firmware_version" => core.version(), - "battery" => core.level().map(|l| l.to_string()), - "battery_v" => core.voltage_avg().map(|v| v.to_string()), - "battery_i" => core.intensity_avg().map(|i| i.to_string()), - "battery_led_amount" => core.led_amount().map(|n| n.to_string()), - "battery_power_plugged" => core.power_plugged().map(|p| p.to_string()), - "battery_allow_charging" => core.allow_charging().map(|a| a.to_string()), - "battery_charging_range" => core - .charging_range() - .map(|r| r.map_or("".to_string(), |r| format!("{},{}", r.0, r.1))), - "battery_charging" => core.charging().map(|c| c.to_string()), - "battery_input_protect_enabled" => core.input_protected().map(|c| c.to_string()), - "battery_output_enabled" => core.output_enabled().map(|o| o.to_string()), - "full_charge_duration" => Ok(core - .config() - .full_charge_duration - .map_or("".to_string(), |d| d.to_string())), - "system_time" => Ok(Local::now().to_rfc3339_opts(SecondsFormat::Millis, false)), - "rtc_time" => core - .read_time() - .map(|t| t.to_rfc3339_opts(SecondsFormat::Millis, false)), - "rtc_time_list" => core.read_raw_time().map(|r| r.to_string()), - "rtc_alarm_flag" => core.read_alarm_flag().map(|f| f.to_string()), - "rtc_alarm_time" => { - let t = core - .read_alarm_time() - .and_then(|r| r.try_into().map_err(|_| Error::Other("Invalid".to_string()))); - t.map(|t: DateTime| { - t.with_timezone(Local::now().offset()) - .to_rfc3339_opts(SecondsFormat::Millis, false) - }) - } - "rtc_alarm_time_list" => core.read_alarm_time().map(|r| r.to_string()), - "rtc_alarm_enabled" => core.read_alarm_enabled().map(|e| e.to_string()), - "rtc_adjust_ppm" => Ok(core.config().rtc_adj_ppm.unwrap_or_default().to_string()), - "alarm_repeat" => Ok(core.config().auto_wake_repeat.to_string()), - "safe_shutdown_level" => Ok(core.config().auto_shutdown_level.unwrap_or(0.0).to_string()), - "safe_shutdown_delay" => Ok(core.config().auto_shutdown_delay.unwrap_or(0.0).to_string()), - "button_enable" => { - if parts.len() > 2 { - let enable = match parts[2].as_str() { - "single" => core.config().single_tap_enable, - "double" => core.config().double_tap_enable, - "long" => core.config().long_tap_enable, - _ => { - log::error!("{} {}: unknown tap type", parts[0], parts[1]); - return err; - } - }; - Ok(format!("{} {}", parts[2], enable)) - } else { - return err; - } - } - "button_shell" => { - if parts.len() > 2 { - let shell = match parts[2].as_str() { - "single" => core.config().single_tap_shell.as_str(), - "double" => core.config().double_tap_shell.as_str(), - "long" => core.config().long_tap_shell.as_str(), - _ => { - log::error!("{} {}: unknown tap type", parts[0], parts[1]); - return err; - } - }; - Ok(format!("{} {}", parts[2], shell)) - } else { - return err; - } - } - "auto_power_on" => Ok(core.config().auto_power_on.unwrap_or(false).to_string()), - "auth_username" => { - let username = core.config().auth_user.clone().unwrap_or_default(); - Ok(username) - } - "anti_mistouch" => Ok(core.config().anti_mistouch.unwrap_or(true).to_string()), - "soft_poweroff" => Ok(core.config().soft_poweroff.unwrap_or(false).to_string()), - "soft_poweroff_shell" => Ok(core.config().soft_poweroff_shell.clone().unwrap_or_default()), - "temperature" => core.get_temperature().map(|x| x.to_string()), - "input_protect" => core.input_protected().map(|x| x.to_string()), - _ => return err, - }; - - return match resp { - Ok(s) => format!("{}: {}\n", parts[1], s), - Err(e) => { - log::error!("{}", e); - err - } - }; - }; - } - "set_battery_charging_range" => { - let mut charging_range = None; - if parts.len() > 1 { - let range: Vec = parts[1].split(',').map(|s| s.to_string()).collect(); - if range.len() == 2 { - if let (Ok(begin), Ok(end)) = (range[0].parse::(), range[1].parse::()) { - charging_range = Some((begin, end)); - } - } - } - return match core.set_charging_range(charging_range) { - Ok(_) => format!("{}: done\n", parts[0]), - Err(e) => { - log::error!("{}", e); - err - } - }; - } - "set_battery_input_protect" => { - if parts.len() > 1 { - if let Ok(enable) = parts[1].parse::() { - if core.toggle_input_protected(enable).is_ok() { - return format!("{}: done\n", parts[0]); - } - } - } - return err; - } - "set_battery_output" => { - if parts.len() > 1 { - if let Ok(enable) = parts[1].parse::() { - if core.toggle_output_enabled(enable).is_ok() { - return format!("{}: done\n", parts[0]); - } - } - } - return err; - } - "set_full_charge_duration" => { - if parts.len() > 1 { - if let Ok(d) = parts[1].parse::() { - core.config_mut().full_charge_duration = Some(d); - if core.save_config().is_ok() { - return format!("{}: done\n", parts[0]); - } - } - } - return err; - } - "set_allow_charging" => { - if parts.len() > 1 { - if let Ok(enable) = parts[1].parse::() { - if core.toggle_allow_charging(enable).is_ok() { - return format!("{}: done\n", parts[0]); - } - } - } - return err; - } - "rtc_clear_flag" => { - return match core.clear_alarm_flag() { - Ok(_) => format!("{}: done\n", parts[0]), - Err(e) => { - log::error!("{}", e); - err - } - }; - } - "rtc_pi2rtc" => { - let now = Local::now(); - return match core.write_time(now) { - Ok(_) => format!("{}: done\n", parts[0]), - Err(e) => { - log::error!("{}", e); - err - } - }; - } - "rtc_rtc2pi" => { - return match core.read_time() { - Ok(t) => { - sys_write_time(t); - format!("{}: done\n", parts[0]) - } - Err(e) => { - log::error!("{}", e); - err - } - }; - } - "rtc_web" => { - tokio::spawn(async move { - match get_ntp_datetime().await { - Ok(ntp_datetime) => { - sys_write_time(ntp_datetime.into()); - if let Ok(core) = core_cloned.lock() { - let _ = core.write_time(ntp_datetime.into()); - } - } - Err(e) => log::warn!("Sync NTP time error: {}", e) - } - }); - return format!("{}: done\n", parts[0]); - } - "rtc_alarm_set" => { - // rtc_alarm_set weekday_repeat - if parts.len() >= 3 { - if let Ok(datetime) = parts[1].parse::>() { - let datetime: DateTime = datetime.into(); - let sd3078_time: RTCRawTime = datetime.into(); - if let Ok(weekday_repeat) = parts[2].parse::() { - match core.write_alarm(sd3078_time, weekday_repeat) { - Ok(_) => { - core.config_mut().auto_wake_repeat = weekday_repeat; - core.config_mut().auto_wake_time = Some(datetime); - if let Err(e) = core.save_config() { - log::warn!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - Err(e) => log::error!("{}", e), - } - } - } - } - return err; - } - "rtc_alarm_disable" => { - return match core.disable_alarm() { - Ok(_) => { - core.config_mut().auto_wake_time = None; - if let Err(e) = core.save_config() { - log::warn!("{}", e); - } - format!("{}: done\n", parts[0]) - } - Err(_) => err, - }; - } - "rtc_adjust_ppm" => { - if !parts.is_empty() { - if let Ok(ppm) = parts[1].parse::() { - let ppm = if ppm > 500.0 { 500.0 } else { ppm }; - let ppm = if ppm < -500.0 { -500.0 } else { ppm }; - return match core.write_rtc_adjust_ppm(ppm) { - Ok(()) => { - core.config_mut().rtc_adj_ppm = Some(ppm); - if let Err(e) = core.save_config() { - log::warn!("{}", e); - } - format!("{}: done\n", parts[0]) - } - Err(e) => { - log::error!("{}", e); - err - } - }; - } - } - } - "set_safe_shutdown_level" => { - if !parts.is_empty() { - if let Ok(level) = parts[1].parse::() { - // level between <30,level < 0 means do not shutdown - let level = if level > 30.0 { 30.0 } else { level }; - core.config_mut().auto_shutdown_level = Some(level); - if let Err(e) = core.save_config() { - log::error!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - } - return err; - } - "set_safe_shutdown_delay" => { - if !parts.is_empty() { - if let Ok(delay) = parts[1].parse::() { - // delay between 0-30 - let delay = if delay < 0.0 { 0.0 } else { delay }; - let delay = if delay > 120.0 { 120.0 } else { delay }; - core.config_mut().auto_shutdown_delay = Some(delay); - if let Err(e) = core.save_config() { - log::error!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - } - return err; - } - "rtc_test_wake" => { - return match core.test_wake() { - Ok(_) => format!("{}: wakeup after 1 min 30 sec\n", parts[0]), - Err(e) => { - log::error!("{}", e); - err - } - }; - } - "set_button_enable" => { - if parts.len() > 2 { - let enable = parts[2].as_str().ne("0"); - match parts[1].as_str() { - "single" => core.config_mut().single_tap_enable = enable, - "double" => core.config_mut().double_tap_enable = enable, - "long" => core.config_mut().long_tap_enable = enable, - _ => { - return err; - } - } - if let Err(e) = core.save_config() { - log::error!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - return err; - } - "set_button_shell" => { - let action = if parts.len() > 1 { parts[1].as_str() } else { "" }; - let cmd = if parts.len() > 2 { - parts[2..].join(" ") - } else { - "".to_string() - }; - match action { - "single" => core.config_mut().single_tap_shell = cmd, - "double" => core.config_mut().double_tap_shell = cmd, - "long" => core.config_mut().long_tap_shell = cmd, - _ => { - return err; - } - } - if let Err(e) = core.save_config() { - log::error!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - "set_auto_power_on" => { - if parts.len() > 1 { - if let Ok(auto_power_on) = parts[1].parse::() { - if let Err(e) = core.toggle_auto_power_on(auto_power_on) { - log::error!("{}", e); - } - return format!("{}: done\n", parts[0]); - } - } - return err; - } - "set_auth" => { - if parts.len() > 2 { - let username = parts[1].as_str(); - let password = parts[2].as_str(); - core.config_mut().auth_user = Some(username.to_string()); - core.config_mut().auth_password = Some(password.to_string()); - } else { - core.config_mut().auth_user = None; - core.config_mut().auth_password = None; - } - if let Err(e) = core.save_config() { - log::error!("{}", e); - return err; - } - return format!("{}: done\n", parts[0]); - } - "force_shutdown" => { - match core.force_shutdown() { - Ok(_) => { - return format!("{}: done\n", parts[0]); - } - Err(e) => { - log::error!("{}", e); - } - } - return err; - } - "set_anti_mistouch" => { - if parts.len() > 1 { - if let Ok(anti_mistouch) = parts[1].parse::() { - match core.toggle_anti_mistouch(anti_mistouch) { - Ok(_) => { - return format!("{}: done\n", parts[0]); - } - Err(e) => { - log::error!("{}", e); - } - } - } - } - return err; - } - "set_soft_poweroff" => { - if parts.len() > 1 { - if let Ok(soft_poweroff) = parts[1].parse::() { - match core.toggle_soft_poweroff(soft_poweroff) { - Ok(_) => { - return format!("{}: done\n", parts[0]); - } - Err(e) => { - log::error!("{}", e); - } - } + let mut core = core_cloned.lock().unwrap(); + let r = match &cmd { + Cmds::Get(get_cmd) => match get_cmd { + cmds::GetCmds::Version => Ok(env!("CARGO_PKG_VERSION").to_string()), + cmds::GetCmds::Model => Ok(core.model()), + cmds::GetCmds::FirmwareVersion => core.version(), + cmds::GetCmds::Battery => core.level().map(|l| l.to_string()), + cmds::GetCmds::BatteryI => core.intensity_avg().map(|i| i.to_string()), + cmds::GetCmds::BatteryV => core.voltage_avg().map(|v| v.to_string()), + cmds::GetCmds::BatteryLedAmount => core.led_amount().map(|n| n.to_string()), + cmds::GetCmds::BatteryPowerPlugged => core.power_plugged().map(|p| p.to_string()), + cmds::GetCmds::BatteryAllowCharging => core.allow_charging().map(|a| a.to_string()), + cmds::GetCmds::BatteryChargingRange => core + .charging_range() + .map(|r| r.map_or("".to_string(), |r| format!("{},{}", r.0, r.1))), + cmds::GetCmds::BatteryCharging => core.charging().map(|c| c.to_string()), + cmds::GetCmds::BatteryInputProtectEnabled => core.input_protected().map(|c| c.to_string()), + cmds::GetCmds::BatteryOutputEnabled => core.output_enabled().map(|o| o.to_string()), + cmds::GetCmds::FullChargeDuration => Ok(core + .config() + .full_charge_duration + .map_or("".to_string(), |d| d.to_string())), + cmds::GetCmds::SystemTime => Ok(Local::now().to_rfc3339_opts(SecondsFormat::Millis, false)), + cmds::GetCmds::RtcTime => core + .read_time() + .map(|t| t.to_rfc3339_opts(SecondsFormat::Millis, false)), + cmds::GetCmds::RtcTimeList => core.read_raw_time().map(|r| r.to_string()), + cmds::GetCmds::RtcAlarmFlag => core.read_alarm_flag().map(|f| f.to_string()), + cmds::GetCmds::RtcAlarmTime => { + let t = core + .read_alarm_time() + .and_then(|r| r.try_into().map_err(|_| Error::Other("Invalid".to_string()))); + t.map(|t: DateTime| { + t.with_timezone(Local::now().offset()) + .to_rfc3339_opts(SecondsFormat::Millis, false) + }) + } + cmds::GetCmds::RtcAlarmTimeList => core.read_alarm_time().map(|r| r.to_string()), + cmds::GetCmds::RtcAlarmEnabled => core.read_alarm_enabled().map(|e| e.to_string()), + cmds::GetCmds::RtcAdjustPpm => Ok(core.config().rtc_adj_ppm.unwrap_or_default().to_string()), + cmds::GetCmds::AlarmRepeat => Ok(core.config().auto_wake_repeat.to_string()), + cmds::GetCmds::SafeShutdownLevel => Ok(core.config().auto_shutdown_level.unwrap_or(0.0).to_string()), + cmds::GetCmds::SafeShutdownDelay => Ok(core.config().auto_shutdown_delay.unwrap_or(0.0).to_string()), + cmds::GetCmds::ButtonEnable { mode } => Ok(match mode { + cmds::ButtonMode::Single => core.config().single_tap_enable, + cmds::ButtonMode::Double => core.config().double_tap_enable, + cmds::ButtonMode::Long => core.config().long_tap_enable, + }) + .map(|b| b.to_string()), + cmds::GetCmds::ButtonShell { mode } => Ok(match mode { + cmds::ButtonMode::Single => core.config().single_tap_shell.clone(), + cmds::ButtonMode::Double => core.config().double_tap_shell.clone(), + cmds::ButtonMode::Long => core.config().long_tap_shell.clone(), + }), + cmds::GetCmds::AutoPowerOn => Ok(core.config().auto_power_on.unwrap_or(false).to_string()), + cmds::GetCmds::AuthUsername => Ok(core.config().auth_user.clone().unwrap_or_default()), + cmds::GetCmds::AntiMistouch => Ok(core.config().anti_mistouch.unwrap_or(true).to_string()), + cmds::GetCmds::SoftPoweroff => Ok(core.config().soft_poweroff.unwrap_or(false).to_string()), + cmds::GetCmds::SoftPoweroffShell => Ok(core.config().soft_poweroff_shell.clone().unwrap_or_default()), + cmds::GetCmds::Temperature => core.get_temperature().map(|x| x.to_string()), + cmds::GetCmds::InputProtect => core.input_protected().map(|x| x.to_string()), + }, + Cmds::SetBatteryChargingRange { range } => { + let charging_range = if range.len() == 2 { + Some((range[0], range[1])) + } else { + None + }; + core.set_charging_range(charging_range) + .map(|_| format!("{}: done\n", parts[0])) + } + Cmds::SetBatteryInputProtect(BoolArg { enable }) => core + .toggle_input_protected(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::SetBatteryOutput(BoolArg { enable }) => core + .toggle_output_enabled(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::SetFullChargeDuration { seconds } => { + core.config_mut().full_charge_duration = Some(*seconds); + core.save_config().map(|_| format!("{}: done\n", parts[0])) + } + Cmds::SetAllowCharging(BoolArg { enable }) => core + .toggle_allow_charging(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::RtcClearFlag => core.clear_alarm_flag().map(|_| format!("{}: done\n", parts[0])), + Cmds::RtcPi2rtc => core.write_time(Local::now()).map(|_| format!("{}: done\n", parts[0])), + Cmds::RtcRtc2pi => core.read_time().map(|t| { + sys_write_time(t); + format!("{}: done\n", parts[0]) + }), + Cmds::RtcWeb => { + let core_cloned = core_cloned.clone(); + tokio::spawn(async move { + match get_ntp_datetime().await { + Ok(ntp_datetime) => { + sys_write_time(ntp_datetime.into()); + if let Ok(core) = core_cloned.lock() { + let _ = core.write_time(ntp_datetime.into()); } - return err; } + Err(e) => log::warn!("Sync NTP time error: {}", e), } - "set_soft_poweroff_shell" => { - if parts.len() > 1 { - let script = parts[1..].join(" "); - core.config_mut().soft_poweroff_shell = Some(script); - } else { - core.config_mut().soft_poweroff_shell = None; - } - if let Err(e) = core.save_config() { - log::error!("{}", e); - return err; - } - return format!("{}: done\n", parts[0]); + }); + Ok(format!("{}: done\n", parts[0])) + } + Cmds::RtcAlarmSet { datetime, weekdays } => { + let datetime: DateTime = datetime.clone().into(); + let sd3078_time: RTCRawTime = datetime.clone().into(); + core.write_alarm(sd3078_time, *weekdays).map(|_| { + core.config_mut().auto_wake_repeat = *weekdays; + core.config_mut().auto_wake_time = Some(datetime.clone()); + if let Err(e) = core.save_config() { + log::warn!("{}", e); } - "set_input_protect" => { - if parts.len() > 1 { - if let Ok(protect) = parts[1].parse::() { - match core.toggle_input_protected(protect) { - Ok(_) => { - return format!("{}: done\n", parts[0]); - } - Err(e) => { - log::error!("{}", e); - } - } - } - return err; - } + format!("{}: done\n", parts[0]) + }) + } + Cmds::RtcAlarmDisable => core.disable_alarm().map(|_| { + core.config_mut().auto_wake_time = None; + if let Err(e) = core.save_config() { + log::warn!("{}", e); + } + format!("{}: done\n", parts[0]) + }), + Cmds::RtcAdjustPpm { ppm } => { + let ppm = if *ppm > 500.0 { 500.0 } else { *ppm }; + let ppm = if ppm < -500.0 { -500.0 } else { ppm }; + core.write_rtc_adjust_ppm(ppm).map(|_| { + core.config_mut().rtc_adj_ppm = Some(ppm); + if let Err(e) = core.save_config() { + log::warn!("{}", e); } - _ => return err, + format!("{}: done\n", parts[0]) + }) + } + Cmds::SetSafeShutdownLevel { level } => { + // level between <30,level < 0 means do not shutdown + let level = if *level > 30.0 { 30.0 } else { *level }; + core.config_mut().auto_shutdown_level = Some(level); + if let Err(e) = core.save_config() { + log::error!("{}", e); } - }; - } + Ok(format!("{}: done\n", parts[0])) + } + Cmds::SetSafeShutdownDelay { delay } => { + // delay between 0-30 + let delay = if *delay < 0.0 { 0.0 } else { *delay }; + let delay = if delay > 120.0 { 120.0 } else { delay }; + core.config_mut().auto_shutdown_delay = Some(delay); + if let Err(e) = core.save_config() { + log::error!("{}", e); + } + Ok(format!("{}: done\n", parts[0])) + } + Cmds::RtcTestWake => core + .test_wake() + .map(|_| format!("{}: wakeup after 1 min 30 sec\n", parts[0])), + Cmds::SetButtonEnable { mode, enable } => { + match *mode { + ButtonMode::Single => core.config_mut().single_tap_enable = *enable, + ButtonMode::Double => core.config_mut().double_tap_enable = *enable, + ButtonMode::Long => core.config_mut().long_tap_enable = *enable, + } + if let Err(e) = core.save_config() { + log::error!("{}", e); + } + Ok(format!("{}: done\n", parts[0])) + } + Cmds::SetButtonShell { mode, shell } => { + let cmd = shell.join(" "); + match mode { + ButtonMode::Single => core.config_mut().single_tap_shell = cmd, + ButtonMode::Double => core.config_mut().double_tap_shell = cmd, + ButtonMode::Long => core.config_mut().long_tap_shell = cmd, + } + if let Err(e) = core.save_config() { + log::error!("{}", e); + } + Ok(format!("{}: done\n", parts[0])) + } + Cmds::SetAutoPowerOn(BoolArg { enable }) => core + .toggle_auto_power_on(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::SetAuth { username, password } => { + if let (Some(username), Some(password)) = (username, password) { + core.config_mut().auth_user = Some(username.to_string()); + core.config_mut().auth_password = Some(password.to_string()); + } else { + core.config_mut().auth_user = None; + core.config_mut().auth_password = None; + } + core.save_config().map(|_| format!("{}: done\n", parts[0])) + } + Cmds::ForceShutdown => core.force_shutdown().map(|_| format!("{}: done\n", parts[0])), + Cmds::SetAntiMistouch(BoolArg { enable }) => core + .toggle_anti_mistouch(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::SetSoftPoweroff(BoolArg { enable }) => core + .toggle_soft_poweroff(*enable) + .map(|_| format!("{}: done\n", parts[0])), + Cmds::SetSoftPoweroffShell { shell } => { + let script = shell.join(" "); + core.config_mut().soft_poweroff_shell = if script.len() > 0 { + Some(script.to_string()) + } else { + None + }; + core.save_config().map(|_| format!("{}: done\n", parts[0])) + } + Cmds::SetInputProtect(BoolArg { enable }) => core + .toggle_input_protected(*enable) + .map(|_| format!("{}: done\n", parts[0])), + }; - err + match r { + Ok(mut r) => { + if !r.ends_with("\n") { + r += "\n"; + } + r + } + Err(e) => { + log::warn!("{}", e); + err + } + } } async fn _handle_stream(core: Arc>, stream: T, mut event_rx: EventRx) -> io::Result<()> @@ -996,13 +803,6 @@ fn init_logging(debug: bool, syslog: bool) { #[tokio::main] async fn main() -> std::io::Result<()> { - let models = vec![ - Model::PiSugar_3.to_string(), - Model::PiSugar_2_Pro.to_string(), - Model::PiSugar_2_2LEDs.to_string(), - Model::PiSugar_2_4LEDs.to_string(), - ]; - let matches = Command::new(env!("CARGO_PKG_NAME")) .version(env!("CARGO_PKG_VERSION")) .author(env!("CARGO_PKG_AUTHORS")) @@ -1055,61 +855,47 @@ async fn main() -> std::io::Result<()> { Arg::new("debug") .short('d') .long("debug") - .takes_value(false) + .action(ArgAction::SetTrue) .help("Debug output"), ) .arg( Arg::new("syslog") .short('s') .long("syslog") - .takes_value(false) + .action(ArgAction::SetTrue) .help("Log to syslog"), ) - .arg( - Arg::new("led") - .long("led") - .takes_value(true) - .default_value("4") - .help("2-led or 4-led"), - ) + .arg(Arg::new("led").long("led").default_value("4").help("2-led or 4-led")) .arg( Arg::new("model") .long("model") - .takes_value(true) .required(true) - .help(format!("{:?}", models).as_str()) - .validator(move |x| { - if models.contains(&x.to_string()) { - Ok(()) - } else { - Err("Invalid model".to_string()) - } - }), + .value_parser(clap::value_parser!(Model)), ) .get_matches(); // init logging - let debug = matches.is_present("debug"); - let syslog = matches.is_present("syslog"); + let debug = matches.get_flag("debug"); + let syslog = matches.get_flag("syslog"); init_logging(debug, syslog); // model - let m = matches.value_of("model").unwrap(); - let model = Model::try_from(m).unwrap_or_else(|_| panic!("Unknown PiSugar model: {}", m)); - log::debug!("Running with model: {}({})", model, m); + let model = matches.get_one::("model").unwrap(); + log::debug!("Running with model: {}", model); // core let core; loop { - let c = if matches.is_present("config") { - PiSugarCore::new_with_path(matches.value_of("config").unwrap(), true, model) - } else { - let config = PiSugarConfig::default(); - PiSugarCore::new(config, model) - }; + let c = matches + .get_one::("config") + .map(|c| PiSugarCore::new_with_path(c, true, model.clone())) + .unwrap_or_else(|| { + let config = PiSugarConfig::default(); + PiSugarCore::new(config, model.clone()) + }); match c { - Ok(_) => { - core = Arc::new(Mutex::new(c.unwrap())); + Ok(c) => { + core = Arc::new(Mutex::new(c)); break; } Err(e) => log::error!("PiSugar init failed: {}", e), @@ -1121,16 +907,15 @@ async fn main() -> std::io::Result<()> { let (event_tx, event_rx) = tokio::sync::watch::channel("".to_string()); // CTRL+C signal handling - let uds = matches.value_of("uds").map(|x| x.to_string()); - let web_dir = matches.value_of("web").map(|x| x.to_string()); + let uds = matches.get_one::("uds").cloned(); + let web_dir = matches.get_one::("web").cloned(); ctrlc::set_handler(move || { clean_up(uds.clone(), web_dir.clone()); }) .expect("Failed to setup ctrl+c"); // tcp - if matches.is_present("tcp") { - let tcp_addr = matches.value_of("tcp").unwrap().to_string(); + if let Some(tcp_addr) = matches.get_one::("tcp").cloned() { let core_cloned = core.clone(); let event_rx_cloned = event_rx.clone(); tokio::spawn(async move { @@ -1157,8 +942,7 @@ async fn main() -> std::io::Result<()> { } // ws - if matches.is_present("ws") { - let ws_addr = matches.value_of("ws").unwrap().to_string(); + if let Some(ws_addr) = matches.get_one::("ws").cloned() { let core_cloned = core.clone(); let event_rx_cloned = event_rx.clone(); tokio::spawn(async move { @@ -1185,8 +969,7 @@ async fn main() -> std::io::Result<()> { } // uds - if matches.is_present("uds") { - let uds_addr = matches.value_of("uds").unwrap().to_string(); + if let Some(uds_addr) = matches.get_one::("uds").cloned() { let core_cloned = core.clone(); let event_rx_cloned = event_rx.clone(); tokio::spawn(async move { @@ -1213,31 +996,32 @@ async fn main() -> std::io::Result<()> { } // http web/ws - if matches.is_present("http") && matches.is_present("web") { + if let (Some(http_addr), Some(web_dir)) = ( + matches.get_one::("http").cloned(), + matches.get_one::("web").cloned(), + ) { let core_cloned = core.clone(); let event_rx = event_rx.clone(); - let web_dir = matches.value_of("web").unwrap().to_string(); - let http_addr = matches.value_of("http").unwrap().parse().unwrap(); let _web_dir_cloned = web_dir.clone(); tokio::spawn(async move { loop { log::info!("Http web server listening..."); - serve_http(http_addr, web_dir.clone(), core_cloned.clone(), event_rx.clone()).await; + serve_http( + http_addr.parse().unwrap(), + web_dir.clone(), + core_cloned.clone(), + event_rx.clone(), + ) + .await; log::info!("Http web server stopped"); tokio::time::sleep(Duration::from_secs(3)).await; } }); // Write a _ws.json file - if matches.is_present("ws") { - let ws_addr = matches.value_of("ws").unwrap(); + if let Some(ws_addr) = matches.get_one::("ws") { let ws_sock_addr: SocketAddr = ws_addr.parse().unwrap(); *WS_ADDR.lock().unwrap() = Some(ws_sock_addr); - // let content = format!("{{\"wsPort\": \"{}\"}}", ws_sock_addr.port()); - // let filename = PathBuf::from(web_dir_cloned).join(WS_JSON); - // let mut file = OpenOptions::default().create(true).write(true).open(filename).await?; - // file.set_len(0).await?; - // file.write_all(content.as_bytes()).await?; } } diff --git a/scripts/aur/PKGBUILD b/scripts/aur/PKGBUILD index 8df89fb..1a410cb 100644 --- a/scripts/aur/PKGBUILD +++ b/scripts/aur/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: PiSugar pkgname=pisugar-bin -pkgver=1.7.8 +pkgver=2.0.0 pkgrel=1 pkgdesc="PiSugar" arch=('arm' 'armv7h' 'aarch64' 'x86_64') diff --git a/scripts/pisugar-power-manager.sh b/scripts/pisugar-power-manager.sh index 013129e..10dc30c 100644 --- a/scripts/pisugar-power-manager.sh +++ b/scripts/pisugar-power-manager.sh @@ -2,7 +2,7 @@ set -e # version -version=1.7.8 +version=2.0.0 # channel: nightly or release channel=release