mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Update
This commit is contained in:
@@ -2,13 +2,9 @@ pub mod modules;
|
|||||||
pub mod services;
|
pub mod services;
|
||||||
mod tools;
|
mod tools;
|
||||||
|
|
||||||
use smartstring::alias::String as SmartString;
|
|
||||||
|
|
||||||
use moka::future::Cache;
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}};
|
use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}};
|
||||||
|
|
||||||
use crate::{bots::approved_bot::services::user_settings::create_or_update_user_settings, bots_manager::AppState};
|
use crate::{bots::approved_bot::services::user_settings::create_or_update_user_settings, bots_manager::USER_ACTIVITY_CACHE};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
modules::{
|
modules::{
|
||||||
@@ -25,10 +21,8 @@ use super::{ignore_channel_messages, BotCommands, BotHandler, bots_manager::get_
|
|||||||
async fn _update_activity(
|
async fn _update_activity(
|
||||||
me: teloxide::types::Me,
|
me: teloxide::types::Me,
|
||||||
user: teloxide::types::User,
|
user: teloxide::types::User,
|
||||||
activity_cache: Cache<UserId, ()>,
|
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
if activity_cache.contains_key(&user.id) {
|
if USER_ACTIVITY_CACHE.contains_key(&user.id) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +30,7 @@ async fn _update_activity(
|
|||||||
let mut update_result = update_user_activity(user.id).await;
|
let mut update_result = update_user_activity(user.id).await;
|
||||||
|
|
||||||
if update_result.is_err() {
|
if update_result.is_err() {
|
||||||
let allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await;
|
let allowed_langs = get_user_or_default_lang_codes(user.id).await;
|
||||||
|
|
||||||
if create_or_update_user_settings(
|
if create_or_update_user_settings(
|
||||||
user.id,
|
user.id,
|
||||||
@@ -45,7 +39,6 @@ async fn _update_activity(
|
|||||||
user.username.clone().unwrap_or("".to_string()),
|
user.username.clone().unwrap_or("".to_string()),
|
||||||
me.username.clone().unwrap(),
|
me.username.clone().unwrap(),
|
||||||
allowed_langs,
|
allowed_langs,
|
||||||
user_langs_cache,
|
|
||||||
).await.is_ok()
|
).await.is_ok()
|
||||||
{
|
{
|
||||||
update_result = update_user_activity(user.id).await;
|
update_result = update_user_activity(user.id).await;
|
||||||
@@ -53,7 +46,7 @@ async fn _update_activity(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if update_result.is_ok() {
|
if update_result.is_ok() {
|
||||||
activity_cache.insert(user.id, ()).await;
|
USER_ACTIVITY_CACHE.insert(user.id, ()).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -64,15 +57,15 @@ fn update_user_activity_handler() -> BotHandler {
|
|||||||
dptree::entry()
|
dptree::entry()
|
||||||
.branch(
|
.branch(
|
||||||
Update::filter_callback_query().chain(dptree::filter_map_async(
|
Update::filter_callback_query().chain(dptree::filter_map_async(
|
||||||
|cq: CallbackQuery, bot: CacheMe<Throttle<Bot>>, app_state: AppState| async move {
|
|cq: CallbackQuery, bot: CacheMe<Throttle<Bot>>| async move {
|
||||||
_update_activity(bot.get_me().await.unwrap(), cq.from, app_state.user_activity_cache, app_state.user_langs_cache).await
|
_update_activity(bot.get_me().await.unwrap(), cq.from).await
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.branch(Update::filter_message().chain(dptree::filter_map_async(
|
.branch(Update::filter_message().chain(dptree::filter_map_async(
|
||||||
|message: Message, bot: CacheMe<Throttle<Bot>>, app_state: AppState| async move {
|
|message: Message, bot: CacheMe<Throttle<Bot>>| async move {
|
||||||
match message.from() {
|
match message.from() {
|
||||||
Some(user) => _update_activity(bot.get_me().await.unwrap(), user.clone(), app_state.user_activity_cache, app_state.user_langs_cache).await,
|
Some(user) => _update_activity(bot.get_me().await.unwrap(), user.clone()).await,
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
|
|
||||||
use moka::future::Cache;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Throttle, CacheMe}};
|
use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Throttle, CacheMe}};
|
||||||
|
|
||||||
use crate::{bots::approved_bot::{
|
use crate::bots::approved_bot::{
|
||||||
services::{
|
services::{
|
||||||
book_library::{
|
book_library::{
|
||||||
formaters::{Format, FormatTitle}, get_author_books, get_sequence_books, get_translator_books,
|
formaters::{Format, FormatTitle}, get_author_books, get_sequence_books, get_translator_books,
|
||||||
@@ -17,7 +16,7 @@ use crate::{bots::approved_bot::{
|
|||||||
user_settings::get_user_or_default_lang_codes,
|
user_settings::get_user_or_default_lang_codes,
|
||||||
},
|
},
|
||||||
tools::filter_callback_query,
|
tools::filter_callback_query,
|
||||||
}, bots_manager::AppState};
|
};
|
||||||
|
|
||||||
use super::utils::{
|
use super::utils::{
|
||||||
filter_command, generic_get_pagination_keyboard, CommandParse, GetPaginationCallbackData,
|
filter_command, generic_get_pagination_keyboard, CommandParse, GetPaginationCallbackData,
|
||||||
@@ -122,7 +121,6 @@ async fn send_book_handler<T, P, Fut>(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
command: BookCommand,
|
command: BookCommand,
|
||||||
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
@@ -152,7 +150,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(user_id).await;
|
||||||
|
|
||||||
let items_page = match books_getter(id, 1, allowed_langs.clone()).await {
|
let items_page = match books_getter(id, 1, allowed_langs.clone()).await {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@@ -194,7 +192,6 @@ async fn send_pagination_book_handler<T, P, Fut>(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: BookCallbackData,
|
callback_data: BookCallbackData,
|
||||||
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
@@ -222,7 +219,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(user_id).await;
|
||||||
|
|
||||||
let mut items_page = match books_getter(id, page, allowed_langs.clone()).await {
|
let mut items_page = match books_getter(id, page, allowed_langs.clone()).await {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@@ -277,7 +274,7 @@ pub fn get_book_handler() -> crate::bots::BotHandler {
|
|||||||
Update::filter_message()
|
Update::filter_message()
|
||||||
.chain(filter_command::<BookCommand>())
|
.chain(filter_command::<BookCommand>())
|
||||||
.endpoint(
|
.endpoint(
|
||||||
|message: Message, bot: CacheMe<Throttle<Bot>>, command: BookCommand, app_state: AppState| async move {
|
|message: Message, bot: CacheMe<Throttle<Bot>>, command: BookCommand| async move {
|
||||||
match command {
|
match command {
|
||||||
BookCommand::Author { .. } => {
|
BookCommand::Author { .. } => {
|
||||||
send_book_handler(
|
send_book_handler(
|
||||||
@@ -285,7 +282,6 @@ pub fn get_book_handler() -> crate::bots::BotHandler {
|
|||||||
bot,
|
bot,
|
||||||
command,
|
command,
|
||||||
get_author_books,
|
get_author_books,
|
||||||
app_state.user_langs_cache
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -295,7 +291,6 @@ pub fn get_book_handler() -> crate::bots::BotHandler {
|
|||||||
bot,
|
bot,
|
||||||
command,
|
command,
|
||||||
get_translator_books,
|
get_translator_books,
|
||||||
app_state.user_langs_cache
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -305,7 +300,6 @@ pub fn get_book_handler() -> crate::bots::BotHandler {
|
|||||||
bot,
|
bot,
|
||||||
command,
|
command,
|
||||||
get_sequence_books,
|
get_sequence_books,
|
||||||
app_state.user_langs_cache,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -316,11 +310,11 @@ pub fn get_book_handler() -> crate::bots::BotHandler {
|
|||||||
.branch(
|
.branch(
|
||||||
Update::filter_callback_query()
|
Update::filter_callback_query()
|
||||||
.chain(filter_callback_query::<BookCallbackData>())
|
.chain(filter_callback_query::<BookCallbackData>())
|
||||||
.endpoint(|cq: CallbackQuery, bot: CacheMe<Throttle<Bot>>, callback_data: BookCallbackData, app_state: AppState| async move {
|
.endpoint(|cq: CallbackQuery, bot: CacheMe<Throttle<Bot>>, callback_data: BookCallbackData| async move {
|
||||||
match callback_data {
|
match callback_data {
|
||||||
BookCallbackData::Author { .. } => send_pagination_book_handler(cq, bot, callback_data, get_author_books, app_state.user_langs_cache).await,
|
BookCallbackData::Author { .. } => send_pagination_book_handler(cq, bot, callback_data, get_author_books).await,
|
||||||
BookCallbackData::Translator { .. } => send_pagination_book_handler(cq, bot, callback_data, get_translator_books, app_state.user_langs_cache).await,
|
BookCallbackData::Translator { .. } => send_pagination_book_handler(cq, bot, callback_data, get_translator_books).await,
|
||||||
BookCallbackData::Sequence { .. } => send_pagination_book_handler(cq, bot, callback_data, get_sequence_books, app_state.user_langs_cache).await,
|
BookCallbackData::Sequence { .. } => send_pagination_book_handler(cq, bot, callback_data, get_sequence_books).await,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::{str::FromStr, time::Duration};
|
use std::{str::FromStr, time::Duration};
|
||||||
|
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use moka::future::Cache;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
@@ -31,7 +30,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
BotHandlerInternal,
|
BotHandlerInternal,
|
||||||
},
|
},
|
||||||
bots_manager::{AppState, BotCache},
|
bots_manager::BotCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::utils::{filter_command, CommandParse};
|
use super::utils::{filter_command, CommandParse};
|
||||||
@@ -208,7 +207,6 @@ async fn send_cached_message(
|
|||||||
message: Message,
|
message: Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
download_data: DownloadQueryData,
|
download_data: DownloadQueryData,
|
||||||
donation_notification_cache: Cache<ChatId, ()>,
|
|
||||||
need_delete_message: bool,
|
need_delete_message: bool,
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
if let Ok(v) = get_cached_message(&download_data).await {
|
if let Ok(v) = get_cached_message(&download_data).await {
|
||||||
@@ -217,13 +215,13 @@ async fn send_cached_message(
|
|||||||
bot.delete_message(message.chat.id, message.id).await?;
|
bot.delete_message(message.chat.id, message.id).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_donation_notification(bot.clone(), message, donation_notification_cache).await?;
|
send_donation_notification(bot.clone(), message).await?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
send_with_download_from_channel(message, bot, download_data, donation_notification_cache, need_delete_message)
|
send_with_download_from_channel(message, bot, download_data, need_delete_message)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -233,7 +231,6 @@ async fn _send_downloaded_file(
|
|||||||
message: &Message,
|
message: &Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
downloaded_data: DownloadFile,
|
downloaded_data: DownloadFile,
|
||||||
donation_notification_cache: Cache<ChatId, ()>,
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let DownloadFile {
|
let DownloadFile {
|
||||||
response,
|
response,
|
||||||
@@ -254,7 +251,7 @@ async fn _send_downloaded_file(
|
|||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
send_donation_notification(bot, message.clone(), donation_notification_cache).await?;
|
send_donation_notification(bot, message.clone()).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -263,12 +260,11 @@ async fn send_with_download_from_channel(
|
|||||||
message: Message,
|
message: Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
download_data: DownloadQueryData,
|
download_data: DownloadQueryData,
|
||||||
donation_notification_cache: Cache<ChatId, ()>,
|
|
||||||
need_delete_message: bool,
|
need_delete_message: bool,
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
match download_file(&download_data).await {
|
match download_file(&download_data).await {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
_send_downloaded_file(&message, bot.clone(), v, donation_notification_cache).await?;
|
_send_downloaded_file(&message, bot.clone(), v).await?;
|
||||||
|
|
||||||
if need_delete_message {
|
if need_delete_message {
|
||||||
bot.delete_message(message.chat.id, message.id).await?;
|
bot.delete_message(message.chat.id, message.id).await?;
|
||||||
@@ -285,7 +281,6 @@ async fn download_handler(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
cache: BotCache,
|
cache: BotCache,
|
||||||
download_data: DownloadQueryData,
|
download_data: DownloadQueryData,
|
||||||
donation_notification_cache: Cache<ChatId, ()>,
|
|
||||||
need_delete_message: bool,
|
need_delete_message: bool,
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
match cache {
|
match cache {
|
||||||
@@ -294,7 +289,6 @@ async fn download_handler(
|
|||||||
message,
|
message,
|
||||||
bot,
|
bot,
|
||||||
download_data,
|
download_data,
|
||||||
donation_notification_cache,
|
|
||||||
need_delete_message,
|
need_delete_message,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -304,7 +298,6 @@ async fn download_handler(
|
|||||||
message,
|
message,
|
||||||
bot,
|
bot,
|
||||||
download_data,
|
download_data,
|
||||||
donation_notification_cache,
|
|
||||||
need_delete_message,
|
need_delete_message,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -362,13 +355,9 @@ async fn get_download_archive_keyboard_handler(
|
|||||||
message: Message,
|
message: Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
command: DownloadArchiveCommand,
|
command: DownloadArchiveCommand,
|
||||||
app_state: AppState,
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let user_langs_cache = app_state.user_langs_cache;
|
|
||||||
|
|
||||||
let allowed_langs = get_user_or_default_lang_codes(
|
let allowed_langs = get_user_or_default_lang_codes(
|
||||||
message.from().unwrap().id,
|
message.from().unwrap().id,
|
||||||
user_langs_cache
|
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
let available_types = match command {
|
let available_types = match command {
|
||||||
@@ -419,11 +408,9 @@ async fn download_archive(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
download_archive_query_data: DownloadArchiveQueryData,
|
download_archive_query_data: DownloadArchiveQueryData,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
app_state: AppState
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let allowed_langs = get_user_or_default_lang_codes(
|
let allowed_langs = get_user_or_default_lang_codes(
|
||||||
cq.from.id,
|
cq.from.id,
|
||||||
app_state.user_langs_cache
|
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
let (id, file_type, task_type) = match download_archive_query_data {
|
let (id, file_type, task_type) = match download_archive_query_data {
|
||||||
@@ -524,7 +511,6 @@ async fn download_archive(
|
|||||||
&message,
|
&message,
|
||||||
bot,
|
bot,
|
||||||
downloaded_data,
|
downloaded_data,
|
||||||
app_state.chat_donation_notifications_cache
|
|
||||||
).await {
|
).await {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -552,14 +538,12 @@ pub fn get_download_hander() -> crate::bots::BotHandler {
|
|||||||
|cq: CallbackQuery,
|
|cq: CallbackQuery,
|
||||||
download_query_data: DownloadQueryData,
|
download_query_data: DownloadQueryData,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
cache: BotCache,
|
cache: BotCache| async move {
|
||||||
app_state: AppState| async move {
|
|
||||||
download_handler(
|
download_handler(
|
||||||
cq.message.unwrap(),
|
cq.message.unwrap(),
|
||||||
bot,
|
bot,
|
||||||
cache,
|
cache,
|
||||||
download_query_data,
|
download_query_data,
|
||||||
app_state.chat_donation_notifications_cache,
|
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use moka::future::Cache;
|
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use strum_macros::{Display, EnumIter};
|
use strum_macros::{Display, EnumIter};
|
||||||
@@ -8,7 +7,7 @@ use teloxide::{
|
|||||||
utils::command::BotCommands, adaptors::{Throttle, CacheMe},
|
utils::command::BotCommands, adaptors::{Throttle, CacheMe},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{bots::{
|
use crate::bots::{
|
||||||
approved_bot::{
|
approved_bot::{
|
||||||
services::{
|
services::{
|
||||||
book_library::{self, formaters::Format},
|
book_library::{self, formaters::Format},
|
||||||
@@ -17,7 +16,7 @@ use crate::{bots::{
|
|||||||
tools::filter_callback_query,
|
tools::filter_callback_query,
|
||||||
},
|
},
|
||||||
BotHandlerInternal,
|
BotHandlerInternal,
|
||||||
}, bots_manager::AppState};
|
};
|
||||||
|
|
||||||
#[derive(BotCommands, Clone)]
|
#[derive(BotCommands, Clone)]
|
||||||
#[command(rename_rule = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
@@ -171,13 +170,12 @@ async fn get_random_item_handler<T, Fut>(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
item_getter: fn(allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
item_getter: fn(allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> BotHandlerInternal
|
) -> BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format,
|
T: Format,
|
||||||
Fut: std::future::Future<Output = Result<T, Box<dyn std::error::Error + Send + Sync>>>,
|
Fut: std::future::Future<Output = Result<T, Box<dyn std::error::Error + Send + Sync>>>,
|
||||||
{
|
{
|
||||||
let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(cq.from.id).await;
|
||||||
|
|
||||||
let item = item_getter(allowed_langs).await;
|
let item = item_getter(allowed_langs).await;
|
||||||
|
|
||||||
@@ -295,9 +293,8 @@ async fn get_random_book_by_genre(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
genre_id: u32,
|
genre_id: u32,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(cq.from.id).await;
|
||||||
|
|
||||||
let item = book_library::get_random_book_by_genre(allowed_langs, Some(genre_id)).await;
|
let item = book_library::get_random_book_by_genre(allowed_langs, Some(genre_id)).await;
|
||||||
|
|
||||||
@@ -321,14 +318,14 @@ pub fn get_random_hander() -> crate::bots::BotHandler {
|
|||||||
.branch(
|
.branch(
|
||||||
Update::filter_callback_query()
|
Update::filter_callback_query()
|
||||||
.chain(filter_callback_query::<RandomCallbackData>())
|
.chain(filter_callback_query::<RandomCallbackData>())
|
||||||
.endpoint(|cq: CallbackQuery, callback_data: RandomCallbackData, bot: CacheMe<Throttle<Bot>>, app_state: AppState| async move {
|
.endpoint(|cq: CallbackQuery, callback_data: RandomCallbackData, bot: CacheMe<Throttle<Bot>>| async move {
|
||||||
match callback_data {
|
match callback_data {
|
||||||
RandomCallbackData::RandomBook => get_random_item_handler(cq, bot, book_library::get_random_book, app_state.user_langs_cache).await,
|
RandomCallbackData::RandomBook => get_random_item_handler(cq, bot, book_library::get_random_book).await,
|
||||||
RandomCallbackData::RandomAuthor => get_random_item_handler(cq, bot, book_library::get_random_author, app_state.user_langs_cache).await,
|
RandomCallbackData::RandomAuthor => get_random_item_handler(cq, bot, book_library::get_random_author).await,
|
||||||
RandomCallbackData::RandomSequence => get_random_item_handler(cq, bot, book_library::get_random_sequence, app_state.user_langs_cache).await,
|
RandomCallbackData::RandomSequence => get_random_item_handler(cq, bot, book_library::get_random_sequence).await,
|
||||||
RandomCallbackData::RandomBookByGenreRequest => get_genre_metas_handler(cq, bot).await,
|
RandomCallbackData::RandomBookByGenreRequest => get_genre_metas_handler(cq, bot).await,
|
||||||
RandomCallbackData::Genres { index } => get_genres_by_meta_handler(cq, bot, index).await,
|
RandomCallbackData::Genres { index } => get_genres_by_meta_handler(cq, bot, index).await,
|
||||||
RandomCallbackData::RandomBookByGenre { id } => get_random_book_by_genre(cq, bot, id, app_state.user_langs_cache).await,
|
RandomCallbackData::RandomBookByGenre { id } => get_random_book_by_genre(cq, bot, id).await,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
|
|
||||||
use moka::future::Cache;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
@@ -12,7 +11,7 @@ use teloxide::{
|
|||||||
types::{InlineKeyboardButton, InlineKeyboardMarkup}, dispatching::dialogue::GetChatId, adaptors::{Throttle, CacheMe},
|
types::{InlineKeyboardButton, InlineKeyboardMarkup}, dispatching::dialogue::GetChatId, adaptors::{Throttle, CacheMe},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{bots::{
|
use crate::bots::{
|
||||||
approved_bot::{
|
approved_bot::{
|
||||||
services::{
|
services::{
|
||||||
book_library::{
|
book_library::{
|
||||||
@@ -24,7 +23,7 @@ use crate::{bots::{
|
|||||||
tools::filter_callback_query,
|
tools::filter_callback_query,
|
||||||
},
|
},
|
||||||
BotHandlerInternal,
|
BotHandlerInternal,
|
||||||
}, bots_manager::AppState};
|
};
|
||||||
|
|
||||||
use super::utils::{generic_get_pagination_keyboard, GetPaginationCallbackData};
|
use super::utils::{generic_get_pagination_keyboard, GetPaginationCallbackData};
|
||||||
|
|
||||||
@@ -115,7 +114,6 @@ async fn generic_search_pagination_handler<T, P, Fut>(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
search_data: SearchCallbackData,
|
search_data: SearchCallbackData,
|
||||||
items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> BotHandlerInternal
|
) -> BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
@@ -140,7 +138,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(user_id).await;
|
||||||
|
|
||||||
let page = match search_data {
|
let page = match search_data {
|
||||||
SearchCallbackData::Book { page } => page,
|
SearchCallbackData::Book { page } => page,
|
||||||
@@ -255,12 +253,12 @@ pub fn get_search_handler() -> crate::bots::BotHandler {
|
|||||||
).branch(
|
).branch(
|
||||||
Update::filter_callback_query()
|
Update::filter_callback_query()
|
||||||
.chain(filter_callback_query::<SearchCallbackData>())
|
.chain(filter_callback_query::<SearchCallbackData>())
|
||||||
.endpoint(|cq: CallbackQuery, callback_data: SearchCallbackData, bot: CacheMe<Throttle<Bot>>, app_state: AppState| async move {
|
.endpoint(|cq: CallbackQuery, callback_data: SearchCallbackData, bot: CacheMe<Throttle<Bot>>| async move {
|
||||||
match callback_data {
|
match callback_data {
|
||||||
SearchCallbackData::Book { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_book, app_state.user_langs_cache).await,
|
SearchCallbackData::Book { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_book).await,
|
||||||
SearchCallbackData::Authors { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_author, app_state.user_langs_cache).await,
|
SearchCallbackData::Authors { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_author).await,
|
||||||
SearchCallbackData::Sequences { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_sequence, app_state.user_langs_cache).await,
|
SearchCallbackData::Sequences { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_sequence).await,
|
||||||
SearchCallbackData::Translators { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_translator, app_state.user_langs_cache).await,
|
SearchCallbackData::Translators { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_translator).await,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::{collections::HashSet, str::FromStr};
|
|||||||
|
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
|
|
||||||
use crate::{bots::{
|
use crate::bots::{
|
||||||
approved_bot::{
|
approved_bot::{
|
||||||
services::user_settings::{
|
services::user_settings::{
|
||||||
create_or_update_user_settings, get_langs, get_user_or_default_lang_codes, Lang,
|
create_or_update_user_settings, get_langs, get_user_or_default_lang_codes, Lang,
|
||||||
@@ -10,11 +10,11 @@ use crate::{bots::{
|
|||||||
tools::filter_callback_query,
|
tools::filter_callback_query,
|
||||||
},
|
},
|
||||||
BotHandlerInternal,
|
BotHandlerInternal,
|
||||||
}, bots_manager::AppState};
|
};
|
||||||
|
|
||||||
|
|
||||||
use moka::future::Cache;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use smallvec::SmallVec;
|
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
types::{InlineKeyboardButton, InlineKeyboardMarkup, Me},
|
types::{InlineKeyboardButton, InlineKeyboardMarkup, Me},
|
||||||
@@ -122,7 +122,6 @@ async fn settings_callback_handler(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: SettingsCallbackData,
|
callback_data: SettingsCallbackData,
|
||||||
me: Me,
|
me: Me,
|
||||||
user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let message = match cq.message {
|
let message = match cq.message {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
@@ -134,7 +133,7 @@ async fn settings_callback_handler(
|
|||||||
|
|
||||||
let user = cq.from;
|
let user = cq.from;
|
||||||
|
|
||||||
let allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await;
|
let allowed_langs = get_user_or_default_lang_codes(user.id).await;
|
||||||
|
|
||||||
let mut allowed_langs_set: HashSet<SmartString> = HashSet::new();
|
let mut allowed_langs_set: HashSet<SmartString> = HashSet::new();
|
||||||
allowed_langs.into_iter().for_each(|v| {
|
allowed_langs.into_iter().for_each(|v| {
|
||||||
@@ -169,7 +168,6 @@ async fn settings_callback_handler(
|
|||||||
user.username.clone().unwrap_or("".to_string()),
|
user.username.clone().unwrap_or("".to_string()),
|
||||||
me.username.clone().unwrap(),
|
me.username.clone().unwrap(),
|
||||||
allowed_langs_set.clone().into_iter().collect(),
|
allowed_langs_set.clone().into_iter().collect(),
|
||||||
user_langs_cache,
|
|
||||||
)
|
)
|
||||||
.await {
|
.await {
|
||||||
bot.send_message(user.id, "Ошибка! Попробуйте заново(").send().await?;
|
bot.send_message(user.id, "Ошибка! Попробуйте заново(").send().await?;
|
||||||
@@ -211,9 +209,8 @@ pub fn get_settings_handler() -> crate::bots::BotHandler {
|
|||||||
|cq: CallbackQuery,
|
|cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: SettingsCallbackData,
|
callback_data: SettingsCallbackData,
|
||||||
me: Me,
|
me: Me| async move {
|
||||||
app_state: AppState| async move {
|
settings_callback_handler(cq, bot, callback_data, me).await
|
||||||
settings_callback_handler(cq, bot, callback_data, me, app_state.user_langs_cache).await
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use moka::future::Cache;
|
use teloxide::{types::Message, adaptors::{CacheMe, Throttle}, Bot};
|
||||||
use teloxide::{types::{ChatId, Message}, adaptors::{CacheMe, Throttle}, Bot};
|
|
||||||
|
|
||||||
use crate::bots::{BotHandlerInternal, approved_bot::modules::support::support_command_handler};
|
use crate::{bots::{BotHandlerInternal, approved_bot::modules::support::support_command_handler}, bots_manager::CHAT_DONATION_NOTIFICATIONS_CACHE};
|
||||||
|
|
||||||
use super::user_settings::{is_need_donate_notifications, mark_donate_notification_sended};
|
use super::user_settings::{is_need_donate_notifications, mark_donate_notification_sended};
|
||||||
|
|
||||||
@@ -9,16 +8,15 @@ use super::user_settings::{is_need_donate_notifications, mark_donate_notificatio
|
|||||||
pub async fn send_donation_notification(
|
pub async fn send_donation_notification(
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
message: Message,
|
message: Message,
|
||||||
donation_notification_cache: Cache<ChatId, ()>,
|
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
if donation_notification_cache.get(&message.chat.id).is_some() {
|
if CHAT_DONATION_NOTIFICATIONS_CACHE.get(&message.chat.id).is_some() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if !is_need_donate_notifications(message.chat.id).await? {
|
} else if !is_need_donate_notifications(message.chat.id).await? {
|
||||||
donation_notification_cache.insert(message.chat.id, ()).await;
|
CHAT_DONATION_NOTIFICATIONS_CACHE.insert(message.chat.id, ()).await;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
donation_notification_cache.insert(message.chat.id, ()).await;
|
CHAT_DONATION_NOTIFICATIONS_CACHE.insert(message.chat.id, ()).await;
|
||||||
mark_donate_notification_sended(message.chat.id).await?;
|
mark_donate_notification_sended(message.chat.id).await?;
|
||||||
|
|
||||||
support_command_handler(message, bot).await?;
|
support_command_handler(message, bot).await?;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use moka::future::Cache;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use teloxide::types::{UserId, ChatId};
|
use teloxide::types::{UserId, ChatId};
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
|
|
||||||
use crate::config;
|
use crate::{config, bots_manager::USER_LANGS_CACHE};
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct Lang {
|
pub struct Lang {
|
||||||
@@ -43,9 +42,8 @@ pub async fn get_user_settings(
|
|||||||
|
|
||||||
pub async fn get_user_or_default_lang_codes(
|
pub async fn get_user_or_default_lang_codes(
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
cache: Cache<UserId, SmallVec<[SmartString; 3]>>
|
|
||||||
) -> SmallVec<[SmartString; 3]> {
|
) -> SmallVec<[SmartString; 3]> {
|
||||||
if let Some(cached_langs) = cache.get(&user_id) {
|
if let Some(cached_langs) = USER_LANGS_CACHE.get(&user_id) {
|
||||||
return cached_langs;
|
return cached_langs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +56,7 @@ pub async fn get_user_or_default_lang_codes(
|
|||||||
match get_user_settings(user_id).await {
|
match get_user_settings(user_id).await {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
let langs: SmallVec<[SmartString; 3]> = v.allowed_langs.into_iter().map(|lang| lang.code).collect();
|
let langs: SmallVec<[SmartString; 3]> = v.allowed_langs.into_iter().map(|lang| lang.code).collect();
|
||||||
cache.insert(user_id, langs.clone()).await;
|
USER_LANGS_CACHE.insert(user_id, langs.clone()).await;
|
||||||
langs
|
langs
|
||||||
},
|
},
|
||||||
Err(_) => default_lang_codes,
|
Err(_) => default_lang_codes,
|
||||||
@@ -72,9 +70,8 @@ pub async fn create_or_update_user_settings(
|
|||||||
username: String,
|
username: String,
|
||||||
source: String,
|
source: String,
|
||||||
allowed_langs: SmallVec<[SmartString; 3]>,
|
allowed_langs: SmallVec<[SmartString; 3]>,
|
||||||
cache: Cache<UserId, SmallVec<[SmartString; 3]>>
|
|
||||||
) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
cache.invalidate(&user_id).await;
|
USER_LANGS_CACHE.invalidate(&user_id).await;
|
||||||
|
|
||||||
let body = json!({
|
let body = json!({
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ pub mod bot_manager_client;
|
|||||||
use axum::extract::{State, Path};
|
use axum::extract::{State, Path};
|
||||||
use axum::response::IntoResponse;
|
use axum::response::IntoResponse;
|
||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use reqwest::StatusCode;
|
use reqwest::StatusCode;
|
||||||
use smartstring::alias::String as SmartString;
|
use smartstring::alias::String as SmartString;
|
||||||
use teloxide::stop::{mk_stop_token, StopToken, StopFlag};
|
use teloxide::stop::{mk_stop_token, StopToken, StopFlag};
|
||||||
@@ -40,12 +41,26 @@ fn tuple_first_mut<A, B>(tuple: &mut (A, B)) -> &mut A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub static USER_ACTIVITY_CACHE: Lazy<Cache<UserId, ()>> = Lazy::new(|| {
|
||||||
pub struct AppState {
|
Cache::builder()
|
||||||
pub user_activity_cache: Cache<UserId, ()>,
|
.time_to_live(Duration::from_secs(5 * 60))
|
||||||
pub user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
|
.max_capacity(2048)
|
||||||
pub chat_donation_notifications_cache: Cache<ChatId, ()>,
|
.build()
|
||||||
}
|
});
|
||||||
|
|
||||||
|
pub static USER_LANGS_CACHE: Lazy<Cache<UserId, SmallVec<[SmartString; 3]>>> = Lazy::new(|| {
|
||||||
|
Cache::builder()
|
||||||
|
.time_to_live(Duration::from_secs(5 * 60))
|
||||||
|
.max_capacity(2048)
|
||||||
|
.build()
|
||||||
|
});
|
||||||
|
|
||||||
|
pub static CHAT_DONATION_NOTIFICATIONS_CACHE: Lazy<Cache<ChatId, ()>> = Lazy::new(|| {
|
||||||
|
Cache::builder()
|
||||||
|
.time_to_live(Duration::from_secs(24 * 60 * 60))
|
||||||
|
.max_capacity(2048)
|
||||||
|
.build()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@@ -54,8 +69,6 @@ struct ServerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct BotsManager {
|
pub struct BotsManager {
|
||||||
app_state: AppState,
|
|
||||||
|
|
||||||
port: u16,
|
port: u16,
|
||||||
stop_data: (StopToken, StopFlag),
|
stop_data: (StopToken, StopFlag),
|
||||||
|
|
||||||
@@ -65,21 +78,6 @@ pub struct BotsManager {
|
|||||||
impl BotsManager {
|
impl BotsManager {
|
||||||
pub fn create() -> Self {
|
pub fn create() -> Self {
|
||||||
BotsManager {
|
BotsManager {
|
||||||
app_state: AppState {
|
|
||||||
user_activity_cache: Cache::builder()
|
|
||||||
.time_to_live(Duration::from_secs(5 * 60))
|
|
||||||
.max_capacity(2048)
|
|
||||||
.build(),
|
|
||||||
user_langs_cache: Cache::builder()
|
|
||||||
.time_to_live(Duration::from_secs(5 * 60))
|
|
||||||
.max_capacity(2048)
|
|
||||||
.build(),
|
|
||||||
chat_donation_notifications_cache: Cache::builder()
|
|
||||||
.time_to_live(Duration::from_secs(24 * 60 * 60))
|
|
||||||
.max_capacity(2048)
|
|
||||||
.build(),
|
|
||||||
},
|
|
||||||
|
|
||||||
port: 8000,
|
port: 8000,
|
||||||
stop_data: mk_stop_token(),
|
stop_data: mk_stop_token(),
|
||||||
|
|
||||||
@@ -127,7 +125,7 @@ impl BotsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut dispatcher = Dispatcher::builder(bot.clone(), handler)
|
let mut dispatcher = Dispatcher::builder(bot.clone(), handler)
|
||||||
.dependencies(dptree::deps![bot_data.cache, self.app_state.clone()])
|
.dependencies(dptree::deps![bot_data.cache])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let (tx, listener) = self.get_listener();
|
let (tx, listener) = self.get_listener();
|
||||||
|
|||||||
Reference in New Issue
Block a user