clean warnings and add tests
This commit is contained in:
parent
baf7ba2ffb
commit
91f6c5f9f9
@ -1,6 +1,4 @@
|
|||||||
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>>,
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,7 @@ use std::error::Error;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub fn check_media(msg: Message) -> bool {
|
pub fn check_media(msg: Message) -> bool {
|
||||||
check_gif(msg.clone()) ||
|
check_gif(msg.clone()) || check_stiker(msg.clone()) || check_photo(msg.clone())
|
||||||
check_stiker(msg.clone()) ||
|
|
||||||
check_photo(msg.clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_stiker(msg: Message) -> bool {
|
pub fn check_stiker(msg: Message) -> bool {
|
||||||
@ -15,7 +13,7 @@ pub fn check_stiker(msg: Message) -> bool {
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
db.media_is_banned(stiker.unique_id.as_str(),database::T_STIKER)
|
db.media_is_banned(stiker.unique_id.as_str(), database::T_STIKER)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_gif(msg: Message) -> bool {
|
pub fn check_gif(msg: Message) -> bool {
|
||||||
@ -24,7 +22,7 @@ pub fn check_gif(msg: Message) -> bool {
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
db.media_is_banned(gif.unique_id.as_str(),database::T_GIF)
|
db.media_is_banned(gif.unique_id.as_str(), database::T_GIF)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_photo(msg: Message) -> bool {
|
pub fn check_photo(msg: Message) -> bool {
|
||||||
@ -32,30 +30,27 @@ pub fn check_photo(msg: Message) -> bool {
|
|||||||
Some(s) => {
|
Some(s) => {
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
for p in s {
|
for p in s {
|
||||||
if db.media_is_banned(p.file.unique_id.as_str(),database::T_PHOTO) {
|
if db.media_is_banned(p.file.unique_id.as_str(), database::T_PHOTO) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
},
|
}
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ban_media(
|
pub async fn ban_media(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
||||||
msg: Message,
|
|
||||||
bot: Bot,
|
|
||||||
) -> anyhow::Result<()>{
|
|
||||||
if !is_admin(msg.clone(), bot).await {
|
if !is_admin(msg.clone(), bot).await {
|
||||||
return get_error("No tienes permiso para hacer esto");
|
return get_error("No tienes permiso para hacer esto");
|
||||||
}
|
}
|
||||||
match msg.reply_to_message() {
|
match msg.reply_to_message() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
insert_ban_stiker((*s).clone());
|
_ = insert_ban_stiker((*s).clone());
|
||||||
insert_ban_gif((*s).clone());
|
_ = insert_ban_gif((*s).clone());
|
||||||
insert_ban_photo((*s).clone());
|
_ = insert_ban_photo((*s).clone());
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
None => get_error("No has seleccionado nada"),
|
None => get_error("No has seleccionado nada"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,15 +59,15 @@ fn insert_ban_stiker(msg: Message) -> anyhow::Result<()> {
|
|||||||
match msg.sticker() {
|
match msg.sticker() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
match db.add_media(s.file.unique_id.as_str(),
|
match db.add_media(
|
||||||
msg.chat.id.to_string().as_str(),
|
s.file.unique_id.as_str(),
|
||||||
database::T_STIKER)
|
msg.chat.id.to_string().as_str(),
|
||||||
{
|
database::T_STIKER,
|
||||||
true => Ok(()),
|
) {
|
||||||
false => get_error("Stiker ya quemado"),
|
true => Ok(()),
|
||||||
}
|
false => get_error("Stiker ya quemado"),
|
||||||
|
}
|
||||||
},
|
}
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,15 +76,15 @@ fn insert_ban_gif(msg: Message) -> anyhow::Result<()> {
|
|||||||
match msg.animation() {
|
match msg.animation() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
match db.add_media(s.file.unique_id.as_str(),
|
match db.add_media(
|
||||||
msg.chat.id.to_string().as_str(),
|
s.file.unique_id.as_str(),
|
||||||
database::T_GIF)
|
msg.chat.id.to_string().as_str(),
|
||||||
{
|
database::T_GIF,
|
||||||
true => Ok(()),
|
) {
|
||||||
false => get_error("Gif ya quemado"),
|
true => Ok(()),
|
||||||
}
|
false => get_error("Gif ya quemado"),
|
||||||
|
}
|
||||||
},
|
}
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,23 +93,28 @@ fn insert_ban_photo(msg: Message) -> anyhow::Result<()> {
|
|||||||
match msg.photo() {
|
match msg.photo() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
let db = database::Database::get_database();
|
let db = database::Database::get_database();
|
||||||
for p in s{
|
for p in s {
|
||||||
match db.add_media(p.file.unique_id.as_str(),
|
match db.add_media(
|
||||||
msg.chat.id.to_string().as_str(),
|
p.file.unique_id.as_str(),
|
||||||
database::T_PHOTO)
|
msg.chat.id.to_string().as_str(),
|
||||||
{
|
database::T_PHOTO,
|
||||||
true => {},
|
) {
|
||||||
|
true => {}
|
||||||
false => return get_error("Foto ya quemado"),
|
false => return get_error("Foto ya quemado"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => {},
|
None => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_admin(msg: Message, bot: Bot)->bool{
|
async fn is_admin(msg: Message, bot: Bot) -> bool {
|
||||||
match bot.get_chat_member(msg.chat.id, msg.from().unwrap().id).send().await {
|
match bot
|
||||||
|
.get_chat_member(msg.chat.id, msg.from().unwrap().id)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(k) => k.kind.is_privileged(),
|
Ok(k) => k.kind.is_privileged(),
|
||||||
Err(_e) => false,
|
Err(_e) => false,
|
||||||
}
|
}
|
||||||
@ -133,7 +133,8 @@ impl fmt::Display for ErrorBanStiker {
|
|||||||
|
|
||||||
impl Error for ErrorBanStiker {}
|
impl Error for ErrorBanStiker {}
|
||||||
|
|
||||||
fn get_error(msg: &str)-> anyhow::Result<()> {
|
fn get_error(msg: &str) -> anyhow::Result<()> {
|
||||||
Err(anyhow::Error::new(ErrorBanStiker{message: String::from(msg),}))
|
Err(anyhow::Error::new(ErrorBanStiker {
|
||||||
}
|
message: String::from(msg),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
#[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::fs;
|
||||||
use std::sync::Mutex;
|
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
@ -16,12 +12,7 @@ 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>>> =
|
#[cfg(not(test))]
|
||||||
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)));
|
|
||||||
|
|
||||||
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
|
content
|
||||||
@ -31,12 +22,22 @@ fn read_ids<'a>(path: &str) -> LinkedList<String> {
|
|||||||
.collect::<LinkedList<String>>()
|
.collect::<LinkedList<String>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn read_ids<'a>(path: &str) -> LinkedList<String> {
|
||||||
|
let mut ret = LinkedList::new();
|
||||||
|
ret.push_front("id_1".to_string());
|
||||||
|
ret.push_front("id_2".to_string());
|
||||||
|
if !path.eq(POLE_PATH) {
|
||||||
|
ret.push_front("id_3".to_string());
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GroupPermissions {
|
pub struct GroupPermissions {
|
||||||
aproved_groups: RwLock<LinkedList<String>>,
|
aproved_groups: RwLock<LinkedList<String>>,
|
||||||
party_groups: RwLock<LinkedList<String>>,
|
party_groups: RwLock<LinkedList<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, automock)]
|
|
||||||
impl GroupPermissions {
|
impl GroupPermissions {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -54,20 +55,16 @@ impl GroupPermissions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare(id: &String) -> bool {
|
#[test]
|
||||||
let ret: bool;
|
pub fn test_compare() {
|
||||||
unsafe {
|
let gp = GroupPermissions::new();
|
||||||
ret = LIST_IDS.lock().unwrap().contains(id);
|
assert_eq!(true, gp.compare(&"id_3".to_string()));
|
||||||
log::info!("{}", id);
|
assert_eq!(false, gp.compare(&"id_4".to_string()));
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare_pole(id: &String) -> bool {
|
#[test]
|
||||||
let ret: bool;
|
pub fn test_compare_pole() {
|
||||||
unsafe {
|
let gp = GroupPermissions::new();
|
||||||
ret = LIST_POLE_IDS.lock().unwrap().contains(id);
|
assert_eq!(true, gp.compar_party(&"id_2".to_string()));
|
||||||
log::info!("{}", id);
|
assert_eq!(false, gp.compar_party(&"id_3".to_string()));
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,19 @@ use lazy_static::lazy_static;
|
|||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
const db_path : &str ="/opt/mini_admin_bot/data.db";
|
const DB_PATH: &str = "/opt/mini_admin_bot/data.db";
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
const db_path : &str ="polesDB";
|
const DB_PATH: &str = "polesDB";
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref DB_CONNECTION : Mutex<Box<sqlite::Connection>> =
|
pub static ref DB_CONNECTION: Mutex<Box<sqlite::Connection>> =
|
||||||
Mutex::new(Box::new(sqlite::open(db_path).unwrap()));
|
Mutex::new(Box::new(sqlite::open(DB_PATH).unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref DB_CONNECTION : Mutex<Box<sqlite::Connection>> =
|
pub static ref DB_CONNECTION: Mutex<Box<sqlite::Connection>> =
|
||||||
Mutex::new(Box::new(sqlite::open("polesDBTest").unwrap()));
|
Mutex::new(Box::new(sqlite::open("polesDBTest").unwrap()));
|
||||||
}
|
}
|
||||||
|
15
src/lib.rs
15
src/lib.rs
@ -6,7 +6,7 @@ pub mod check_permissions;
|
|||||||
mod database;
|
mod database;
|
||||||
mod filter_files;
|
mod filter_files;
|
||||||
mod pole_dialogue;
|
mod pole_dialogue;
|
||||||
mod rewrite_links;
|
pub mod rewrite_links;
|
||||||
mod spoiler_mangas;
|
mod spoiler_mangas;
|
||||||
mod telegram_utils;
|
mod telegram_utils;
|
||||||
|
|
||||||
@ -39,7 +39,6 @@ pub async fn run() {
|
|||||||
let permissions = Arc::new(check_permissions::GroupPermissions::new());
|
let permissions = Arc::new(check_permissions::GroupPermissions::new());
|
||||||
let p1 = Arc::clone(&permissions);
|
let p1 = Arc::clone(&permissions);
|
||||||
let p2 = Arc::clone(&permissions);
|
let p2 = Arc::clone(&permissions);
|
||||||
//Command::repl(bot.clone(), answer).await;
|
|
||||||
let handler = Update::filter_message()
|
let handler = Update::filter_message()
|
||||||
.branch(
|
.branch(
|
||||||
dptree::filter(move |msg: Message| !p1.compare(&msg.chat.id.to_string())).endpoint(
|
dptree::filter(move |msg: Message| !p1.compare(&msg.chat.id.to_string())).endpoint(
|
||||||
@ -72,14 +71,12 @@ pub async fn run() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
/*
|
|
||||||
Now is useless because the group doesn't make any spoiler
|
|
||||||
.branch(
|
.branch(
|
||||||
dptree::filter(move |msg: Message| {
|
dptree::filter(move |msg: Message| {
|
||||||
(is_photo(msg.clone()) && p2.compar_party(&msg.chat.id.to_string()))
|
is_photo(msg.clone()) && p2.compar_party(&msg.chat.id.to_string())
|
||||||
})
|
})
|
||||||
.endpoint(|msg: Message, bot: Bot| spoiler_mangas::check_image(msg, bot)),
|
.endpoint(|msg: Message, bot: Bot| spoiler_mangas::check_image(msg, bot)),
|
||||||
)*/
|
)
|
||||||
.branch(
|
.branch(
|
||||||
dptree::filter(move |msg: Message| filter_files::analyce_name::check_file(msg.clone()))
|
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)),
|
.endpoint(|msg: Message, bot: Bot| filter_files::action::take_actions(msg, bot)),
|
||||||
@ -131,21 +128,21 @@ fn is_media(msg: Message) -> bool {
|
|||||||
|
|
||||||
fn is_stiker(msg: Message) -> bool {
|
fn is_stiker(msg: Message) -> bool {
|
||||||
match msg.sticker() {
|
match msg.sticker() {
|
||||||
Some(s) => true,
|
Some(_) => true,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_gif(msg: Message) -> bool {
|
fn is_gif(msg: Message) -> bool {
|
||||||
match msg.animation() {
|
match msg.animation() {
|
||||||
Some(s) => true,
|
Some(_) => true,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_photo(msg: Message) -> bool {
|
fn is_photo(msg: Message) -> bool {
|
||||||
match msg.photo() {
|
match msg.photo() {
|
||||||
Some(s) => true,
|
Some(_) => true,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ 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 result: bool;
|
||||||
match con.execute(
|
match con.execute(
|
||||||
"
|
"
|
||||||
DROP TABLE IF EXISTS poles;
|
DROP TABLE IF EXISTS poles;
|
||||||
@ -188,7 +188,7 @@ impl<'a> DatabasePole {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
statement.bind((1, group_id)).unwrap();
|
statement.bind((1, group_id)).unwrap();
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
for i in 1..10 {
|
for _ in 1..10 {
|
||||||
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(),
|
||||||
|
@ -59,7 +59,7 @@ fn do_fail(group_id: &str, user_id: &str, user_name: &str) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_user_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
|
fn check_user_points(msg: &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(
|
let ret = data.check_user_pole(
|
||||||
&msg.chat.id.to_string(),
|
&msg.chat.id.to_string(),
|
||||||
@ -75,7 +75,7 @@ enum Rewards {
|
|||||||
FAIL = 1,
|
FAIL = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
|
fn check_group_points(msg: &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(), &get_actual_day());
|
let ret = data.check_group_points(&msg.chat.id.to_string(), &get_actual_day());
|
||||||
match rw {
|
match rw {
|
||||||
@ -86,7 +86,7 @@ fn check_group_points(msg: &teloxide::prelude::Message, rw: Rewards) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn exe_pole(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
pub async fn exe_pole(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(()),
|
||||||
};
|
};
|
||||||
|
@ -2,17 +2,19 @@ use phf::phf_map;
|
|||||||
|
|
||||||
use curl::easy::Easy;
|
use curl::easy::Easy;
|
||||||
|
|
||||||
static URLS: phf::Map<&'static str, &'static str> = phf_map! {
|
static URLS: phf::Map<&'static str, (&'static str, bool)> = phf_map! {
|
||||||
"www.tiktok.com" => "vxtiktok.com",
|
"www.tiktok.com" => ("vxtiktok.com", false),
|
||||||
"vm.tiktok.com" => "vxtiktok.com",
|
"vm.tiktok.com" => ("vxtiktok.com", true),
|
||||||
"lite.tiktok.com" => "vxtiktok.com",
|
"vt.tiktok.com" => ("vxtiktok.com", true),
|
||||||
"https://x.com" => "https://fxtwitter.com",
|
"lite.tiktok.com" => ("vxtiktok.com", true),
|
||||||
"https://twitter.com" => "https://fxtwitter.com",
|
"www.instagram.com" => ("ddinstagram.com", false),
|
||||||
|
"https://x.com" => ("https://fxtwitter.com", false),
|
||||||
|
"https://twitter.com" => ("https://fxtwitter.com",false),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn filter_string(url: String, domain: String) -> Option<String> {
|
pub fn filter_string(url: String, domain: String) -> Option<String> {
|
||||||
let ret = match URLS.get(domain.as_str()) {
|
let ret = match URLS.get(domain.as_str()) {
|
||||||
Some(fixed_domain) => url.replacen(domain.as_str(),fixed_domain,1),
|
Some(fixed_domain) => url.replacen(domain.as_str(), fixed_domain.0, 1),
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,19 +24,10 @@ pub fn filter_string(url: String, domain: String) -> Option<String> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_domain(url: String) -> Option<String> {
|
|
||||||
for domain in URLS.keys() {
|
|
||||||
if url.contains(domain) {
|
|
||||||
return Some(String::from(*domain))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_domains(text: String) -> bool {
|
pub fn check_domains(text: String) -> bool {
|
||||||
for domain in URLS.keys() {
|
for domain in URLS.keys() {
|
||||||
if text.contains(domain) {
|
if text.contains(domain) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -44,14 +37,14 @@ pub fn get_domain_from_text(text: String) -> (String, String) {
|
|||||||
for word in text.split(' ') {
|
for word in text.split(' ') {
|
||||||
for domain in URLS.keys() {
|
for domain in URLS.keys() {
|
||||||
if word.contains(domain) {
|
if word.contains(domain) {
|
||||||
if String::from(*domain).contains("vm.tiktok.com") || String::from(*domain).contains("lite.tiktok.com") {
|
if URLS[domain].1 {
|
||||||
let url = match get_tiktok_redirection(String::from(word)) {
|
let url = match get_tiktok_redirection(String::from(word)) {
|
||||||
Ok(furl) => furl,
|
Ok(furl) => furl,
|
||||||
Err(_e) => String::from(word),
|
Err(_e) => String::from(word),
|
||||||
};
|
};
|
||||||
return (String::from(url), String::from("www.tiktok.com"))
|
return (String::from(url), String::from("www.tiktok.com"));
|
||||||
}
|
}
|
||||||
return (String::from(word), String::from(*domain))
|
return (String::from(word), String::from(*domain));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,3 +60,37 @@ fn get_tiktok_redirection(url: String) -> Result<String, curl::Error> {
|
|||||||
None => url,
|
None => url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_check_domains() {
|
||||||
|
assert_eq!(
|
||||||
|
true,
|
||||||
|
check_domains("https://vm.tiktok.com/ZGeouHd2t/".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
false,
|
||||||
|
check_domains("https://randomwebsite.com".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rewrite_clean_tiktok() {
|
||||||
|
let domain = get_domain_from_text(
|
||||||
|
"https://www.tiktok.com/@kramkang/video/7417808362957589778".to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(domain.1, "www.tiktok.com");
|
||||||
|
assert_eq!(
|
||||||
|
domain.0,
|
||||||
|
"https://www.tiktok.com/@kramkang/video/7417808362957589778"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rewrite_refered_tiktok() {
|
||||||
|
let url_and_domain = get_domain_from_text("https://vm.tiktok.com/ZGeouHd2t/".to_string());
|
||||||
|
let domain = filter_string(url_and_domain.0, url_and_domain.1);
|
||||||
|
assert_eq!(
|
||||||
|
domain,
|
||||||
|
Some("https://vxtiktok.com/@/video/7417808362957589778".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -1,39 +1,39 @@
|
|||||||
|
use crate::telegram_utils::*;
|
||||||
|
use image::{DynamicImage, GenericImageView};
|
||||||
|
use std::io::Cursor;
|
||||||
use teloxide::prelude::*;
|
use teloxide::prelude::*;
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
net::Download,
|
net::Download,
|
||||||
requests::{Requester,MultipartRequest},
|
|
||||||
types::{MessageEntity, MessageEntityKind},
|
|
||||||
payloads::SendPhoto,
|
payloads::SendPhoto,
|
||||||
|
requests::{MultipartRequest, Requester},
|
||||||
|
types::{MessageEntity, MessageEntityKind},
|
||||||
Bot,
|
Bot,
|
||||||
};
|
};
|
||||||
use image::{DynamicImage,GenericImageView};
|
|
||||||
use std::io::Cursor;
|
|
||||||
use tokio::io::BufStream;
|
use tokio::io::BufStream;
|
||||||
use crate::telegram_utils::*;
|
|
||||||
|
|
||||||
const TOLERANCE: i16 = 10;
|
const TOLERANCE: i16 = 10;
|
||||||
const PERCENT_ACEPTANCE: u8 = 5;
|
const PERCENT_ACEPTANCE: u8 = 5;
|
||||||
const WHITE : u8 = 160;
|
const WHITE: u8 = 160;
|
||||||
const WHITE_ACEPTANCE: u8 = 40;
|
const WHITE_ACEPTANCE: u8 = 40;
|
||||||
|
|
||||||
fn check_percent(img: DynamicImage) -> (u8,u8) {
|
fn check_percent(img: DynamicImage) -> (u8, u8) {
|
||||||
let mut cont = 0;
|
let mut cont = 0;
|
||||||
let mut cont_wite = 0;
|
let mut cont_wite = 0;
|
||||||
for pixel in img.pixels() {
|
for pixel in img.pixels() {
|
||||||
let diference_rg:i16 = (pixel.2[0] as i16 - pixel.2[1] as i16).abs();
|
let diference_rg: i16 = (pixel.2[0] as i16 - pixel.2[1] as i16).abs();
|
||||||
let diference_gb:i16 = (pixel.2[1] as i16 - pixel.2[2] as i16).abs();
|
let diference_gb: i16 = (pixel.2[1] as i16 - pixel.2[2] as i16).abs();
|
||||||
let diference_br:i16 = (pixel.2[0] as i16 - pixel.2[2] as i16).abs();
|
let diference_br: i16 = (pixel.2[0] as i16 - pixel.2[2] as i16).abs();
|
||||||
let diference_pixel = diference_rg + diference_gb + diference_br;
|
let diference_pixel = diference_rg + diference_gb + diference_br;
|
||||||
if pixel.2[0] > WHITE && pixel.2[1] > WHITE && pixel.2[2] > WHITE {
|
if pixel.2[0] > WHITE && pixel.2[1] > WHITE && pixel.2[2] > WHITE {
|
||||||
cont_wite+=1
|
cont_wite += 1
|
||||||
}
|
}
|
||||||
if diference_pixel > TOLERANCE {
|
if diference_pixel > TOLERANCE {
|
||||||
cont += 1;
|
cont += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let percent = ((cont as f64 /(img.width() * img.height()) as f64)*100.0) as u8;
|
let percent = ((cont as f64 / (img.width() * img.height()) as f64) * 100.0) as u8;
|
||||||
let white = ((cont_wite as f64 /(img.width() * img.height()) as f64)*100.0) as u8;
|
let white = ((cont_wite as f64 / (img.width() * img.height()) as f64) * 100.0) as u8;
|
||||||
(percent,white)
|
(percent, white)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_from(msg: &Message, append_text: bool) -> String {
|
fn generate_from(msg: &Message, append_text: bool) -> String {
|
||||||
@ -45,42 +45,58 @@ fn generate_from(msg: &Message, append_text: bool) -> String {
|
|||||||
msg_from
|
msg_from
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_text(new_msg: MultipartRequest<SendPhoto>, old_msg: Message) -> MultipartRequest<SendPhoto> {
|
pub fn append_text(
|
||||||
|
new_msg: MultipartRequest<SendPhoto>,
|
||||||
|
old_msg: Message,
|
||||||
|
) -> MultipartRequest<SendPhoto> {
|
||||||
let msg_from;
|
let msg_from;
|
||||||
match old_msg.caption() {
|
match old_msg.caption() {
|
||||||
Some(caption) => {
|
Some(caption) => {
|
||||||
msg_from = generate_from(&old_msg, true);
|
msg_from = generate_from(&old_msg, true);
|
||||||
let from_offset = msg_from.encode_utf16().count();
|
let from_offset = msg_from.encode_utf16().count();
|
||||||
//new_msg.caption(caption).caption_entities(generate_entity_spoiler(caption.len())).has_spoiler(true)
|
//new_msg.caption(caption).caption_entities(generate_entity_spoiler(caption.len())).has_spoiler(true)
|
||||||
new_msg.caption(msg_from + caption).caption_entities(generate_captions(old_msg.caption_entities().unwrap().to_vec(),caption.encode_utf16().count(), from_offset))
|
new_msg
|
||||||
},
|
.caption(msg_from + caption)
|
||||||
|
.caption_entities(generate_captions(
|
||||||
|
old_msg.caption_entities().unwrap().to_vec(),
|
||||||
|
caption.encode_utf16().count(),
|
||||||
|
from_offset,
|
||||||
|
))
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
msg_from = generate_from(&old_msg, false);
|
msg_from = generate_from(&old_msg, false);
|
||||||
new_msg.caption(msg_from)
|
new_msg.caption(msg_from)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_captions(captions: Vec<MessageEntity>, len: usize, offset: usize) -> Vec<MessageEntity> {
|
pub fn generate_captions(
|
||||||
|
captions: Vec<MessageEntity>,
|
||||||
|
len: usize,
|
||||||
|
offset: usize,
|
||||||
|
) -> Vec<MessageEntity> {
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
let mut last_hole = 0;
|
let mut last_hole = 0;
|
||||||
for mut cap in captions {
|
for mut cap in captions {
|
||||||
match cap.kind {
|
match cap.kind {
|
||||||
MessageEntityKind::TextMention { user: ref User } => {
|
MessageEntityKind::TextMention { user: ref _user } => {
|
||||||
if cap.offset == 0 {
|
if cap.offset == 0 {
|
||||||
last_hole = cap.length;
|
last_hole = cap.length;
|
||||||
}else if cap.offset >= last_hole {
|
} else if cap.offset >= last_hole {
|
||||||
ret.push(MessageEntity::spoiler(last_hole+offset,cap.offset-last_hole));
|
ret.push(MessageEntity::spoiler(
|
||||||
|
last_hole + offset,
|
||||||
|
cap.offset - last_hole,
|
||||||
|
));
|
||||||
last_hole = cap.offset + cap.length;
|
last_hole = cap.offset + cap.length;
|
||||||
}
|
}
|
||||||
cap.offset += offset;
|
cap.offset += offset;
|
||||||
ret.push(cap.clone());
|
ret.push(cap.clone());
|
||||||
},
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if last_hole < len {
|
if last_hole < len {
|
||||||
ret.push(MessageEntity::spoiler(last_hole+offset,len - last_hole));
|
ret.push(MessageEntity::spoiler(last_hole + offset, len - last_hole));
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@ -89,7 +105,7 @@ pub async fn check_image(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
|||||||
Some(s) => {
|
Some(s) => {
|
||||||
let mut percent = 0;
|
let mut percent = 0;
|
||||||
let mut white = 0;
|
let mut white = 0;
|
||||||
let mut id : Option<(String, u32)> = None;
|
let mut id: Option<(String, u32)> = None;
|
||||||
let mut failed = true;
|
let mut failed = true;
|
||||||
for p in s {
|
for p in s {
|
||||||
let file = bot.get_file(p.file.id.clone()).await?;
|
let file = bot.get_file(p.file.id.clone()).await?;
|
||||||
@ -112,30 +128,34 @@ pub async fn check_image(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
|||||||
} else {
|
} else {
|
||||||
Some(i)
|
Some(i)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => Some((p.clone().file.id, p.clone().width)),
|
None => Some((p.clone().file.id, p.clone().width)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(_e) => continue,
|
Err(_e) => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !failed && percent < PERCENT_ACEPTANCE && white > WHITE_ACEPTANCE {
|
if !failed && percent < PERCENT_ACEPTANCE && white > WHITE_ACEPTANCE {
|
||||||
bot.delete_message(msg.chat.id, msg.id).await?;
|
bot.delete_message(msg.chat.id, msg.id).await?;
|
||||||
let response = match id {
|
let response = match id {
|
||||||
Some(i) => bot.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(i.0)).has_spoiler(true),
|
Some(i) => bot
|
||||||
None => {
|
.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(i.0))
|
||||||
match msg.photo().unwrap().iter().max_by_key(|p| p.width) {
|
.has_spoiler(true),
|
||||||
Some(f) => bot.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(f.file.id.clone())).has_spoiler(true),
|
None => match msg.photo().unwrap().iter().max_by_key(|p| p.width) {
|
||||||
None => return Ok(()),
|
Some(f) => bot
|
||||||
}
|
.send_photo(
|
||||||
|
msg.chat.id,
|
||||||
|
teloxide::types::InputFile::file_id(f.file.id.clone()),
|
||||||
|
)
|
||||||
|
.has_spoiler(true),
|
||||||
|
None => return Ok(()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
append_text(response, msg).await?;
|
append_text(response, msg).await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
use mini_admin_bot::ban_stiker;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
pub fn db_media_is_banned() {
|
|
||||||
assert_eq!(0, 0);
|
|
||||||
}
|
|
1
tests/mocks/mod.rs
Normal file
1
tests/mocks/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod teloxide_mocks;
|
54
tests/mocks/teloxide_mocks.rs
Normal file
54
tests/mocks/teloxide_mocks.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use chrono::DateTime;
|
||||||
|
use teloxide::types::{
|
||||||
|
Chat, ChatId, ChatKind, ChatPublic, MediaKind::Text, MediaText, Message, MessageCommon,
|
||||||
|
MessageId, MessageKind::Common, PublicChatGroup, PublicChatKind::Group,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generate_msg_mock(text: &str) -> Message {
|
||||||
|
let chat_id = ChatId { 0: 0 };
|
||||||
|
let public_chat_kind = Group(PublicChatGroup { permissions: None });
|
||||||
|
let chat_kind = ChatKind::Public(ChatPublic {
|
||||||
|
title: None,
|
||||||
|
kind: public_chat_kind,
|
||||||
|
description: None,
|
||||||
|
invite_link: None,
|
||||||
|
has_protected_content: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let chat = Chat {
|
||||||
|
has_aggressive_anti_spam_enabled: false,
|
||||||
|
has_hidden_members: false,
|
||||||
|
id: chat_id,
|
||||||
|
pinned_message: None,
|
||||||
|
photo: None,
|
||||||
|
message_auto_delete_time: None,
|
||||||
|
kind: chat_kind,
|
||||||
|
};
|
||||||
|
|
||||||
|
let media_kind = Text(MediaText {
|
||||||
|
text: text.to_string(),
|
||||||
|
entities: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let message_kind = Common(MessageCommon {
|
||||||
|
from: None,
|
||||||
|
sender_chat: None,
|
||||||
|
author_signature: None,
|
||||||
|
forward: None,
|
||||||
|
reply_to_message: None,
|
||||||
|
edit_date: None,
|
||||||
|
media_kind,
|
||||||
|
reply_markup: None,
|
||||||
|
is_topic_message: false,
|
||||||
|
is_automatic_forward: false,
|
||||||
|
has_protected_content: false,
|
||||||
|
});
|
||||||
|
Message {
|
||||||
|
chat,
|
||||||
|
via_bot: None,
|
||||||
|
thread_id: None,
|
||||||
|
kind: message_kind,
|
||||||
|
date: DateTime::from_timestamp_nanos(0),
|
||||||
|
id: MessageId { 0: 0 },
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
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"));
|
|
||||||
}
|
|
19
tests/test_links_to_rewrite.rs
Normal file
19
tests/test_links_to_rewrite.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use mini_admin_bot::rewrite_links;
|
||||||
|
|
||||||
|
mod mocks;
|
||||||
|
#[test]
|
||||||
|
pub fn test_contain_links() {
|
||||||
|
assert_eq!(
|
||||||
|
false,
|
||||||
|
rewrite_links::check_contain_links::contain_links(
|
||||||
|
mocks::teloxide_mocks::generate_msg_mock("hola")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
true,
|
||||||
|
rewrite_links::check_contain_links::contain_links(
|
||||||
|
mocks::teloxide_mocks::generate_msg_mock("https://x.com")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user