Added new handle.

Signed-off-by: Pavel Kirilin <win10@list.ru>
This commit is contained in:
2024-04-04 03:02:57 +02:00
parent 07c6ff69e0
commit 90ac6d77aa
10 changed files with 77 additions and 32 deletions

View File

@ -74,7 +74,7 @@ lazy_static::lazy_static! {
); );
static ref CUR_REGEX: Regex = { static ref CUR_REGEX: Regex = {
#[allow(clippy::clone_double_ref)] #[allow(suspicious_double_ref_op)]
let a = CONVERTION_ALIASES.keys() let a = CONVERTION_ALIASES.keys()
.copied() .copied()
.chain(SUPPORTED_CURS.iter().copied()) .chain(SUPPORTED_CURS.iter().copied())
@ -115,7 +115,9 @@ impl Filter for CurrencyTextFilter {
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for CurrencyConverter { impl Handler for CurrencyConverter {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Some(message) = get_message(update) else{ return Ok(())}; let Some(message) = get_message(update) else {
return Ok(());
};
let response = self let response = self
.client .client
.get("https://www.cbr-xml-daily.ru/daily_json.js") .get("https://www.cbr-xml-daily.ru/daily_json.js")
@ -127,10 +129,11 @@ impl Handler for CurrencyConverter {
let Some(valutes) = response let Some(valutes) = response
.get("Valute") .get("Valute")
.and_then(serde_json::Value::as_object) else{ .and_then(serde_json::Value::as_object)
log::warn!("Can't get valutes fom response."); else {
return Ok(()); log::warn!("Can't get valutes fom response.");
}; return Ok(());
};
let mut calucates = Vec::new(); let mut calucates = Vec::new();
@ -142,17 +145,19 @@ impl Handler for CurrencyConverter {
// Convert match to string. // Convert match to string.
.map(|mtch| mtch.as_str()) .map(|mtch| mtch.as_str())
// Parse it. // Parse it.
.and_then(|val| val.parse::<f64>().ok()) else{ .and_then(|val| val.parse::<f64>().ok())
continue; else {
}; continue;
};
let cur_name = capture.name("cur_name").map(|mtch| mtch.as_str()); let cur_name = capture.name("cur_name").map(|mtch| mtch.as_str());
let Some(cur_name) = cur_name let Some(cur_name) = cur_name
// We check if the value is an alias. // We check if the value is an alias.
.and_then(|val| CONVERTION_ALIASES.get(val).copied()) .and_then(|val| CONVERTION_ALIASES.get(val).copied())
// get previous value if not. // get previous value if not.
.or(cur_name) else{ .or(cur_name)
continue; else {
}; continue;
};
let fingerprint = format!("{num_value:.5} {cur_name}"); let fingerprint = format!("{num_value:.5} {cur_name}");
// Check if we already processed this value. // Check if we already processed this value.
if mapped.contains(&fingerprint) { if mapped.contains(&fingerprint) {
@ -167,19 +172,19 @@ impl Handler for CurrencyConverter {
.and_then(|info| info.get("Nominal")) .and_then(|info| info.get("Nominal"))
.map(ToString::to_string) .map(ToString::to_string)
.and_then(|value| value.as_str().parse::<f64>().ok()) .and_then(|value| value.as_str().parse::<f64>().ok())
// If the name cannot be found, we continue. // If the name cannot be found, we continue.
else{ else {
continue; continue;
}; };
// Now we want to know multiplier. // Now we want to know multiplier.
let Some(multiplier) = valutes let Some(multiplier) = valutes
.get(cur_name) .get(cur_name)
.and_then(|info| info.get("Value")) .and_then(|info| info.get("Value"))
.map(ToString::to_string) .map(ToString::to_string)
.and_then(|value| value.as_str().parse::<f64>().ok()) .and_then(|value| value.as_str().parse::<f64>().ok())
else{ else {
continue; continue;
}; };
calucates.push(format!( calucates.push(format!(
"<pre>{num_value} {cur_name} = {value:.2} RUB</pre><br>", "<pre>{num_value} {cur_name} = {value:.2} RUB</pre><br>",

View File

@ -0,0 +1,24 @@
use grammers_client::{types::Chat, Client, InputMessage, Update};
use crate::{bot::handlers::Handler, utils::messages::get_message};
#[derive(Clone)]
pub struct GetUserId;
#[async_trait::async_trait]
impl Handler for GetUserId {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let message = get_message(update);
let Some(msg) = message else {
return Ok(());
};
let Chat::User(user) = msg.chat() else {
return Ok(());
};
let username = user.username().unwrap_or("Unknown username");
let user_id = user.id();
msg.reply(InputMessage::text(format!("{username}: {user_id}")).silent(true))
.await?;
Ok(())
}
}

View File

@ -8,7 +8,9 @@ pub struct Help;
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for Help { impl Handler for Help {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Update::NewMessage(message) = update else {return Ok(())}; let Update::NewMessage(message) = update else {
return Ok(());
};
message.reply("Я больше не рассказываю что я умею.").await?; message.reply("Я больше не рассказываю что я умею.").await?;

View File

@ -1,5 +1,6 @@
pub mod currency_converter; pub mod currency_converter;
pub mod get_chat_id; pub mod get_chat_id;
pub mod get_user_id;
pub mod help; pub mod help;
pub mod notify_all; pub mod notify_all;
pub mod time_converter; pub mod time_converter;

View File

@ -8,7 +8,9 @@ pub struct NotifyAll;
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for NotifyAll { impl Handler for NotifyAll {
async fn react(&self, client: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, client: &Client, update: &Update) -> anyhow::Result<()> {
let Some(message) = get_message(update) else {return Ok(());}; let Some(message) = get_message(update) else {
return Ok(());
};
let Chat::Group(group) = message.chat() else { let Chat::Group(group) = message.chat() else {
return Ok(()); return Ok(());
}; };

View File

@ -24,15 +24,15 @@ pub fn convert_time(offsets: &[FixedOffset], times: &[NaiveTime]) -> Vec<String>
let mut replies = Vec::new(); let mut replies = Vec::new();
let now = Utc::now(); let now = Utc::now();
let Some(main_offset) = offsets.get(0) else { let Some(main_offset) = offsets.first() else {
return vec![]; return vec![];
}; };
for time in times { for time in times {
let dt = NaiveDateTime::new(now.date_naive(), *time); let dt = NaiveDateTime::new(now.date_naive(), *time);
let Some(start_time) = main_offset.from_local_datetime(&dt).latest() else { let Some(start_time) = main_offset.from_local_datetime(&dt).latest() else {
continue; continue;
}; };
for offset in offsets { for offset in offsets {
if offset == main_offset && offsets.len() > 1 { if offset == main_offset && offsets.len() > 1 {
@ -56,7 +56,9 @@ pub fn convert_time(offsets: &[FixedOffset], times: &[NaiveTime]) -> Vec<String>
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for TimeConverter { impl Handler for TimeConverter {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Some(message) = get_message(update) else{return Ok(());}; let Some(message) = get_message(update) else {
return Ok(());
};
let mut offsets = Vec::new(); let mut offsets = Vec::new();
let mut times = Vec::new(); let mut times = Vec::new();
@ -97,7 +99,7 @@ impl Handler for TimeConverter {
if times.is_empty() { if times.is_empty() {
offsets = [FixedOffset::east_opt(0).unwrap()] offsets = [FixedOffset::east_opt(0).unwrap()]
.into_iter() .into_iter()
.chain(offsets.into_iter()) .chain(offsets)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
times.push(Utc::now().time()); times.push(Utc::now().time());
} }

View File

@ -21,7 +21,9 @@ pub struct Greeter;
#[async_trait] #[async_trait]
impl Handler for Greeter { impl Handler for Greeter {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Update::NewMessage(message) = update else {return Ok(())}; let Update::NewMessage(message) = update else {
return Ok(());
};
// Choose random greeting from the list of greetings. // Choose random greeting from the list of greetings.
let reply_text = GREETINGS.iter().choose(&mut rand::rngs::OsRng).copied(); let reply_text = GREETINGS.iter().choose(&mut rand::rngs::OsRng).copied();

View File

@ -8,7 +8,9 @@ pub struct Repeator;
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for Repeator { impl Handler for Repeator {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Some(message) = get_message(update) else { return Ok(()) }; let Some(message) = get_message(update) else {
return Ok(());
};
message message
.respond(InputMessage::from(message.text()).silent(true)) .respond(InputMessage::from(message.text()).silent(true))
.await?; .await?;

View File

@ -37,7 +37,7 @@ async fn rotator(replied_message: Message, text: String) {
#[async_trait::async_trait] #[async_trait::async_trait]
impl Handler for Rotator { impl Handler for Rotator {
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> { async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
let Some(message) = get_message(update) else{ let Some(message) = get_message(update) else {
return Ok(()); return Ok(());
}; };
if let Some(text) = message.text().strip_prefix(".rl").map(str::trim) { if let Some(text) = message.text().strip_prefix(".rl").map(str::trim) {

View File

@ -19,6 +19,7 @@ use super::{
basic::{ basic::{
currency_converter::{CurrencyConverter, CurrencyTextFilter}, currency_converter::{CurrencyConverter, CurrencyTextFilter},
get_chat_id::GetChatId, get_chat_id::GetChatId,
get_user_id::GetUserId,
help::Help, help::Help,
notify_all::NotifyAll, notify_all::NotifyAll,
time_converter::TimeConverter, time_converter::TimeConverter,
@ -97,6 +98,7 @@ async fn handle_with_log(handler: Box<dyn Handler>, client: Client, update_data:
/// and spawns correcsponding handlers. /// and spawns correcsponding handlers.
/// ///
/// Also, every available handler is defined here. /// Also, every available handler is defined here.
#[allow(clippy::too_many_lines)]
async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> { async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
let me = client.get_me().await?; let me = client.get_me().await?;
let handlers: Vec<FilteredHandler> = vec![ let handlers: Vec<FilteredHandler> = vec![
@ -118,6 +120,11 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
.add_filter(ExcludedChatsFilter(args.excluded_chats.clone())) .add_filter(ExcludedChatsFilter(args.excluded_chats.clone()))
.add_filter(TextFilter(&[".cid"], TextMatchMethod::Matches)) .add_filter(TextFilter(&[".cid"], TextMatchMethod::Matches))
.add_filter(OnlyFromId(me.id())), .add_filter(OnlyFromId(me.id())),
// Get user id.
FilteredHandler::new(GetUserId)
.add_filter(SilentFilter)
.add_filter(MessageDirectionFilter(MessageDirection::Outgoing))
.add_filter(TextFilter(&[".uid"], TextMatchMethod::Matches)),
// Make бля fun again. // Make бля fun again.
FilteredHandler::new(Blyaficator) FilteredHandler::new(Blyaficator)
.add_filter(ExcludedChatsFilter(args.excluded_chats.clone())) .add_filter(ExcludedChatsFilter(args.excluded_chats.clone()))
@ -168,8 +175,6 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
&[".cid"], &[".cid"],
TextMatchMethod::StartsWith, TextMatchMethod::StartsWith,
))), ))),
// .add_filter(TextFilter(&[".cid"], TextMatchMethod::)),
// Notify all.
FilteredHandler::new(NotifyAll) FilteredHandler::new(NotifyAll)
.add_filter(ExcludedChatsFilter(args.excluded_chats.clone())) .add_filter(ExcludedChatsFilter(args.excluded_chats.clone()))
.add_filter(UpdateTypeFilter(&[UpdateType::New])) .add_filter(UpdateTypeFilter(&[UpdateType::New]))
@ -265,7 +270,7 @@ pub async fn start(args: BotConfig, web_code: Arc<RwLock<Option<String>>>) -> an
Err(err) => { Err(err) => {
log::error!("{err}"); log::error!("{err}");
} }
Ok(_) => { Ok(()) => {
log::info!("Lol, messages are ended."); log::info!("Lol, messages are ended.");
} }
} }