From 5870f790ba2472713d076bec850283a7a0d474ad Mon Sep 17 00:00:00 2001 From: Evann Date: Wed, 20 Mar 2024 02:32:43 +0100 Subject: [PATCH] 1.5.0 - Webp attachments --- Cargo.lock | 376 +++++++++++++++++++++++++++++++++++++-- Cargo.toml | 5 +- src/commands/events.rs | 73 ++++++-- src/main.rs | 10 +- src/utils/image_saver.rs | 19 ++ src/utils/mod.rs | 1 + 6 files changed, 446 insertions(+), 38 deletions(-) create mode 100644 src/utils/image_saver.rs diff --git a/Cargo.lock b/Cargo.lock index 1523e32..f942211 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.7.6" @@ -28,6 +34,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +dependencies = [ + "memchr", +] + [[package]] name = "aho-corasick" version = "1.0.2" @@ -128,6 +143,15 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "979d348dc50dfcd050a87df408ec61f01a0a27ee9b4ebdc6085baba8275b2c7f" +dependencies = [ + "byteorder", +] + [[package]] name = "base64" version = "0.13.1" @@ -161,6 +185,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" + [[package]] name = "bitflags" version = "1.3.2" @@ -207,7 +237,7 @@ dependencies = [ "indexmap 1.9.3", "js-sys", "lazy_static", - "rand", + "rand 0.8.5", "serde", "serde_bytes", "serde_json", @@ -254,13 +284,19 @@ dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", - "num-traits", + "num-traits 0.2.15", "serde", "time 0.1.45", "wasm-bindgen", "winapi", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "convert_case" version = "0.4.0" @@ -312,6 +348,31 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +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" @@ -412,6 +473,16 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + [[package]] name = "derivative" version = "2.2.0" @@ -513,6 +584,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +dependencies = [ + "num-traits 0.1.43", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -603,6 +683,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -707,6 +793,12 @@ dependencies = [ "slab", ] +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + [[package]] name = "generator" version = "0.7.5" @@ -741,6 +833,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gif" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e41945ba23db3bf51b24756d73d81acb4f28d85c3dccc32c6fae904438c25f" +dependencies = [ + "color_quant", + "lzw", +] + [[package]] name = "gimli" version = "0.27.3" @@ -979,6 +1081,36 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95816db758249fe16f23a4e23f1a3a817fe11892dbfd1c5836f625324702158" +dependencies = [ + "byteorder", + "enum_primitive", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits 0.1.43", + "png", + "scoped_threadpool", +] + +[[package]] +name = "image-base64" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ebeec3f3b7e9bc25e92efad331332cb5c9a386d91c4163bbe94a7cac3edce52" +dependencies = [ + "base64 0.4.2", + "image", + "regex 0.2.11", + "rust-crypto", + "rustc-serialize", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1000,6 +1132,12 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "inflate" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" + [[package]] name = "inlinable_string" version = "0.1.15" @@ -1061,6 +1199,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.64" @@ -1146,6 +1293,12 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + [[package]] name = "mac" version = "0.1.1" @@ -1282,7 +1435,7 @@ dependencies = [ "md-5", "pbkdf2", "percent-encoding", - "rand", + "rand 0.8.5", "rustc_version_runtime", "rustls 0.20.8", "rustls-pemfile", @@ -1360,6 +1513,45 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits 0.2.15", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.15", +] + +[[package]] +name = "num-rational" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +dependencies = [ + "num-integer", + "num-traits 0.2.15", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.15", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1390,15 +1582,16 @@ dependencies = [ [[package]] name = "obsessed-yanqing" -version = "1.4.6" +version = "1.5.0" dependencies = [ "chrono", + "image-base64", "levenshtein", "mongodb", "poise", "prometheus-client", - "rand", - "regex", + "rand 0.8.5", + "regex 1.9.1", "reqwest", "rocket", "select", @@ -1466,7 +1659,7 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ - "num-traits", + "num-traits 0.2.15", ] [[package]] @@ -1562,7 +1755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -1592,6 +1785,18 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "png" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb773e9a557edb568ce9935cf783e3cdcabe06a9449d41b3e5506d88e582c82" +dependencies = [ + "bitflags 0.7.0", + "deflate", + "inflate", + "num-iter", +] + [[package]] name = "poise" version = "0.5.5" @@ -1606,7 +1811,7 @@ dependencies = [ "once_cell", "parking_lot", "poise_macros", - "regex", + "regex 1.9.1", "serenity", "tokio", ] @@ -1701,6 +1906,29 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +dependencies = [ + "libc", + "rand 0.4.6", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.8.5" @@ -1709,7 +1937,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1719,9 +1947,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -1731,6 +1974,35 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1760,13 +2032,26 @@ dependencies = [ "syn 2.0.27", ] +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +dependencies = [ + "aho-corasick 0.6.10", + "memchr", + "regex-syntax 0.5.6", + "thread_local 0.3.6", + "utf8-ranges", +] + [[package]] name = "regex" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.2", "memchr", "regex-automata 0.3.3", "regex-syntax 0.7.4", @@ -1787,11 +2072,20 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.2", "memchr", "regex-syntax 0.7.4", ] +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +dependencies = [ + "ucd-util", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -1896,7 +2190,7 @@ dependencies = [ "num_cpus", "parking_lot", "pin-project-lite", - "rand", + "rand 0.8.5", "ref-cast", "rocket_codegen", "rocket_http", @@ -1955,12 +2249,31 @@ dependencies = [ "uncased", ] +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +dependencies = [ + "gcc", + "libc", + "rand 0.3.23", + "rustc-serialize", + "time 0.1.45", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-serialize" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2086,6 +2399,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -2530,6 +2849,15 @@ dependencies = [ "syn 2.0.27", ] +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +dependencies = [ + "lazy_static", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -2774,10 +3102,10 @@ dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex 1.9.1", "sharded-slab", "smallvec", - "thread_local", + "thread_local 1.1.7", "tracing", "tracing-core", "tracing-log", @@ -2800,7 +3128,7 @@ dependencies = [ "ipnet", "lazy_static", "log", - "rand", + "rand 0.8.5", "smallvec", "thiserror", "tinyvec", @@ -2846,7 +3174,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "rustls 0.20.8", "sha-1", "thiserror", @@ -2887,6 +3215,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ucd-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd2fc5d32b590614af8b0a20d837f32eca055edd0bbead59a9cfe80858be003" + [[package]] name = "uncased" version = "0.9.9" @@ -2957,6 +3291,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + [[package]] name = "uuid" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index e81f8ac..a864837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsessed-yanqing" -version = "1.4.7" +version = "1.5.0" edition = "2021" authors = ["Evann Regnault"] license = "MIT" @@ -21,4 +21,5 @@ rand = "0.8.5" mongodb = "2.6.0" chrono = "0.4.26" prometheus-client = "0.21.2" -rocket = "0.5.0-rc.3" \ No newline at end of file +rocket = "0.5.0-rc.3" +image-base64 = "0.1.0" \ No newline at end of file diff --git a/src/commands/events.rs b/src/commands/events.rs index 5966cd3..125920e 100644 --- a/src/commands/events.rs +++ b/src/commands/events.rs @@ -6,7 +6,7 @@ use chrono::{NaiveDateTime}; use regex::{Regex}; use select::document::Document; use select::node::Node; -use select::predicate::{Class, Name, Predicate}; +use select::predicate::{Attr, Class, Name, Not, Predicate}; use serenity::builder::CreateEmbed; use serenity::http::CacheHttp; use serenity::model::channel::Channel; @@ -14,13 +14,14 @@ use serenity::model::id::{ChannelId, MessageId}; use serenity::utils::{Color, Colour}; use crate::data::{Context, Error}; use crate::mongo::core::{add_discord_status_message, get_discord_status_message, StatusMessage}; +use crate::utils; pub async fn get_main_prydwen() -> String { reqwest::get("https://www.prydwen.gg/star-rail/").await.expect("Cannot get Prydwen").text().await.expect("Cannot get data") } -#[derive(Clone)] +#[derive(Clone, Debug)] enum EventType { CharacterBanner, ConeBanner, @@ -28,29 +29,35 @@ enum EventType { Other, } -#[derive(Clone)] +#[derive(Clone, Debug)] struct BannerData { five_stars: String, four_stars: Vec } -#[derive(Clone)] +#[derive(Clone, Debug)] struct EventTime { start: Option, end: Option } -#[derive(Clone)] +#[derive(Clone, Debug)] struct Event { name: String, description: Option<(String, String)>, time: EventTime, - image: Option, + image: Option, banner_data: Option, color: Option, event_type: EventType } +#[derive(Clone, Debug)] +enum ImageType { + Url(String), + LocalPath(String) +} + struct Code { code: String, new: bool @@ -133,7 +140,6 @@ fn get_time(event: Node) -> EventTime { event.find(Class("duration")).next().map(|x| { let text = x.text(); let dates = Regex::new(r"[-—–]").expect("Can't create split time regex").split(text.as_str()).collect::>(); - println!("{:?}", dates); let start_date_text = dates.first().expect("Cannot get start date string").to_owned(); let start = get_date(start_date_text).map(|x| { @@ -189,15 +195,28 @@ fn get_description(event: Node) -> Option<(String, String)> { description } -fn get_image_color(doc: &str, attributes: &mut Split) -> (Option, Option) { +fn get_image_color(doc: &str, attributes: &mut Split) -> (Option, Option) { let id = attributes.find(|p| !p.to_owned().eq("accordion-item")).expect("Error while getting other id"); - let image_regex = Regex::new(r".accordion-item\.idofevent button\{background-color:#([0-9a-f]{6});background-image:url\((/static/.*?\.jpg)\)}".replace("idofevent", id).as_str()).expect("Cannot created REGEX"); + let image_regex = Regex::new(r".accordion-item\.idofevent button\{background-color:#([0-9a-f]{6});background-image:url\((/static/.*?\.(jpg|webp)|data:image/webp;base64,[A-Za-z0-9+/]*[=]*)\)}".replace("idofevent", id).as_str()).expect("Cannot created REGEX"); let captures = image_regex.captures(doc).expect("Cannot scan document"); let color = captures.get(1).map(|c| { let num = i32::from_str_radix(c.as_str(), 16).expect("Cannot convert color to int"); Color::from_rgb(((num >> 16) & 0xff) as u8, ((num >> 8) & 0xff) as u8, (num & 0xff) as u8) }); - let image = captures.get(2).map(|x| format!("https://www.prydwen.gg{}", x.as_str())); + + let image = match captures.get(2) { + Some(x) if x.as_str().starts_with("/static") => { + Some(ImageType::Url(format!("https://www.prydwen.gg{}", x.as_str()))) + }, + Some(x) => { + let b64 = x.as_str(); + Some(ImageType::LocalPath(utils::image_saver::write_image_from_b64(id.into(), b64.into()))) + }, + None => { + None + } + }; + (image, color) } @@ -220,11 +239,11 @@ fn get_event_type(event: Node, description: &Option<(String, String)>) -> EventT } fn get_banner_data(event: Node) -> Option { - let five_stars = event.find(Class("rarity-5").and(Class("avatar").or(Class("hsr-set-image"))).descendant(Name("picture").descendant(Name("img")))).next().map(|x|{ + let five_stars = event.find(Class("rarity-5").and(Class("avatar").or(Class("hsr-set-image"))).descendant(Name("img").and(Not(Attr("role", "presentation"))))).next().map(|x|{ x.attr("alt").expect("Cannot get five star") }).or(None); let four_stars = event.find(Class("rarity-4").and(Class("avatar").or(Class("hsr-set-image")))).take(3).map(|four_stars_node| { - four_stars_node.find(Name("picture").descendant(Name("img"))).next().map(|x| x.attr("alt").expect("Cannot get four stars").to_string()).expect("") + four_stars_node.find(Name("img").and(Not(Attr("role", "presentation")))).next().map(|x| x.attr("alt").expect("Cannot get four stars").to_string()).expect("No four stars") }).collect::>(); match five_stars { @@ -247,7 +266,10 @@ fn create_current_events_embeds(doc : &str) -> Vec { .title(event.name); if let Some(image) = event.image { - embed = embed.image(image); + match image { + ImageType::Url(x) => {embed = embed.image(x)} + ImageType::LocalPath(x) => {embed = embed.attachment(x)} + } } if let Some(color) = event.color { @@ -380,10 +402,13 @@ pub async fn create_event_message( } let embeds = create_event_embeds().await; + let files = get_files_from_embeds(&embeds); - let msg = channel.id().send_message(ctx, |f| { + let msg = channel.id() + .send_files(ctx, files.iter().map(|x| x.as_str()).collect::>(), |f| { f.add_embeds(embeds) - }).await.unwrap(); + } + ).await.unwrap(); let sm = StatusMessage { message_id: *msg.id.as_u64() as i64, @@ -400,7 +425,23 @@ pub async fn create_event_message( e.title("Success !") .description(format!("The event message has been created in #{}", channel_name)) }).ephemeral(true) - }).await.expect("TODO: panic message"); + }).await.unwrap(); Ok(()) +} + +pub fn get_files_from_embeds(embeds: &Vec) -> Vec { + embeds.clone().into_iter().map(|e| { + if let Some(x) = e.clone().0.get("image") { + let name = x.as_object().unwrap().get("url").unwrap().to_string(); + let name = name.replace("\"", ""); + if name.starts_with("a") { + Some(name.replace("attachment://", "./images/")) + } else { + None + } + } else { + None + } + }).filter(|x| x.is_some()).map(|x| x.unwrap()).collect::>() } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ec937ab..bfb1e85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use serenity::client::Context; use serenity::http::GuildPagination; use serenity::model::id::ChannelId; use serenity::model::prelude::Activity; -use crate::commands::events::create_event_embeds; +use crate::commands::events::{create_event_embeds, get_files_from_embeds}; use crate::data::{Data}; use crate::metrics::core::{AllRegistries, create_registries, Empty, setup_server}; use crate::mongo::core::get_all_status_messages; @@ -28,18 +28,24 @@ fn update_daily(ctx: Context, all_registries: Arc) { loop { get_total_guilds_count(&ctx, &all_registries).await; let status_messages = get_all_status_messages().await; + let embeds = create_event_embeds().await; + let files = get_files_from_embeds(&embeds); + for sm in status_messages { let ctx = ctx.clone(); let embeds = embeds.clone(); + let files = files.clone(); tokio::spawn(async move { if sm.channel_id == 0 { return } let msg = ChannelId::from(sm.channel_id as u64).message(ctx.clone().http, sm.message_id as u64).await; match msg { Ok(mut m) => { + let to_delete = m.attachments.clone(); match m.edit(&ctx.http, |f| { - f.set_embeds(embeds) + let f = to_delete.iter().fold(f, |f, a| f.remove_existing_attachment(a.id)); + files.iter().fold(f, |f, a| f.attachment(a.as_str())).set_embeds(embeds) }).await { Ok(..) => {}, Err(e) => println!("Error while editing message {}", e) diff --git a/src/utils/image_saver.rs b/src/utils/image_saver.rs new file mode 100644 index 0000000..407f63a --- /dev/null +++ b/src/utils/image_saver.rs @@ -0,0 +1,19 @@ +use std::fs; +use std::io::Write; + +fn create_images_folder() { + match fs::create_dir("./images") { + Ok(_) => {} + Err(_) => {} + } +} +pub fn write_image_from_b64(name: String, b64_image: String) -> String { + create_images_folder(); + let data = image_base64::from_base64(b64_image.into()); + let mut_file = fs::OpenOptions::new() + .create(true) + .write(true) + .open(format!("./images/{}.webp", name)); + mut_file.unwrap().write_all(data.as_slice()).expect("Cannot write image"); + return format!("{}.webp", name) +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 5bd89cd..c7016b3 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,4 @@ pub mod color_manager; pub mod emote_manager; +pub mod image_saver;