diff --git a/Cargo.lock b/Cargo.lock index b89b662..890eb89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,54 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "arc-swap" version = "1.6.0" @@ -48,30 +96,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] -name = "async-trait" -version = "0.1.74" +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "serde", ] [[package]] -name = "async-tungstenite" -version = "0.17.2" +name = "async-trait" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ - "futures-io", - "futures-util", - "log", - "pin-project-lite", - "tokio", - "tokio-rustls 0.23.4", - "tungstenite", - "webpki-roots 0.22.6", + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] @@ -95,12 +136,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.5" @@ -134,6 +169,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "bytecount" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" + [[package]] name = "byteorder" version = "1.5.0" @@ -146,6 +187,37 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.0.83" @@ -201,6 +273,12 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "combine" version = "4.6.6" @@ -249,6 +327,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -261,9 +354,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -271,27 +364,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -308,6 +401,12 @@ dependencies = [ "serde", ] +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + [[package]] name = "deranged" version = "0.3.10" @@ -367,16 +466,26 @@ dependencies = [ ] [[package]] -name = "env_logger" -version = "0.10.1" +name = "env_filter" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" dependencies = [ - "humantime", - "is-terminal", "log", "regex", - "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e7cf40684ae96ade6232ed84582f40ce0a66efcd43a5117aef610534f8e0b8" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", ] [[package]] @@ -395,6 +504,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + [[package]] name = "eyre" version = "0.6.9" @@ -405,6 +523,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "flate2" version = "1.0.28" @@ -486,7 +610,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", ] [[package]] @@ -519,6 +643,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -548,6 +681,12 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gray_matter" version = "0.2.6" @@ -677,10 +816,10 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.10", + "rustls", "rustls-native-certs", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", ] [[package]] @@ -766,17 +905,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itoa" version = "1.0.10" @@ -798,10 +926,10 @@ version = "9.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" dependencies = [ - "base64 0.21.5", + "base64", "js-sys", "pem", - "ring 0.17.7", + "ring", "serde", "serde_json", "simple_asn1", @@ -869,6 +997,21 @@ dependencies = [ "unicase", ] +[[package]] +name = "mini-moka" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" +dependencies = [ + "crossbeam-channel", + "crossbeam-utils", + "dashmap", + "skeptic", + "smallvec", + "tagptr", + "triomphe", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -940,13 +1083,13 @@ dependencies = [ [[package]] name = "octocrab" -version = "0.32.0" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfeeafb5fa0da7046229ec3c7b3bd2981aae05c549871192c408d59fc0fffd5" +checksum = "054a8bf47dfa8f89bb0dcf17e485e9f49f2586c05bf0aa67b8ec5a9e7bc8dfd5" dependencies = [ "arc-swap", "async-trait", - "base64 0.21.5", + "base64", "bytes", "cfg-if", "chrono", @@ -987,15 +1130,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - [[package]] name = "owo-colors" version = "3.5.0" @@ -1031,7 +1165,7 @@ version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ - "base64 0.21.5", + "base64", "serde", ] @@ -1058,7 +1192,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", ] [[package]] @@ -1075,33 +1209,31 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "poise" -version = "0.5.7" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d104e4b5847283b2fbd6a7ec19fb6a8af328e2145623d056b66d750a30073fdf" +checksum = "1819d5a45e3590ef33754abce46432570c54a120798bdbf893112b4211fa09a6" dependencies = [ "async-trait", "derivative", - "futures-core", "futures-util", - "log", - "once_cell", "parking_lot", "poise_macros", "regex", "serenity", "tokio", + "tracing", ] [[package]] name = "poise_macros" -version = "0.5.7" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb516a8cf4e4ae4bd7ef5819d08c6ca408976461a9bea3ee3eec5138ac070c1" +checksum = "8fa2c123c961e78315cd3deac7663177f12be4460f5440dbf62a7ed37b1effea" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1118,18 +1250,29 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] -name = "quote" -version = "1.0.33" +name = "pulldown-cmark" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1169,6 +1312,21 @@ name = "redis" version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f49cdc0bb3f412bf8e7d1bd90fe1d9eb10bc5c399ba90973c14662a27b3f8ba" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "socket2 0.4.10", + "url", +] + +[[package]] +name = "redis" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c580d9cbbe1d1b479e8d67cf9daf6a62c957e6846048408b80b43ac3f6af84cd" dependencies = [ "async-trait", "bytes", @@ -1177,13 +1335,15 @@ dependencies = [ "itoa", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls", "rustls-native-certs", + "rustls-pemfile", + "rustls-webpki", "ryu", "sha1_smol", "socket2 0.4.10", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tokio-util", "url", ] @@ -1194,7 +1354,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60eb39e2b44d4c0f9c84e7c5fc4fc3adc8dd26ec48f1ac3a160033f7c03b18fd" dependencies = [ - "redis", + "redis 0.23.3", "redis-macros-derive", "serde", "serde_json", @@ -1234,7 +1394,7 @@ dependencies = [ "once_cell", "poise", "rand", - "redis", + "redis 0.24.0", "redis-macros", "regex", "reqwest", @@ -1246,9 +1406,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -1258,9 +1418,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -1275,11 +1435,11 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.5", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1297,14 +1457,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -1312,25 +1472,10 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.25.3", + "webpki-roots", "winreg", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.7" @@ -1340,8 +1485,8 @@ dependencies = [ "cc", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.48.0", ] @@ -1364,18 +1509,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" -dependencies = [ - "log", - "ring 0.16.20", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.21.10" @@ -1383,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.7", + "ring", "rustls-webpki", "sct", ] @@ -1406,7 +1539,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64", ] [[package]] @@ -1415,22 +1548,25 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring", + "untrusted", ] -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "ryu" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -1452,8 +1588,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -1462,6 +1598,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" dependencies = [ + "serde", "zeroize", ] @@ -1489,40 +1626,39 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.193" +name = "semver" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" dependencies = [ "itoa", "ryu", @@ -1553,41 +1689,41 @@ dependencies = [ [[package]] name = "serenity" -version = "0.11.7" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7a89cef23483fc9d4caf2df41e6d3928e18aada84c56abd237439d929622c6" +checksum = "385647faa24a889929028973650a4f158fb1b4272b2fcf94feb9fcc3c009e813" dependencies = [ + "arrayvec", "async-trait", - "async-tungstenite", - "base64 0.21.5", - "bitflags 1.3.2", + "base64", + "bitflags 2.4.1", "bytes", - "cfg-if", "chrono", "dashmap", "flate2", "futures", - "mime", + "fxhash", "mime_guess", "parking_lot", "percent-encoding", "reqwest", - "rustversion", + "secrecy", "serde", - "serde-value", "serde_json", "time", "tokio", + "tokio-tungstenite", "tracing", "typemap_rev", + "typesize", "url", ] [[package]] -name = "sha-1" -version = "0.10.1" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -1630,6 +1766,21 @@ dependencies = [ "time", ] +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob", + "pulldown-cmark", + "tempfile", + "walkdir", +] + [[package]] name = "slab" version = "0.4.9" @@ -1688,12 +1839,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -1719,9 +1864,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.40" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1750,12 +1895,22 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.4.0" +name = "tagptr" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ - "winapi-util", + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.52.0", ] [[package]] @@ -1775,7 +1930,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", ] [[package]] @@ -1834,9 +1989,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -1868,18 +2023,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", -] - -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls 0.20.9", - "tokio", - "webpki", + "syn 2.0.48", ] [[package]] @@ -1888,10 +2032,25 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls", "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -1985,7 +2144,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", ] [[package]] @@ -2019,6 +2178,12 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "try-lock" version = "0.2.5" @@ -2027,30 +2192,29 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.17.3" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "base64 0.13.1", "byteorder", "bytes", + "data-encoding", "http", "httparse", "log", "rand", - "rustls 0.20.9", - "sha-1", + "rustls", + "sha1", "thiserror", "url", "utf-8", - "webpki", ] [[package]] name = "typemap_rev" -version = "0.1.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" +checksum = "74b08b0c1257381af16a5c3605254d529d3e7e109f3c62befc5d168968192998" [[package]] name = "typenum" @@ -2058,6 +2222,35 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typesize" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36924509726e38224322c8c90ddfbf4317324338327b7c11b7cf8672cb786da1" +dependencies = [ + "chrono", + "dashmap", + "hashbrown", + "mini-moka", + "parking_lot", + "secrecy", + "serde_json", + "time", + "typesize-derive", + "url", +] + +[[package]] +name = "typesize-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b122284365ba8497be951b9a21491f70c9688eb6fddc582931a0703f6a00ece" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "unicase" version = "2.7.0" @@ -2088,12 +2281,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -2118,6 +2305,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "valuable" version = "0.1.0" @@ -2130,6 +2323,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2166,7 +2369,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -2200,7 +2403,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.40", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2234,25 +2437,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.25.3" diff --git a/Cargo.toml b/Cargo.toml index a629f5c..8c3f3df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,30 +10,30 @@ build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] gray_matter = "0.2.6" -poise = "0.5.7" -serde = "1.0.193" -serde_json = "1.0.108" +poise = "0.6.1" +serde = "1.0.196" +serde_json = "1.0.112" [dependencies] -async-trait = "0.1.74" +async-trait = "0.1.77" color-eyre = "0.6.2" dotenvy = "0.15.7" -env_logger = "0.10.0" +env_logger = "0.11.1" log = "0.4.20" -poise = "0.5.7" -octocrab = "0.32.0" -once_cell = "1.18.0" +poise = "0.6.1" +octocrab = "0.33.3" +once_cell = "1.19.0" rand = "0.8.5" -redis = { version = "0.23.3", features = ["tokio-comp", "tokio-rustls-comp"] } +redis = { version = "0.24.0", features = ["tokio-comp", "tokio-rustls-comp"] } redis-macros = "0.2.1" -regex = "1.10.2" -reqwest = { version = "0.11.22", default-features = false, features = [ +regex = "1.10.3" +reqwest = { version = "0.11.23", default-features = false, features = [ "rustls-tls", "json", ] } -serde = "1.0.193" -serde_json = "1.0.108" -tokio = { version = "1.33.0", features = [ +serde = "1.0.196" +serde_json = "1.0.112" +tokio = { version = "1.35.1", features = [ "macros", "rt-multi-thread", "signal", diff --git a/src/commands/general/members.rs b/src/commands/general/members.rs index a971e65..99a3c03 100644 --- a/src/commands/general/members.rs +++ b/src/commands/general/members.rs @@ -1,11 +1,16 @@ use crate::{consts, Context}; use color_eyre::eyre::{eyre, Result}; +use poise::serenity_prelude::CreateEmbed; +use poise::CreateReply; /// Returns the number of members in the server #[poise::command(slash_command, prefix_command)] pub async fn members(ctx: Context<'_>) -> Result<()> { - let guild = ctx.guild().ok_or_else(|| eyre!("Couldn't fetch guild!"))?; + let guild = ctx + .guild() + .ok_or_else(|| eyre!("Couldn't fetch guild!"))? + .to_owned(); let count = guild.member_count; let online = if let Some(count) = guild.approximate_presence_count { @@ -14,13 +19,12 @@ pub async fn members(ctx: Context<'_>) -> Result<()> { "Undefined".to_string() }; - ctx.send(|m| { - m.embed(|e| { - e.title(format!("{count} total members!")) - .description(format!("{online} online members")) - .color(consts::COLORS["blue"]) - }) - }) - .await?; + let embed = CreateEmbed::new() + .title(format!("{count} total members!")) + .description(format!("{online} online members")) + .color(consts::COLORS["blue"]); + let reply = CreateReply::default().embed(embed); + + ctx.send(reply).await?; Ok(()) } diff --git a/src/commands/general/rory.rs b/src/commands/general/rory.rs index f20700c..6bddc5f 100644 --- a/src/commands/general/rory.rs +++ b/src/commands/general/rory.rs @@ -2,6 +2,8 @@ use crate::api::rory::get_rory; use crate::Context; use color_eyre::eyre::Result; +use poise::serenity_prelude::{CreateEmbed, CreateEmbedFooter}; +use poise::CreateReply; /// Gets a Rory photo! #[poise::command(slash_command, prefix_command)] @@ -11,19 +13,22 @@ pub async fn rory( ) -> Result<()> { let rory = get_rory(id).await?; - ctx.send(|m| { - m.embed(|e| { - if let Some(error) = rory.error { - e.title("Error!").description(error) - } else { - e.title("Rory :3") - .url(&rory.url) - .image(rory.url) - .footer(|f| f.text(format!("ID {}", rory.id))) - } - }) - }) - .await?; + let embed = { + let embed = CreateEmbed::new(); + if let Some(error) = rory.error { + embed.title("Error!").description(error) + } else { + let footer = CreateEmbedFooter::new(format!("ID {}", rory.id)); + embed + .title("Rory :3") + .url(&rory.url) + .image(rory.url) + .footer(footer) + } + }; + + let reply = CreateReply::default().embed(embed); + ctx.send(reply).await?; Ok(()) } diff --git a/src/commands/general/say.rs b/src/commands/general/say.rs index aad9836..796d55b 100644 --- a/src/commands/general/say.rs +++ b/src/commands/general/say.rs @@ -1,6 +1,7 @@ use crate::Context; use color_eyre::eyre::{eyre, Result}; +use poise::serenity_prelude::{CreateEmbed, CreateEmbedAuthor, CreateMessage}; /// Say something through the bot #[poise::command( @@ -11,7 +12,10 @@ use color_eyre::eyre::{eyre, Result}; required_permissions = "MODERATE_MEMBERS" )] pub async fn say(ctx: Context<'_>, #[description = "Just content?"] content: String) -> Result<()> { - let guild = ctx.guild().ok_or_else(|| eyre!("Couldn't get guild!"))?; + let guild = ctx + .guild() + .ok_or_else(|| eyre!("Couldn't get guild!"))? + .to_owned(); let channel = ctx .guild_channel() .await @@ -28,23 +32,16 @@ pub async fn say(ctx: Context<'_>, #[description = "Just content?"] content: Str .find(|c| c.0 == &channel_id) .ok_or_else(|| eyre!("Couldn't get log channel from guild!"))?; - log_channel - .1 - .clone() - .guild() - .ok_or_else(|| eyre!("Couldn't cast channel we found from guild as GuildChannel?????"))? - .send_message(ctx, |m| { - m.embed(|e| { - e.title("Say command used!") - .description(content) - .author(|a| { - a.name(ctx.author().tag()).icon_url( - ctx.author().avatar_url().unwrap_or("undefined".to_string()), - ) - }) - }) - }) - .await?; + let author = CreateEmbedAuthor::new(ctx.author().tag()) + .icon_url(ctx.author().avatar_url().unwrap_or("Undefined".to_string())); + + let embed = CreateEmbed::default() + .title("Say command used!") + .description(content) + .author(author); + + let message = CreateMessage::new().embed(embed); + log_channel.1.send_message(ctx, message).await?; } Ok(()) diff --git a/src/commands/general/stars.rs b/src/commands/general/stars.rs index 470712f..c1b850c 100644 --- a/src/commands/general/stars.rs +++ b/src/commands/general/stars.rs @@ -1,6 +1,8 @@ -use crate::{consts::COLORS, Context}; +use crate::{consts, Context}; use color_eyre::eyre::{Context as _, Result}; +use poise::serenity_prelude::CreateEmbed; +use poise::CreateReply; /// Returns GitHub stargazer count #[poise::command(slash_command, prefix_command)] @@ -19,13 +21,12 @@ pub async fn stars(ctx: Context<'_>) -> Result<()> { "undefined".to_string() }; - ctx.send(|m| { - m.embed(|e| { - e.title(format!("⭐ {count} total stars!")) - .color(COLORS["yellow"]) - }) - }) - .await?; + let embed = CreateEmbed::new() + .title(format!("⭐ {count} total stars!")) + .color(consts::COLORS["yellow"]); + let reply = CreateReply::default().embed(embed); + + ctx.send(reply).await?; Ok(()) } diff --git a/src/commands/general/tag.rs b/src/commands/general/tag.rs index 7d1c55f..4273d03 100644 --- a/src/commands/general/tag.rs +++ b/src/commands/general/tag.rs @@ -5,7 +5,8 @@ use std::env; use color_eyre::eyre::{eyre, Result}; use once_cell::sync::Lazy; -use poise::serenity_prelude::{Color, User}; +use poise::serenity_prelude::{Color, CreateEmbed, User}; +use poise::CreateReply; include!(concat!(env!("OUT_DIR"), "/generated.rs")); static TAGS: Lazy> = Lazy::new(|| serde_json::from_str(env!("TAGS")).unwrap()); @@ -25,36 +26,40 @@ pub async fn tag( let frontmatter = &tag.frontmatter; - ctx.send(|m| { - if let Some(user) = user { - m.content(format!("<@{}>", user.id)); + let embed = { + let mut e = CreateEmbed::new(); + + if let Some(color) = &frontmatter.color { + let color = *consts::COLORS + .get(color.as_str()) + .unwrap_or(&Color::default()); + e = e.color(color); } - m.embed(|e| { - e.title(&frontmatter.title); - e.description(&tag.content); + if let Some(image) = &frontmatter.image { + e = e.image(image); + } - if let Some(color) = &frontmatter.color { - let color = *consts::COLORS - .get(color.as_str()) - .unwrap_or(&Color::default()); - e.color(color); + if let Some(fields) = &frontmatter.fields { + for field in fields { + e = e.field(&field.name, &field.value, field.inline); } + } - if let Some(image) = &frontmatter.image { - e.image(image); - } + e + }; - if let Some(fields) = &frontmatter.fields { - for field in fields { - e.field(&field.name, &field.value, field.inline); - } - } + let reply = { + let mut r = CreateReply::default(); - e - }) - }) - .await?; + if let Some(user) = user { + r = r.content(format!("<@{}>", user.id)); + } + + r.embed(embed) + }; + + ctx.send(reply).await?; Ok(()) } diff --git a/src/handlers/error.rs b/src/handlers/error.rs index 12e4980..1d0cc2c 100644 --- a/src/handlers/error.rs +++ b/src/handlers/error.rs @@ -3,8 +3,8 @@ use crate::Data; use color_eyre::eyre::Report; use log::*; -use poise::serenity_prelude::Timestamp; -use poise::FrameworkError; +use poise::serenity_prelude::{CreateEmbed, Timestamp}; +use poise::{CreateReply, FrameworkError}; pub async fn handle(error: FrameworkError<'_, Data, Report>) { match error { @@ -12,23 +12,23 @@ pub async fn handle(error: FrameworkError<'_, Data, Report>) { error, framework, .. } => { error!("Error setting up client! Bailing out"); - framework.shard_manager().lock().await.shutdown_all().await; + framework.shard_manager().shutdown_all().await; panic!("{error}") } - FrameworkError::Command { error, ctx } => { + FrameworkError::Command { error, ctx, .. } => { error!("Error in command {}:\n{error:?}", ctx.command().name); - ctx.send(|c| { - c.embed(|e| { - e.title("Something went wrong!") - .description("oopsie") - .timestamp(Timestamp::now()) - .color(COLORS["red"]) - }) - }) - .await - .ok(); + + let embed = CreateEmbed::new() + .title("Something went wrong!") + .description("oopsie") + .timestamp(Timestamp::now()) + .color(COLORS["red"]); + + let reply = CreateReply::default().embed(embed); + + ctx.send(reply).await.ok(); } FrameworkError::EventHandler { @@ -36,13 +36,17 @@ pub async fn handle(error: FrameworkError<'_, Data, Report>) { ctx: _, event, framework: _, + .. } => { - error!("Error while handling event {}:\n{error:?}", event.name()); + error!( + "Error while handling event {}:\n{error:?}", + event.snake_case_name() + ); } error => { if let Err(e) = poise::builtins::on_error(error).await { - error!("Unhandled error occured:\n{e:#?}"); + error!("Unhandled error occurred:\n{e:#?}"); } } } diff --git a/src/handlers/event/analyze_logs/mod.rs b/src/handlers/event/analyze_logs/mod.rs index 80c660d..d8823d2 100644 --- a/src/handlers/event/analyze_logs/mod.rs +++ b/src/handlers/event/analyze_logs/mod.rs @@ -3,7 +3,9 @@ use crate::Data; use color_eyre::eyre::Result; use log::*; -use poise::serenity_prelude::{Context, Message}; +use poise::serenity_prelude::{ + Context, CreateAllowedMentions, CreateEmbed, CreateMessage, Message, +}; mod issues; mod providers; @@ -17,16 +19,16 @@ pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()> let log = find_log(message).await; if log.is_err() { - channel - .send_message(ctx, |m| { - m.reference_message(message) - .allowed_mentions(|am| am.replied_user(true)) - .embed(|e| { - e.title("Analyze failed!") - .description("Couldn't download log") - }) - }) - .await?; + let embed = CreateEmbed::new() + .title("Analyze failed!") + .description("Couldn't download log"); + let allowed_mentions = CreateAllowedMentions::new().replied_user(true); + let our_message = CreateMessage::new() + .reference_message(message) + .allowed_mentions(allowed_mentions) + .embed(embed); + + channel.send_message(ctx, our_message).await?; return Ok(()); } @@ -38,31 +40,32 @@ pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()> let issues = find_issues(&log, data).await?; - channel - .send_message(ctx, |m| { - m.reference_message(message) - .allowed_mentions(|am| am.replied_user(true)) - .embed(|e| { - e.title("Log analysis"); + let embed = { + let mut e = CreateEmbed::new().title("Log analysis"); - if issues.is_empty() { - e.color(COLORS["green"]).field( - "Analyze failed!", - "No issues found automatically", - false, - ); - } else { - e.color(COLORS["red"]); + if issues.is_empty() { + e = e.color(COLORS["green"]).field( + "Analyze failed!", + "No issues found automatically", + false, + ); + } else { + e = e.color(COLORS["red"]); - for (title, description) in issues { - e.field(title, description, false); - } - } + for (title, description) in issues { + e = e.field(title, description, false); + } + } - e - }) - }) - .await?; + e + }; + + let allowed_mentions = CreateAllowedMentions::new().replied_user(true); + let message = CreateMessage::new() + .allowed_mentions(allowed_mentions) + .embed(embed); + + channel.send_message(ctx, message).await?; Ok(()) } diff --git a/src/handlers/event/delete_on_reaction.rs b/src/handlers/event/delete_on_reaction.rs index c17deb5..cd8b65e 100644 --- a/src/handlers/event/delete_on_reaction.rs +++ b/src/handlers/event/delete_on_reaction.rs @@ -13,7 +13,7 @@ pub async fn handle(ctx: &Context, reaction: &Reaction) -> Result<()> { .wrap_err_with(|| "Couldn't fetch message from reaction!")?; if let Some(interaction) = &message.interaction { - if interaction.kind == InteractionType::ApplicationCommand + if interaction.kind == InteractionType::Command && interaction.user == user && reaction.emoji.unicode_eq("❌") { diff --git a/src/handlers/event/expand_link.rs b/src/handlers/event/expand_link.rs index 30504f1..3c41c61 100644 --- a/src/handlers/event/expand_link.rs +++ b/src/handlers/event/expand_link.rs @@ -1,27 +1,20 @@ -use color_eyre::eyre::{eyre, Context as _, Result}; -use poise::serenity_prelude::{Context, Message}; +use color_eyre::eyre::Result; +use poise::serenity_prelude::{Context, CreateAllowedMentions, CreateMessage, Message}; use crate::utils; pub async fn handle(ctx: &Context, message: &Message) -> Result<()> { let embeds = utils::resolve_message(ctx, message).await?; - // TOOD getchoo: actually reply to user + // TODO getchoo: actually reply to user // ...not sure why Message doesn't give me a builder in reply() or equivalents - let our_channel = message - .channel(ctx) - .await - .wrap_err_with(|| "Couldn't get channel from message!")? - .guild() - .ok_or_else(|| eyre!("Couldn't convert to GuildChannel!"))?; - if !embeds.is_empty() { - our_channel - .send_message(ctx, |m| { - m.set_embeds(embeds) - .allowed_mentions(|am| am.replied_user(false)) - }) - .await?; + let allowed_mentions = CreateAllowedMentions::new().replied_user(false); + let reply = CreateMessage::new() + .embeds(embeds) + .allowed_mentions(allowed_mentions); + + message.channel_id.send_message(ctx, reply).await?; } Ok(()) diff --git a/src/handlers/event/mod.rs b/src/handlers/event/mod.rs index 8d82984..a916ed0 100644 --- a/src/handlers/event/mod.rs +++ b/src/handlers/event/mod.rs @@ -2,8 +2,8 @@ use crate::{api, Data}; use color_eyre::eyre::{Report, Result}; use log::*; -use poise::serenity_prelude::{Activity, Context, OnlineStatus}; -use poise::{Event, FrameworkContext}; +use poise::serenity_prelude::{ActivityData, Context, FullEvent, OnlineStatus}; +use poise::FrameworkContext; mod analyze_logs; mod delete_on_reaction; @@ -14,22 +14,22 @@ mod support_onboard; pub async fn handle( ctx: &Context, - event: &Event<'_>, + event: &FullEvent, _framework: FrameworkContext<'_, Data, Report>, data: &Data, ) -> Result<()> { match event { - Event::Ready { data_about_bot } => { + FullEvent::Ready { data_about_bot } => { info!("Logged in as {}!", data_about_bot.user.name); let latest_minecraft_version = api::prism_meta::get_latest_minecraft_version().await?; - let activity = Activity::playing(format!("Minecraft {}", latest_minecraft_version)); + let activity = ActivityData::playing(format!("Minecraft {}", latest_minecraft_version)); info!("Setting presence to activity {activity:#?}"); - ctx.set_presence(Some(activity), OnlineStatus::Online).await; + ctx.set_presence(Some(activity), OnlineStatus::Online); } - Event::Message { new_message } => { + FullEvent::Message { new_message } => { // ignore new messages from bots // NOTE: the webhook_id check allows us to still respond to PK users if new_message.author.bot && new_message.webhook_id.is_none() { @@ -52,11 +52,13 @@ pub async fn handle( analyze_logs::handle(ctx, new_message, data).await?; } - Event::ReactionAdd { add_reaction } => { - delete_on_reaction::handle(ctx, add_reaction).await? + FullEvent::ReactionAdd { add_reaction } => { + delete_on_reaction::handle(ctx, add_reaction).await?; } - Event::ThreadCreate { thread } => support_onboard::handle(ctx, thread).await?, + FullEvent::ThreadCreate { thread } => { + support_onboard::handle(ctx, thread).await?; + } _ => {} } diff --git a/src/handlers/event/support_onboard.rs b/src/handlers/event/support_onboard.rs index e83a239..be08309 100644 --- a/src/handlers/event/support_onboard.rs +++ b/src/handlers/event/support_onboard.rs @@ -1,22 +1,23 @@ use color_eyre::eyre::{eyre, Result}; use log::*; -use poise::serenity_prelude::{ChannelType, Context, GuildChannel}; +use poise::serenity_prelude::{ + ChannelType, Context, CreateAllowedMentions, CreateMessage, GuildChannel, +}; pub async fn handle(ctx: &Context, thread: &GuildChannel) -> Result<()> { if thread.kind != ChannelType::PublicThread { + debug!("Not doing support onboard in non-thread channel"); return Ok(()); } - let parent_id = thread + if thread .parent_id - .ok_or_else(|| eyre!("Couldn't get parent ID from thread {}!", thread.name))?; - - let parent_channel = ctx - .cache - .guild_channel(parent_id) - .ok_or_else(|| eyre!("Couldn't get GuildChannel {}!", parent_id))?; - - if parent_channel.name != "support" { + .ok_or_else(|| eyre!("Couldn't get parent ID from thread {}!", thread.name))? + .name(ctx) + .await + .unwrap_or("".to_string()) + != "support" + { debug!("Not posting onboarding message to threads outside of support"); return Ok(()); } @@ -32,12 +33,15 @@ pub async fn handle(ctx: &Context, thread: &GuildChannel) -> Result<()> { "Please don't ping people for support questions, unless you have their permission." ); - thread - .send_message(ctx, |m| { - m.content(msg) - .allowed_mentions(|am| am.replied_user(true).users(Vec::from([owner]))) - }) - .await?; + let allowed_mentions = CreateAllowedMentions::new() + .replied_user(true) + .users(Vec::from([owner])); + + let message = CreateMessage::new() + .content(msg) + .allowed_mentions(allowed_mentions); + + thread.send_message(ctx, message).await?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index cf89bd6..72ccddc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,6 @@ use poise::{ serenity_prelude as serenity, EditTracker, Framework, FrameworkOptions, PrefixFrameworkOptions, }; -use serenity::ShardManager; - use redis::ConnectionLike; use tokio::signal::ctrl_c; @@ -19,7 +17,6 @@ use tokio::signal::ctrl_c; use tokio::signal::unix::{signal, SignalKind}; #[cfg(target_family = "windows")] use tokio::signal::windows::ctrl_close; -use tokio::sync::Mutex; mod api; mod commands; @@ -78,9 +75,9 @@ async fn setup( Ok(data) } -async fn handle_shutdown(shard_manager: Arc>, reason: &str) { +async fn handle_shutdown(shard_manager: Arc, reason: &str) { warn!("{reason}! Shutting down bot..."); - shard_manager.lock().await.shutdown_all().await; + shard_manager.shutdown_all().await; println!("{}", "Everything is shutdown. Goodbye!".green()) } @@ -111,7 +108,9 @@ async fn main() -> Result<()> { prefix_options: PrefixFrameworkOptions { prefix: Some("r".into()), - edit_tracker: Some(EditTracker::for_timespan(Duration::from_secs(3600))), + edit_tracker: Some(Arc::from(EditTracker::for_timespan(Duration::from_secs( + 3600, + )))), ..Default::default() }, @@ -119,22 +118,23 @@ async fn main() -> Result<()> { }; let framework = Framework::builder() - .token(token) - .intents(intents) .options(options) .setup(|ctx, ready, framework| Box::pin(setup(ctx, ready, framework))) - .build() - .await - .wrap_err_with(|| "Failed to build framework!")?; + .build(); + + let mut client = serenity::ClientBuilder::new(token, intents) + .framework(framework) + .await?; + + let shard_manager = client.shard_manager.clone(); - let shard_manager = framework.shard_manager().clone(); #[cfg(target_family = "unix")] let mut sigterm = signal(SignalKind::terminate())?; #[cfg(target_family = "windows")] let mut sigterm = ctrl_close()?; tokio::select! { - result = framework.start() => result.map_err(Report::from), + result = client.start() => result.map_err(Report::from), _ = sigterm.recv() => { handle_shutdown(shard_manager, "Received SIGTERM").await; std::process::exit(0); diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 022a051..6bbed10 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -69,7 +69,7 @@ impl Storage { Ok(()) } - async fn expire_key(&self, key: &str, expire_seconds: usize) -> Result<()> { + async fn expire_key(&self, key: &str, expire_seconds: i64) -> Result<()> { debug!("Expiring key {key} in {expire_seconds}"); let mut con = self.client.get_async_connection().await?; diff --git a/src/utils/resolve_message.rs b/src/utils/resolve_message.rs index 165e8c9..b29de97 100644 --- a/src/utils/resolve_message.rs +++ b/src/utils/resolve_message.rs @@ -1,7 +1,12 @@ +use std::str::FromStr; + use color_eyre::eyre::{eyre, Context as _, Result}; use log::*; use once_cell::sync::Lazy; -use poise::serenity_prelude::{ChannelType, Colour, Context, CreateEmbed, Message}; +use poise::serenity_prelude::{ + ChannelId, ChannelType, Colour, Context, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, + Message, MessageId, +}; use regex::Regex; static MESSAGE_PATTERN: Lazy = Lazy::new(|| { @@ -21,103 +26,84 @@ pub fn find_first_image(msg: &Message) -> Option { } pub async fn resolve(ctx: &Context, msg: &Message) -> Result> { - let matches = MESSAGE_PATTERN.captures_iter(&msg.content); + let matches = MESSAGE_PATTERN + .captures_iter(&msg.content) + .map(|capture| capture.extract()); + let mut embeds: Vec = vec![]; - for captured in matches.take(3) { - // don't leak messages from other servers - if let Some(server_id) = captured.get(0) { - let other_server: u64 = server_id.as_str().parse().unwrap_or_default(); - let current_id = msg.guild_id.unwrap_or_default(); + for (_, [_server_id, channel_id, message_id]) in matches { + let channel = ChannelId::from_str(channel_id) + .wrap_err_with(|| format!("Couldn't parse channel ID {channel_id}!"))? + .to_channel_cached(ctx.as_ref()) + .ok_or_else(|| eyre!("Couldn't find Guild Channel from {channel_id}!"))? + .to_owned(); - if &other_server != current_id.as_u64() { - debug!("Not resolving message of other guild."); - continue; - } - } else { - warn!("Couldn't find server_id from Discord link! Not resolving message to be safe"); - continue; - } + let author_can_view = if channel.kind == ChannelType::PublicThread + || channel.kind == ChannelType::PrivateThread + { + let thread_members = channel + .id + .get_thread_members(ctx) + .await + .wrap_err("Couldn't get members from thread!")?; - if let Some(channel_id) = captured.get(1) { - let parsed: u64 = channel_id.as_str().parse().unwrap_or_default(); - let req_channel = ctx - .cache - .channel(parsed) - .ok_or_else(|| eyre!("Couldn't get channel_id from Discord regex!"))? - .guild() - .ok_or_else(|| { - eyre!("Couldn't convert to GuildChannel from channel_id {parsed}!") - })?; - - if !req_channel.is_text_based() { - debug!("Not resolving message is non-text-based channel."); - continue; - } - - if req_channel.kind == ChannelType::PrivateThread { - if let Some(id) = req_channel.parent_id { - let parent = ctx.cache.guild_channel(id).ok_or_else(|| { - eyre!("Couldn't get parent channel {id} for thread {req_channel}!") - })?; - let parent_members = parent.members(ctx).await.unwrap_or_default(); - - if !parent_members.iter().any(|m| m.user.id == msg.author.id) { - debug!("Not resolving message for user not a part of a private thread."); - continue; - } - } - } else if req_channel - .members(ctx) - .await? + thread_members .iter() - .any(|m| m.user.id == msg.author.id) - { - debug!("Not resolving for message for user not a part of a channel"); - continue; - } + .any(|member| member.user_id == msg.author.id) + } else { + channel + .members(ctx) + .wrap_err_with(|| format!("Couldn't get members for channel {channel_id}!"))? + .iter() + .any(|member| member.user.id == msg.author.id) + }; - let message_id: u64 = captured - .get(2) - .ok_or_else(|| eyre!("Couldn't get message_id from Discord regex!"))? - .as_str() - .parse() - .wrap_err_with(|| { - eyre!("Couldn't parse message_id from Discord regex as a MessageId!") - })?; - - let original_message = req_channel.message(ctx, message_id).await?; - let mut embed = CreateEmbed::default(); - embed - .author(|a| { - a.name(original_message.author.tag()) - .icon_url(original_message.author.default_avatar_url()) - }) - .color(Colour::BLITZ_BLUE) - .timestamp(original_message.timestamp) - .footer(|f| f.text(format!("#{}", req_channel.name))) - .description(format!( - "{}\n\n[Jump to original message]({})", - original_message.content, - original_message.link() - )); - - if !original_message.attachments.is_empty() { - embed.fields(original_message.attachments.iter().map(|a| { - ( - "Attachments".to_string(), - format!("[{}]({})", a.filename, a.url), - false, - ) - })); - - if let Some(image) = find_first_image(msg) { - embed.image(image); - } - } - - embeds.push(embed); + if !author_can_view { + debug!("Not resolving message for author who can't see it"); } + + let original_message = channel + .message( + ctx, + MessageId::from_str(message_id) + .wrap_err_with(|| format!("Couldn't parse message ID {message_id}!"))?, + ) + .await + .wrap_err_with(|| { + format!("Couldn't get message from ID {message_id} in channel {channel_id}!") + })?; + + let author = CreateEmbedAuthor::new(original_message.author.tag()) + .icon_url(original_message.author.default_avatar_url()); + let footer = CreateEmbedFooter::new(format!("#{}", channel.name)); + + let mut embed = CreateEmbed::new() + .author(author) + .color(Colour::BLITZ_BLUE) + .timestamp(original_message.timestamp) + .footer(footer) + .description(format!( + "{}\n\n[Jump to original message]({})", + original_message.content, + original_message.link() + )); + + if !original_message.attachments.is_empty() { + embed = embed.fields(original_message.attachments.iter().map(|a| { + ( + "Attachments".to_string(), + format!("[{}]({})", a.filename, a.url), + false, + ) + })); + + if let Some(image) = find_first_image(msg) { + embed = embed.image(image); + } + } + + embeds.push(embed); } Ok(embeds)