From 6aa0d2d4bb160ca3fc55ff70021ccdae195bc660 Mon Sep 17 00:00:00 2001 From: Bulat Kurbanov Date: Sun, 5 May 2024 14:56:38 +0200 Subject: [PATCH] Add copy message --- Cargo.lock | 454 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 7 +- src/config.rs | 6 + src/services/bots.rs | 32 +++ src/services/mod.rs | 85 +++++++- src/views.rs | 32 ++- 6 files changed, 596 insertions(+), 20 deletions(-) create mode 100644 src/services/bots.rs diff --git a/Cargo.lock b/Cargo.lock index 0254b4a..4d258ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,19 +79,43 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +[[package]] +name = "aquamarine" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" +dependencies = [ + "itertools 0.9.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ascii" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-mutex" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] @@ -142,6 +166,38 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core 0.3.4", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "axum" version = "0.7.5" @@ -149,7 +205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.4.3", "bytes", "futures-util", "http 1.1.0", @@ -176,6 +232,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "axum-core" version = "0.4.3" @@ -203,7 +276,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b683cbc43010e9a3d72c2f31ca464155ff4f95819e88a32924b0f47a43898978" dependencies = [ - "axum", + "axum 0.7.5", "bytes", "futures", "futures-core", @@ -216,7 +289,7 @@ dependencies = [ "pin-project", "tokio", "tower", - "tower-http", + "tower-http 0.5.2", ] [[package]] @@ -405,6 +478,15 @@ dependencies = [ "unreachable", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "connection-string" version = "0.1.13" @@ -414,6 +496,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "convert_case" version = "0.5.0" @@ -539,6 +627,41 @@ dependencies = [ "sha3", ] +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "datamodel-renderer" version = "0.1.0" @@ -569,6 +692,19 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + [[package]] name = "diagnostics" version = "0.1.0" @@ -658,6 +794,15 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dptree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d81175dab5ec79c30e0576df2ed2c244e1721720c302000bb321b107e82e265c" +dependencies = [ + "futures", +] + [[package]] name = "either" version = "1.11.0" @@ -705,6 +850,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erasable" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f11890ce181d47a64e5d1eb4b6caba0e7bae911a356723740d058a5d0340b7d" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "errno" version = "0.3.8" @@ -721,6 +876,38 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + [[package]] name = "failure" version = "0.1.8" @@ -1036,6 +1223,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1135,6 +1328,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + [[package]] name = "httparse" version = "1.8.0" @@ -1264,6 +1463,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -1331,6 +1536,15 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1370,7 +1584,7 @@ version = "0.1.0" source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.10#c4aeef82dbae310e974d6122160c7e3b5fb6df53" dependencies = [ "backtrace", - "heck", + "heck 0.3.3", "serde", "toml", ] @@ -1787,6 +2001,30 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "moka" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0d88686dc561d743b40de8269b26eaf0dc58781bde087b0984646602021d08" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener 5.3.0", + "futures-util", + "once_cell", + "parking_lot 0.12.1", + "quanta 0.12.3", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -1805,6 +2043,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "never" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + [[package]] name = "nibble_vec" version = "0.1.0" @@ -2042,6 +2286,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.11.2" @@ -2406,6 +2656,30 @@ dependencies = [ "uuid", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.81" @@ -2701,6 +2975,15 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "rc-box" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0690759eabf094030c2cdabc25ade1395bac02210d920d655053c1d49583fd8" +dependencies = [ + "erasable", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2816,6 +3099,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -2828,10 +3112,12 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls 0.3.1", + "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", "winreg 0.50.0", ] @@ -3219,6 +3505,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with_macros" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "sha2" version = "0.9.9" @@ -3454,6 +3752,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.5.0" @@ -3527,12 +3831,30 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "takecell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e" + [[package]] name = "telegram_files_cache_server" version = "0.1.0" dependencies = [ "async-stream", - "axum", + "axum 0.7.5", "axum-prometheus", "base64 0.22.0", "bytes", @@ -3540,20 +3862,96 @@ dependencies = [ "futures", "futures-core", "minio-rsc", + "moka", "once_cell", "prisma-client-rust", "reqwest 0.12.4", "sentry", "serde", "serde_json", + "teloxide", "tempfile", "tokio", "tokio-util", - "tower-http", + "tower-http 0.5.2", "tracing", "tracing-subscriber", ] +[[package]] +name = "teloxide" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63345cf32a8850ebddcdd769dc2d5193d5e231262d5dada264b79da01a664da" +dependencies = [ + "aquamarine", + "axum 0.6.20", + "bytes", + "derive_more", + "dptree", + "futures", + "log", + "mime", + "pin-project", + "rand 0.8.5", + "serde", + "serde_json", + "serde_with_macros", + "teloxide-core", + "teloxide-macros", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-http 0.3.5", + "url", +] + +[[package]] +name = "teloxide-core" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "303db260110c238e3af77bb9dff18bf7a5b5196f783059b0852aab75f91d5a16" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "chrono", + "derive_more", + "either", + "futures", + "log", + "mime", + "never", + "once_cell", + "pin-project", + "rc-box", + "reqwest 0.11.27", + "serde", + "serde_json", + "serde_with_macros", + "take_mut", + "takecell", + "thiserror", + "tokio", + "tokio-util", + "url", + "uuid", + "vecrem", +] + +[[package]] +name = "teloxide-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1d653b093dba5e44cada57a516f572167df37b8a619443e59c8c517bb6d804" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "tempfile" version = "3.10.1" @@ -3714,6 +4112,17 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -3754,6 +4163,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "http-range-header", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-http" version = "0.5.2" @@ -3890,6 +4318,12 @@ dependencies = [ "tracing-log 0.2.0", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "try-lock" version = "0.2.5" @@ -4051,6 +4485,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vecrem" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4808a28789238714a29163e4cb8031f0f050dd670f7a0cc74b6d80f3ce343fa" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index cd41b58..e908b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,13 @@ name = "telegram_files_cache_server" version = "0.1.0" edition = "2021" + [workspace] members = [ "prisma-cli" ] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] once_cell = "1.19.0" @@ -39,3 +38,7 @@ async-stream = "0.3.5" minio-rsc = "0.2.2" tempfile = "3.10.1" bytes = "1.6.0" + +teloxide = { version = "0.12.2", features = ["macros", "webhooks-axum", "cache-me", "throttle"] } + +moka = { version = "0.12.7", features = ["future"] } diff --git a/src/config.rs b/src/config.rs index 2348aa0..867eeed 100644 --- a/src/config.rs +++ b/src/config.rs @@ -24,6 +24,9 @@ pub struct Config { pub files_api_key: String, pub files_url: String, + pub bot_tokens: Vec, + pub temp_channel_username: String, + pub sentry_dsn: String, } @@ -57,6 +60,9 @@ impl Config { files_api_key: get_env("FILES_SERVER_API_KEY"), files_url: get_env("FILES_SERVER_URL"), + bot_tokens: serde_json::from_str(&get_env("BOT_TOKENS")).unwrap(), + temp_channel_username: get_env("TEMP_CHANNEL_USERNAME"), + sentry_dsn: get_env("SENTRY_DSN"), } } diff --git a/src/services/bots.rs b/src/services/bots.rs new file mode 100644 index 0000000..303d040 --- /dev/null +++ b/src/services/bots.rs @@ -0,0 +1,32 @@ +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; + +use once_cell::sync::Lazy; + +use teloxide::Bot; + +use crate::config; + +pub struct RoundRobinBot { + bot_tokens: Arc>, + current_index: AtomicUsize, +} + +impl RoundRobinBot { + pub fn new(bot_tokens: Vec) -> Self { + RoundRobinBot { + bot_tokens: Arc::new(bot_tokens), + current_index: AtomicUsize::new(0), + } + } + + pub fn get_bot(&self) -> Bot { + let index = self.current_index.fetch_add(1, Ordering::Relaxed) % self.bot_tokens.len(); + Bot::new(self.bot_tokens[index].clone()) + } +} + +pub static ROUND_ROBIN_BOT: Lazy = + Lazy::new(|| RoundRobinBot::new(config::CONFIG.bot_tokens.clone())); diff --git a/src/services/mod.rs b/src/services/mod.rs index 9316a8c..f599edd 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,23 +1,59 @@ pub mod book_library; +pub mod bots; pub mod download_utils; pub mod downloader; pub mod minio; pub mod telegram_files; use chrono::Duration; +use moka::future::Cache; +use once_cell::sync::Lazy; use serde::Serialize; +use teloxide::{ + requests::Requester, + types::{ChatId, MessageId}, +}; use tracing::log; -use crate::{prisma::cached_file, views::Database}; +use crate::{ + config::{self}, + prisma::cached_file, + views::Database, +}; use self::{ book_library::{get_book, get_books, types::BaseBook}, + bots::ROUND_ROBIN_BOT, download_utils::{response_to_tempfile, DownloadResult}, downloader::{download_from_downloader, get_filename, FilenameData}, minio::upload_to_minio, telegram_files::{download_from_telegram_files, upload_to_telegram_files, UploadData}, }; +#[derive(Serialize)] +pub struct CacheData { + pub id: Option, + pub object_id: i32, + pub object_type: String, + pub message_id: i32, + pub chat_id: String, +} + +pub static CHAT_DONATION_NOTIFICATIONS_CACHE: Lazy> = Lazy::new(|| { + Cache::builder() + .time_to_idle(std::time::Duration::from_secs(16)) + .max_capacity(4098) + .async_eviction_listener(|_data_id, message_id, _cause| { + Box::pin(async move { + let bot = ROUND_ROBIN_BOT.get_bot(); + let _ = bot + .delete_message(config::CONFIG.temp_channel_username.to_string(), message_id) + .await; + }) + }) + .build() +}); + pub async fn get_cached_file_or_cache( object_id: i32, object_type: String, @@ -39,6 +75,53 @@ pub async fn get_cached_file_or_cache( } } +pub async fn get_cached_file_copy(original: cached_file::Data, db: Database) -> CacheData { + let bot = ROUND_ROBIN_BOT.get_bot(); + + let message_id = match bot + .copy_message( + config::CONFIG.temp_channel_username.to_string(), + ChatId(original.chat_id), + MessageId(original.message_id.try_into().unwrap()), + ) + .await + { + Ok(v) => v, + Err(_) => { + let _ = db + .cached_file() + .delete(cached_file::id::equals(original.id)) + .exec() + .await; + + let new_original = + get_cached_file_or_cache(original.object_id, original.object_type.clone(), db) + .await + .unwrap(); + + bot.copy_message( + config::CONFIG.temp_channel_username.to_string(), + ChatId(new_original.chat_id), + MessageId(new_original.message_id.try_into().unwrap()), + ) + .await + .unwrap() + } + }; + + CHAT_DONATION_NOTIFICATIONS_CACHE + .insert(original.id, message_id) + .await; + + CacheData { + id: None, + object_id: original.object_id, + object_type: original.object_type, + message_id: message_id.0, + chat_id: config::CONFIG.temp_channel_username.to_string(), + } +} + pub async fn cache_file( object_id: i32, object_type: String, diff --git a/src/views.rs b/src/views.rs index 3088d01..f6a4c28 100644 --- a/src/views.rs +++ b/src/views.rs @@ -1,6 +1,6 @@ use axum::{ body::Body, - extract::Path, + extract::{Path, Query}, http::{self, header, Request, StatusCode}, middleware::{self, Next}, response::{AppendHeaders, IntoResponse, Response}, @@ -9,6 +9,7 @@ use axum::{ }; use axum_prometheus::PrometheusMetricLayer; use base64::{engine::general_purpose, Engine}; +use serde::Deserialize; use std::sync::Arc; use tokio_util::io::ReaderStream; use tower_http::trace::{self, TraceLayer}; @@ -17,13 +18,10 @@ use tracing::{log, Level}; use crate::{ config::CONFIG, db::get_prisma_client, - prisma::{ - cached_file::{self}, - PrismaClient, - }, + prisma::{cached_file, PrismaClient}, services::{ - download_from_cache, download_utils::get_response_async_read, get_cached_file_or_cache, - get_download_link, start_update_cache, + download_from_cache, download_utils::get_response_async_read, get_cached_file_copy, + get_cached_file_or_cache, get_download_link, start_update_cache, CacheData, }, }; @@ -31,14 +29,28 @@ pub type Database = Arc; // +#[derive(Deserialize)] +pub struct GetCachedFileQuery { + pub copy: bool, +} + async fn get_cached_file( Path((object_id, object_type)): Path<(i32, String)>, + Query(GetCachedFileQuery { copy }): Query, Extension(Ext { db, .. }): Extension, ) -> impl IntoResponse { - match get_cached_file_or_cache(object_id, object_type, db).await { - Some(cached_file) => Json(cached_file).into_response(), - None => StatusCode::NOT_FOUND.into_response(), + let cached_file = match get_cached_file_or_cache(object_id, object_type, db.clone()).await { + Some(cached_file) => cached_file, + None => return StatusCode::NOT_FOUND.into_response(), + }; + + if !copy { + return Json(cached_file).into_response(); } + + let copy_file: CacheData = get_cached_file_copy(cached_file, db).await; + + Json(copy_file).into_response() } async fn download_cached_file(