Add missing file
This commit is contained in:
97
src/images.rs
Normal file
97
src/images.rs
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Valentin Lorentz
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
|
||||
use matrix_sdk::ruma::events::room::message::ImageMessageEventContent;
|
||||
use matrix_sdk::ruma::{OwnedEventId, OwnedRoomId, RoomId};
|
||||
use matrix_sdk::Client;
|
||||
|
||||
use crate::buffers::room::OwnedBufferItemContent;
|
||||
use crate::config::Config;
|
||||
use crate::html::{escape_html, format_html};
|
||||
|
||||
pub(crate) async fn decode_image(
|
||||
client: &Client,
|
||||
config: &Config,
|
||||
event_id: Option<OwnedEventId>,
|
||||
sender: &str,
|
||||
content: &ImageMessageEventContent,
|
||||
) -> OwnedBufferItemContent {
|
||||
// Like `format!()` but returns OwnedBufferItemContent::Text, with is_message=true
|
||||
macro_rules! msg {
|
||||
($prefix: expr, $($tokens:tt)*) => {
|
||||
OwnedBufferItemContent::Text {
|
||||
event_id,
|
||||
is_message: true,
|
||||
text: format_html(&config, $prefix, &format!($($tokens)*))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ImageMessageEventContent { body, info, .. } = content;
|
||||
match client.media().get_file(content, /* use_cache */ true).await {
|
||||
Ok(Some(file)) => {
|
||||
let mut reader = match info
|
||||
.as_ref()
|
||||
.and_then(|info| info.mimetype.as_ref())
|
||||
.and_then(|mimetype| image::ImageFormat::from_mime_type(mimetype))
|
||||
{
|
||||
Some(format) => {
|
||||
// Known format provided by the sender
|
||||
image::io::Reader::with_format(Cursor::new(file), format)
|
||||
},
|
||||
None => {
|
||||
// Unknown format or not provided by the sender, try guessing it
|
||||
let reader = image::io::Reader::new(Cursor::new(file));
|
||||
match reader.with_guessed_format() {
|
||||
Ok(reader) => reader,
|
||||
Err(e) => {
|
||||
log::warn!("Could not guess image format: {:?}", e);
|
||||
return msg!(" ", "<{}> {}", sender, escape_html(body));
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Arbitrary values to avoid DoS. TODO: make them configurable
|
||||
let mut limits = image::io::Limits::default();
|
||||
limits.max_image_width = Some(10 * 1024);
|
||||
limits.max_image_height = Some(10 * 1024);
|
||||
limits.max_alloc = Some(100 * 1024 * 1024);
|
||||
reader.limits(limits);
|
||||
|
||||
let image = match reader.decode() {
|
||||
Ok(image) => image,
|
||||
Err(e) => {
|
||||
log::warn!("Could not decode image: {:?}", e);
|
||||
return msg!(" ", "<{}> {}", sender, escape_html(body));
|
||||
},
|
||||
};
|
||||
OwnedBufferItemContent::Image {
|
||||
event_id,
|
||||
is_message: true,
|
||||
image,
|
||||
}
|
||||
},
|
||||
Ok(None) => msg!(" ", "<{}> {}", sender, escape_html(body)),
|
||||
Err(e) => {
|
||||
log::error!("Could not get image file: {:?}", e);
|
||||
msg!(" ", "<{}> {}", sender, escape_html(body))
|
||||
},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user