DELETED: useless function for HTML parsing

This commit is contained in:
doryan 2024-06-05 14:13:24 +04:00
parent 00f59465b3
commit 009a42990a
27 changed files with 269 additions and 158 deletions

View File

@ -1,3 +1,5 @@
[profile.release]
opt-level = 3
[package]
name = "dorya"
@ -10,10 +12,8 @@ edition = "2021"
anyhow = "1.0.86"
async-trait = "0.1.80"
chrono = "0.4.38"
dashmap = "5.5.3"
dotenvy = "0.15.7"
futures = "0.3.30"
telers = "1.0.0-alpha.18"
telers = { git = "https://github.com/doryan04/telers.git" }
tokio = { version="1.37.0", features=["rt-multi-thread"] }
tracing = "0.1.40"
tracing-subscriber = {version="0.3.18", features=["env-filter"]}

8
src/assets/mod.rs Normal file
View File

@ -0,0 +1,8 @@
use std::include_str;
pub mod files {
use super::*;
pub const MUTE_COMMAND_HELP: &str = include_str!("mute_command_help.html");
pub const UNMUTE_COMMAND_HELP: &str = include_str!("unmute_command_help.html");
}

View File

@ -0,0 +1,10 @@
<code>/mute [ID | REPLY] &lt;DURATION: i64 (long long int)&gt; [TIME METRIC]</code>
<b>Обязательные критерий:</b>
<b><em>1. Участник чата</em></b>. Введите ID участника чата, либо ответьте на его сообщение, чтобы его замьютить;
<b><em>2. Длительность</em></b>. Введите длительность мьюта, длительность должна быть не меньше нуля.
<b>Необязательные критерий:</b>
<b><em>1. Временная метрика.</em></b> Если она не указана, то автоматически участнику чата выдаётся мьют в днях.

View File

@ -0,0 +1,6 @@
<code>/unmute [ID | REPLY]</code>
<b>Обязательные критерий:</b>
<b><em>1. Участник чата</em></b>. Введите ID участника чата, либо ответьте на его сообщение, чтобы c него снять мьют.

View File

@ -10,12 +10,10 @@ use crate::{
enums::target_user::TargetUser,
structs::handler_entity::{ExtractedEntityData, HandlerEntity},
},
utils::telegram::{get_bot_response_text::get_bot_response_text, try_do::try_restrict},
utils::telegram::{ban_member::ban_chat_member, try_do::try_restrict},
};
use crate::utils::telegram::ban_member::ban_chat_member;
pub async fn ban(
pub async fn ban_member(
handler_entity: HandlerEntity,
chat_id: i64,
user: TargetUser,
@ -23,11 +21,12 @@ pub async fn ban(
) -> HandlerResult {
let (bot, message, mut sender_builder): ExtractedEntityData = handler_entity.extract();
println!("дошло");
let user_id: i64 = match user.get_id() {
Some(id) => id,
None => {
sender_builder
.text(get_bot_response_text(&message, "забанить", "/ban [ID | REPLY]").unwrap())
.text("Ответьте на сообщение участника чата, которого вы хотите забанить")
.reply_to(message.id())
.build()
.send(&bot)

View File

@ -7,19 +7,17 @@ use tokio::time::{sleep, Duration};
use crate::{
types::{
enums::target_user::{self, TargetUser},
enums::target_user::TargetUser,
structs::handler_entity::{ExtractedEntityData, HandlerEntity},
TimeValues,
},
utils::{
general::get_duration::{get_duration, ExtractedDuration},
telegram::{
get_bot_response_text::get_bot_response_text, restrict::restrict, try_do::try_restrict,
},
telegram::{restrict::restrict, try_do::try_restrict},
},
};
pub async fn mute(
pub async fn mute_member(
handler_entity: HandlerEntity,
chat_id: i64,
user: TargetUser,
@ -31,7 +29,7 @@ pub async fn mute(
Some(id) => id,
None => {
sender_builder
.text(get_bot_response_text(&message, "замьютить", "/mute [ID | REPLY]").unwrap())
.text("Ответьте на сообщение участника чата, которого вы хотите замьютить")
.reply_to(message.id())
.build()
.send(&bot)
@ -54,6 +52,7 @@ pub async fn mute(
.await
.is_err()
{
sender_builder.build().send(&bot).await?;
Ok(EventReturn::Cancel)
} else {
let muted_user_name: String = user.get_user_name(&bot, &message).await.unwrap();

View File

@ -9,7 +9,7 @@ use crate::types::{
structs::handler_entity::{ExtractedEntityData, HandlerEntity},
};
pub async fn unmute(
pub async fn unmute_member(
handler_entity: HandlerEntity,
chat_id: i64,
user: TargetUser,
@ -40,7 +40,7 @@ pub async fn unmute(
sender_builder
.reply_to(message.id())
.text(format!("С пользователя {} был снят мьут.", muted_user_name))
.text(format!("С пользователя {} был снят мьют.", muted_user_name))
.build()
.send(&bot)
.await

View File

@ -8,8 +8,10 @@ use crate::types::structs::message_sender::MessageSender;
const HELP_TEXT: &str = "\
/help - помощь по боту.\n\
/unmute - снимает с человека мьют, для подробностей, введите команду без ID и без ответа \
на сообщение участника чата (только для админов).\n\
/unmute - снимает с участника чата мьют, для подробностей, введите команду без аргументов \
(только для админов).\n\
/mute - накладывает на участника чата мьют, для подробностей, введите команду без аргументов \
(только для админов).\n\
🎲 - выдаёт мут, для этого нужно отправить ТОЛЬКО эмодзи в ответ на сообщение участника. \
чата, которого вы хотите замьютить (только для админов).\n\
🎰 - выдаёт бан в случае джекпота, напротив, мьют, всё так же кидайте этот эмодзи в ответ \

View File

@ -1,2 +1,3 @@
pub mod help_command;
pub mod mute_command;
pub mod unmute_command;

View File

@ -0,0 +1,96 @@
use telers::{
enums::ParseMode,
event::{telegram::HandlerResult, EventReturn},
filters::CommandObject,
types::Message,
Bot,
};
use crate::{
assets::files::MUTE_COMMAND_HELP,
handlers::actions::mute::mute_member,
types::{
enums::{target_user::TargetUser, time_metrics::TimeMetrics},
structs::{handler_entity::HandlerEntity, message_sender::MessageSender},
},
utils::general::parse_boxed_array::parse_boxed,
};
pub async fn mute(bot: Bot, message: Message, command: CommandObject) -> HandlerResult {
let args: Vec<&'static str> = parse_boxed(command.args);
let (message_id, chat_id): (i64, i64) = (message.id(), message.chat().id());
let sender = MessageSender::builder(chat_id).reply_to(message_id);
let mut handler_entity: HandlerEntity = HandlerEntity::new(bot, message, sender);
let mut duration_argument_position: usize = 0;
let target_user: TargetUser = match (
handler_entity.message_reciever.reply_to_message(),
args.first(),
) {
(Some(msg), _) => TargetUser::CurrentMessage(msg.clone()),
(None, Some(raw_id)) => {
duration_argument_position += 1;
if let Ok(id) = raw_id.parse::<i64>() {
TargetUser::Id(id)
} else {
handler_entity.message_sender_builder
.text("Ответьте на сообщение или укажите первым аргументом ID человека, которого вы хотите замьютить")
.build()
.send(&handler_entity.bot_instance)
.await?;
return Ok(EventReturn::Cancel);
}
}
(None, None) => {
handler_entity
.message_sender_builder
.text(MUTE_COMMAND_HELP)
.parse_mode(ParseMode::HTML)
.build()
.send(&handler_entity.bot_instance)
.await?;
return Ok(EventReturn::Cancel);
}
};
handler_entity
.message_sender_builder
.set_text("Укажите число, характеризующее длительность мьюта.");
match args.get(duration_argument_position).cloned() {
Some(duration_str) => {
let metric = args
.get(duration_argument_position + 1)
.cloned()
.unwrap_or("d");
if let Ok(duration) = duration_str.parse::<i64>() {
let mute_duration = TimeMetrics::from(metric, duration);
mute_member(handler_entity, chat_id, target_user, (mute_duration, 0)).await?;
} else {
handler_entity
.message_sender_builder
.build()
.send(&handler_entity.bot_instance)
.await?;
return Ok(EventReturn::Cancel);
}
}
None => {
handler_entity
.message_sender_builder
.build()
.send(&handler_entity.bot_instance)
.await?;
return Ok(EventReturn::Cancel);
}
}
Ok(EventReturn::Finish)
}

View File

@ -0,0 +1,62 @@
use telers::{
enums::ParseMode,
event::{telegram::HandlerResult, EventReturn},
filters::CommandObject,
types::Message,
Bot,
};
use crate::{
assets::files::UNMUTE_COMMAND_HELP,
handlers::actions::unmute::unmute_member,
types::{
enums::target_user::TargetUser,
structs::{handler_entity::HandlerEntity, message_sender::MessageSender},
},
utils::general::parse_boxed_array::parse_boxed,
};
pub async fn unmute(bot: Bot, message: Message, command: CommandObject) -> HandlerResult {
let args: Vec<&'static str> = parse_boxed(command.args);
let (message_id, chat_id): (i64, i64) = (message.id(), message.chat().id());
let sender = MessageSender::builder(chat_id).reply_to(message_id);
let mut handler_entity: HandlerEntity = HandlerEntity::new(bot, message, sender);
match args.first().cloned() {
Some(raw_id) => {
handler_entity
.message_sender_builder
.set_text("Укажите id пользователя, с которого вы хотите снять мьют");
if let Ok(parsed_id) = raw_id.parse::<i64>() {
let on_id: TargetUser = TargetUser::Id(parsed_id);
unmute_member(handler_entity, chat_id, on_id).await?;
} else {
handler_entity
.message_sender_builder
.build()
.send(&handler_entity.bot_instance)
.await
.unwrap();
}
}
None => {
if handler_entity.message_reciever.reply_to_message().is_none() {
handler_entity
.message_sender_builder
.text(UNMUTE_COMMAND_HELP)
.parse_mode(ParseMode::HTML)
.build()
.send(&handler_entity.bot_instance)
.await
.unwrap();
} else {
let on_reply = TargetUser::Reply(handler_entity.message_reciever.clone());
unmute_member(handler_entity, chat_id, on_reply).await?;
}
}
}
Ok(EventReturn::Finish)
}

View File

@ -1,89 +0,0 @@
use telers::{
enums::ParseMode,
event::{telegram::HandlerResult, EventReturn},
filters::CommandObject,
types::Message,
utils::text::{html_formatter::Formatter as HTMLFormatter, Builder as TextBuilder},
Bot,
};
use crate::{
handlers::actions::unmute::unmute,
types::{
enums::target_user::TargetUser,
structs::{
handler_entity::HandlerEntity,
message_sender::{MessageSender, MessageSenderBuilder},
},
},
};
async fn unmute_help(sender: MessageSenderBuilder, bot: &Bot) {
let help_response_builder: TextBuilder<HTMLFormatter> =
TextBuilder::new(HTMLFormatter::default())
.monowidth("/unmute [ID | REPLY]")
.text(
"
\n\nВведите либо ID юзера, либо ответьте на \
сообщение участника чата, с которого вы хотите \
снять мьют.
",
);
let help_response: &str = help_response_builder.get_text();
sender
.text(help_response)
.parse_mode(ParseMode::HTML)
.build()
.send(bot)
.await
.unwrap();
}
pub async fn unmute_command(bot: Bot, message: Message, command: CommandObject) -> HandlerResult {
let args: Vec<&str> = command.args.iter().map(|boxed| &**boxed).collect();
let (message_id, chat_id): (i64, i64) = (message.id(), message.chat().id());
let sender: MessageSenderBuilder = MessageSender::builder(chat_id).reply_to(message_id);
let mut handler_entity: HandlerEntity = HandlerEntity {
bot_instance: bot,
message_reciever: message,
message_sender_builder: sender,
};
match args.first().cloned() {
None => {
if handler_entity.message_reciever.reply_to_message().is_none() {
unmute_help(
handler_entity.message_sender_builder,
&handler_entity.bot_instance,
)
.await;
} else {
let on_reply = TargetUser::Reply(handler_entity.message_reciever.clone());
unmute(handler_entity, chat_id, on_reply).await?;
}
}
Some(id) => {
handler_entity
.message_sender_builder
.set_text("Укажите id пользователя, с которого вы хотите снять мьют");
if let Ok(parsed_id) = id.parse::<i64>() {
let on_id: TargetUser = TargetUser::Id(parsed_id);
unmute(handler_entity, chat_id, on_id).await?;
} else {
handler_entity
.message_sender_builder
.build()
.send(&handler_entity.bot_instance)
.await
.unwrap();
}
}
}
Ok(EventReturn::Finish)
}

View File

@ -5,7 +5,7 @@ use telers::{
};
use crate::{
handlers::actions::{ban::ban, mute::mute},
handlers::actions::{ban::ban_member, mute::mute_member},
types::{
enums::{target_user::TargetUser, time_metrics::TimeMetrics},
structs::{handler_entity::HandlerEntity, message_sender::MessageSender},
@ -18,24 +18,21 @@ const CASINO_DELAY_MS: u64 = 1500u64;
pub async fn dice_handler(bot: Bot, message: Message) -> HandlerResult {
let (chat_id, dice): (i64, Dice) = (message.chat().id(), message.dice().unwrap().clone());
let handler_entity: HandlerEntity = HandlerEntity {
bot_instance: bot,
message_reciever: message,
message_sender_builder: MessageSender::builder(chat_id),
};
let sender = MessageSender::builder(chat_id);
let handler_entity: HandlerEntity = HandlerEntity::new(bot, message, sender);
let (mute_time, emoji): (TimeMetrics, &str) = (TimeMetrics::Days(dice.value), &dice.emoji);
let target: TargetUser = TargetUser::Reply(handler_entity.message_reciever.clone());
match emoji {
"🎲" => {
mute(handler_entity, chat_id, target, (mute_time, DICE_DELAY_MS)).await?;
mute_member(handler_entity, chat_id, target, (mute_time, DICE_DELAY_MS)).await?;
}
"🎰" => {
if dice.value == 64 {
ban(handler_entity, chat_id, target, CASINO_DELAY_MS).await?;
ban_member(handler_entity, chat_id, target, CASINO_DELAY_MS).await?;
} else {
mute(
mute_member(
handler_entity,
chat_id,
target,

View File

@ -1,3 +1,3 @@
pub mod actions;
pub mod commands_handler;
pub mod command_handlers;
pub mod dice_handler;

View File

@ -1,4 +1,5 @@
use dotenvy::dotenv;
use telers::{
enums::ContentType,
event::ToServiceProvider,
@ -8,6 +9,7 @@ use telers::{
use tracing_subscriber::{fmt, layer::SubscriberExt as _, util::SubscriberInitExt as _, EnvFilter};
mod assets;
mod middlewares;
mod types;
mod utils;
@ -16,7 +18,7 @@ use middlewares::admin_check_middleware::AdminCheck;
mod handlers;
use handlers::{
commands_handler::{help_command::help, unmute_command::unmute_command},
command_handlers::{help_command::help, mute_command::mute, unmute_command::unmute},
dice_handler::dice::dice_handler,
};
@ -50,9 +52,14 @@ async fn main() {
admin_commands
.message
.register(unmute_command)
.register(unmute)
.filter(Command::one("unmute"));
admin_commands
.message
.register(mute)
.filter(Command::one("mute"));
admin_commands
.message
.inner_middlewares

View File

@ -35,7 +35,7 @@ impl InnerMiddleware for AdminCheck {
return Ok(response);
} else {
MessageSender::builder(chat_id)
.text("У вам нет прав администратора, чтобы использовать эту команду.")
.text("У ваc нет прав администратора, чтобы использовать эту команду.")
.build()
.send(&bot)
.await

View File

@ -9,6 +9,7 @@ use telers::{
pub enum TargetUser {
Id(i64),
Reply(Message),
CurrentMessage(Message),
#[default]
None,
}
@ -24,6 +25,7 @@ impl TargetUser {
None
}
}
Self::CurrentMessage(msg) => msg.from().map(|user| user.id),
Self::None => None,
}
}
@ -53,7 +55,14 @@ impl TargetUser {
None
}
}
_ => None,
Self::CurrentMessage(msg) => {
if let Some(replied_msg) = msg.from() {
replied_msg.username.clone()
} else {
None
}
}
Self::None => None,
}
}
}

View File

@ -9,6 +9,24 @@ pub enum TimeMetrics {
}
impl TimeMetrics {
pub fn from(metric: impl Into<&'static str>, duration: i64) -> Self {
match metric.into() {
"min" | "minutes" | "minute" | "минута" | "минуты" | "минут" | "мин" => {
Self::Minutes(duration)
}
"h" | "hours" | "hour" | "час" | "часов" | "ч" => Self::Hours(duration),
"d" | "days" | "day" | "день" | "дня" | "дней" | "д" => {
Self::Days(duration)
}
"w" | "weeks" | "week" | "недель" | "недели" | "неделя" | "н" => {
Self::Weeks(duration)
}
"m" | "mounths" | "mounth" | "месяц" | "месяца" | "месяцев" | "мес" => {
Self::Mounths(duration)
}
_ => Self::Days(duration),
}
}
pub fn extract(self) -> i64 {
match self {
Self::Minutes(min) => min,

View File

@ -10,6 +10,13 @@ pub struct HandlerEntity {
}
impl HandlerEntity {
pub fn new(bot: Bot, msg: Message, msg_builder: MessageSenderBuilder) -> Self {
Self {
bot_instance: bot,
message_reciever: msg,
message_sender_builder: msg_builder,
}
}
#[inline]
pub fn extract(self) -> ExtractedEntityData {
(

View File

@ -30,6 +30,7 @@ pub struct MessageSenderBuilder {
send_message: SendMessage,
}
#[allow(dead_code)]
impl MessageSenderBuilder {
pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
self.send_message = self.send_message.parse_mode(parse_mode);

View File

@ -1,4 +1,4 @@
#[must_use]
#[allow(dead_code)]
pub trait ICountable<T, M> {
fn new() -> Self;

View File

@ -1,8 +1,7 @@
use chrono::NaiveDateTime;
use crate::types::{
enums::time_metrics::TimeMetrics, structs::countable_time::CountableTime,
traits::countable_interface::ICountable, TimeValues,
structs::countable_time::CountableTime, traits::countable_interface::ICountable, TimeValues,
};
use super::unrestrict_date::unrestrict_date;

View File

@ -1,2 +1,3 @@
pub mod get_duration;
pub mod parse_boxed_array;
pub mod unrestrict_date;

View File

@ -0,0 +1,11 @@
pub fn parse_box<'a>(boxed: Box<str>) -> &'a str {
unsafe { &*Box::into_raw(boxed) }
}
#[allow(clippy::boxed_local)]
pub fn parse_boxed<'a>(boxed_array: Box<[Box<str>]>) -> Vec<&'a str> {
boxed_array
.iter()
.map(|arg| parse_box(arg.to_owned()))
.collect()
}

View File

@ -1,32 +0,0 @@
use telers::{
types::Message,
utils::text::{html_formatter::Formatter as HTMLFormatter, Builder as TextBuilder},
};
pub fn get_bot_response_text(
msg: &Message,
action: impl Into<String>,
command: impl Into<String>,
) -> Option<String> {
match msg {
Message::Dice(_) => Some(format!(
"Ответьте на сообщение, чтобы {} участника чата.",
action.into()
)),
Message::Text(_) => {
let help_response_builder: TextBuilder<HTMLFormatter> =
TextBuilder::new(HTMLFormatter::default())
.monowidth(command.into())
.text(format!(
"
\n\nВведите либо ID юзера, либо ответьте на \
сообщение участника чата, с которого вы хотите {}.
",
action.into()
));
Some(help_response_builder.get_text().into())
}
_ => None,
}
}

View File

@ -2,6 +2,5 @@ pub mod admin_check;
pub mod ban_member;
pub mod demote;
pub mod get_all_admins;
pub mod get_bot_response_text;
pub mod restrict;
pub mod try_do;

View File

@ -1,6 +1,6 @@
use telers::{errors::SessionErrorKind as ErrorKind, event::EventReturn, Bot};
use crate::types::{enums::target_user::TargetUser, structs::message_sender::MessageSender};
use crate::types::structs::message_sender::MessageSender;
use std::future::Future;
use super::demote::demote_user;