REFACTOR!: remove a lot of bad code + structures, remake command args parser, and etc.
This commit is contained in:
parent
d3d13b32c9
commit
dd306b7000
|
@ -4,7 +4,7 @@ lto = "fat"
|
|||
overflow-checks = false
|
||||
|
||||
[package]
|
||||
name = "dorya"
|
||||
name = "gluon"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
@ -8,91 +8,39 @@ use telers::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
actions::{ban::ban_member, mute::mute_member, unmute::unmute_member},
|
||||
assets::files::{BAN_COMMAND_HELP, MUTE_COMMAND_HELP, UNMUTE_COMMAND_HELP},
|
||||
types::{
|
||||
enums::{target_user::TargetUser, time_metrics::TimeMetrics},
|
||||
structs::handler_entity::HandlerEntity,
|
||||
},
|
||||
utils::{
|
||||
general::cast_boxed_array::cast_boxed,
|
||||
telegram::{args_parsers::get_user, data_getters::get_chat_data, senders::send_html},
|
||||
},
|
||||
assets::files::{BAN_COMMAND_HELP, MUTE_COMMAND_HELP, UNBAN_COMMAND_HELP, UNMUTE_COMMAND_HELP},
|
||||
utils::telegram::{args_parser::parse_args, senders::send_html},
|
||||
};
|
||||
|
||||
pub async fn admin_command_endpoint(
|
||||
#[allow(unused)]
|
||||
const USER_ID_NOT_FOUND: &str = "Для выполнение команды нужно знать ID пользователя, или ввести команду и выполнить её, ответив на сообщение пользователя";
|
||||
#[allow(unused)]
|
||||
const COMMAND_EXECUTION_REJECTED: &str = "Выполнение данной команды невозможно, поскольку пользователю были выданы права администратора модераторами или основателем";
|
||||
|
||||
pub async fn admin_commands_endpoint(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
command: CommandObject,
|
||||
command_object: CommandObject,
|
||||
) -> HandlerResult {
|
||||
let command_type: &str = command.command.deref();
|
||||
let (command_type, args) = (command_object.command.deref(), command_object.args.deref());
|
||||
|
||||
let args: Vec<&'static str> = cast_boxed(command.args);
|
||||
let chat_id = message.chat().id();
|
||||
|
||||
let (chat_id, mut handler_entity): (i64, HandlerEntity) = get_chat_data(&bot, &message);
|
||||
|
||||
let mut duration_argument_position = 0usize;
|
||||
|
||||
let target_user: TargetUser = get_user(
|
||||
handler_entity.clone(),
|
||||
args.first().copied(),
|
||||
&mut duration_argument_position,
|
||||
);
|
||||
|
||||
if args.is_empty() && !target_user.exist() {
|
||||
if let Some(_args) = parse_args(args, &message, command_type) {
|
||||
match command_type {
|
||||
"ban" | "unban" | "mute" | "unmute" => todo!(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
} else {
|
||||
let help_txt = match command_type {
|
||||
"ban" => BAN_COMMAND_HELP,
|
||||
"mute" => MUTE_COMMAND_HELP,
|
||||
"unban" => UNBAN_COMMAND_HELP,
|
||||
"unmute" => UNMUTE_COMMAND_HELP,
|
||||
_ => "Такой команды не существует.",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
send_html(bot, message, help_txt).await?;
|
||||
|
||||
return Ok(EventReturn::Cancel);
|
||||
send_html(&bot, chat_id, help_txt).await?;
|
||||
}
|
||||
|
||||
handler_entity
|
||||
.message_sender_builder
|
||||
.set_text("Нет ID или ответа на сообщение пользователя.");
|
||||
|
||||
match command_type {
|
||||
"ban" => ban_member(handler_entity, chat_id, target_user, 0).await?,
|
||||
"mute" => 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
|
||||
.text("Не указана длительность мута.")
|
||||
.build()
|
||||
.send(&handler_entity.bot_instance)
|
||||
.await?;
|
||||
|
||||
return Ok(EventReturn::Cancel);
|
||||
}
|
||||
},
|
||||
"unmute" => unmute_member(handler_entity, chat_id, target_user).await?,
|
||||
_ => EventReturn::Finish,
|
||||
};
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use telers::{event::telegram::HandlerResult, filters::CommandObject, types::Message, Bot};
|
||||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
filters::CommandObject,
|
||||
types::Message,
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
assets::files::{HELP_COMMAND_TEXT, PRIVACY_COMMAND_TEXT},
|
||||
|
@ -10,12 +15,13 @@ use crate::{
|
|||
#[inline]
|
||||
pub async fn info_commands_endpoint(
|
||||
bot: Bot,
|
||||
msg: Message,
|
||||
command: CommandObject,
|
||||
message: Message,
|
||||
command_object: CommandObject,
|
||||
) -> HandlerResult {
|
||||
match command.command.deref() {
|
||||
"help" => send_html(bot, msg, HELP_COMMAND_TEXT).await,
|
||||
"privacy" => send_html(bot, msg, PRIVACY_COMMAND_TEXT).await,
|
||||
_ => Ok(telers::event::EventReturn::Cancel),
|
||||
let chat_id = message.chat().id();
|
||||
match command_object.command.deref() {
|
||||
"help" => send_html(&bot, chat_id, HELP_COMMAND_TEXT).await,
|
||||
"privacy" => send_html(&bot, chat_id, PRIVACY_COMMAND_TEXT).await,
|
||||
_ => Ok(EventReturn::Cancel),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
pub mod admin_commands;
|
||||
pub mod info_commands;
|
||||
mod admin_commands;
|
||||
mod info_commands;
|
||||
|
||||
pub use admin_commands::*;
|
||||
pub use info_commands::*;
|
||||
|
|
|
@ -1,48 +1,43 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
types::{Dice, Message},
|
||||
Bot,
|
||||
};
|
||||
use tokio::time::sleep;
|
||||
|
||||
use crate::{
|
||||
actions::{ban::ban_member, mute::mute_member},
|
||||
types::{
|
||||
enums::{target_user::TargetUser, time_metrics::TimeMetrics},
|
||||
structs::{handler_entity::HandlerEntity, message_sender::MessageSender},
|
||||
},
|
||||
types::enums::{target_user::TargetUser, time_metrics::TimeDuration},
|
||||
utils::telegram::args_parser::Argument,
|
||||
};
|
||||
|
||||
const DICE_DELAY_MS: u64 = 4000u64;
|
||||
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());
|
||||
pub async fn dice_handler(_bot: Bot, message: Message) -> HandlerResult {
|
||||
let (_chat_id, dice): (i64, Dice) = (message.chat().id(), message.dice().unwrap().clone());
|
||||
|
||||
let sender = MessageSender::builder(chat_id);
|
||||
let handler_entity = HandlerEntity::new(bot, message, sender);
|
||||
let (mute_time, emoji): (TimeDuration, &str) = (TimeDuration::Days(dice.value), &dice.emoji);
|
||||
|
||||
let (mute_time, emoji): (TimeMetrics, &str) = (TimeMetrics::Days(dice.value), &dice.emoji);
|
||||
|
||||
let target = TargetUser::Reply(handler_entity.message_reciever.clone());
|
||||
let target_user = TargetUser::Reply(message.clone());
|
||||
let _args = [Argument::User(target_user), Argument::Time(mute_time)];
|
||||
|
||||
match emoji {
|
||||
"🎲" => {
|
||||
mute_member(handler_entity, chat_id, target, (mute_time, DICE_DELAY_MS)).await?;
|
||||
sleep(Duration::from_millis(DICE_DELAY_MS)).await;
|
||||
todo!()
|
||||
}
|
||||
"🎰" => {
|
||||
if dice.value == 64 {
|
||||
ban_member(handler_entity, chat_id, target, CASINO_DELAY_MS).await?;
|
||||
sleep(Duration::from_millis(CASINO_DELAY_MS)).await;
|
||||
todo!()
|
||||
} else {
|
||||
mute_member(
|
||||
handler_entity,
|
||||
chat_id,
|
||||
target,
|
||||
(mute_time, CASINO_DELAY_MS),
|
||||
)
|
||||
.await?;
|
||||
sleep(Duration::from_millis(CASINO_DELAY_MS)).await;
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
pub mod dice_handler;
|
||||
mod dice_handler;
|
||||
|
||||
pub use dice_handler::*;
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -7,7 +7,6 @@ use telers::{
|
|||
Bot, Dispatcher, Router,
|
||||
};
|
||||
|
||||
mod actions;
|
||||
mod assets;
|
||||
mod handlers;
|
||||
mod middlewares;
|
||||
|
@ -17,8 +16,8 @@ mod utils;
|
|||
use middlewares::admin_check_middleware::AdminCheck;
|
||||
|
||||
use handlers::{
|
||||
commands::{admin_commands::admin_command_endpoint, info_commands::info_commands_endpoint},
|
||||
dice::dice_handler::dice_handler,
|
||||
commands::{admin_commands_endpoint, info_commands_endpoint},
|
||||
dice::dice_handler,
|
||||
};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -65,7 +64,14 @@ async fn main() {
|
|||
let mut default_commands = Router::new("default_commands");
|
||||
|
||||
create_handler!(default_commands, info_commands_endpoint, help, privacy);
|
||||
create_handler!(admin_commands, admin_command_endpoint, mute, unmute, ban);
|
||||
create_handler!(
|
||||
admin_commands,
|
||||
admin_commands_endpoint,
|
||||
ban,
|
||||
unban,
|
||||
mute,
|
||||
unmute
|
||||
);
|
||||
|
||||
admin_commands
|
||||
.message
|
||||
|
|
|
@ -2,6 +2,7 @@ use async_trait::async_trait;
|
|||
use telers::{
|
||||
errors::{EventErrorKind, HandlerError},
|
||||
event::telegram::HandlerResponse,
|
||||
methods::SendMessage,
|
||||
middlewares::{InnerMiddleware, Next},
|
||||
types::Message,
|
||||
Request,
|
||||
|
@ -9,10 +10,7 @@ use telers::{
|
|||
|
||||
use anyhow::Error as Reject;
|
||||
|
||||
use crate::{
|
||||
types::structs::message_sender::MessageSender,
|
||||
utils::telegram::{admin_check::is_admin, data_getters::get_all_admins},
|
||||
};
|
||||
use crate::utils::telegram::{admin_check::is_admin, data_getters::get_all_admins};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AdminCheck {}
|
||||
|
@ -20,16 +18,23 @@ pub struct AdminCheck {}
|
|||
#[async_trait]
|
||||
impl InnerMiddleware for AdminCheck {
|
||||
async fn call(&self, request: Request, next: Next) -> Result<HandlerResponse, EventErrorKind> {
|
||||
let (bot, message) = (request.clone().bot, request.clone().update);
|
||||
let (bot, message) = (request.bot.clone(), request.update.clone());
|
||||
|
||||
let is_replying_dice: Option<Message> = match message.kind().message().unwrap() {
|
||||
Message::Dice(dice) => dice.reply_to_message.clone(),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let admins_list = get_all_admins(&bot, message.chat().unwrap().id())
|
||||
.await
|
||||
.unwrap();
|
||||
let chat = match message.chat() {
|
||||
Some(chat) => chat,
|
||||
None => {
|
||||
return Err(EventErrorKind::Handler(HandlerError::from_display(
|
||||
"Chat not found",
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
let admins_list = get_all_admins(&bot, chat.id()).await.unwrap();
|
||||
|
||||
let chat_id: i64 = message.chat_id().unwrap();
|
||||
|
||||
|
@ -38,12 +43,12 @@ impl InnerMiddleware for AdminCheck {
|
|||
return Ok(response);
|
||||
} else {
|
||||
if is_replying_dice.is_some() {
|
||||
MessageSender::builder(chat_id)
|
||||
.text("Недостаточно прав для использования данной команды.")
|
||||
.build()
|
||||
.send(&bot)
|
||||
.await
|
||||
.unwrap();
|
||||
bot.send(SendMessage::new(
|
||||
chat_id,
|
||||
"Недостаточно прав для использования данной команды.",
|
||||
))
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
|
||||
return Err(EventErrorKind::Handler(HandlerError::new(Reject::msg(
|
||||
|
|
|
@ -14,6 +14,15 @@ pub enum TargetUser {
|
|||
None,
|
||||
}
|
||||
|
||||
impl From<Option<i64>> for TargetUser {
|
||||
fn from(value: Option<i64>) -> Self {
|
||||
match value {
|
||||
Some(id) => TargetUser::Id(id),
|
||||
None => TargetUser::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TargetUser {
|
||||
#[allow(dead_code)]
|
||||
pub fn exist(&self) -> bool {
|
||||
|
@ -21,10 +30,9 @@ impl TargetUser {
|
|||
Self::Id(_id) => true,
|
||||
Self::Reply(msg) => {
|
||||
if let Some(replied_msg) = msg.reply_to_message() {
|
||||
replied_msg.from().map(|user| user.id).is_some()
|
||||
} else {
|
||||
false
|
||||
return replied_msg.from().map(|user| user.id).is_some();
|
||||
}
|
||||
false
|
||||
}
|
||||
Self::CurrentMessage(msg) => msg.from().map(|user| user.id).is_some(),
|
||||
Self::None => false,
|
||||
|
@ -36,10 +44,9 @@ impl TargetUser {
|
|||
Self::Id(id) => Some(*id),
|
||||
Self::Reply(msg) => {
|
||||
if let Some(replied_msg) = msg.reply_to_message() {
|
||||
replied_msg.from().map(|user| user.id)
|
||||
} else {
|
||||
None
|
||||
return replied_msg.from().map(|user| user.id);
|
||||
}
|
||||
None
|
||||
}
|
||||
Self::CurrentMessage(msg) => msg.from().map(|user| user.id),
|
||||
Self::None => None,
|
||||
|
@ -53,31 +60,28 @@ impl TargetUser {
|
|||
bot.send(GetChatMember::new(msg.chat().id(), *id)).await;
|
||||
|
||||
if let Ok(member_kind) = get_chat_member_result {
|
||||
match member_kind {
|
||||
return match member_kind {
|
||||
ChatMember::Owner(member) => member.user.username,
|
||||
ChatMember::Administrator(member) => member.user.username,
|
||||
ChatMember::Member(member) => member.user.username,
|
||||
ChatMember::Restricted(member) => member.user.username,
|
||||
ChatMember::Left(member) => member.user.username,
|
||||
ChatMember::Banned(member) => member.user.username,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
None
|
||||
}
|
||||
Self::Reply(msg) => {
|
||||
if let Some(replied_msg) = msg.reply_to_message() {
|
||||
replied_msg.from().unwrap().username.clone()
|
||||
} else {
|
||||
None
|
||||
return replied_msg.from().unwrap().username.clone();
|
||||
}
|
||||
None
|
||||
}
|
||||
Self::CurrentMessage(msg) => {
|
||||
if let Some(replied_msg) = msg.from() {
|
||||
replied_msg.username.clone()
|
||||
} else {
|
||||
None
|
||||
return replied_msg.username.clone();
|
||||
}
|
||||
None
|
||||
}
|
||||
Self::None => None,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum TimeMetrics {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum TimeDuration {
|
||||
Minutes(i64),
|
||||
Hours(i64),
|
||||
Days(i64),
|
||||
|
@ -8,23 +8,23 @@ pub enum TimeMetrics {
|
|||
Mounths(i64),
|
||||
}
|
||||
|
||||
impl TimeMetrics {
|
||||
pub fn from(metric: impl Into<&'static str>, duration: i64) -> Self {
|
||||
impl<'a> TimeDuration {
|
||||
pub fn from(metric: impl Into<&'a str>, duration: i64) -> Option<Self> {
|
||||
match metric.into() {
|
||||
"m" | "min" | "minutes" | "minute" | "минута" | "минуты" | "минут" | "мин" | "м" => {
|
||||
Self::Minutes(duration)
|
||||
Some(Self::Minutes(duration))
|
||||
}
|
||||
"h" | "hours" | "hour" | "час" | "часов" | "ч" => Self::Hours(duration),
|
||||
"h" | "hours" | "hour" | "час" | "часов" | "ч" => Some(Self::Hours(duration)),
|
||||
"d" | "days" | "day" | "день" | "дня" | "дней" | "д" => {
|
||||
Self::Days(duration)
|
||||
Some(Self::Days(duration))
|
||||
}
|
||||
"w" | "weeks" | "week" | "недель" | "недели" | "неделя" | "н" => {
|
||||
Self::Weeks(duration)
|
||||
Some(Self::Weeks(duration))
|
||||
}
|
||||
"M" | "months" | "month" | "месяц" | "месяца" | "месяцев" | "мес" | "М" => {
|
||||
Self::Mounths(duration)
|
||||
Some(Self::Mounths(duration))
|
||||
}
|
||||
_ => Self::Days(duration),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
use enums::time_metrics::TimeMetrics;
|
||||
|
||||
pub mod enums;
|
||||
pub mod structs;
|
||||
pub mod traits;
|
||||
|
||||
pub type TimeValues = (TimeMetrics, u64);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::types::{enums::time_metrics::TimeMetrics, traits::countable_interface::ICountable};
|
||||
use crate::types::{enums::time_metrics::TimeDuration, traits::countable_interface::ICountable};
|
||||
|
||||
pub struct CountableTime(i64, i64);
|
||||
|
||||
impl ICountable<(i64, i64), TimeMetrics> for CountableTime {
|
||||
impl ICountable<(i64, i64), TimeDuration> for CountableTime {
|
||||
#[inline]
|
||||
fn new() -> Self {
|
||||
Self(0, 0)
|
||||
|
@ -23,7 +23,7 @@ impl ICountable<(i64, i64), TimeMetrics> for CountableTime {
|
|||
Self((value / 10) % 10, value % 10)
|
||||
}
|
||||
|
||||
fn get_postfix(&self, metrics: TimeMetrics) -> Option<String> {
|
||||
fn get_postfix(&self, metrics: TimeDuration) -> Option<String> {
|
||||
let all_word_declensions = metrics.get_word_declensions();
|
||||
let (first, second, third): (String, String, String) = (
|
||||
all_word_declensions.0.into(),
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
use crate::types::structs::message_sender::MessageSenderBuilder;
|
||||
use telers::{types::Message, Bot};
|
||||
|
||||
pub type ExtractedEntityData = (Bot, Message, MessageSenderBuilder);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HandlerEntity {
|
||||
pub bot_instance: Bot,
|
||||
pub message_reciever: Message,
|
||||
pub message_sender_builder: MessageSenderBuilder,
|
||||
}
|
||||
|
||||
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 {
|
||||
(
|
||||
self.bot_instance,
|
||||
self.message_reciever,
|
||||
self.message_sender_builder,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
use core::convert::Into;
|
||||
use telers::{
|
||||
enums::ParseMode,
|
||||
errors::session::ErrorKind,
|
||||
methods::SendMessage,
|
||||
types::{Message, ReplyParameters},
|
||||
Bot,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MessageSender {
|
||||
message: SendMessage,
|
||||
}
|
||||
|
||||
impl MessageSender {
|
||||
pub fn builder(group_id: i64) -> MessageSenderBuilder {
|
||||
MessageSenderBuilder {
|
||||
chat_id: group_id,
|
||||
send_message: SendMessage::new(group_id, ""),
|
||||
}
|
||||
}
|
||||
pub async fn send(self, bot: &Bot) -> Result<Message, ErrorKind> {
|
||||
bot.send(self.message).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MessageSenderBuilder {
|
||||
chat_id: i64,
|
||||
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);
|
||||
self
|
||||
}
|
||||
pub fn group_id(mut self, val: i64) -> Self {
|
||||
self.chat_id = val;
|
||||
self.send_message = self.send_message.chat_id(val);
|
||||
self
|
||||
}
|
||||
pub fn text(mut self, val: impl Into<String>) -> Self {
|
||||
self.send_message = self.send_message.text(val);
|
||||
self
|
||||
}
|
||||
pub fn disable_notification(mut self, val: bool) -> Self {
|
||||
self.send_message = self.send_message.disable_notification(val);
|
||||
self
|
||||
}
|
||||
pub fn reply_to(mut self, msg_id: i64) -> Self {
|
||||
let reply = ReplyParameters::new(msg_id).chat_id(self.chat_id);
|
||||
self.send_message = self.send_message.reply_parameters(reply);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_parse_mode(&mut self, parse_mode: ParseMode) {
|
||||
self.send_message = self.send_message.clone().parse_mode(parse_mode);
|
||||
}
|
||||
pub fn set_group_id(&mut self, val: i64) {
|
||||
self.chat_id = val;
|
||||
self.send_message = self.send_message.clone().chat_id(val);
|
||||
}
|
||||
pub fn set_text(&mut self, val: impl Into<String>) {
|
||||
self.send_message = self.send_message.clone().text(val);
|
||||
}
|
||||
pub fn set_disable_notification(&mut self, val: bool) {
|
||||
self.send_message = self.send_message.clone().disable_notification(val);
|
||||
}
|
||||
pub fn set_reply_to(&mut self, msg_id: i64) {
|
||||
let reply = ReplyParameters::new(msg_id).chat_id(self.chat_id);
|
||||
self.send_message = self.send_message.clone().reply_parameters(reply);
|
||||
}
|
||||
|
||||
pub fn build(self) -> MessageSender {
|
||||
MessageSender {
|
||||
message: self.send_message,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1 @@
|
|||
pub mod countable_time;
|
||||
pub mod handler_entity;
|
||||
pub mod message_sender;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
pub fn cast_box<'a>(boxed: Box<str>) -> &'a str {
|
||||
unsafe { &*Box::into_raw(boxed) }
|
||||
}
|
||||
|
||||
#[allow(clippy::boxed_local)]
|
||||
pub fn cast_boxed<'a>(boxed_array: Box<[Box<str>]>) -> Vec<&'a str> {
|
||||
boxed_array
|
||||
.iter()
|
||||
.map(|arg| cast_box(arg.to_owned()))
|
||||
.collect()
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
use chrono::{Duration, Local, NaiveDateTime};
|
||||
|
||||
use crate::types::{enums::time_metrics::TimeMetrics, TimeValues};
|
||||
|
||||
#[inline]
|
||||
pub fn expiration_date(duration: TimeValues) -> NaiveDateTime {
|
||||
let mute_duration = match duration.0 {
|
||||
TimeMetrics::Minutes(min) => Duration::minutes(min),
|
||||
TimeMetrics::Hours(hrs) => Duration::hours(hrs),
|
||||
TimeMetrics::Days(day) => Duration::days(day),
|
||||
TimeMetrics::Weeks(wks) => Duration::weeks(wks),
|
||||
TimeMetrics::Mounths(mon) => Duration::weeks(mon * 4),
|
||||
};
|
||||
Local::now().naive_utc() + mute_duration
|
||||
}
|
|
@ -1,18 +1,29 @@
|
|||
use chrono::NaiveDateTime;
|
||||
|
||||
use crate::types::{
|
||||
structs::countable_time::CountableTime, traits::countable_interface::ICountable, TimeValues,
|
||||
enums::time_metrics::TimeDuration, structs::countable_time::CountableTime,
|
||||
traits::countable_interface::ICountable,
|
||||
};
|
||||
|
||||
use super::expiration_date::expiration_date;
|
||||
use chrono::{Duration, Local, NaiveDateTime};
|
||||
|
||||
pub type ExtractedDuration = (NaiveDateTime, String, i64);
|
||||
|
||||
pub fn get_expiration_time(time: TimeValues) -> ExtractedDuration {
|
||||
let time_duration = time.0.extract();
|
||||
let unmute_date = expiration_date(time);
|
||||
#[inline]
|
||||
pub fn get_expiration_date(duration: TimeDuration) -> NaiveDateTime {
|
||||
let mute_duration = match duration {
|
||||
TimeDuration::Minutes(min) => Duration::minutes(min),
|
||||
TimeDuration::Hours(hrs) => Duration::hours(hrs),
|
||||
TimeDuration::Days(day) => Duration::days(day),
|
||||
TimeDuration::Weeks(wks) => Duration::weeks(wks),
|
||||
TimeDuration::Mounths(mon) => Duration::weeks(mon * 4),
|
||||
};
|
||||
Local::now().naive_utc() + mute_duration
|
||||
}
|
||||
|
||||
pub fn get_expiration_time(time: TimeDuration) -> ExtractedDuration {
|
||||
let time_duration = time.extract();
|
||||
let unmute_date = get_expiration_date(time);
|
||||
let postfix = CountableTime::from_value(time_duration)
|
||||
.get_postfix(time.0)
|
||||
.get_postfix(time)
|
||||
.unwrap();
|
||||
|
||||
(unmute_date, postfix, time_duration)
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
pub mod expiration_date;
|
||||
pub mod get_expiration_time;
|
||||
pub mod cast_boxed_array;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#[macro_export]
|
||||
macro_rules! create_handler {
|
||||
($branch:expr, $command:expr) => {
|
||||
$($branch
|
||||
$branch
|
||||
.message
|
||||
.register($command)
|
||||
.filter(Command::one(stringify!($command)));
|
||||
)*
|
||||
};
|
||||
($branch:expr, $command:expr, $($endpoint:expr), *) => {
|
||||
$branch
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
use std::{collections::VecDeque, ops::Deref};
|
||||
|
||||
use telers::types::Message;
|
||||
|
||||
use crate::types::enums::{target_user::TargetUser, time_metrics::TimeDuration};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Argument {
|
||||
User(TargetUser),
|
||||
Time(TimeDuration),
|
||||
Reason(String),
|
||||
}
|
||||
|
||||
pub fn parse_args(
|
||||
args: &[Box<str>],
|
||||
message: &Message,
|
||||
command_type: &str,
|
||||
) -> Option<Vec<Argument>> {
|
||||
if args.is_empty() && message.reply_to_message().is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut raw_args: VecDeque<&str> = args.iter().map(|arg| arg.deref()).collect();
|
||||
let mut parsed_args: Vec<Argument> = Vec::new();
|
||||
|
||||
let user_id = match message.reply_to_message() {
|
||||
Some(reply_message) => TargetUser::from(reply_message.from_id()),
|
||||
None => match raw_args.pop_front() {
|
||||
Some(arg) => TargetUser::from(arg.parse::<i64>().ok()),
|
||||
None => TargetUser::default(),
|
||||
},
|
||||
};
|
||||
|
||||
parsed_args.push(Argument::User(user_id));
|
||||
|
||||
match command_type {
|
||||
"mute" | "tban" => 'raw_time_parsing: {
|
||||
let time = match raw_args.pop_front() {
|
||||
Some(raw_time) => raw_time.parse::<i64>().unwrap_or(0),
|
||||
None => break 'raw_time_parsing,
|
||||
};
|
||||
|
||||
if time == 0 {
|
||||
break 'raw_time_parsing;
|
||||
}
|
||||
|
||||
if let Some(raw_time_metric) = raw_args.pop_front() {
|
||||
let time_metric = match TimeDuration::from(raw_time_metric, time) {
|
||||
Some(metric) => metric,
|
||||
None => TimeDuration::Days(time),
|
||||
};
|
||||
|
||||
parsed_args.push(Argument::Time(time_metric));
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if !raw_args.is_empty() {
|
||||
let reason = raw_args.iter().fold(String::new(), |acc, v| acc + v + " ");
|
||||
|
||||
parsed_args.push(Argument::Reason(reason.trim_end().to_string()));
|
||||
}
|
||||
|
||||
Some(parsed_args)
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
use crate::types::{
|
||||
enums::target_user::TargetUser,
|
||||
structs::handler_entity::HandlerEntity
|
||||
};
|
||||
|
||||
pub fn get_user(
|
||||
handler_entity: HandlerEntity,
|
||||
arg: Option<&str>,
|
||||
arg_pos: &mut usize,
|
||||
) -> TargetUser {
|
||||
match (
|
||||
handler_entity.message_reciever.reply_to_message(),
|
||||
arg,
|
||||
) {
|
||||
(Some(msg), _) => TargetUser::CurrentMessage(msg.clone()),
|
||||
(None, Some(raw_id)) => {
|
||||
*arg_pos += 1;
|
||||
if let Ok(id) = raw_id.parse::<i64>() {
|
||||
TargetUser::Id(id)
|
||||
} else {
|
||||
TargetUser::None
|
||||
}
|
||||
}
|
||||
(None, None) => {
|
||||
TargetUser::None
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +1,6 @@
|
|||
use telers::{
|
||||
methods::GetChatAdministrators,
|
||||
types::{ChatMember, Message},
|
||||
Bot,
|
||||
errors::SessionErrorKind
|
||||
};
|
||||
|
||||
use crate::types::structs::{handler_entity::HandlerEntity, message_sender::MessageSender};
|
||||
|
||||
pub fn get_chat_data(bot: &Bot, message: &Message) -> (i64, HandlerEntity) {
|
||||
let (message_id, chat_id): (i64, i64) = (message.id(), message.chat().id());
|
||||
let sender = MessageSender::builder(chat_id).reply_to(message_id);
|
||||
let handler_entity: HandlerEntity = HandlerEntity::new(bot.clone(), message.clone(), sender);
|
||||
|
||||
(chat_id, handler_entity)
|
||||
}
|
||||
use telers::{errors::SessionErrorKind, methods::GetChatAdministrators, types::ChatMember, Bot};
|
||||
|
||||
#[inline]
|
||||
pub async fn get_all_admins(bot: &Bot, chat_id: i64) -> Result<Vec<ChatMember>, SessionErrorKind> {
|
||||
bot.send(GetChatAdministrators::new(chat_id))
|
||||
.await
|
||||
bot.send(GetChatAdministrators::new(chat_id)).await
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub async fn restrict(
|
|||
chat_id: i64,
|
||||
) -> Result<bool, ErrorKind> {
|
||||
bot.send(
|
||||
restrict_chat_member::RestrictChatMember::new(
|
||||
RestrictChatMember::new(
|
||||
chat_id,
|
||||
user_id,
|
||||
ChatPermissions::new()
|
|
@ -1,6 +1,6 @@
|
|||
pub mod admin_check;
|
||||
pub mod args_parsers;
|
||||
pub mod args_parser;
|
||||
pub mod data_getters;
|
||||
pub mod rights_control;
|
||||
pub mod member_rights;
|
||||
pub mod senders;
|
||||
pub mod try_do;
|
||||
pub mod try_admin_action;
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
use telers::{
|
||||
event::{
|
||||
telegram::HandlerResult,
|
||||
EventReturn
|
||||
},
|
||||
enums::ParseMode,
|
||||
types::Message,
|
||||
Bot
|
||||
enums::ParseMode,
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
methods::SendMessage,
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::types::structs::message_sender::MessageSender;
|
||||
|
||||
pub async fn send_html(bot: Bot, message: Message, info_text: &str) -> HandlerResult {
|
||||
MessageSender::builder(message.chat().id())
|
||||
.text(info_text)
|
||||
.parse_mode(ParseMode::HTML)
|
||||
.build()
|
||||
.send(&bot)
|
||||
pub async fn send_html(bot: &Bot, chat_id: i64, text: &str) -> HandlerResult {
|
||||
bot.send(SendMessage::new(chat_id, text).parse_mode(ParseMode::HTML))
|
||||
.await?;
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
use telers::{
|
||||
errors::{HandlerError, SessionErrorKind},
|
||||
event::simple::HandlerResult,
|
||||
methods::SendMessage,
|
||||
Bot,
|
||||
};
|
||||
|
||||
use super::member_rights::demote_user;
|
||||
|
||||
const DEMOTE_ERROR: &str = "Невозможно снять привелегий администратора в силу того, что права были выданы одним из администраторов или основателем";
|
||||
|
||||
pub async fn try_admin_action<F>(
|
||||
callback: F,
|
||||
bot: &Bot,
|
||||
chat_id: i64,
|
||||
user_id: i64,
|
||||
) -> HandlerResult
|
||||
where
|
||||
F: Copy + AsyncFnOnce(i64) -> Result<bool, SessionErrorKind>,
|
||||
{
|
||||
if callback(user_id).await.is_err() {
|
||||
if demote_user(bot, user_id, chat_id).await.is_err() {
|
||||
bot.send(SendMessage::new(chat_id, DEMOTE_ERROR)).await?;
|
||||
return Err(HandlerError::from_display("DemoteFailure"));
|
||||
} else {
|
||||
callback(user_id).await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
use telers::{errors::SessionErrorKind as ErrorKind, event::EventReturn, types::ChatMember, Bot};
|
||||
|
||||
use crate::types::structs::message_sender::MessageSender;
|
||||
use std::future::Future;
|
||||
|
||||
use super::{admin_check::is_admin, data_getters::get_all_admins, rights_control::demote_user};
|
||||
|
||||
const DEMOTE_FAILURE_MESSAGE: &str = "Команда не может быть выполнена: \
|
||||
не удалось удалить административные привилегии пользователя.";
|
||||
|
||||
pub async fn try_restrict<F, R>(
|
||||
future_callback: F,
|
||||
demote_args: (&Bot, i64, i64),
|
||||
failure_sender: MessageSender,
|
||||
) -> Result<(), EventReturn>
|
||||
where
|
||||
R: Future<Output = Result<bool, ErrorKind>>,
|
||||
F: Copy + Fn() -> R,
|
||||
{
|
||||
let (bot, user_id, chat_id): (&Bot, i64, i64) = demote_args;
|
||||
|
||||
let admins: Vec<ChatMember> = get_all_admins(bot, chat_id).await.unwrap();
|
||||
|
||||
if is_admin(&admins, user_id) {
|
||||
MessageSender::builder(chat_id)
|
||||
.text("Нельзя применить эту команду на пользователе/бота, имеющего привелегии администратора.")
|
||||
.build()
|
||||
.send(bot)
|
||||
.await
|
||||
.unwrap();
|
||||
return Err(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
if future_callback().await.is_err() {
|
||||
if demote_user(bot, user_id, chat_id).await.is_err() {
|
||||
MessageSender::builder(chat_id)
|
||||
.text(DEMOTE_FAILURE_MESSAGE)
|
||||
.build()
|
||||
.send(bot)
|
||||
.await
|
||||
.unwrap();
|
||||
return Err(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
if future_callback().await.is_err() {
|
||||
failure_sender.send(bot).await.unwrap();
|
||||
return Err(EventReturn::Cancel);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue