diff --git a/Cargo.lock b/Cargo.lock index f158643..a41f9a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -53,6 +53,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "anyhow" version = "1.0.89" @@ -412,6 +418,12 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "dptree" version = "0.3.0" @@ -555,6 +567,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + [[package]] name = "frunk" version = "0.4.3" @@ -1125,6 +1143,31 @@ dependencies = [ "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]] name = "minimal-lexical" version = "0.2.1" @@ -1162,6 +1205,32 @@ dependencies = [ "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]] name = "native-tls" version = "0.2.12" @@ -1430,6 +1499,32 @@ dependencies = [ "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]] name = "pretty_env_logger" version = "0.4.0" @@ -2139,28 +2234,10 @@ dependencies = [ ] [[package]] -name = "test_bot" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "curl", - "derive_more", - "frunk", - "frunk_core", - "futures", - "image", - "lazy_static", - "log", - "once_cell", - "phf", - "pretty_env_logger", - "sqlite", - "teloxide", - "tokio", - "tokio-stream", - "turbojpeg", -] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "thiserror" diff --git a/Cargo.toml b/Cargo.toml index 80f0341..ddf942d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "test_bot" +name = "mini_admin_bot" version = "0.1.0" edition = "2018" @@ -9,7 +9,7 @@ teloxide = { version = "0.12", features = ["macros", "auto-send"] } futures = "0.3.5" log = "0.4" pretty_env_logger = "0.4.0" -tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] } tokio-stream = "0.1.8" derive_more = "0.99.9" frunk = "0.4" @@ -24,6 +24,9 @@ turbojpeg = "*" phf = { version = "0.11", features = ["macros"] } curl = "*" +[dev-dependencies] +mockall = "0.13.1" + [profile.release] lto = true codegen-units = 1 diff --git a/src/ban_stiker/database.rs b/src/ban_stiker/database.rs index 9b93f70..a043edb 100644 --- a/src/ban_stiker/database.rs +++ b/src/ban_stiker/database.rs @@ -1,8 +1,8 @@ -use sqlite::{State, Error}; use crate::database; +use sqlite::{Error, State}; pub struct Database { - ins_connection: &'static database::DB_CONNECTION,//Mutex>, + ins_connection: &'static database::DB_CONNECTION, //Mutex>, } pub const T_STIKER: i64 = 1; @@ -10,8 +10,8 @@ pub const T_GIF: i64 = 2; pub const T_PHOTO: i64 = 3; impl<'a> Database { - pub fn get_database()->Self{ - let ret = Self{ + pub fn get_database() -> Self { + let ret = Self { ins_connection: &database::DB_CONNECTION, }; ret.create_table(); @@ -34,8 +34,8 @@ impl<'a> Database { pub fn media_is_banned(&self, stiker_id: &str, media_type: i64) -> bool { let builder = self.ins_connection.lock().unwrap(); let mut statement = builder - .prepare("SELECT id_stiker FROM bmedia WHERE id_stiker = ? and media_type=?") - .unwrap(); + .prepare("SELECT id_stiker FROM bmedia WHERE id_stiker = ? and media_type=?") + .unwrap(); statement.bind((1, stiker_id)).unwrap(); statement.bind((2, media_type)).unwrap(); statement.next().unwrap(); @@ -45,17 +45,17 @@ impl<'a> Database { } } - pub fn add_media(&self, stiker_id: &str, group_id: &str, media_type: i64)->bool{ + pub fn add_media(&self, stiker_id: &str, group_id: &str, media_type: i64) -> bool { let builder = self.ins_connection.lock().unwrap(); let mut statement = builder - .prepare("INSERT INTO bmedia (id_stiker, id_group, media_type) VALUES (?,?,?)") - .unwrap(); + .prepare("INSERT INTO bmedia (id_stiker, id_group, media_type) VALUES (?,?,?)") + .unwrap(); statement.bind((1, stiker_id)).unwrap(); statement.bind((2, group_id)).unwrap(); statement.bind((3, media_type)).unwrap(); - match statement.next(){ - Ok(_s)=>true, - Err(_e)=>false, + match statement.next() { + Ok(_s) => true, + Err(_e) => false, } } } diff --git a/src/check_permissions/mod.rs b/src/check_permissions/mod.rs index a19d1f5..79c7d2e 100644 --- a/src/check_permissions/mod.rs +++ b/src/check_permissions/mod.rs @@ -1,36 +1,45 @@ -use std::fs; +#[cfg(test)] +use mockall::{automock, mock, predicate::*}; +use once_cell::sync::Lazy; use std::collections::LinkedList; +use std::fs; use std::sync::Mutex; use std::sync::RwLock; -use once_cell::sync::Lazy; #[cfg(not(debug_assertions))] -const ALLOW_PATH : &str ="/opt/mini_admin_bot/allow_users"; +const ALLOW_PATH: &str = "/opt/mini_admin_bot/allow_users"; #[cfg(not(debug_assertions))] -const POLE_PATH : &str ="/opt/mini_admin_bot/allow_pole"; +const POLE_PATH: &str = "/opt/mini_admin_bot/allow_pole"; #[cfg(debug_assertions)] -const ALLOW_PATH : &str ="allow_users"; +const ALLOW_PATH: &str = "allow_users"; #[cfg(debug_assertions)] -const POLE_PATH : &str ="allow_pole"; +const POLE_PATH: &str = "allow_pole"; -static mut LIST_IDS: Lazy>> = Lazy::new(|| Mutex::new(read_ids(ALLOW_PATH))); +static mut LIST_IDS: Lazy>> = + Lazy::new(|| Mutex::new(read_ids(ALLOW_PATH))); -static mut LIST_POLE_IDS: Lazy>> = Lazy::new(|| Mutex::new(read_ids(POLE_PATH))); +static mut LIST_POLE_IDS: Lazy>> = + Lazy::new(|| Mutex::new(read_ids(POLE_PATH))); -fn read_ids<'a>(path: &str)-> LinkedList { +fn read_ids<'a>(path: &str) -> LinkedList { let content = fs::read_to_string(path).expect("Something went wrong reading the file"); - content.split('\n').into_iter().map(|item| format!("{}", item)).collect::>() + content + .split('\n') + .into_iter() + .map(|item| format!("{}", item)) + .collect::>() } -pub struct group_permissions { +pub struct GroupPermissions { aproved_groups: RwLock>, party_groups: RwLock>, } -impl group_permissions { +#[cfg_attr(test, automock)] +impl GroupPermissions { pub fn new() -> Self { - Self{ + Self { aproved_groups: RwLock::new(read_ids(ALLOW_PATH)), party_groups: RwLock::new(read_ids(POLE_PATH)), } @@ -45,22 +54,20 @@ impl group_permissions { } } -pub fn compare(id: &String) -> bool{ +pub fn compare(id: &String) -> bool { let ret: bool; unsafe { - ret=LIST_IDS.lock().unwrap().contains(id); - log::info!("{}",id); - + ret = LIST_IDS.lock().unwrap().contains(id); + log::info!("{}", id); } ret } -pub fn compare_pole(id: &String) -> bool{ +pub fn compare_pole(id: &String) -> bool { let ret: bool; unsafe { - ret=LIST_POLE_IDS.lock().unwrap().contains(id); - log::info!("{}",id); - + ret = LIST_POLE_IDS.lock().unwrap().contains(id); + log::info!("{}", id); } ret } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ccd8e40 --- /dev/null +++ b/src/lib.rs @@ -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::() + .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, + } +} diff --git a/src/main.rs b/src/main.rs index 511724f..e562621 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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] async fn main() { - 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::() - .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, - } + mini_admin_bot::run().await; } diff --git a/src/pole_dialogue/database.rs b/src/pole_dialogue/database.rs index 3d24558..95c439b 100644 --- a/src/pole_dialogue/database.rs +++ b/src/pole_dialogue/database.rs @@ -1,38 +1,40 @@ -use sqlite::{State, Error}; use crate::database; +use sqlite::{Error, State}; #[cfg(test)] fn drop_all(con: &sqlite::Connection) -> bool { let mut result: bool; - match con - .execute( - " + match con.execute( + " DROP TABLE IF EXISTS poles; ", - ) - { - Ok(_a) => result = true, - Err(e) => {log::error!("error drop pole {}",e);result = false}, - }; + ) { + Ok(_a) => result = true, + Err(e) => { + log::error!("error drop pole {}", e); + result = false + } + }; - match con - .execute( - " + match con.execute( + " DROP TABLE IF EXISTS last; ", - ) - { - Ok(_a) => result && true, - Err(e) => {log::error!("error drop last {}",e);result && false}, + ) { + Ok(_a) => result && true, + Err(e) => { + log::error!("error drop last {}", e); + result && false } + } } 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 { - match con + match con .execute( " CREATE TABLE IF NOT EXISTS poles (npole INTEGER, user TEXT, user_name TEXT, id_group TEXT, id INTEGER PRIMARY KEY AUTOINCREMENT); @@ -42,10 +44,10 @@ fn create_poles_database(con: &sqlite::Connection) -> bool { Ok(_a) => return true, Err(e) => {log::error!("error pole {}",e);return false}, } - } +} fn create_last_database(con: &sqlite::Connection) -> bool { - match con + match con .execute( " CREATE TABLE IF NOT EXISTS last (date TEXT, id_group TEXT, user TEXT, points INTEGER, id INTEGER PRIMARY KEY AUTOINCREMENT); @@ -55,18 +57,16 @@ fn create_last_database(con: &sqlite::Connection) -> bool { Ok(_a) => return true, Err(e) => {log::error!("error last {}",e);return false}, } - } - - - -pub struct DatabasePole { - ins_connection: &'static database::DB_CONNECTION,//Mutex>, } -impl<'a> DatabasePole{ +pub struct DatabasePole { + ins_connection: &'static database::DB_CONNECTION, //Mutex>, +} + +impl<'a> DatabasePole { #[cfg(not(test))] - pub fn get_database()->Self{ - let ret = Self{ + pub fn get_database() -> Self { + let ret = Self { ins_connection: &database::DB_CONNECTION, }; let raw = &**ret.ins_connection.lock().unwrap(); @@ -76,9 +76,9 @@ impl<'a> DatabasePole{ } #[cfg(test)] - pub fn get_database()->Self{ - let ret = Self{ - ins_connection: &DB_CONNECTION, + pub fn get_database() -> Self { + let ret = Self { + ins_connection: &database::DB_CONNECTION, }; let raw = &**ret.ins_connection.lock().unwrap(); drop_all(raw); @@ -87,50 +87,60 @@ impl<'a> DatabasePole{ ret } - pub fn last_pole(&self, group_id : &str) -> Result{ + pub fn last_pole(&self, group_id: &str) -> Result { let builder = self.ins_connection.lock().unwrap(); let mut statement = builder - .prepare("SELECT date FROM last WHERE id_group = ? order by date desc") - .unwrap(); + .prepare("SELECT date FROM last WHERE id_group = ? order by date desc") + .unwrap(); statement.bind((1, group_id)).unwrap(); statement.next().unwrap(); statement.read::(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 mut statement = builder - .prepare("SELECT npole FROM poles WHERE user = ? AND id_group = ?") - .unwrap(); + .prepare("SELECT npole FROM poles WHERE user = ? AND id_group = ?") + .unwrap(); statement.bind((1, user_id)).unwrap(); statement.bind((2, group_id)).unwrap(); match statement.next().unwrap() { State::Row => { let mut statement2 = builder - .prepare("UPDATE poles SET npole=? WHERE user=? AND id_group=?") - .unwrap(); - statement2.bind((1, statement.read::(0).unwrap()+points)).unwrap(); + .prepare("UPDATE poles SET npole=? WHERE user=? AND id_group=?") + .unwrap(); + statement2 + .bind((1, statement.read::(0).unwrap() + points)) + .unwrap(); statement2.bind((2, user_id)).unwrap(); statement2.bind((3, group_id)).unwrap(); statement2.next().unwrap(); } State::Done => { let mut statement2 = builder - .prepare("INSERT INTO poles (npole, user, user_name, id_group) VALUES (?,?,?,?)") - .unwrap(); + .prepare( + "INSERT INTO poles (npole, user, user_name, id_group) VALUES (?,?,?,?)", + ) + .unwrap(); statement2.bind((1, points)).unwrap(); statement2.bind((2, user_id)).unwrap(); statement2.bind((3, user_name)).unwrap(); statement2.bind((4, group_id)).unwrap(); statement2.next().unwrap(); } - }; let mut statement3 = builder - .prepare("INSERT INTO last (date, id_group, user, points) VALUES (?,?,?,?)") - .unwrap(); + .prepare("INSERT INTO last (date, id_group, user, points) VALUES (?,?,?,?)") + .unwrap(); statement3.bind((1, date)).unwrap(); statement3.bind((2, group_id)).unwrap(); statement3.bind((3, user_id)).unwrap(); @@ -141,11 +151,11 @@ impl<'a> DatabasePole{ //} } - pub fn check_user_pole(&self, group_id : &str, user_id: &str, date: &str) -> i64{ + pub fn check_user_pole(&self, group_id: &str, user_id: &str, date: &str) -> i64 { let builder = self.ins_connection.lock().unwrap(); let mut statement = builder - .prepare("SELECT points FROM last WHERE id_group = ? AND user = ? AND date = :date") - .unwrap(); + .prepare("SELECT points FROM last WHERE id_group = ? AND user = ? AND date = :date") + .unwrap(); statement.bind((1, group_id)).unwrap(); statement.bind((2, user_id)).unwrap(); statement.bind((3, date)).unwrap(); @@ -155,11 +165,11 @@ impl<'a> DatabasePole{ } } - pub fn check_group_points(&self, group_id : &str, date: &str) -> i64{ + pub fn check_group_points(&self, group_id: &str, date: &str) -> i64 { let builder = self.ins_connection.lock().unwrap(); let mut statement = builder - .prepare("SELECT points FROM last WHERE id_group = ? AND date = ?") - .unwrap(); + .prepare("SELECT points FROM last WHERE id_group = ? AND date = ?") + .unwrap(); statement.bind((1, group_id)).unwrap(); statement.bind((2, date)).unwrap(); let mut ret = 0; @@ -169,27 +179,29 @@ impl<'a> DatabasePole{ ret } - 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 mut statement = builder - .prepare("SELECT npole, user_name FROM poles where id_group=? order by npole desc limit 10") - .unwrap(); + .prepare( + "SELECT npole, user_name FROM poles where id_group=? order by npole desc limit 10", + ) + .unwrap(); statement.bind((1, group_id)).unwrap(); let mut ret = Vec::new(); - for i in 1 .. 10 { + for i in 1..10 { match statement.next().unwrap() { State::Row => ret.push(( - statement.read::(0).unwrap(), - statement.read::(1).unwrap() - )), + statement.read::(0).unwrap(), + statement.read::(1).unwrap(), + )), State::Done => return ret, } } ret } - } +/* #[cfg(test)] #[test] fn write_points(){ @@ -207,3 +219,4 @@ fn last_pole(){ data.write_points(group_id, "000", "2020-01-02", 3); assert_eq!("2020-01-02", data.last_pole(group_id).unwrap()); } +*/ diff --git a/src/pole_dialogue/mod.rs b/src/pole_dialogue/mod.rs index 5cf76d6..a836259 100644 --- a/src/pole_dialogue/mod.rs +++ b/src/pole_dialogue/mod.rs @@ -1,17 +1,20 @@ -use teloxide::prelude::*; -use chrono::Local; -use std::ops::Add; -use std::cmp::Ordering::Equal; -use std::str; use crate::telegram_utils::*; +use chrono::Local; +use std::cmp::Ordering::Equal; +use std::ops::Add; +use std::str; +use teloxide::prelude::*; mod database; -fn change_day(last_day: &str) -> bool{ +fn change_day(last_day: &str) -> bool { last_day.cmp(&get_actual_day()) != Equal } 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 { @@ -23,26 +26,46 @@ fn check_pole(group_id: &str) -> bool { change_day(&slast_pole) } -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(); - 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(); - 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(); - 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 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(), - &get_actual_day()); + &get_actual_day(), + ); check_group_points(msg, rw) && (ret == 0) } @@ -54,44 +77,52 @@ enum Rewards { fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool { let data: database::DatabasePole = database::DatabasePole::get_database(); - let ret = data.check_group_points(&msg.chat.id.to_string(), - &get_actual_day()); + let ret = data.check_group_points(&msg.chat.id.to_string(), &get_actual_day()); match rw { Rewards::PLATA => ret == (Rewards::POLE as i64), Rewards::FAIL => ret == (Rewards::PLATA as i64 + Rewards::POLE as i64), - _=> false, + _ => false, } } -pub async fn exe_pole( - msg: Message, - bot: Bot, -) -> anyhow::Result<()>{ - let text_lower = match msg.text(){ +pub async fn exe_pole(msg: Message, bot: Bot) -> anyhow::Result<()> { + let text_lower = match msg.text() { Some(t) => t.to_lowercase(), None => return Ok(()), }; - if pole_conditions(msg.clone()){ - do_pole(&msg.chat.id.to_string(), + if pole_conditions(msg.clone()) { + do_pole( + &msg.chat.id.to_string(), &*msg.from().unwrap().id.to_string(), - &get_alias(&msg)); - bot.send_message(msg.chat.id, format!("{} ha hecho la pole",get_alias(&msg))).await?; + &get_alias(&msg), + ); + bot.send_message(msg.chat.id, format!("{} ha hecho la pole", get_alias(&msg))) + .await?; } else if plata_conditions(msg.clone()) { - do_plata(&msg.chat.id.to_string(), - &*msg.from().unwrap().id.to_string(), - &get_alias(&msg)); - bot.send_message(msg.chat.id, format!("{} ha hecho la plata", get_alias(&msg))).await?; + do_plata( + &msg.chat.id.to_string(), + &*msg.from().unwrap().id.to_string(), + &get_alias(&msg), + ); + bot.send_message( + msg.chat.id, + format!("{} ha hecho la plata", get_alias(&msg)), + ) + .await?; } else if bronce_conditions(msg.clone()) { - do_fail(&msg.chat.id.to_string(), - &*msg.from().unwrap().id.to_string(), - &get_alias(&msg)); - bot.send_message(msg.chat.id, format!("{} buen fail", get_alias(&msg))).await?; + do_fail( + &msg.chat.id.to_string(), + &*msg.from().unwrap().id.to_string(), + &get_alias(&msg), + ); + bot.send_message(msg.chat.id, format!("{} buen fail", get_alias(&msg))) + .await?; } return Ok(()); } -fn pole_conditions(msg: Message) -> bool{ - let text_lower = match msg.text(){ +fn pole_conditions(msg: Message) -> bool { + let text_lower = match msg.text() { Some(t) => t.to_lowercase(), None => return false, }; @@ -103,21 +134,21 @@ fn pole_conditions(msg: Message) -> bool{ false } -fn plata_conditions(msg: Message) -> bool{ - let text_lower = match msg.text(){ +fn plata_conditions(msg: Message) -> bool { + let text_lower = match msg.text() { Some(t) => t.to_lowercase(), None => return false, }; if text_lower.contains("plata") || text_lower.contains("subpole") { - if check_user_points(&msg, Rewards::PLATA) { + if check_user_points(&msg, Rewards::PLATA) { return true; } } false } -fn bronce_conditions(msg: Message) -> bool{ - let text_lower = match msg.text(){ +fn bronce_conditions(msg: Message) -> bool { + let text_lower = match msg.text() { Some(t) => t.to_lowercase(), None => return false, }; @@ -129,7 +160,7 @@ fn bronce_conditions(msg: Message) -> bool{ false } -pub fn get_top(msg: Message, bot: Bot) -> ::SendMessage{ +pub fn get_top(msg: Message, bot: Bot) -> ::SendMessage { let db = database::DatabasePole::get_database(); let top = db.get_top_users(&msg.chat.id.0.to_string()); let mut repl = String::new(); @@ -139,11 +170,10 @@ pub fn get_top(msg: Message, bot: Bot) -> ::SendMessage{ bot.send_message(msg.chat.id, format!("{}", repl)) } -#[cfg(test)] +/*#[cfg(test)] #[test] fn compare_dates(){ assert_eq!(false, change_day("2020-01-01")); assert_eq!(true, change_day("3025-01-01")); } - - +*/ diff --git a/tests/ban_stiker.rs b/tests/ban_stiker.rs new file mode 100644 index 0000000..edab31f --- /dev/null +++ b/tests/ban_stiker.rs @@ -0,0 +1,6 @@ +use mini_admin_bot::ban_stiker; + +#[test] +pub fn db_media_is_banned() { + assert_eq!(0, 0); +} diff --git a/tests/permissions.rs b/tests/permissions.rs new file mode 100644 index 0000000..a487eba --- /dev/null +++ b/tests/permissions.rs @@ -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")); +}