From 19dc2963f50e1c05c2837160090195131ec2acec Mon Sep 17 00:00:00 2001 From: tretrauit Date: Sat, 30 Dec 2023 21:39:44 +0700 Subject: [PATCH] feat: add proper logging --- .gitignore | 3 + Cargo.lock | 672 +++++++++++++++++++++++++++ Cargo.toml | 12 +- swordfish-common/Cargo.toml | 6 + swordfish-common/src/constants.rs | 2 + swordfish-common/src/lib.rs | 43 +- swordfish-common/src/tesseract.rs | 1 + swordfish-common/src/utils/karuta.rs | 3 + swordfish/Cargo.toml | 8 + swordfish/src/config.rs | 42 ++ swordfish/src/katana.rs | 37 ++ swordfish/src/main.rs | 155 +++++- swordfish/src/utils.rs | 0 13 files changed, 961 insertions(+), 23 deletions(-) create mode 100644 swordfish-common/src/constants.rs create mode 100644 swordfish-common/src/tesseract.rs create mode 100644 swordfish-common/src/utils/karuta.rs create mode 100644 swordfish/src/config.rs create mode 100644 swordfish/src/katana.rs create mode 100644 swordfish/src/utils.rs diff --git a/.gitignore b/.gitignore index ea8c4bf..bbed3f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ +*.log +.env +config.toml /target diff --git a/Cargo.lock b/Cargo.lock index a14acf0..f875f68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -79,6 +88,34 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -112,6 +149,12 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + [[package]] name = "byteorder" version = "1.5.0" @@ -164,6 +207,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -183,6 +235,23 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "command_attr" version = "0.5.1" @@ -238,6 +307,28 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.18" @@ -247,6 +338,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -297,6 +394,18 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -331,12 +440,46 @@ dependencies = [ "version_check", ] +[[package]] +name = "exr" +version = "1.71.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "fdeflate" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fern" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" +dependencies = [ + "log", +] + [[package]] name = "flate2" version = "1.0.28" @@ -347,6 +490,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -469,6 +621,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.28.1" @@ -500,12 +662,36 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "0.2.11" @@ -540,6 +726,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.28" @@ -611,6 +803,25 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "qoi", + "tiff", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -633,6 +844,15 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.66" @@ -642,6 +862,56 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "leptess" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8964e3d3270be667dda2d0026e8c77011bafaad33936011b93750489987513" +dependencies = [ + "tesseract-plumbing", + "thiserror", +] + +[[package]] +name = "leptonica-plumbing" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21713d6ceb6f5f83b8f2facac6ae762cfc1c394f239cd2a7366a0e736fced731" +dependencies = [ + "leptonica-sys", + "libc", + "thiserror", +] + +[[package]] +name = "leptonica-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335aadd5fa8d493d62d5596a980ce6ee823a72da45e89bcc45be3841e6d74bff" +dependencies = [ + "bindgen", + "pkg-config", + "vcpkg", +] + [[package]] name = "levenshtein" version = "1.0.5" @@ -654,6 +924,16 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -676,6 +956,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.6.4" @@ -713,6 +1002,12 @@ dependencies = [ "triomphe", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -720,6 +1015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -733,6 +1029,47 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[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-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -742,6 +1079,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.32.2" @@ -757,6 +1104,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -780,6 +1133,12 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -798,6 +1157,25 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + +[[package]] +name = "png" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -830,6 +1208,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quote" version = "1.0.33" @@ -869,6 +1256,26 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -878,6 +1285,50 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.3.6", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + [[package]] name = "reqwest" version = "0.11.23" @@ -941,6 +1392,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.28" @@ -1066,6 +1523,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1125,6 +1591,36 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "skeptic" version = "0.13.7" @@ -1170,6 +1666,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "static_assertions" @@ -1181,12 +1680,26 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" name = "swordfish" version = "0.1.0" dependencies = [ + "dotenvy", + "image", + "serde", "serenity", + "swordfish-common", + "tokio", + "toml", ] [[package]] name = "swordfish-common" version = "0.1.0" +dependencies = [ + "fern", + "humantime", + "leptess", + "log", + "tracing", + "tracing-subscriber", +] [[package]] name = "syn" @@ -1250,6 +1763,29 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "tesseract-plumbing" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25fbbb95169954a9262a565fbfb001c4d9dad271d48142e6632a3e2b7314b35" +dependencies = [ + "leptonica-plumbing", + "tesseract-sys", + "thiserror", +] + +[[package]] +name = "tesseract-sys" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd33f6f216124cfaf0fa86c2c0cdf04da39b6257bd78c5e44fa4fa98c3a5857b" +dependencies = [ + "bindgen", + "leptonica-sys", + "pkg-config", + "vcpkg", +] + [[package]] name = "thiserror" version = "1.0.52" @@ -1270,6 +1806,27 @@ dependencies = [ "syn 2.0.43", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.31" @@ -1324,7 +1881,10 @@ dependencies = [ "bytes", "libc", "mio", + "num_cpus", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.48.0", @@ -1380,6 +1940,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -1416,6 +2010,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -1551,6 +2175,18 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -1677,6 +2313,24 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1849,6 +2503,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.5.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -1864,3 +2527,12 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] diff --git a/Cargo.toml b/Cargo.toml index ec67dfc..7696445 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ -[workspace] -resolver = "1" -members = [ - "swordfish-common", - "swordfish" -] \ No newline at end of file +[workspace] +resolver = "1" +members = [ + "swordfish-common", + "swordfish" +] diff --git a/swordfish-common/Cargo.toml b/swordfish-common/Cargo.toml index 829f3ec..471bf70 100644 --- a/swordfish-common/Cargo.toml +++ b/swordfish-common/Cargo.toml @@ -6,3 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +fern = "0.6.2" +humantime = "2.1.0" +leptess = "0.14.0" +log = "0.4.20" +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } diff --git a/swordfish-common/src/constants.rs b/swordfish-common/src/constants.rs new file mode 100644 index 0000000..cfbfb18 --- /dev/null +++ b/swordfish-common/src/constants.rs @@ -0,0 +1,2 @@ +pub const KATANA_ID: u64 = 646937666251915264; +pub const SOFA_ID: u64 = 853629533855809596; diff --git a/swordfish-common/src/lib.rs b/swordfish-common/src/lib.rs index 7d12d9a..979a793 100644 --- a/swordfish-common/src/lib.rs +++ b/swordfish-common/src/lib.rs @@ -1,14 +1,33 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} +pub use log; +pub use tracing::{debug, error, info, trace, warn}; +use tracing_subscriber::{self, fmt, EnvFilter}; +pub mod constants; +pub mod tesseract; -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +pub fn setup_logger(level: &str) -> Result<(), fern::InitError> { + // I don't really know how to do it because the unset variable trick doesn't work + // since the types can be + let formatter = fmt::format() + .with_level(true) + .with_target(true) + .with_thread_ids(false) + .with_thread_names(false); // include the name of the current thread.pretty(); + let filter = EnvFilter::builder() + .from_env() + .unwrap() + .add_directive( + format!("swordfish={}", level.to_lowercase()) + .parse() + .unwrap(), + ) + .add_directive( + format!("swordfish-common={}", level.to_lowercase()) + .parse() + .unwrap(), + ); + tracing_subscriber::fmt() + .event_format(formatter) + .with_env_filter(filter) + .init(); + Ok(()) } diff --git a/swordfish-common/src/tesseract.rs b/swordfish-common/src/tesseract.rs new file mode 100644 index 0000000..a416b0b --- /dev/null +++ b/swordfish-common/src/tesseract.rs @@ -0,0 +1 @@ +pub use leptess::LepTess; diff --git a/swordfish-common/src/utils/karuta.rs b/swordfish-common/src/utils/karuta.rs new file mode 100644 index 0000000..fee54aa --- /dev/null +++ b/swordfish-common/src/utils/karuta.rs @@ -0,0 +1,3 @@ +fn parse_card() { + +} \ No newline at end of file diff --git a/swordfish/Cargo.toml b/swordfish/Cargo.toml index 602cb82..60f2018 100644 --- a/swordfish/Cargo.toml +++ b/swordfish/Cargo.toml @@ -6,4 +6,12 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +dotenvy = "0.15.7" +image = "0.24.7" +serde = "1.0.193" serenity = "0.12.0" +tokio = { version = "1.35.1", features = ["full"] } +toml = "0.8.8" + +[dependencies.swordfish-common] +path = "../swordfish-common" diff --git a/swordfish/src/config.rs b/swordfish/src/config.rs new file mode 100644 index 0000000..6f7ba64 --- /dev/null +++ b/swordfish/src/config.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; +use std::fs; + +#[derive(Serialize, Deserialize, Debug)] +pub struct FileLog { + pub enabled: bool, + pub path: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Log { + pub level: String, + pub file: FileLog, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Config { + pub log: Log, +} + +impl Config { + pub fn new() -> Config { + Config { + log: Log { + level: "info".to_string(), + file: FileLog { + enabled: false, + path: "swordfish.log".to_string(), + }, + }, + } + } + pub fn save(&self, path: &str) { + let toml = toml::to_string(&self).unwrap(); + fs::write(path, toml).expect("Failed to write config file"); + } + pub fn load(path: &str) -> Config { + let content = fs::read_to_string(path).expect("Failed to read config file"); + let config: Config = toml::from_str(&content.as_str()).unwrap(); + return config; + } +} diff --git a/swordfish/src/katana.rs b/swordfish/src/katana.rs new file mode 100644 index 0000000..1bcfff1 --- /dev/null +++ b/swordfish/src/katana.rs @@ -0,0 +1,37 @@ +use image::io::Reader as ImageReader; +use serenity::framework::standard::macros::{command, group}; +use serenity::framework::standard::{CommandResult, Configuration, StandardFramework}; +use serenity::model::channel::Message; +use serenity::prelude::*; +use std::io::Cursor; +use swordfish_common::tesseract::LepTess; +use swordfish_common::{debug, error, info, trace, warn}; + +pub async fn analyze_drop_message(message: &Message) -> Result<(), String> { + if message.attachments.len() < 1 { + return Err("No attachments found".to_string()); + }; + trace!("Initializing Tesseract OCR engine..."); + let mut lep_tess = LepTess::new(None, "eng").unwrap(); + // Get the image attachment + let attachment = &message.attachments[0]; + let image_bytes = match attachment.download().await { + Ok(bytes) => bytes, + Err(why) => return Err(format!("Failed to download attachment: {:?}", why)), + }; + // Pre-process the image + let mut img = match ImageReader::new(Cursor::new(image_bytes)).with_guessed_format() { + Ok(reader) => match reader.decode() { + Ok(img) => img, + Err(why) => return Err(format!("Failed to decode image: {:?}", why)), + }, + Err(why) => return Err(format!("Failed to read image: {:?}", why)), + }; + img = img.grayscale(); + img.save("debug.png").unwrap(); + match lep_tess.set_image_from_mem(&img.as_bytes()) { + Ok(_) => (), + Err(why) => return Err(format!("Failed to set image: {:?}", why)), + }; + Ok(()) +} diff --git a/swordfish/src/main.rs b/swordfish/src/main.rs index a531866..4470c8a 100644 --- a/swordfish/src/main.rs +++ b/swordfish/src/main.rs @@ -1,7 +1,152 @@ -#[path = "../../swordfish-common/src/lib.rs"] -mod swordfish_common; +use dotenvy::dotenv; +use serenity::async_trait; +use serenity::framework::standard::macros::{command, group}; +use serenity::framework::standard::{CommandResult, Configuration, StandardFramework}; +use serenity::model::{ + channel::Message, + id::{ChannelId, MessageId}, +}; +use serenity::prelude::*; +use std::env; +use std::path::Path; +use swordfish_common::*; -fn main() { - println!("lol blud"); - swordfish_common::add(1, 2); +mod config; +mod katana; + +const GITHUB_URL: &str = "https://github.com/teppyboy/swordfish"; + +#[group] +#[commands(ping, drop_analyze)] +struct General; +struct Handler; +#[async_trait] +impl EventHandler for Handler { + async fn message(&self, ctx: Context, msg: Message) { + if msg.author.id == ctx.cache.current_user().id { + trace!("Ignoring message from self"); + return; + } + trace!("Message: {}, sender: {}", msg.content, msg.author.id); + if msg.author.id.get() == constants::KATANA_ID { + parse_katana(&ctx, &msg).await.unwrap(); + } + if msg.content == "pong" { + info!("Message contains 'pong'"); + if let Err(why) = msg.channel_id.say(&ctx.http, "Pongo!").await { + println!("Error sending message: {:?}", why); + } + } + } +} + +async fn parse_katana(ctx: &Context, msg: &Message) -> Result<(), String> { + if msg.content.contains("is dropping 3 cards!") + || msg + .content + .contains("I'm dropping 3 cards since this server is currently active!") + { + trace!("Card drop detected, executing drop analyzer..."); + katana::analyze_drop_message(msg).await?; + } + Ok(()) +} + +#[tokio::main] +async fn main() { + dotenv().unwrap(); + let token = env::var("DISCORD_TOKEN").expect("Token not found"); + let config: config::Config; + if Path::new("./config.toml").exists() { + config = config::Config::load("./config.toml"); + } else { + config = config::Config::new(); + config.save("./config.toml"); + } + let log_level = env::var("LOG_LEVEL").unwrap_or(config.log.level); + setup_logger(&log_level).expect("Failed to setup logger"); + info!("Swordfish v{} - {}", env!("CARGO_PKG_VERSION"), GITHUB_URL); + info!("Log level: {}", log_level); + info!("Loading database..."); + warn!("Databases are not implemented yet"); + info!("Initializing Discord client..."); + let framework = StandardFramework::new().group(&GENERAL_GROUP); + framework.configure(Configuration::new().prefix("~")); // set the bot's prefix to "~" + + // Login with a bot token from the environment + let intents = GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT; + let mut client = Client::builder(token, intents) + .event_handler(Handler) + .framework(framework) + .await + .expect("Error creating client"); + + info!("Starting client..."); + // start listening for events by starting a single shard + if let Err(why) = client.start().await { + eprintln!("An error occurred while running the client: {:?}", why); + } +} + +#[command] +async fn ping(ctx: &Context, msg: &Message) -> CommandResult { + msg.reply(ctx, "Pong!").await?; + Ok(()) +} + +#[command] +async fn drop_analyze(ctx: &Context, msg: &Message) -> CommandResult { + let target_channel_id = match msg.content.split(" ").nth(1) { + Some(content) => match content.parse::() { + Ok(id) => id, + Err(why) => { + msg.reply(ctx, format!("Failed to parse message ID: {:?}", why)) + .await?; + return Ok(()); + } + }, + None => { + msg.reply(ctx, "No message ID provided").await?; + return Ok(()); + } + }; + let target_msg_id = match msg.content.split(" ").nth(2) { + Some(content) => match content.parse::() { + Ok(id) => id, + Err(why) => { + msg.reply(ctx, format!("Failed to parse message ID: {:?}", why)) + .await?; + return Ok(()); + } + }, + None => { + msg.reply(ctx, "No message ID provided").await?; + return Ok(()); + } + }; + let target_msg = match ctx + .http() + .get_message( + ChannelId::new(target_channel_id), + MessageId::new(target_msg_id), + ) + .await + { + Ok(msg) => msg, + Err(why) => { + msg.reply(ctx, format!("Failed to get message: {:?}", why)) + .await?; + return Ok(()); + } + }; + match katana::analyze_drop_message(&target_msg).await { + Ok(_) => { + msg.reply(ctx, "Drop analysis complete").await?; + } + Err(why) => { + msg.reply(ctx, format!("Failed to analyze drop: {:?}", why)) + .await?; + } + }; + Ok(()) } diff --git a/swordfish/src/utils.rs b/swordfish/src/utils.rs new file mode 100644 index 0000000..e69de29