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