clean warnings and add tests
This commit is contained in:
parent
baf7ba2ffb
commit
91f6c5f9f9
@ -1,6 +1,4 @@
|
||||
use crate::database;
|
||||
use sqlite::{Error, State};
|
||||
|
||||
pub struct Database {
|
||||
ins_connection: &'static database::DB_CONNECTION, //Mutex<Box<sqlite::Connection>>,
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
pub fn check_media(msg: Message) -> bool {
|
||||
check_gif(msg.clone()) ||
|
||||
check_stiker(msg.clone()) ||
|
||||
check_photo(msg.clone())
|
||||
check_gif(msg.clone()) || check_stiker(msg.clone()) || check_photo(msg.clone())
|
||||
}
|
||||
|
||||
pub fn check_stiker(msg: Message) -> bool {
|
||||
@ -15,7 +13,7 @@ pub fn check_stiker(msg: Message) -> bool {
|
||||
None => return false,
|
||||
};
|
||||
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 {
|
||||
@ -24,7 +22,7 @@ pub fn check_gif(msg: Message) -> bool {
|
||||
None => return false,
|
||||
};
|
||||
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 {
|
||||
@ -32,30 +30,27 @@ pub fn check_photo(msg: Message) -> bool {
|
||||
Some(s) => {
|
||||
let db = database::Database::get_database();
|
||||
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;
|
||||
}
|
||||
}
|
||||
false
|
||||
},
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn ban_media(
|
||||
msg: Message,
|
||||
bot: Bot,
|
||||
) -> anyhow::Result<()>{
|
||||
pub async fn ban_media(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
||||
if !is_admin(msg.clone(), bot).await {
|
||||
return get_error("No tienes permiso para hacer esto");
|
||||
}
|
||||
match msg.reply_to_message() {
|
||||
Some(s) => {
|
||||
insert_ban_stiker((*s).clone());
|
||||
insert_ban_gif((*s).clone());
|
||||
insert_ban_photo((*s).clone());
|
||||
_ = insert_ban_stiker((*s).clone());
|
||||
_ = insert_ban_gif((*s).clone());
|
||||
_ = insert_ban_photo((*s).clone());
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
None => get_error("No has seleccionado nada"),
|
||||
}
|
||||
}
|
||||
@ -64,15 +59,15 @@ fn insert_ban_stiker(msg: Message) -> anyhow::Result<()> {
|
||||
match msg.sticker() {
|
||||
Some(s) => {
|
||||
let db = database::Database::get_database();
|
||||
match db.add_media(s.file.unique_id.as_str(),
|
||||
match db.add_media(
|
||||
s.file.unique_id.as_str(),
|
||||
msg.chat.id.to_string().as_str(),
|
||||
database::T_STIKER)
|
||||
{
|
||||
database::T_STIKER,
|
||||
) {
|
||||
true => Ok(()),
|
||||
false => get_error("Stiker ya quemado"),
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
@ -81,15 +76,15 @@ fn insert_ban_gif(msg: Message) -> anyhow::Result<()> {
|
||||
match msg.animation() {
|
||||
Some(s) => {
|
||||
let db = database::Database::get_database();
|
||||
match db.add_media(s.file.unique_id.as_str(),
|
||||
match db.add_media(
|
||||
s.file.unique_id.as_str(),
|
||||
msg.chat.id.to_string().as_str(),
|
||||
database::T_GIF)
|
||||
{
|
||||
database::T_GIF,
|
||||
) {
|
||||
true => Ok(()),
|
||||
false => get_error("Gif ya quemado"),
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
@ -98,23 +93,28 @@ fn insert_ban_photo(msg: Message) -> anyhow::Result<()> {
|
||||
match msg.photo() {
|
||||
Some(s) => {
|
||||
let db = database::Database::get_database();
|
||||
for p in s{
|
||||
match db.add_media(p.file.unique_id.as_str(),
|
||||
for p in s {
|
||||
match db.add_media(
|
||||
p.file.unique_id.as_str(),
|
||||
msg.chat.id.to_string().as_str(),
|
||||
database::T_PHOTO)
|
||||
{
|
||||
true => {},
|
||||
database::T_PHOTO,
|
||||
) {
|
||||
true => {}
|
||||
false => return get_error("Foto ya quemado"),
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn is_admin(msg: Message, bot: Bot)->bool{
|
||||
match bot.get_chat_member(msg.chat.id, msg.from().unwrap().id).send().await {
|
||||
async fn is_admin(msg: Message, bot: Bot) -> bool {
|
||||
match bot
|
||||
.get_chat_member(msg.chat.id, msg.from().unwrap().id)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(k) => k.kind.is_privileged(),
|
||||
Err(_e) => false,
|
||||
}
|
||||
@ -133,7 +133,8 @@ impl fmt::Display for ErrorBanStiker {
|
||||
|
||||
impl Error for ErrorBanStiker {}
|
||||
|
||||
fn get_error(msg: &str)-> anyhow::Result<()> {
|
||||
Err(anyhow::Error::new(ErrorBanStiker{message: String::from(msg),}))
|
||||
fn get_error(msg: &str) -> anyhow::Result<()> {
|
||||
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::fs;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::RwLock;
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
@ -16,12 +12,7 @@ const ALLOW_PATH: &str = "allow_users";
|
||||
#[cfg(debug_assertions)]
|
||||
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_POLE_IDS: Lazy<Mutex<LinkedList<String>>> =
|
||||
Lazy::new(|| Mutex::new(read_ids(POLE_PATH)));
|
||||
|
||||
#[cfg(not(test))]
|
||||
fn read_ids<'a>(path: &str) -> LinkedList<String> {
|
||||
let content = fs::read_to_string(path).expect("Something went wrong reading the file");
|
||||
content
|
||||
@ -31,12 +22,22 @@ fn read_ids<'a>(path: &str) -> 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 {
|
||||
aproved_groups: RwLock<LinkedList<String>>,
|
||||
party_groups: RwLock<LinkedList<String>>,
|
||||
}
|
||||
|
||||
#[cfg_attr(test, automock)]
|
||||
impl GroupPermissions {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -54,20 +55,16 @@ impl GroupPermissions {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compare(id: &String) -> bool {
|
||||
let ret: bool;
|
||||
unsafe {
|
||||
ret = LIST_IDS.lock().unwrap().contains(id);
|
||||
log::info!("{}", id);
|
||||
}
|
||||
ret
|
||||
#[test]
|
||||
pub fn test_compare() {
|
||||
let gp = GroupPermissions::new();
|
||||
assert_eq!(true, gp.compare(&"id_3".to_string()));
|
||||
assert_eq!(false, gp.compare(&"id_4".to_string()));
|
||||
}
|
||||
|
||||
pub fn compare_pole(id: &String) -> bool {
|
||||
let ret: bool;
|
||||
unsafe {
|
||||
ret = LIST_POLE_IDS.lock().unwrap().contains(id);
|
||||
log::info!("{}", id);
|
||||
}
|
||||
ret
|
||||
#[test]
|
||||
pub fn test_compare_pole() {
|
||||
let gp = GroupPermissions::new();
|
||||
assert_eq!(true, gp.compar_party(&"id_2".to_string()));
|
||||
assert_eq!(false, gp.compar_party(&"id_3".to_string()));
|
||||
}
|
||||
|
@ -2,19 +2,19 @@ use lazy_static::lazy_static;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[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)]
|
||||
const db_path : &str ="polesDB";
|
||||
const DB_PATH: &str = "polesDB";
|
||||
|
||||
#[cfg(not(test))]
|
||||
lazy_static! {
|
||||
pub static ref DB_CONNECTION : Mutex<Box<sqlite::Connection>> =
|
||||
Mutex::new(Box::new(sqlite::open(db_path).unwrap()));
|
||||
pub static ref DB_CONNECTION: Mutex<Box<sqlite::Connection>> =
|
||||
Mutex::new(Box::new(sqlite::open(DB_PATH).unwrap()));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
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()));
|
||||
}
|
||||
|
15
src/lib.rs
15
src/lib.rs
@ -6,7 +6,7 @@ pub mod check_permissions;
|
||||
mod database;
|
||||
mod filter_files;
|
||||
mod pole_dialogue;
|
||||
mod rewrite_links;
|
||||
pub mod rewrite_links;
|
||||
mod spoiler_mangas;
|
||||
mod telegram_utils;
|
||||
|
||||
@ -39,7 +39,6 @@ pub async fn run() {
|
||||
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(
|
||||
@ -72,14 +71,12 @@ pub async fn run() {
|
||||
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()))
|
||||
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)),
|
||||
@ -131,21 +128,21 @@ fn is_media(msg: Message) -> bool {
|
||||
|
||||
fn is_stiker(msg: Message) -> bool {
|
||||
match msg.sticker() {
|
||||
Some(s) => true,
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_gif(msg: Message) -> bool {
|
||||
match msg.animation() {
|
||||
Some(s) => true,
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_photo(msg: Message) -> bool {
|
||||
match msg.photo() {
|
||||
Some(s) => true,
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use sqlite::{Error, State};
|
||||
|
||||
#[cfg(test)]
|
||||
fn drop_all(con: &sqlite::Connection) -> bool {
|
||||
let mut result: bool;
|
||||
let result: bool;
|
||||
match con.execute(
|
||||
"
|
||||
DROP TABLE IF EXISTS poles;
|
||||
@ -188,7 +188,7 @@ impl<'a> DatabasePole {
|
||||
.unwrap();
|
||||
statement.bind((1, group_id)).unwrap();
|
||||
let mut ret = Vec::new();
|
||||
for i in 1..10 {
|
||||
for _ in 1..10 {
|
||||
match statement.next().unwrap() {
|
||||
State::Row => ret.push((
|
||||
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 ret = data.check_user_pole(
|
||||
&msg.chat.id.to_string(),
|
||||
@ -75,7 +75,7 @@ enum Rewards {
|
||||
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 ret = data.check_group_points(&msg.chat.id.to_string(), &get_actual_day());
|
||||
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<()> {
|
||||
let text_lower = match msg.text() {
|
||||
let _text_lower = match msg.text() {
|
||||
Some(t) => t.to_lowercase(),
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
@ -2,17 +2,19 @@ use phf::phf_map;
|
||||
|
||||
use curl::easy::Easy;
|
||||
|
||||
static URLS: phf::Map<&'static str, &'static str> = phf_map! {
|
||||
"www.tiktok.com" => "vxtiktok.com",
|
||||
"vm.tiktok.com" => "vxtiktok.com",
|
||||
"lite.tiktok.com" => "vxtiktok.com",
|
||||
"https://x.com" => "https://fxtwitter.com",
|
||||
"https://twitter.com" => "https://fxtwitter.com",
|
||||
static URLS: phf::Map<&'static str, (&'static str, bool)> = phf_map! {
|
||||
"www.tiktok.com" => ("vxtiktok.com", false),
|
||||
"vm.tiktok.com" => ("vxtiktok.com", true),
|
||||
"vt.tiktok.com" => ("vxtiktok.com", true),
|
||||
"lite.tiktok.com" => ("vxtiktok.com", true),
|
||||
"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> {
|
||||
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,
|
||||
};
|
||||
|
||||
@ -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 {
|
||||
for domain in URLS.keys() {
|
||||
if text.contains(domain) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
@ -44,14 +37,14 @@ pub fn get_domain_from_text(text: String) -> (String, String) {
|
||||
for word in text.split(' ') {
|
||||
for domain in URLS.keys() {
|
||||
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)) {
|
||||
Ok(furl) => furl,
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
#[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::{
|
||||
net::Download,
|
||||
requests::{Requester,MultipartRequest},
|
||||
types::{MessageEntity, MessageEntityKind},
|
||||
payloads::SendPhoto,
|
||||
requests::{MultipartRequest, Requester},
|
||||
types::{MessageEntity, MessageEntityKind},
|
||||
Bot,
|
||||
};
|
||||
use image::{DynamicImage,GenericImageView};
|
||||
use std::io::Cursor;
|
||||
use tokio::io::BufStream;
|
||||
use crate::telegram_utils::*;
|
||||
|
||||
const TOLERANCE: i16 = 10;
|
||||
const PERCENT_ACEPTANCE: u8 = 5;
|
||||
const WHITE : u8 = 160;
|
||||
const WHITE: u8 = 160;
|
||||
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_wite = 0;
|
||||
for pixel in img.pixels() {
|
||||
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_br:i16 = (pixel.2[0] as i16 - pixel.2[2] 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_br: i16 = (pixel.2[0] as i16 - pixel.2[2] as i16).abs();
|
||||
let diference_pixel = diference_rg + diference_gb + diference_br;
|
||||
if pixel.2[0] > WHITE && pixel.2[1] > WHITE && pixel.2[2] > WHITE {
|
||||
cont_wite+=1
|
||||
cont_wite += 1
|
||||
}
|
||||
if diference_pixel > TOLERANCE {
|
||||
cont += 1;
|
||||
}
|
||||
}
|
||||
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;
|
||||
(percent,white)
|
||||
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;
|
||||
(percent, white)
|
||||
}
|
||||
|
||||
fn generate_from(msg: &Message, append_text: bool) -> String {
|
||||
@ -45,42 +45,58 @@ fn generate_from(msg: &Message, append_text: bool) -> String {
|
||||
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;
|
||||
match old_msg.caption() {
|
||||
Some(caption) => {
|
||||
msg_from = generate_from(&old_msg, true);
|
||||
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(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 => {
|
||||
msg_from = generate_from(&old_msg, false);
|
||||
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 last_hole = 0;
|
||||
for mut cap in captions {
|
||||
match cap.kind {
|
||||
MessageEntityKind::TextMention { user: ref User } => {
|
||||
MessageEntityKind::TextMention { user: ref _user } => {
|
||||
if cap.offset == 0 {
|
||||
last_hole = cap.length;
|
||||
}else if cap.offset >= last_hole {
|
||||
ret.push(MessageEntity::spoiler(last_hole+offset,cap.offset-last_hole));
|
||||
} else if cap.offset >= last_hole {
|
||||
ret.push(MessageEntity::spoiler(
|
||||
last_hole + offset,
|
||||
cap.offset - last_hole,
|
||||
));
|
||||
last_hole = cap.offset + cap.length;
|
||||
}
|
||||
cap.offset += offset;
|
||||
ret.push(cap.clone());
|
||||
},
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
@ -89,7 +105,7 @@ pub async fn check_image(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
||||
Some(s) => {
|
||||
let mut percent = 0;
|
||||
let mut white = 0;
|
||||
let mut id : Option<(String, u32)> = None;
|
||||
let mut id: Option<(String, u32)> = None;
|
||||
let mut failed = true;
|
||||
for p in s {
|
||||
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 {
|
||||
Some(i)
|
||||
}
|
||||
},
|
||||
}
|
||||
None => Some((p.clone().file.id, p.clone().width)),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(_e) => continue,
|
||||
}
|
||||
}
|
||||
if !failed && percent < PERCENT_ACEPTANCE && white > WHITE_ACEPTANCE {
|
||||
bot.delete_message(msg.chat.id, msg.id).await?;
|
||||
let response = match id {
|
||||
Some(i) => bot.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(i.0)).has_spoiler(true),
|
||||
None => {
|
||||
match msg.photo().unwrap().iter().max_by_key(|p| p.width) {
|
||||
Some(f) => bot.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(f.file.id.clone())).has_spoiler(true),
|
||||
Some(i) => bot
|
||||
.send_photo(msg.chat.id, teloxide::types::InputFile::file_id(i.0))
|
||||
.has_spoiler(true),
|
||||
None => match msg.photo().unwrap().iter().max_by_key(|p| p.width) {
|
||||
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?;
|
||||
}
|
||||
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