diff --git a/.cargo/config.toml b/.cargo/config.toml index dd033b8..ae5a587 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,3 @@ [build] target-dir = 'dist/target' +rustflags = ["-Clink-args=-fuse-ld=lld"] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e82ba69..bcbc41c 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -21,6 +21,7 @@ "streetsidesoftware.code-spell-checker-french", "usernamehw.errorlens", "eamodio.gitlens", - "oderwat.indent-rainbow" + "oderwat.indent-rainbow", + "fill-labs.dependi" ] } diff --git a/Cargo.lock b/Cargo.lock index eb59f8f..086c627 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,14 +202,17 @@ dependencies = [ [[package]] name = "actix-web-prom" -version = "0.6.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df3127d20a5d01c9fc9aceb969a38d31a6767e1b48a54d55a8f56c769a84923" +checksum = "a7eb266b4c692a4a7e68429fcbe4eb3bd55c053f6d84c0522dc83df22395edf6" dependencies = [ "actix-web", "futures-core", + "log", "pin-project-lite", "prometheus", + "regex", + "strfmt", ] [[package]] @@ -533,9 +536,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" dependencies = [ "serde", ] @@ -564,9 +567,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.23" +version = "1.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" dependencies = [ "jobserver", "libc", @@ -616,9 +619,9 @@ dependencies = [ [[package]] name = "clickhouse" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9894248c4c5a4402f76a56c273836a0c32547ec8a68166aedee7e01b7b8d102" +checksum = "9a9a81a1dffadd762ee662635ce409232258ce9beebd7cc0fa227df0b5e7efc0" dependencies = [ "bstr", "bytes", @@ -668,7 +671,7 @@ dependencies = [ "prometheus", "serde", "serde_derive", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "url", ] @@ -1242,9 +1245,9 @@ checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "http" @@ -1404,17 +1407,21 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.3.1", "http-body 1.0.1", "hyper 1.6.0", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -1592,6 +1599,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1676,9 +1693,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -1763,14 +1780,14 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1834,9 +1851,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ "hermit-abi", "libc", @@ -1859,9 +1876,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl" -version = "0.10.72" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags 2.9.1", "cfg-if", @@ -1891,9 +1908,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.108" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -1925,7 +1942,7 @@ dependencies = [ "bytes", "http 1.3.1", "opentelemetry", - "reqwest 0.12.15", + "reqwest 0.12.19", "tracing", ] @@ -1942,7 +1959,7 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost", - "reqwest 0.12.15", + "reqwest 0.12.19", "thiserror 2.0.12", "tokio", "tonic", @@ -1989,9 +2006,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -1999,9 +2016,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", @@ -2118,9 +2135,9 @@ dependencies = [ [[package]] name = "prometheus" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +checksum = "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a" dependencies = [ "cfg-if", "fnv", @@ -2128,7 +2145,7 @@ dependencies = [ "memchr", "parking_lot", "protobuf", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -2156,9 +2173,23 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.28.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror 1.0.69", +] [[package]] name = "pulldown-cmark" @@ -2356,9 +2387,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" dependencies = [ "base64 0.22.1", "bytes", @@ -2383,12 +2414,12 @@ dependencies = [ "sync_wrapper 1.0.2", "tokio", "tower 0.5.2", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows-registry", ] [[package]] @@ -2491,9 +2522,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -2780,9 +2811,9 @@ checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2800,6 +2831,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strfmt" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65" + [[package]] name = "strsim" version = "0.11.1" @@ -3071,9 +3108,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.45.0" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", @@ -3310,6 +3347,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" +dependencies = [ + "bitflags 2.9.1", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -3629,12 +3684,14 @@ dependencies = [ [[package]] name = "uuid" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ "getrandom 0.3.3", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -3894,7 +3951,7 @@ dependencies = [ "windows-interface", "windows-link", "windows-result", - "windows-strings 0.4.2", + "windows-strings", ] [[package]] @@ -3925,17 +3982,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" -[[package]] -name = "windows-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" -dependencies = [ - "windows-result", - "windows-strings 0.3.1", - "windows-targets 0.53.0", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -3945,15 +3991,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -4014,29 +4051,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4049,12 +4070,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4067,12 +4082,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4085,24 +4094,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4115,12 +4112,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4133,12 +4124,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -4151,12 +4136,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4169,12 +4148,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.7.10" diff --git a/Cargo.toml b/Cargo.toml index 3bf20c9..839979f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,22 +13,25 @@ members = [ ] [workspace.dependencies] -poise = { git = 'https://github.com/serenity-rs/poise', branch = 'current' } -tokio = { version = '1.45.0', features = [ - 'macros', - 'rt-multi-thread', - 'io-std', +poise = { git = 'https://github.com/serenity-rs/poise', branch = 'current', features = [ + 'chrono', ] } +tokio = { version = '1.45', features = ['macros', 'rt-multi-thread', 'io-std'] } serde = '1.0' tracing = '0.1' serde_json = '1.0' clickhouse = { version = '0.13', features = ['native-tls', 'uuid', 'chrono'] } -uuid = { version = '1.16', features = ['serde', 'v4'] } +uuid = { version = '1.17', features = ['serde', 'v4'] } chrono = { version = '0.4.41', features = ['serde'] } -croner = { version = "*" } +croner = "2.0.5" [profile.release] lto = true +[profile.dev] +opt-level = 2 +lto = false +incremental = true + [patch.crates-io] serenity = { git = 'https://github.com/serenity-rs/serenity', branch = 'current' } diff --git a/libs/api/src/lib.rs b/libs/api/src/lib.rs index 6687c33..28a6778 100644 --- a/libs/api/src/lib.rs +++ b/libs/api/src/lib.rs @@ -14,7 +14,7 @@ use utoipa_scalar::{Scalar, Servable as ScalarServable}; pub mod apidocs; pub async fn init_api(config: Config, pool: Arc, http: Arc) -> Result<(), ()> { - let port = config.port.clone(); + let port = config.port; HttpServer::new(move || { let cors = Cors::default() .allow_any_origin() @@ -50,13 +50,11 @@ pub async fn init_api(config: Config, pool: Arc, http: Arc) - .bind((Ipv4Addr::UNSPECIFIED, port)) .map_err(|e| { error!("Failed to bind API server: {}", e); - () - })? + })? .run() .await .map_err(|e| { eprintln!("Failed to start API server: {}", e); - () })?; info!("Api server stopped"); Ok(()) diff --git a/libs/bot/src/event/mod.rs b/libs/bot/src/event/mod.rs index 47ffc0f..aa742bb 100644 --- a/libs/bot/src/event/mod.rs +++ b/libs/bot/src/event/mod.rs @@ -1,6 +1,12 @@ use crate::{Data, Error}; -use poise::serenity_prelude::{self as serenity, ActivityData}; -use tracing::{info, span}; +use clickhouse_pool::traits::Model; +use database::{ + trivial::{Trivial, TrivialStatus}, + trivial_question::TrivialQuestion, + trivial_round::TrivialRound, +}; +use poise::serenity_prelude::{self as serenity, ActivityData, FullEvent}; +use tracing::{info, span, Instrument}; pub async fn event_handler( ctx: &serenity::Context, @@ -25,6 +31,115 @@ pub async fn event_handler( ); }); } + FullEvent::Message { new_message, .. } => { + if new_message.author.bot || new_message.guild_id.is_none() { + return Ok(()); + } + let guild_id = match new_message.guild_id { + Some(id) => Some(id), + None => None, + }; + + let channel_id = new_message.channel_id; + + let manager_pool = data.datalake_config.clone(); + + let trivia_query = Trivial::build_select_query( + Some(&format!( + "guild_id = {} and channel_id = {}", + guild_id.unwrap().get(), + channel_id.get() + )), + None, + None, + ); + let trivia_games: Vec = manager_pool + .execute_select_with_retry(&trivia_query) + .await?; + if trivia_games.is_empty() { + return Ok(()); + } + let trivia = &trivia_games[0]; + if trivia.status != TrivialStatus::Started { + return Ok(()); + } + let trivia_round_query = TrivialRound::build_select_query( + Some(&format!( + "trivial_id = '{}' and finished = false", + trivia.id + )), + None, + None, + ); + let trivia_rounds: Vec = manager_pool + .execute_select_with_retry(&trivia_round_query) + .await?; + if trivia_rounds.is_empty() { + return Ok(()); + } + + return async { + let mut trivia_round = trivia_rounds[0].clone(); + let trivia_question_query = TrivialQuestion::build_select_query( + Some(&format!("id = '{}'", trivia_round.question_id)), + None, + None, + ); + let trivia_questions: Vec = manager_pool + .execute_select_with_retry(&trivia_question_query) + .await?; + if trivia_questions.is_empty() { + return Ok(()); + } + let trivia_question = &trivia_questions[0]; + let answer = trivia_question.answer.to_lowercase(); + let mutate_round = match trivia.reward_kind { + database::trivial::TrivialRewardKind::TopThree => { + trivia_round.answer.len() < 3 + && trivia_round + .answer + .iter() + .filter(|&&(id, _, _)| new_message.author.id.get() == id) + .count() + == 0 + } + database::trivial::TrivialRewardKind::TopFive => { + trivia_round.answer.len() < 5 + && trivia_round + .answer + .iter() + .filter(|&&(id, _, _)| new_message.author.id.get() == id) + .count() + == 0 + } + database::trivial::TrivialRewardKind::OnlyTheFirstOne => { + trivia_round.answer.is_empty() + } + }; + if !mutate_round || !new_message.content.contains(&answer) { + return Ok(()); + } + let mut inserter = manager_pool + .get_insert::(TrivialRound::table_name()) + .await?; + trivia_round.sign = -1; // Set sign to -1 to indicate an update + inserter.write(&trivia_round.clone()).await?; + trivia_round.sign = 1; // Set sign to 1 to indicate a new answer + trivia_round.answer.push(( + new_message.author.id.get(), + new_message.content.clone(), + *new_message.timestamp, + )); + inserter.write(&trivia_round.clone()).await?; + Ok(()) + } + .instrument(span!( + tracing::Level::INFO, + "event_handler", + event = "Message" + )) + .await; + } _ => {} } Ok(()) diff --git a/libs/bot/src/helper/mod.rs b/libs/bot/src/helper/mod.rs index 5a87559..ccaa69e 100644 --- a/libs/bot/src/helper/mod.rs +++ b/libs/bot/src/helper/mod.rs @@ -53,15 +53,13 @@ pub async fn is_user_admin_right(ctx: Context<'_>) -> Result { return Ok(false); } let guild = &guilds[0]; - if guild.enrolled { - if guild.moderator.contains(&ctx.author().id.get()) { - info!( - "User {} is a moderator in guild {}.", - ctx.author().id, - guild_id - ); - return Ok(true); - } + if guild.enrolled && guild.moderator.contains(&ctx.author().id.get()) { + info!( + "User {} is a moderator in guild {}.", + ctx.author().id, + guild_id + ); + return Ok(true); } info!( "User {} does not have admin rights in guild {}.", diff --git a/libs/bot/src/lib.rs b/libs/bot/src/lib.rs index d1d0368..a1499e0 100644 --- a/libs/bot/src/lib.rs +++ b/libs/bot/src/lib.rs @@ -58,7 +58,7 @@ pub async fn start_bot( poise::builtins::register_globally(ctx, &framework.options().commands).await?; Ok(Data { config: config.clone(), - datalake_config: datalake_config, + datalake_config, entity_name: format!("{}-{}", config.bot_name, env!("CARGO_PKG_VERSION")), }) }) diff --git a/libs/bot/src/trivia/list.rs b/libs/bot/src/trivia/list.rs index 825ccbb..7dfdab4 100644 --- a/libs/bot/src/trivia/list.rs +++ b/libs/bot/src/trivia/list.rs @@ -17,7 +17,14 @@ pub fn trivia_list_embed(trivia: &Trivial, current_channel: bool) -> serenity_pr .field("Channel", format!("<#{}>", trivia.channel_id), true) .field("Status", format!("{:?}", trivia.status), true) .field("Reward Kind", format!("{:?}", trivia.reward_kind), true) - .field("Reward Amount", trivia.reward_amount.to_string(), true); + .field("Reward Amount", trivia.reward_amount.to_string(), true) + .field("Random Question", trivia.random_question.to_string(), true) + .field( + "Question Asked time", + trivia.question_asked.to_string(), + true, + ) + .field("Answer given time", trivia.answer_given.to_string(), true); if current_channel { embed = embed.color(serenity_prelude::Color::GOLD); diff --git a/libs/bot/src/trivia/load.rs b/libs/bot/src/trivia/load.rs index 72aeb58..0565abd 100644 --- a/libs/bot/src/trivia/load.rs +++ b/libs/bot/src/trivia/load.rs @@ -1,10 +1,8 @@ use crate::helper::is_user_admin_right; use crate::{Context, Error}; use clickhouse_pool::traits::Model; -use database::trivial::Trivial; -use database::trivial_question::TrivialQuestion; -use poise::serenity_prelude; -use poise::serenity_prelude::Channel; +use database::{trivial::Trivial, trivial_question::TrivialQuestion}; +use poise::serenity_prelude::{self, Channel}; use tracing::{info, instrument, warn}; /// Load a csv file containing trivia questions and answers into the database. @@ -158,10 +156,10 @@ pub async fn load( for (question, answer) in parsed_content { let trivial_question = TrivialQuestion { trivial_id: trivia.id, - guild_id: guild_id, - channel_id: channel_id, - question: question, - answer: answer, + guild_id, + channel_id, + question, + answer, creator_id: ctx.author().id.get(), updater_id: ctx.author().id.get(), ..Default::default() diff --git a/libs/clickhouse_pool/Cargo.toml b/libs/clickhouse_pool/Cargo.toml index 16aabb9..74e5734 100644 --- a/libs/clickhouse_pool/Cargo.toml +++ b/libs/clickhouse_pool/Cargo.toml @@ -14,9 +14,9 @@ futures-util = "0.3" serde = { workspace = true } serde_derive = "1.0" log = { version = "^0.4.21", features = ["kv_serde"] } -prometheus = "0.13" -actix-web-prom = "0.6" +prometheus = "0.14" +actix-web-prom = "0.10" url = "2.5.2" anyhow = "1.0" -thiserror = "1.0.31" +thiserror = "2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/libs/clickhouse_pool/src/pool_manager.rs b/libs/clickhouse_pool/src/pool_manager.rs index f8a575d..845a687 100644 --- a/libs/clickhouse_pool/src/pool_manager.rs +++ b/libs/clickhouse_pool/src/pool_manager.rs @@ -28,7 +28,7 @@ impl PoolManager { metrics.clone(), )); - let _ = match pool.initialize().await { + match pool.initialize().await { Ok(_) => { log::debug!("Pool warmed up and initialized successfully"); } @@ -49,12 +49,12 @@ impl PoolManager { self.pool.clone() } - pub async fn get_insert( + pub async fn get_insert( &self, table_name: &str, ) -> Result, clickhouse::error::Error> where - T: Model + Send + Sync + 'static, + T: Model + Row + Send + Sync + 'static, { self.pool .clone() diff --git a/libs/config/src/dotenv/mod.rs b/libs/config/src/dotenv/mod.rs index 55750a5..d2ca2fd 100644 --- a/libs/config/src/dotenv/mod.rs +++ b/libs/config/src/dotenv/mod.rs @@ -1,14 +1,13 @@ use std::{ env::{self, set_var}, io::Read, - path::PathBuf, }; use tracing::info; // Load environment variables from a .env file without external dependencies pub fn load_dot_env() { - let mut d = PathBuf::from(env::current_dir().unwrap()); + let mut d = env::current_dir().unwrap(); d.push(".env"); if !d.exists() { info!("No .env file found"); diff --git a/libs/config/src/lib.rs b/libs/config/src/lib.rs index 626d833..76c3e12 100644 --- a/libs/config/src/lib.rs +++ b/libs/config/src/lib.rs @@ -37,7 +37,7 @@ pub struct Config { } pub fn parse_local_config() -> Config { - let mut d = PathBuf::from(env::current_dir().unwrap()); + let mut d = env::current_dir().unwrap(); d.push("resources/config.toml"); dotenv::load_dot_env(); parse_config(d) @@ -45,10 +45,8 @@ pub fn parse_local_config() -> Config { pub fn parse_config(path_buff: PathBuf) -> Config { let config_file_string = - read_to_string(path_buff.clone().into_os_string().into_string().unwrap()).expect(&format!( - "Failed to read config file: {}", - path_buff.display() - )); + read_to_string(path_buff.clone().into_os_string().into_string().unwrap()) + .unwrap_or_else(|_| panic!("Failed to read config file: {}", path_buff.display())); let mut config: Config = toml::from_str(&config_file_string).expect("Failed to parse config file"); override_config_with_env_vars(&mut config); diff --git a/libs/database/Cargo.toml b/libs/database/Cargo.toml index 70cedad..c940e59 100644 --- a/libs/database/Cargo.toml +++ b/libs/database/Cargo.toml @@ -12,7 +12,7 @@ clickhouse = { workspace = true } uuid = { workspace = true } chrono = { workspace = true } poise = { workspace = true } -serde_repr = "0.1.20" +serde_repr = "0.1" serde_json = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/libs/database/src/lib.rs b/libs/database/src/lib.rs index 8624ad1..fb96a12 100644 --- a/libs/database/src/lib.rs +++ b/libs/database/src/lib.rs @@ -91,7 +91,7 @@ pub async fn create_manager_and_init( #[instrument(skip(manager))] pub async fn create_table(manager: PoolManager) -> Result> { - let _ = match manager.execute_with_retry(T::create_table_sql()).await { + match manager.execute_with_retry(T::create_table_sql()).await { Ok(_) => { info!("Table {} created successfully", T::table_name()); } diff --git a/libs/database/src/trivial.rs b/libs/database/src/trivial.rs index 25cac01..1ec5ca8 100644 --- a/libs/database/src/trivial.rs +++ b/libs/database/src/trivial.rs @@ -103,8 +103,8 @@ impl Default for Trivial { taken_into_account: true, status: TrivialStatus::Init, sign: 1, - question_asked: "".to_string(), - answer_given: "".to_string(), + question_asked: "0 9 * * *".to_string(), + answer_given: "30 22 * * *".to_string(), } } } diff --git a/libs/database/src/trivial_round.rs b/libs/database/src/trivial_round.rs index 5c2ed31..f2c26b2 100644 --- a/libs/database/src/trivial_round.rs +++ b/libs/database/src/trivial_round.rs @@ -12,6 +12,7 @@ pub struct TrivialRound { pub trivial_id: Uuid, #[serde(with = "clickhouse::serde::uuid")] pub question_id: Uuid, + /// User ID, Answer, Timestamp pub answer: Vec<(u64, String, DateTime)>, pub finished: bool, @@ -20,6 +21,23 @@ pub struct TrivialRound { pub created_at: DateTime, #[serde(with = "clickhouse::serde::chrono::datetime64::millis")] pub updated_at: DateTime, + + pub sign: i8, +} + +impl Default for TrivialRound { + fn default() -> Self { + Self { + id: Uuid::new_v4(), + trivial_id: Uuid::new_v4(), + question_id: Uuid::new_v4(), + answer: Vec::new(), + finished: false, + created_at: Utc::now(), + updated_at: Utc::now(), + sign: 1, + } + } } impl Model for TrivialRound { @@ -45,8 +63,9 @@ impl Model for TrivialRound { answer Array(Tuple(UInt64, String, DateTime64(3))), finished Bool, created_at DateTime64(3), - updated_at DateTime64(3) - ) ENGINE = MergeTree() + updated_at DateTime64(3), + sign Int8 + ) ENGINE = CollapsingMergeTree(sign) ORDER BY (id, trivial_id) "# .trim() @@ -61,6 +80,7 @@ impl Model for TrivialRound { "finished", "created_at", "updated_at", + "sign", ] } @@ -75,6 +95,7 @@ impl Model for TrivialRound { self.finished.to_string(), self.created_at.to_string(), self.updated_at.to_string(), + self.sign.to_string(), ], ) }