forked from groche97/mini_admin_bot
131 lines
5.1 KiB
Rust
131 lines
5.1 KiB
Rust
use teloxide::prelude::*;
|
|
use teloxide::{
|
|
net::Download,
|
|
requests::{Requester,MultipartRequest},
|
|
types::{MessageEntity, MessageEntityKind},
|
|
payloads::SendPhoto,
|
|
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_ACEPTANCE: u8 = 40;
|
|
|
|
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_pixel = diference_rg + diference_gb + diference_br;
|
|
if pixel.2[0] > WHITE && pixel.2[1] > WHITE && pixel.2[2] > WHITE {
|
|
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)
|
|
}
|
|
|
|
pub fn append_text(new_msg: MultipartRequest<SendPhoto>, old_msg: Message) -> MultipartRequest<SendPhoto> {
|
|
match old_msg.caption() {
|
|
Some(caption) => {
|
|
let mut msg_from = get_alias(&old_msg);
|
|
msg_from.push_str(": ");
|
|
msg_from = String::from("Mensaje de ") + &msg_from;
|
|
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))
|
|
},
|
|
None => new_msg,
|
|
}
|
|
}
|
|
|
|
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 } => {
|
|
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));
|
|
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
|
|
}
|
|
pub async fn check_image(msg: Message, bot: Bot) -> anyhow::Result<()> {
|
|
match msg.photo() {
|
|
Some(s) => {
|
|
let mut percent = 0;
|
|
let mut white = 0;
|
|
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?;
|
|
let empty_memory: Vec<u8> = Vec::new();
|
|
let cursor = Cursor::new(empty_memory);
|
|
let mut reader = BufStream::new(cursor);
|
|
bot.download_file(&file.path, &mut reader).await?;
|
|
let raw = reader.into_inner().into_inner().leak();
|
|
match image::load_from_memory(raw) {
|
|
Ok(img) => {
|
|
failed = false;
|
|
let img_percent = check_percent(img);
|
|
if img_percent.0 >= percent {
|
|
percent = img_percent.0;
|
|
white = img_percent.1;
|
|
id = match id {
|
|
Some(i) => {
|
|
if i.1 > p.width {
|
|
Some((p.clone().file.id, p.clone().width))
|
|
} 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),
|
|
None => return Ok(()),
|
|
}
|
|
},
|
|
};
|
|
append_text(response, msg).await?;
|
|
}
|
|
Ok(())
|
|
},
|
|
None => Ok(()),
|
|
}
|
|
}
|
|
|