diff --git a/.env b/.env index 758970d..cb87fe5 100644 --- a/.env +++ b/.env @@ -1,3 +1,6 @@ -ALTEREGO_TELEGRAM_TOKEN= -ALTEREGO_CLIMATE_DSN= -ALTEREGO_HOSTTEMP_CMD= +ALTEREGO_TELEGRAM_TOKEN=170515067:AAElDJ8Sq_oIqo9WaL4DKvUr13nSEIdHCYs +ALTEREGO_CLIMATE_DSN=http://192.168.1.159/ +ALTEREGO_HOSTTEMP_CMD="/opt/vc/bin/vcgencmd measure_temp" +ALTEREGO_DATABASE_URL=sqlite://.testdata/db.sqlite +DATABASE_URL=sqlite://.testdata/db.sqlite +RUST_LOG=debug diff --git a/.gitignore b/.gitignore index ea8c4bf..6f0155e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +.testdata +.vscode diff --git a/Cargo.lock b/Cargo.lock index d153938..7cb0beb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,18 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.6", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.15" @@ -13,30 +26,62 @@ dependencies = [ name = "altherego" version = "0.9.5" dependencies = [ + "anyhow", + "async-trait", + "chrono", "env_logger", "envconfig", "log", - "openssl", + "rand 0.8.5", "reqwest", "serde", "serde_json", + "sqlx", "teloxide", - "teloxide-macros", "tokio", + "tokio-stream", "uuid", ] [[package]] -name = "async-trait" -version = "0.1.41" +name = "anyhow" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" + +[[package]] +name = "aquamarine" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96e14cb2a51c8b45d26a4219981985c7350fc05eacb7b5b2939bceb2ffefdf3e" +dependencies = [ + "itertools 0.9.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + [[package]] name = "atty" version = "0.2.14" @@ -45,7 +90,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -56,15 +101,24 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "base64" -version = "0.12.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] [[package]] name = "bumpalo" @@ -72,12 +126,24 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cc" version = "1.0.62" @@ -96,6 +162,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + [[package]] name = "core-foundation" version = "0.9.1" @@ -113,10 +192,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] -name = "darling" -version = "0.10.2" +name = "cpufeatures" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crossbeam-queue" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -124,9 +257,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -138,9 +271,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -159,10 +292,35 @@ dependencies = [ ] [[package]] -name = "dtoa" -version = "0.4.6" +name = "digest" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dptree" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90018d2d80bd5c16aaa022271b2747ea8d461a21934c79404c26f568b60cca3d" +dependencies = [ + "futures", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encoding_rs" @@ -206,6 +364,34 @@ dependencies = [ "syn", ] +[[package]] +name = "erasable" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f11890ce181d47a64e5d1eb4b6caba0e7bae911a356723740d058a5d0340b7d" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "event-listener" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" + +[[package]] +name = "flume" +version = "0.10.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -237,27 +423,11 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "futures" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -270,9 +440,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -280,15 +450,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -296,18 +466,28 @@ dependencies = [ ] [[package]] -name = "futures-io" -version = "0.3.8" +name = "futures-intrusive" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" +checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -315,24 +495,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" -dependencies = [ - "once_cell", -] +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.8" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -341,13 +518,21 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project 1.0.1", + "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.1.15" @@ -356,16 +541,27 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "h2" -version = "0.2.7" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ - "bytes", + "bytes 1.1.0", "fnv", "futures-core", "futures-sink", @@ -374,9 +570,8 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util", + "tokio-util 0.7.1", "tracing", - "tracing-futures", ] [[package]] @@ -385,6 +580,33 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.17" @@ -394,38 +616,45 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ - "bytes", + "bytes 0.5.6", "fnv", - "itoa", + "itoa 0.4.6", ] [[package]] name = "http-body" -version = "0.3.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ - "bytes", + "bytes 1.1.0", "http", + "pin-project-lite", ] [[package]] name = "httparse" -version = "1.3.4" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "httpdate" -version = "0.3.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "humantime" @@ -435,11 +664,11 @@ checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] name = "hyper" -version = "0.13.9" +version = "0.14.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" dependencies = [ - "bytes", + "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", @@ -448,8 +677,8 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", - "pin-project 1.0.1", + "itoa 1.0.1", + "pin-project-lite", "socket2", "tokio", "tower-service", @@ -459,15 +688,15 @@ dependencies = [ [[package]] name = "hyper-tls" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes", + "bytes 1.1.0", "hyper", "native-tls", "tokio", - "tokio-tls", + "tokio-native-tls", ] [[package]] @@ -494,16 +723,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.9.1", ] [[package]] -name = "iovec" -version = "0.1.4" +name = "instant" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "libc", + "cfg-if 1.0.0", ] [[package]] @@ -512,12 +741,36 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "js-sys" version = "0.3.45" @@ -527,16 +780,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -545,26 +788,37 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] -name = "lockfree" -version = "0.5.1" +name = "libsqlite3-sys" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" dependencies = [ - "owned-alloc", + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", ] [[package]] name = "log" -version = "0.4.11" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] @@ -575,9 +829,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "memchr" -version = "2.3.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" @@ -596,74 +850,28 @@ dependencies = [ ] [[package]] -name = "mio" -version = "0.6.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow 0.2.1", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-named-pipes" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" -dependencies = [ - "log", - "mio", - "miow 0.3.5", - "winapi 0.3.9", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" +name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "miow" -version = "0.3.5" +name = "mio" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" dependencies = [ - "socket2", - "winapi 0.3.9", + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", ] [[package]] name = "native-tls" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcc7939b5edc4e4f86b1b4a04bb1498afaaf871b1a6691838ed06fcb48d3a3f" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ "lazy_static", "libc", @@ -678,14 +886,38 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.35" +name = "never" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", ] [[package]] @@ -700,9 +932,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.5.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "openssl" @@ -724,15 +956,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -[[package]] -name = "openssl-src" -version = "111.13.0+1.1.1i" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045e4dc48af57aad93d665885789b43222ae26f4886494da12d1ed58d309dcb6" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.58" @@ -742,16 +965,63 @@ dependencies = [ "autocfg", "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] [[package]] -name = "owned-alloc" -version = "0.2.0" +name = "parking_lot" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.13", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.13", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" [[package]] name = "percent-encoding" @@ -761,38 +1031,18 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" -version = "0.4.27" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" dependencies = [ - "pin-project-internal 0.4.27", -] - -[[package]] -name = "pin-project" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" -dependencies = [ - "pin-project-internal 1.0.1", + "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.27" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ "proc-macro2", "quote", @@ -801,9 +1051,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.1.11" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -824,31 +1074,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] -name = "proc-macro-hack" -version = "0.5.19" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] [[package]] -name = "proc-macro-nested" -version = "0.1.6" +name = "proc-macro-error-attr" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -859,13 +1121,24 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.15", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -873,7 +1146,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] @@ -882,7 +1165,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.15", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.6", ] [[package]] @@ -891,7 +1183,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rc-box" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0690759eabf094030c2cdabc25ade1395bac02210d920d655053c1d49583fd8" +dependencies = [ + "erasable", ] [[package]] @@ -900,6 +1201,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.4.2" @@ -924,20 +1234,21 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] name = "reqwest" -version = "0.10.8" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e" +checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" dependencies = [ "base64", - "bytes", + "bytes 1.1.0", "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "hyper", @@ -955,7 +1266,8 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-tls", + "tokio-native-tls", + "tokio-util 0.6.9", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -976,9 +1288,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", - "winapi 0.3.9", + "winapi", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "security-framework" version = "2.0.0" @@ -1004,18 +1322,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.117" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -1024,32 +1342,32 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] [[package]] name = "serde_urlencoded" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "dtoa", - "itoa", + "form_urlencoded", + "itoa 1.0.1", + "ryu", "serde", - "url", ] [[package]] name = "serde_with_macros" -version = "1.2.2" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c747a9ab2e833b807f74f6b6141530655010bfa9c9c06d5508bce75c8f8072f" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling", "proc-macro2", @@ -1057,6 +1375,17 @@ dependencies = [ "syn", ] +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook-registry" version = "1.2.2" @@ -1073,28 +1402,146 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] -name = "socket2" -version = "0.3.16" +name = "smallvec" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ - "cfg-if 0.1.10", "libc", - "redox_syscall", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "spin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools 0.10.3", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash", + "atoi", + "bitflags", + "byteorder", + "bytes 1.1.0", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa 1.0.1", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "native-tls", + "once_cell", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "strsim" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.48" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" +checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" dependencies = [ "proc-macro2", "quote", @@ -1102,35 +1549,81 @@ dependencies = [ ] [[package]] -name = "teloxide" -version = "0.3.3" +name = "take_mut" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ccb8b4fbb953413b0887f70dce70fbf28dad1b764793dc66a1d6d854355aa9" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "takecell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e" + +[[package]] +name = "teloxide" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ebffe5b67e1fba9fc14d43572c7a8392cf14edba7584aa8938ae940aed7da7" dependencies = [ - "async-trait", - "bytes", + "aquamarine", + "bytes 1.1.0", "derive_more", + "dptree", "futures", - "lockfree", "log", "mime", - "pin-project 0.4.27", + "pin-project", + "serde", + "serde_json", + "serde_with_macros", + "teloxide-core", + "teloxide-macros", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util 0.6.9", + "url", +] + +[[package]] +name = "teloxide-core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad48e747287e6b77aafc5f1a3d31936738cca72e742c86bbdae85bfff39104b" +dependencies = [ + "bitflags", + "bytes 1.1.0", + "chrono", + "derive_more", + "either", + "futures", + "log", + "mime", + "never", + "once_cell", + "pin-project", + "rc-box", "reqwest", "serde", "serde_json", "serde_with_macros", - "teloxide-macros", + "take_mut", + "takecell", "thiserror", "tokio", - "tokio-util", + "tokio-util 0.6.9", + "url", + "uuid", ] [[package]] name = "teloxide-macros" -version = "0.3.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d8854ad575520d8b37f4a7fdfcd381f48849557f0907b1a7d8163dbd8e952f" +checksum = "4f734a9766b169a6795cac8429bb4184b58689442a80a9d2eb3674e14ecb0364" dependencies = [ + "heck", "proc-macro2", "quote", "syn", @@ -1144,10 +1637,10 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if 0.1.10", "libc", - "rand", - "redox_syscall", + "rand 0.7.3", + "redox_syscall 0.1.57", "remove_dir_all", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1161,18 +1654,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.22" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.22" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -1188,6 +1681,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "tinyvec" version = "1.0.1" @@ -1205,33 +1708,29 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "0.2.23" +version = "1.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff" +checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" dependencies = [ - "bytes", - "fnv", - "futures-core", - "iovec", - "lazy_static", + "bytes 1.1.0", "libc", "memchr", "mio", - "mio-named-pipes", - "mio-uds", "num_cpus", + "once_cell", + "parking_lot 0.12.0", "pin-project-lite", "signal-hook-registry", - "slab", + "socket2", "tokio-macros", - "winapi 0.3.9", + "winapi", ] [[package]] name = "tokio-macros" -version = "0.2.6" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -1239,22 +1738,33 @@ dependencies = [ ] [[package]] -name = "tokio-tls" -version = "0.3.1" +name = "tokio-native-tls" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", "tokio", ] [[package]] -name = "tokio-util" -version = "0.3.1" +name = "tokio-stream" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" dependencies = [ - "bytes", + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +dependencies = [ + "bytes 1.1.0", "futures-core", "futures-sink", "log", @@ -1262,6 +1772,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +dependencies = [ + "bytes 1.1.0", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "tower-service" version = "0.3.0" @@ -1270,33 +1794,34 @@ checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "tracing" -version = "0.1.21" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ - "cfg-if 0.1.10", - "log", + "cfg-if 1.0.0", "pin-project-lite", + "tracing-attributes", "tracing-core", ] [[package]] -name = "tracing-core" -version = "0.1.17" +name = "tracing-attributes" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ - "lazy_static", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "tracing-futures" -version = "0.2.4" +name = "tracing-core" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ - "pin-project 0.4.27", - "tracing", + "lazy_static", ] [[package]] @@ -1305,6 +1830,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + [[package]] name = "unicase" version = "2.6.0" @@ -1333,21 +1864,34 @@ dependencies = [ ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-segmentation" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-xid" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "url" -version = "2.2.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", "matches", "percent-encoding", + "serde", ] [[package]] @@ -1356,7 +1900,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" dependencies = [ - "rand", + "rand 0.7.3", ] [[package]] @@ -1387,6 +1931,18 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.68" @@ -1394,8 +1950,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" dependencies = [ "cfg-if 0.1.10", - "serde", - "serde_json", "wasm-bindgen-macro", ] @@ -1465,12 +2019,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -1481,12 +2029,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1499,7 +2041,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1509,20 +2051,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "winreg" -version = "0.7.0" +name = "windows-sys" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "winapi 0.3.9", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "windows_aarch64_msvc" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index 8d137c7..0f8b4e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,21 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -teloxide = "0.3" -teloxide-macros = "0.3" -tokio = {version = "0.2.23", features = ["full"]} -reqwest = "0.10.8" -serde = "1.0.117" -serde_json = "1.0.59" +teloxide = { version = "0.9.0", features = ["macros", "auto-send"] } +tokio = {version = "1.8", features = ["full"]} uuid = { version = "0.8.1", features = ["v4"] } log = "0.4" env_logger = "0.8.1" envconfig = "0.9.1" -openssl = {version="*", features = ["vendored"]} +serde = "1.0.137" +reqwest = { version = "0.11.10", features = ["tokio-native-tls"] } +serde_json = "1.0.81" +sqlx = { version = "0.5.13", features = ["sqlite", "runtime-tokio-native-tls", "chrono", "migrate"] } +chrono = "0.4.19" +anyhow = "1.0.57" +async-trait = "0.1.53" +tokio-stream = "0.1.8" +rand = "0.8.5" + +[profile.dev.package.sqlx-macros] +opt-level = 3 diff --git a/build.rs b/build.rs index ecb1a94..1ba960d 100644 --- a/build.rs +++ b/build.rs @@ -12,6 +12,23 @@ fn main() { println!("cargo:rustc-env=GIT_REVISION={}", rev); println!("cargo:rustc-env=GIT_BRANCH={}", branch); println!("cargo:rerun-if-env-changed=GIT_REVISION"); + + if let Ok(data) = std::fs::read_to_string(".env") { + data.split('\n').into_iter().for_each(|v| { + if v.starts_with("DATABASE") { + return; + } + + let kv: Vec<&str> = v.split('=').collect(); + if kv.len() != 2 { + return; + } + + let (key, value) = (kv[0], kv[1]); + println!("cargo:rustc-env={}={}", key, value); + println!("cargo:rerun-if-env-changed={}", key); + }) + } } fn get_value_from_env(key: &str) -> Option { diff --git a/db/001_initial.sql b/db/001_initial.sql new file mode 100644 index 0000000..2ef6d10 --- /dev/null +++ b/db/001_initial.sql @@ -0,0 +1,37 @@ +BEGIN; + +CREATE TABLE IF NOT EXISTS users ( + `user_id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, + `chat_id` integer NOT NULL UNIQUE, + `name` VARCHAR(64) NOT NULL, + created_at datetime NOT NULL +); + +CREATE TABLE IF NOT EXISTS parameters ( + `param_id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, + `user_id` integer NOT NULL, + `key` VARCHAR(64) NOT NULL, + `value` VARCHAR(64) NOT NULL, + FOREIGN KEY(user_id) + REFERENCES users(user_id) + ON DELETE CASCADE +); + +CREATE UNIQUE INDEX IF NOT EXISTS actions_action_id_user_id_idx + ON parameters (`user_id`, `key`); + +CREATE TABLE IF NOT EXISTS actions ( + `action_id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, + `user_id` integer NOT NULL, + `name` VARCHAR(64) NOT NULL, + FOREIGN KEY(user_id) + REFERENCES users(user_id) + ON DELETE CASCADE +); + +COMMIT; + +-- drop index actions_action_id_user_id_idx; +-- drop table users; +-- drop table parameters; +-- drop table actions; diff --git a/makefile b/makefile index f9fa345..10a898f 100644 --- a/makefile +++ b/makefile @@ -8,7 +8,7 @@ DOCKERFLAGS:=-it --rm \ DOCKERIMG:="rust-build-env:V1" APP_NAME:=altherego -IMAGE:=rust:1.49 +IMAGE:=rust:1.60 TARGET_ARCH:=armv7-unknown-linux-gnueabihf image: diff --git a/src/climate.rs b/src/climate.rs new file mode 100644 index 0000000..d8907d1 --- /dev/null +++ b/src/climate.rs @@ -0,0 +1,63 @@ +use anyhow::{anyhow, Result}; + +#[derive(Clone)] +pub struct Client { + addr: String, + client: reqwest::Client, +} + +#[derive(serde::Deserialize, Debug)] +pub struct Climate { + pub humidity: f32, + pub temp: f32, +} + +impl Client { + pub fn new(addr: &str) -> Self { + let addr = addr.to_owned(); + let client = reqwest::Client::builder() + .connect_timeout(std::time::Duration::from_secs(2)) + .build() + .expect("building client"); + + Self { addr, client } + } + + pub async fn fetch(&self) -> Result { + let request = self.client.get(&self.addr).build()?; + Ok(self.client.execute(request).await?.json().await?) + } +} + +#[derive(Clone)] +pub struct SelfTemperature { + cmd: String, + arg: String, +} + +impl SelfTemperature { + pub fn new(cmd: &str, arg: &str) -> Self { + let cmd = cmd.to_owned(); + let arg = arg.to_owned(); + + Self { cmd, arg } + } + + pub async fn fetch(&self) -> Result { + let output = tokio::process::Command::new(&self.cmd) + .arg(&self.arg) + .output() + .await?; + + if !output.status.success() { + let msg = std::string::String::from_utf8(output.stderr)?; + + return Err(anyhow!("getting temp from command: {}", msg)); + } + + let output = std::string::String::from_utf8(output.stdout)?; + let out = output.replace("temp=", "").parse()?; + + Ok(out) + } +} diff --git a/src/main.rs b/src/main.rs index c5cc25d..4c9743f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,40 @@ +#![allow(unused)] + +mod climate; +mod repo; +mod utils; + +use anyhow::Result; +use climate::SelfTemperature; use env_logger; use envconfig::Envconfig; use log::{debug, info, warn}; -use teloxide::{prelude::*, utils::command::BotCommand}; +use teloxide::{ + dispatching::{update_listeners::AsUpdateStream, UpdateFilterExt}, + dptree::di::Injectable, + filter_command, + payloads::SendMessage, + prelude::*, + utils::command::BotCommands, +}; +use tokio_stream::StreamExt; + +use crate::repo::Storage; const VERSION: &'static str = env!("GIT_REVISION"); const BRANCH: &'static str = env!("GIT_BRANCH"); #[tokio::main] async fn main() { + env_logger::init(); + debug!("starting the application"); + println!("starting the application"); tokio::spawn(run()).await.unwrap(); } -#[derive(Envconfig, Clone)] +#[derive(Envconfig, Clone, Debug)] struct Settings { #[envconfig(from = "ALTEREGO_TELEGRAM_TOKEN")] pub telegram_token: String, @@ -29,31 +50,204 @@ struct Settings { default = "/opt/vc/bin/vcgencmd measure_temp" )] pub hosttemp_cmd: String, + + #[envconfig(from = "ALTEREGO_DATABASE_URL", default = "./db.sqlite")] + pub db_source: String, } -async fn run() { - env_logger::init(); +async fn run() -> anyhow::Result<()> { + info!("starting"); let settings = Settings::init_from_env().expect("reading config values"); - let startup = std::sync::Arc::from(std::time::SystemTime::now()); + let bot = teloxide::Bot::new(&settings.telegram_token).auto_send(); - let bot = teloxide::Bot::builder() - .token(&settings.telegram_token) - .build(); - let bot_name = "AlterEgo"; + let repo_config = repo::SqliteConfig { + source: settings.db_source, + ..Default::default() + }; - teloxide::commands_repl(bot, bot_name, move |cx, command| { - let climate = settings.climate_dsn.clone(); - let cmd: String = settings.hosttemp_cmd.clone(); - let cmd: Vec<&str> = cmd.split(" ").collect(); - let console_cmd = cmd.get(0).expect("getting console command").to_string(); - let arg: String = cmd.get(1).unwrap_or_else(|| &"").to_string(); - // let startup = std::sync::Arc::from(*startup); - let startup = *startup; + info!("repo config: {repo_config:?}"); - async move { handler(cx, command, climate, console_cmd, arg, startup).await } - }) - .await; + let sqlite_storage = repo::SqliteRepo::from_config(repo_config).await?; + + let climate_client = climate::Client::new(&settings.climate_dsn); + + let self_temp_client = { + let splitted: Vec<&str> = settings.hosttemp_cmd.split(" ").into_iter().collect(); + let (cmd, arg) = (splitted[0], splitted[1]); + + climate::SelfTemperature::new(cmd, arg) + }; + + let handler = Update::filter_message() + .filter_command::() + .chain(dptree::filter(|msg: Message| msg.chat.is_private())) + .chain(dptree::filter_map_async( + |msg: Message, storage: repo::SqliteRepo| async move { + let chat_id = msg.chat.id.0; + + info!("checking if the user {chat_id} exists"); + let user = storage.load_user_by_chat_id(chat_id).await.unwrap(); + match user { + Some(user) => Some(user), + None => { + let fname = msg.chat.first_name().unwrap_or_default(); + let lname = msg.chat.last_name().unwrap_or_default(); + + info!("performing upsert for user {lname} {fname}"); + + let user_db = storage + .create_user(chat_id, [fname, lname].join(" ")) + .await + .unwrap(); + + info!("upserted user {user_db:?}"); + + Some(user_db) + } + } + }, + )) + .branch(dptree::case![Command::RoomTemperature].endpoint(handle_temperature_sensor)) + .branch(dptree::case![Command::HostTemperature].endpoint(handle_host_temperature)) + .branch(dptree::case![Command::VersionRequest].endpoint(handle_version)) + .branch(dptree::case![Command::Help].endpoint(handle_help)); + + let mut dependencies = DependencyMap::new(); + dependencies.insert(sqlite_storage); + dependencies.insert(climate_client); + dependencies.insert(self_temp_client); + dependencies.insert(utils::Generators::new()); + + info!("running"); + + Dispatcher::builder(bot, handler) + .dependencies(dependencies) + .default_handler(|upd| async move { + warn!("unhandled update: {:?}", upd); + }) + .build() + .setup_ctrlc_handler() + .dispatch() + .await; + + Ok(()) +} + +type HandlerResult = std::result::Result>; + +fn error_msg(reqid: &utils::RequestID) -> String { + format!("There was an error handling command, sorry. Reffer to {reqid}") +} + +async fn handle_temperature_sensor( + bot: AutoSend, + msg: Message, + climate: climate::Client, + next_req_id: utils::Generators, + storage: repo::SqliteRepo, + user: repo::UserDB, +) -> Result<()> { + let chat_id = msg.chat.id; + let reqid = next_req_id.next_request_id(); + + let name = user.name; + bot.send_message(chat_id, format!("Just a second, {name}, asking...")) + .await?; + + match climate.fetch().await { + Ok(temp) => { + let text = format!( + "Humidity is {} and temperature is {}", + temp.humidity, temp.temp, + ); + + bot.send_message(chat_id, text).await?; + } + Err(err) => { + warn!("[{reqid}] unable to fetch self_temp: {err}"); + let msg = error_msg(&reqid); + bot.send_message(chat_id, msg).await?; + } + }; + + Ok(()) +} + +async fn handle_host_temperature( + bot: AutoSend, + msg: Message, + temp: SelfTemperature, + next_req_id: utils::Generators, +) -> Result<()> { + let chat_id = msg.chat.id; + let reqid = next_req_id.next_request_id(); + + bot.send_message(chat_id, "Just a second, asking...") + .await?; + + match temp.fetch().await { + Ok(temp) => { + let text = format!("Host temperature is {} degrees celcius", temp,); + + bot.send_message(chat_id, text).await?; + } + Err(err) => { + warn!("[{reqid}] unable to fetch self_temp: {err}"); + let msg = error_msg(&reqid); + bot.send_message(chat_id, msg).await?; + } + } + + Ok(()) +} + +async fn handle_version(bot: AutoSend, msg: Message) -> Result<()> { + let chat_id = msg.chat.id; + let text = format!("Bot version is {} (branch: {})", VERSION, BRANCH,); + + bot.send_message(chat_id, text).await?; + + Ok(()) +} + +async fn handle_help( + bot: AutoSend, + msg: Message, +) -> Result<()> { + let chat_id = msg.chat.id; + + bot.send_message(chat_id, Command::descriptions().to_string()) + .await?; + + Ok(()) +} + +struct Handler { + storage: S, + climate: climate::Client, + self_temp: climate::SelfTemperature, + started: std::time::Instant, +} + +fn log_error<'a, E: std::fmt::Display>(req_id: &'a str, msg: &'a str) -> impl FnOnce(E) -> E + 'a { + move |err: E| -> E { + warn!( + "request_id={}, {} err={}", + req_id.to_owned(), + msg.to_owned(), + err + ); + err + } +} + +fn log_message(req_id: &str, msg: Message) { + info!( + "message sent to chat_id={}, text={}", + msg.chat.id, + msg.text().unwrap_or_default(), + ) } #[derive(serde::Deserialize, Debug)] @@ -62,99 +256,7 @@ struct Climate { temp: f32, } -async fn handler( - cx: UpdateWithCx, - command: Command, - dsn: String, - console_command: String, - console_arg: String, - startup: std::time::SystemTime, -) -> ResponseResult<()> { - let request_id = uuid::Uuid::new_v4(); - - info!( - "incoming request xreqid={} command={:?}", - request_id, command - ); - - match command { - Command::Help => cx.answer(Command::descriptions()).send().await?, - Command::HostTemperature => { - info!( - "querying command {} with arg {}", - console_command, console_arg - ); - - let cmd = std::process::Command::new(&console_command) - .arg(&console_arg) - .stdout(std::process::Stdio::piped()) - .spawn() - .expect("running vcgencmd command"); - - let output = cmd.wait_with_output().expect("waiting for output"); - - let parsed = - std::string::String::from_utf8(output.stdout).expect("casting into string"); - - let parsed = parsed.replace("temp=", ""); - - cx.answer_str(format!("Your Raspberry PI temperature is {}", parsed)) - .await? - } - Command::RoomTemperature => { - info!("sending request to {}", dsn); - - let response = match reqwest::get(&dsn).await { - Ok(response) => response, - Err(err) => { - warn!( - "unable to handle request xreqid={} error={:?}", - request_id, err - ); - cx.answer_str(format!("something went wrong, reference to {}", request_id)) - .await?; - - return Err(RequestError::NetworkError(err)); - } - }; - - let info: Climate = match response.json::().await { - Ok(result) => result, - Err(err) => { - warn!( - "unable to handle request xreqid={} error={:?}", - request_id, err - ); - cx.answer_str(format!("something went wrong, reference to {}", request_id)) - .await?; - - return Err(RequestError::NetworkError(err)); - } - }; - - debug!("parsed value: {:?}", info); - - cx.answer_str(format!( - "Your room temperature is {:.2} and humidity is {:.2}.", - info.temp, info.humidity - )) - .await? - } - Command::VersionRequest => { - cx.answer_str(format!( - "app version is {}@{}, uptime is {} second(-s)", - VERSION, - BRANCH, - startup.elapsed().unwrap().as_secs() - )) - .await? - } - }; - - Ok(()) -} - -#[derive(BotCommand, Debug)] +#[derive(BotCommands, Debug, Clone, PartialEq, Eq)] #[command(rename = "lowercase", description = "These commands are supported:")] enum Command { #[command(description = "display this text.")] diff --git a/src/repo.rs b/src/repo.rs new file mode 100644 index 0000000..1e14174 --- /dev/null +++ b/src/repo.rs @@ -0,0 +1,229 @@ +use std::str::FromStr; + +use anyhow::Result; +use log::debug; +use sqlx::{ + sqlite::{ + SqliteConnectOptions, SqliteError, SqliteJournalMode, SqlitePoolOptions, SqliteSynchronous, + }, + Executor, Pool, Sqlite, +}; +use teloxide::types::User; + +#[derive(Debug)] +pub struct SqliteConfig { + pub source: String, + pub timeout: std::time::Duration, + pub max_conns: u32, +} + +impl Default for SqliteConfig { + fn default() -> Self { + Self { + source: ":memory:".to_string(), + timeout: std::time::Duration::from_secs(10), + max_conns: 2, + } + } +} + +#[derive(Clone)] +pub struct SqliteRepo { + pool: Pool, +} + +impl SqliteRepo { + pub async fn from_config(config: SqliteConfig) -> Result { + let dsn = if !config.source.starts_with("sqlite://") { + format!("sqlite://{}", &config.source) + } else { + config.source + }; + + debug!("connecting to {}", dsn); + + let opts = SqliteConnectOptions::from_str(&dsn)? + .create_if_missing(true) + .journal_mode(SqliteJournalMode::Wal) + .synchronous(SqliteSynchronous::Normal) + .busy_timeout(config.timeout); + + let pool = SqlitePoolOptions::new() + .max_connections(config.max_conns) + .connect_timeout(config.timeout) + .connect_with(opts) + .await?; + + // sqlx::migrate!("./db").run(&pool).await?; + + sqlx::query("pragma temp_store = memory;") + .execute(&pool) + .await?; + + sqlx::query("pragma mmap_size = 30000000000;") + .execute(&pool) + .await?; + + sqlx::query("pragma page_size = 4096;") + .execute(&pool) + .await?; + + Ok(Self { pool }) + } +} + +#[derive(sqlx::FromRow, Debug, Clone)] +pub struct UserDB { + pub user_id: i64, + pub chat_id: i64, + pub name: String, + pub created_at: chrono::NaiveDateTime, +} + +#[derive(sqlx::FromRow)] +pub struct ParameterDB { + pub param_id: i64, + pub user_id: i64, + pub key: String, + pub value: String, +} + +pub type MappedParameter = std::collections::HashMap; + +pub struct ParameterBase { + pub param_id: i64, + pub user_id: i64, + pub value: String, +} + +#[async_trait::async_trait] +pub trait Storage { + async fn create_user(&self, chat_id: i64, name: String) -> Result; + async fn get_user(&self, user_id: i64) -> Result>; + async fn load_user_by_chat_id(&self, chat_id: i64) -> Result>; + async fn get_user_parameters(&self, user_id: i64) -> Result; + + async fn upsert_parameter( + &self, + user_id: i64, + key: String, + value: String, + ) -> Result; + async fn delete_parameter(&self, param_id: i64) -> Result<()>; + + async fn insert_action(&self, user_id: i64, name: String) -> Result<()>; +} + +#[async_trait::async_trait] +impl Storage for SqliteRepo { + async fn create_user(&self, chat_id: i64, name: String) -> Result { + Ok(sqlx::query_as!( + UserDB, + "INSERT INTO users (chat_id, name, created_at)" + + " VALUES (?, ?, datetime('now'))" + + " RETURNING user_id, chat_id, name, created_at;", + chat_id, + name, + ) + .fetch_one(&self.pool) + .await?) + } + + async fn load_user_by_chat_id(&self, chat_id: i64) -> Result> { + let result: std::result::Result = sqlx::query_as!( + UserDB, + "SELECT user_id, chat_id, name, created_at" + " FROM users WHERE `chat_id` = ?;", + chat_id, + ) + .fetch_one(&self.pool) + .await; + + match result { + Ok(row) => Ok(Some(row)), + Err(err) => match err { + sqlx::Error::RowNotFound => Ok(None), + err => Err(anyhow::anyhow!(err)), + }, + } + } + + + async fn get_user(&self, user_id: i64) -> Result> { + let result: std::result::Result = sqlx::query_as!( + UserDB, + "SELECT user_id, chat_id, name, created_at" + " FROM users WHERE `user_id` = ?;", + user_id, + ) + .fetch_one(&self.pool) + .await; + + match result { + Ok(row) => Ok(Some(row)), + Err(err) => match err { + sqlx::Error::RowNotFound => Ok(None), + err => Err(anyhow::anyhow!(err)), + }, + } + } + + async fn get_user_parameters(&self, user_id: i64) -> Result { + let mut mp: MappedParameter = std::collections::HashMap::new(); + sqlx::query_as!( + ParameterDB, + "SELECT `param_id`, `user_id`, `key`, `value`" + " FROM parameters WHERE `user_id` = ?", + user_id, + ) + .fetch_all(&self.pool) + .await? + .into_iter() + .for_each(|result| { + let param = ParameterBase { + param_id: result.param_id, + user_id: result.user_id, + value: result.value, + }; + + mp.insert(result.key, param); + }); + + Ok(mp) + } + + async fn upsert_parameter( + &self, + user_id: i64, + key: String, + value: String, + ) -> Result { + Ok(sqlx::query_as!( + ParameterDB, + "INSERT INTO parameters (`user_id`, `key`, `value`)" + + " VALUES (?, ?, ?)" + + " RETURNING `param_id`, `user_id`, `key`, `value`;", + user_id, + key, + value, + ) + .fetch_one(&self.pool) + .await?) + } + + async fn delete_parameter(&self, param_id: i64) -> Result<()> { + sqlx::query("DELETE FROM parameters WHERE `param_id` = ?;") + .bind(param_id) + .execute(&self.pool) + .await?; + + Ok(()) + } + + async fn insert_action(&self, user_id: i64, name: String) -> Result<()> { + sqlx::query("INSERT INTO actions (`user_id`, `name`) VALUES (?, ?)") + .bind(user_id) + .bind(name) + .execute(&self.pool) + .await?; + + Ok(()) + } +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..d5931d3 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,25 @@ +pub struct RequestID(String); + +impl std::fmt::Display for RequestID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +#[derive(Clone)] +pub struct Generators; + +impl Generators { + pub fn new() -> Self { + Self + } + + pub fn next_request_id(&self) -> RequestID { + let data: u32 = rand::random(); + let data_hex = format!("{:x}", data); + + log::info!("issued new request: {}", data_hex); + + RequestID(data_hex) + } +}