start the refactor

This commit is contained in:
Guillermo Roche 2025-05-10 21:49:23 +02:00
parent ae79359990
commit baf7ba2ffb
Signed by: groche97
GPG Key ID: 041FB85BEEA4B9B0
10 changed files with 473 additions and 321 deletions

123
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@ -53,6 +53,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.89" version = "1.0.89"
@ -412,6 +418,12 @@ dependencies = [
"syn 2.0.77", "syn 2.0.77",
] ]
[[package]]
name = "downcast"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
[[package]] [[package]]
name = "dptree" name = "dptree"
version = "0.3.0" version = "0.3.0"
@ -555,6 +567,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fragile"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
[[package]] [[package]]
name = "frunk" name = "frunk"
version = "0.4.3" version = "0.4.3"
@ -1125,6 +1143,31 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "mini_admin_bot"
version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"curl",
"derive_more",
"frunk",
"frunk_core",
"futures",
"image",
"lazy_static",
"log",
"mockall",
"once_cell",
"phf",
"pretty_env_logger",
"sqlite",
"teloxide",
"tokio",
"tokio-stream",
"turbojpeg",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@ -1162,6 +1205,32 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "mockall"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"
dependencies = [
"cfg-if",
"downcast",
"fragile",
"mockall_derive",
"predicates",
"predicates-tree",
]
[[package]]
name = "mockall_derive"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"
dependencies = [
"cfg-if",
"proc-macro2",
"quote",
"syn 2.0.77",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.12" version = "0.2.12"
@ -1430,6 +1499,32 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "predicates"
version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
dependencies = [
"anstyle",
"predicates-core",
]
[[package]]
name = "predicates-core"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
[[package]]
name = "predicates-tree"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
dependencies = [
"predicates-core",
"termtree",
]
[[package]] [[package]]
name = "pretty_env_logger" name = "pretty_env_logger"
version = "0.4.0" version = "0.4.0"
@ -2139,28 +2234,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "test_bot" name = "termtree"
version = "0.1.0" version = "0.5.1"
dependencies = [ source = "registry+https://github.com/rust-lang/crates.io-index"
"anyhow", checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
"chrono",
"curl",
"derive_more",
"frunk",
"frunk_core",
"futures",
"image",
"lazy_static",
"log",
"once_cell",
"phf",
"pretty_env_logger",
"sqlite",
"teloxide",
"tokio",
"tokio-stream",
"turbojpeg",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"

View File

@ -1,5 +1,5 @@
[package] [package]
name = "test_bot" name = "mini_admin_bot"
version = "0.1.0" version = "0.1.0"
edition = "2018" edition = "2018"
@ -24,6 +24,9 @@ turbojpeg = "*"
phf = { version = "0.11", features = ["macros"] } phf = { version = "0.11", features = ["macros"] }
curl = "*" curl = "*"
[dev-dependencies]
mockall = "0.13.1"
[profile.release] [profile.release]
lto = true lto = true
codegen-units = 1 codegen-units = 1

View File

@ -1,5 +1,5 @@
use sqlite::{State, Error};
use crate::database; use crate::database;
use sqlite::{Error, State};
pub struct Database { pub struct Database {
ins_connection: &'static database::DB_CONNECTION, //Mutex<Box<sqlite::Connection>>, ins_connection: &'static database::DB_CONNECTION, //Mutex<Box<sqlite::Connection>>,

View File

@ -1,8 +1,10 @@
use std::fs; #[cfg(test)]
use mockall::{automock, mock, predicate::*};
use once_cell::sync::Lazy;
use std::collections::LinkedList; use std::collections::LinkedList;
use std::fs;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::RwLock; use std::sync::RwLock;
use once_cell::sync::Lazy;
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
const ALLOW_PATH: &str = "/opt/mini_admin_bot/allow_users"; const ALLOW_PATH: &str = "/opt/mini_admin_bot/allow_users";
@ -14,21 +16,28 @@ const ALLOW_PATH : &str ="allow_users";
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
const POLE_PATH: &str = "allow_pole"; const POLE_PATH: &str = "allow_pole";
static mut LIST_IDS: Lazy<Mutex<LinkedList<String>>> = Lazy::new(|| Mutex::new(read_ids(ALLOW_PATH))); static mut LIST_IDS: Lazy<Mutex<LinkedList<String>>> =
Lazy::new(|| Mutex::new(read_ids(ALLOW_PATH)));
static mut LIST_POLE_IDS: Lazy<Mutex<LinkedList<String>>> = Lazy::new(|| Mutex::new(read_ids(POLE_PATH))); static mut LIST_POLE_IDS: Lazy<Mutex<LinkedList<String>>> =
Lazy::new(|| Mutex::new(read_ids(POLE_PATH)));
fn read_ids<'a>(path: &str) -> LinkedList<String> { fn read_ids<'a>(path: &str) -> LinkedList<String> {
let content = fs::read_to_string(path).expect("Something went wrong reading the file"); let content = fs::read_to_string(path).expect("Something went wrong reading the file");
content.split('\n').into_iter().map(|item| format!("{}", item)).collect::<LinkedList<String>>() content
.split('\n')
.into_iter()
.map(|item| format!("{}", item))
.collect::<LinkedList<String>>()
} }
pub struct group_permissions { pub struct GroupPermissions {
aproved_groups: RwLock<LinkedList<String>>, aproved_groups: RwLock<LinkedList<String>>,
party_groups: RwLock<LinkedList<String>>, party_groups: RwLock<LinkedList<String>>,
} }
impl group_permissions { #[cfg_attr(test, automock)]
impl GroupPermissions {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
aproved_groups: RwLock::new(read_ids(ALLOW_PATH)), aproved_groups: RwLock::new(read_ids(ALLOW_PATH)),
@ -50,7 +59,6 @@ pub fn compare(id: &String) -> bool{
unsafe { unsafe {
ret = LIST_IDS.lock().unwrap().contains(id); ret = LIST_IDS.lock().unwrap().contains(id);
log::info!("{}", id); log::info!("{}", id);
} }
ret ret
} }
@ -60,7 +68,6 @@ pub fn compare_pole(id: &String) -> bool{
unsafe { unsafe {
ret = LIST_POLE_IDS.lock().unwrap().contains(id); ret = LIST_POLE_IDS.lock().unwrap().contains(id);
log::info!("{}", id); log::info!("{}", id);
} }
ret ret
} }

158
src/lib.rs Normal file
View File

@ -0,0 +1,158 @@
use chrono::Local;
use std::sync::Arc;
use teloxide::{prelude::*, utils::command::BotCommands};
pub mod ban_stiker;
pub mod check_permissions;
mod database;
mod filter_files;
mod pole_dialogue;
mod rewrite_links;
mod spoiler_mangas;
mod telegram_utils;
#[derive(BotCommands, Clone)]
#[command(
rename_rule = "lowercase",
description = "These commands are supported:"
)]
enum Command {
#[command(description = "ban a stiker")]
Torquemada,
#[command(description = "display this text.")]
Help,
#[command(description = "list pole points")]
Top,
#[command(description = "get the server time")]
Time,
}
/*#[tokio::main]
async fn main() {
run().await;
}*/
pub async fn run() {
//teloxide::enable_logging!();
pretty_env_logger::init();
log::info!("Starting bot");
let bot = Bot::from_env();
let permissions = Arc::new(check_permissions::GroupPermissions::new());
let p1 = Arc::clone(&permissions);
let p2 = Arc::clone(&permissions);
//Command::repl(bot.clone(), answer).await;
let handler = Update::filter_message()
.branch(
dptree::filter(move |msg: Message| !p1.compare(&msg.chat.id.to_string())).endpoint(
|msg: Message, bot: Bot| async move {
if !msg.chat.is_private() {
println!("{}", msg.chat.id.0);
bot.leave_chat(msg.chat.id).await?;
}
Ok(())
},
),
)
.branch(
dptree::filter(|msg: Message| is_channel_user(msg)).endpoint(
|msg: Message, bot: Bot| async move {
bot.delete_message(msg.chat.id, msg.id).await?;
Ok(())
},
),
)
.branch(
Update::filter_message()
.filter_command::<Command>()
.endpoint(|msg: Message, bot: Bot, command: Command| answer(bot, msg, command)),
)
.branch(
dptree::filter(|msg: Message| is_media(msg.clone()) && ban_stiker::check_media(msg))
.endpoint(|msg: Message, bot: Bot| async move {
bot.delete_message(msg.chat.id, msg.id).await?;
Ok(())
}),
)
/*
Now is useless because the group doesn't make any spoiler
.branch(
dptree::filter(move |msg: Message| {
(is_photo(msg.clone()) && p2.compar_party(&msg.chat.id.to_string()))
})
.endpoint(|msg: Message, bot: Bot| spoiler_mangas::check_image(msg, bot)),
)*/
.branch(
dptree::filter(move |msg: Message| filter_files::analyce_name::check_file(msg.clone()))
.endpoint(|msg: Message, bot: Bot| filter_files::action::take_actions(msg, bot)),
)
.branch(
dptree::filter(move |msg: Message| {
rewrite_links::check_contain_links::contain_links(msg.clone())
})
.endpoint(|msg: Message, bot: Bot| {
rewrite_links::check_contain_links::fix_links(msg, bot)
}),
)
.branch(
dptree::filter(move |msg: Message| permissions.compar_party(&msg.chat.id.to_string()))
.endpoint(|msg: Message, bot: Bot| pole_dialogue::exe_pole(msg, bot)),
);
Dispatcher::builder(bot, handler).build().dispatch().await;
}
async fn answer(bot: Bot, msg: Message, command: Command) -> anyhow::Result<()> {
match command {
Command::Torquemada => match ban_stiker::ban_media(msg.clone(), bot.clone()).await {
Ok(_o) => {
bot.send_message(msg.chat.id, "Otro fichero que se va a la hoguera")
.await?
}
Err(e) => bot.send_message(msg.chat.id, e.to_string()).await?,
},
Command::Help => {
bot.send_message(msg.chat.id, Command::descriptions().to_string())
.await?
}
Command::Top => pole_dialogue::get_top(msg, bot).await?,
Command::Time => {
bot.send_message(
msg.chat.id,
Local::now().format("%Y-%m-%d:%H:%M:%S").to_string(),
)
.await?
}
};
Ok(())
}
fn is_media(msg: Message) -> bool {
is_stiker(msg.clone()) || is_gif(msg.clone()) || is_photo(msg.clone())
}
fn is_stiker(msg: Message) -> bool {
match msg.sticker() {
Some(s) => true,
None => false,
}
}
fn is_gif(msg: Message) -> bool {
match msg.animation() {
Some(s) => true,
None => false,
}
}
fn is_photo(msg: Message) -> bool {
match msg.photo() {
Some(s) => true,
None => false,
}
}
fn is_channel_user(msg: Message) -> bool {
match msg.from() {
Some(u) => u.is_channel(),
None => false,
}
}

View File

@ -1,158 +1,4 @@
use chrono::Local;
use std::sync::Arc;
use teloxide::{prelude::*, utils::command::BotCommands};
mod ban_stiker;
mod check_permissions;
mod database;
mod filter_files;
mod pole_dialogue;
mod rewrite_links;
mod spoiler_mangas;
mod telegram_utils;
#[derive(BotCommands, Clone)]
#[command(
rename_rule = "lowercase",
description = "These commands are supported:"
)]
enum Command {
#[command(description = "ban a stiker")]
Torquemada,
#[command(description = "display this text.")]
Help,
#[command(description = "list pole points")]
Top,
#[command(description = "get the server time")]
Time,
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
run().await; mini_admin_bot::run().await;
}
async fn run() {
//teloxide::enable_logging!();
pretty_env_logger::init();
log::info!("Starting bot");
let bot = Bot::from_env();
let permissions = Arc::new(check_permissions::group_permissions::new());
let p1 = Arc::clone(&permissions);
let p2 = Arc::clone(&permissions);
//Command::repl(bot.clone(), answer).await;
let handler = Update::filter_message()
.branch(
dptree::filter(move |msg: Message| !p1.compare(&msg.chat.id.to_string())).endpoint(
|msg: Message, bot: Bot| async move {
if !msg.chat.is_private() {
println!("{}", msg.chat.id.0);
bot.leave_chat(msg.chat.id).await?;
}
Ok(())
},
),
)
.branch(
dptree::filter(|msg: Message| is_channel_user(msg)).endpoint(
|msg: Message, bot: Bot| async move {
bot.delete_message(msg.chat.id, msg.id).await?;
Ok(())
},
),
)
.branch(
Update::filter_message()
.filter_command::<Command>()
.endpoint(|msg: Message, bot: Bot, command: Command| answer(bot, msg, command)),
)
.branch(
dptree::filter(|msg: Message| is_media(msg.clone()) && ban_stiker::check_media(msg))
.endpoint(|msg: Message, bot: Bot| async move {
bot.delete_message(msg.chat.id, msg.id).await?;
Ok(())
}),
)
/*
Now is useless because the group doesn't make any spoiler
.branch(
dptree::filter(move |msg: Message| {
(is_photo(msg.clone()) && p2.compar_party(&msg.chat.id.to_string()))
})
.endpoint(|msg: Message, bot: Bot| spoiler_mangas::check_image(msg, bot)),
)*/
.branch(
dptree::filter(move |msg: Message| filter_files::analyce_name::check_file(msg.clone()))
.endpoint(|msg: Message, bot: Bot| filter_files::action::take_actions(msg, bot)),
)
.branch(
dptree::filter(move |msg: Message| {
rewrite_links::check_contain_links::contain_links(msg.clone())
})
.endpoint(|msg: Message, bot: Bot| {
rewrite_links::check_contain_links::fix_links(msg, bot)
}),
)
.branch(
dptree::filter(move |msg: Message| permissions.compar_party(&msg.chat.id.to_string()))
.endpoint(|msg: Message, bot: Bot| pole_dialogue::exe_pole(msg, bot)),
);
Dispatcher::builder(bot, handler).build().dispatch().await;
}
async fn answer(bot: Bot, msg: Message, command: Command) -> anyhow::Result<()> {
match command {
Command::Torquemada => match ban_stiker::ban_media(msg.clone(), bot.clone()).await {
Ok(_o) => {
bot.send_message(msg.chat.id, "Otro fichero que se va a la hoguera")
.await?
}
Err(e) => bot.send_message(msg.chat.id, e.to_string()).await?,
},
Command::Help => {
bot.send_message(msg.chat.id, Command::descriptions().to_string())
.await?
}
Command::Top => pole_dialogue::get_top(msg, bot).await?,
Command::Time => {
bot.send_message(
msg.chat.id,
Local::now().format("%Y-%m-%d:%H:%M:%S").to_string(),
)
.await?
}
};
Ok(())
}
fn is_media(msg: Message) -> bool {
is_stiker(msg.clone()) || is_gif(msg.clone()) || is_photo(msg.clone())
}
fn is_stiker(msg: Message) -> bool {
match msg.sticker() {
Some(s) => true,
None => false,
}
}
fn is_gif(msg: Message) -> bool {
match msg.animation() {
Some(s) => true,
None => false,
}
}
fn is_photo(msg: Message) -> bool {
match msg.photo() {
Some(s) => true,
None => false,
}
}
fn is_channel_user(msg: Message) -> bool {
match msg.from() {
Some(u) => u.is_channel(),
None => false,
}
} }

View File

@ -1,34 +1,36 @@
use sqlite::{State, Error};
use crate::database; use crate::database;
use sqlite::{Error, State};
#[cfg(test)] #[cfg(test)]
fn drop_all(con: &sqlite::Connection) -> bool { fn drop_all(con: &sqlite::Connection) -> bool {
let mut result: bool; let mut result: bool;
match con match con.execute(
.execute(
" "
DROP TABLE IF EXISTS poles; DROP TABLE IF EXISTS poles;
", ",
) ) {
{
Ok(_a) => result = true, Ok(_a) => result = true,
Err(e) => {log::error!("error drop pole {}",e);result = false}, Err(e) => {
log::error!("error drop pole {}", e);
result = false
}
}; };
match con match con.execute(
.execute(
" "
DROP TABLE IF EXISTS last; DROP TABLE IF EXISTS last;
", ",
) ) {
{
Ok(_a) => result && true, Ok(_a) => result && true,
Err(e) => {log::error!("error drop last {}",e);result && false}, Err(e) => {
log::error!("error drop last {}", e);
result && false
}
} }
} }
fn create_databases(con: &sqlite::Connection) -> bool { fn create_databases(con: &sqlite::Connection) -> bool {
return create_poles_database(con) && create_last_database(con) return create_poles_database(con) && create_last_database(con);
} }
fn create_poles_database(con: &sqlite::Connection) -> bool { fn create_poles_database(con: &sqlite::Connection) -> bool {
@ -57,8 +59,6 @@ fn create_last_database(con: &sqlite::Connection) -> bool {
} }
} }
pub struct DatabasePole { pub struct DatabasePole {
ins_connection: &'static database::DB_CONNECTION, //Mutex<Box<sqlite::Connection>>, ins_connection: &'static database::DB_CONNECTION, //Mutex<Box<sqlite::Connection>>,
} }
@ -78,7 +78,7 @@ impl<'a> DatabasePole{
#[cfg(test)] #[cfg(test)]
pub fn get_database() -> Self { pub fn get_database() -> Self {
let ret = Self { let ret = Self {
ins_connection: &DB_CONNECTION, ins_connection: &database::DB_CONNECTION,
}; };
let raw = &**ret.ins_connection.lock().unwrap(); let raw = &**ret.ins_connection.lock().unwrap();
drop_all(raw); drop_all(raw);
@ -97,7 +97,14 @@ impl<'a> DatabasePole{
statement.read::<String, _>(0) statement.read::<String, _>(0)
} }
pub fn write_points(&self, group_id : &str, user_id: &str, user_name: &str, date: &str, points: i64){ pub fn write_points(
&self,
group_id: &str,
user_id: &str,
user_name: &str,
date: &str,
points: i64,
) {
let builder = self.ins_connection.lock().unwrap(); let builder = self.ins_connection.lock().unwrap();
let mut statement = builder let mut statement = builder
.prepare("SELECT npole FROM poles WHERE user = ? AND id_group = ?") .prepare("SELECT npole FROM poles WHERE user = ? AND id_group = ?")
@ -110,14 +117,18 @@ impl<'a> DatabasePole{
let mut statement2 = builder let mut statement2 = builder
.prepare("UPDATE poles SET npole=? WHERE user=? AND id_group=?") .prepare("UPDATE poles SET npole=? WHERE user=? AND id_group=?")
.unwrap(); .unwrap();
statement2.bind((1, statement.read::<i64, _>(0).unwrap()+points)).unwrap(); statement2
.bind((1, statement.read::<i64, _>(0).unwrap() + points))
.unwrap();
statement2.bind((2, user_id)).unwrap(); statement2.bind((2, user_id)).unwrap();
statement2.bind((3, group_id)).unwrap(); statement2.bind((3, group_id)).unwrap();
statement2.next().unwrap(); statement2.next().unwrap();
} }
State::Done => { State::Done => {
let mut statement2 = builder let mut statement2 = builder
.prepare("INSERT INTO poles (npole, user, user_name, id_group) VALUES (?,?,?,?)") .prepare(
"INSERT INTO poles (npole, user, user_name, id_group) VALUES (?,?,?,?)",
)
.unwrap(); .unwrap();
statement2.bind((1, points)).unwrap(); statement2.bind((1, points)).unwrap();
statement2.bind((2, user_id)).unwrap(); statement2.bind((2, user_id)).unwrap();
@ -125,7 +136,6 @@ impl<'a> DatabasePole{
statement2.bind((4, group_id)).unwrap(); statement2.bind((4, group_id)).unwrap();
statement2.next().unwrap(); statement2.next().unwrap();
} }
}; };
let mut statement3 = builder let mut statement3 = builder
@ -172,7 +182,9 @@ impl<'a> DatabasePole{
pub fn get_top_users(&self, group_id: &str) -> Vec<(i64, String)> { pub fn get_top_users(&self, group_id: &str) -> Vec<(i64, String)> {
let builder = self.ins_connection.lock().unwrap(); let builder = self.ins_connection.lock().unwrap();
let mut statement = builder let mut statement = builder
.prepare("SELECT npole, user_name FROM poles where id_group=? order by npole desc limit 10") .prepare(
"SELECT npole, user_name FROM poles where id_group=? order by npole desc limit 10",
)
.unwrap(); .unwrap();
statement.bind((1, group_id)).unwrap(); statement.bind((1, group_id)).unwrap();
let mut ret = Vec::new(); let mut ret = Vec::new();
@ -180,16 +192,16 @@ impl<'a> DatabasePole{
match statement.next().unwrap() { match statement.next().unwrap() {
State::Row => ret.push(( State::Row => ret.push((
statement.read::<i64, _>(0).unwrap(), statement.read::<i64, _>(0).unwrap(),
statement.read::<String, _>(1).unwrap() statement.read::<String, _>(1).unwrap(),
)), )),
State::Done => return ret, State::Done => return ret,
} }
} }
ret ret
} }
} }
/*
#[cfg(test)] #[cfg(test)]
#[test] #[test]
fn write_points(){ fn write_points(){
@ -207,3 +219,4 @@ fn last_pole(){
data.write_points(group_id, "000", "2020-01-02", 3); data.write_points(group_id, "000", "2020-01-02", 3);
assert_eq!("2020-01-02", data.last_pole(group_id).unwrap()); assert_eq!("2020-01-02", data.last_pole(group_id).unwrap());
} }
*/

View File

@ -1,9 +1,9 @@
use teloxide::prelude::*;
use chrono::Local;
use std::ops::Add;
use std::cmp::Ordering::Equal;
use std::str;
use crate::telegram_utils::*; use crate::telegram_utils::*;
use chrono::Local;
use std::cmp::Ordering::Equal;
use std::ops::Add;
use std::str;
use teloxide::prelude::*;
mod database; mod database;
fn change_day(last_day: &str) -> bool { fn change_day(last_day: &str) -> bool {
@ -11,7 +11,10 @@ fn change_day(last_day: &str) -> bool{
} }
fn get_actual_day() -> String { fn get_actual_day() -> String {
Local::now().add(chrono::TimeDelta::hours(2)).format("%Y-%m-%d").to_string() Local::now()
.add(chrono::TimeDelta::hours(2))
.format("%Y-%m-%d")
.to_string()
} }
fn check_pole(group_id: &str) -> bool { fn check_pole(group_id: &str) -> bool {
@ -25,24 +28,44 @@ fn check_pole(group_id: &str) -> bool {
fn do_pole(group_id: &str, user_id: &str, user_name: &str) { fn do_pole(group_id: &str, user_id: &str, user_name: &str) {
let data: database::DatabasePole = database::DatabasePole::get_database(); let data: database::DatabasePole = database::DatabasePole::get_database();
data.write_points(group_id, user_id, user_name, &get_actual_day(),Rewards::POLE as i64); data.write_points(
group_id,
user_id,
user_name,
&get_actual_day(),
Rewards::POLE as i64,
);
} }
fn do_plata(group_id: &str, user_id: &str, user_name: &str) { fn do_plata(group_id: &str, user_id: &str, user_name: &str) {
let data: database::DatabasePole = database::DatabasePole::get_database(); let data: database::DatabasePole = database::DatabasePole::get_database();
data.write_points(group_id, user_id, user_name, &get_actual_day(),Rewards::PLATA as i64); data.write_points(
group_id,
user_id,
user_name,
&get_actual_day(),
Rewards::PLATA as i64,
);
} }
fn do_fail(group_id: &str, user_id: &str, user_name: &str) { fn do_fail(group_id: &str, user_id: &str, user_name: &str) {
let data: database::DatabasePole = database::DatabasePole::get_database(); let data: database::DatabasePole = database::DatabasePole::get_database();
data.write_points(group_id, user_id, user_name, &get_actual_day(),Rewards::FAIL as i64); data.write_points(
group_id,
user_id,
user_name,
&get_actual_day(),
Rewards::FAIL as i64,
);
} }
fn check_user_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool { fn check_user_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
let data: database::DatabasePole = database::DatabasePole::get_database(); let data: database::DatabasePole = database::DatabasePole::get_database();
let ret = data.check_user_pole(&msg.chat.id.to_string(), let ret = data.check_user_pole(
&msg.chat.id.to_string(),
&msg.from().unwrap().id.to_string(), &msg.from().unwrap().id.to_string(),
&get_actual_day()); &get_actual_day(),
);
check_group_points(msg, rw) && (ret == 0) check_group_points(msg, rw) && (ret == 0)
} }
@ -54,8 +77,7 @@ enum Rewards {
fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool { fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
let data: database::DatabasePole = database::DatabasePole::get_database(); let data: database::DatabasePole = database::DatabasePole::get_database();
let ret = data.check_group_points(&msg.chat.id.to_string(), let ret = data.check_group_points(&msg.chat.id.to_string(), &get_actual_day());
&get_actual_day());
match rw { match rw {
Rewards::PLATA => ret == (Rewards::POLE as i64), Rewards::PLATA => ret == (Rewards::POLE as i64),
Rewards::FAIL => ret == (Rewards::PLATA as i64 + Rewards::POLE as i64), Rewards::FAIL => ret == (Rewards::PLATA as i64 + Rewards::POLE as i64),
@ -63,29 +85,38 @@ fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
} }
} }
pub async fn exe_pole( pub async fn exe_pole(msg: Message, bot: Bot) -> anyhow::Result<()> {
msg: Message,
bot: Bot,
) -> anyhow::Result<()>{
let text_lower = match msg.text() { let text_lower = match msg.text() {
Some(t) => t.to_lowercase(), Some(t) => t.to_lowercase(),
None => return Ok(()), None => return Ok(()),
}; };
if pole_conditions(msg.clone()) { if pole_conditions(msg.clone()) {
do_pole(&msg.chat.id.to_string(), do_pole(
&msg.chat.id.to_string(),
&*msg.from().unwrap().id.to_string(), &*msg.from().unwrap().id.to_string(),
&get_alias(&msg)); &get_alias(&msg),
bot.send_message(msg.chat.id, format!("{} ha hecho la pole",get_alias(&msg))).await?; );
bot.send_message(msg.chat.id, format!("{} ha hecho la pole", get_alias(&msg)))
.await?;
} else if plata_conditions(msg.clone()) { } else if plata_conditions(msg.clone()) {
do_plata(&msg.chat.id.to_string(), do_plata(
&msg.chat.id.to_string(),
&*msg.from().unwrap().id.to_string(), &*msg.from().unwrap().id.to_string(),
&get_alias(&msg)); &get_alias(&msg),
bot.send_message(msg.chat.id, format!("{} ha hecho la plata", get_alias(&msg))).await?; );
bot.send_message(
msg.chat.id,
format!("{} ha hecho la plata", get_alias(&msg)),
)
.await?;
} else if bronce_conditions(msg.clone()) { } else if bronce_conditions(msg.clone()) {
do_fail(&msg.chat.id.to_string(), do_fail(
&msg.chat.id.to_string(),
&*msg.from().unwrap().id.to_string(), &*msg.from().unwrap().id.to_string(),
&get_alias(&msg)); &get_alias(&msg),
bot.send_message(msg.chat.id, format!("{} buen fail", get_alias(&msg))).await?; );
bot.send_message(msg.chat.id, format!("{} buen fail", get_alias(&msg)))
.await?;
} }
return Ok(()); return Ok(());
} }
@ -139,11 +170,10 @@ pub fn get_top(msg: Message, bot: Bot) -> <Bot as Requester>::SendMessage{
bot.send_message(msg.chat.id, format!("{}", repl)) bot.send_message(msg.chat.id, format!("{}", repl))
} }
#[cfg(test)] /*#[cfg(test)]
#[test] #[test]
fn compare_dates(){ fn compare_dates(){
assert_eq!(false, change_day("2020-01-01")); assert_eq!(false, change_day("2020-01-01"));
assert_eq!(true, change_day("3025-01-01")); assert_eq!(true, change_day("3025-01-01"));
} }
*/

6
tests/ban_stiker.rs Normal file
View File

@ -0,0 +1,6 @@
use mini_admin_bot::ban_stiker;
#[test]
pub fn db_media_is_banned() {
assert_eq!(0, 0);
}

12
tests/permissions.rs Normal file
View File

@ -0,0 +1,12 @@
use mini_admin_bot::check_permissions;
use mockall::{automock, mock, predicate::*};
#[test]
fn test_permissions() {
let mut mock = check_permissions::MockGroupPermissions::new();
mock.expect_compare()
.with("user_id")
.times(1)
.returning(true);
assert_eq!(true, mock.compare("user_id"));
}