108 lines
3.9 KiB
Rust
108 lines
3.9 KiB
Rust
use crate::Bot;
|
|
use anyhow::Context;
|
|
use log::{error, info, warn};
|
|
use matrix_sdk::{
|
|
api::r0::media::create_content,
|
|
events::{
|
|
room::message::{ImageMessageEventContent, MessageEventContent, MessageType},
|
|
AnyMessageEventContent,
|
|
},
|
|
identifiers::MxcUri,
|
|
room::{Joined, Room},
|
|
};
|
|
use std::io::Cursor;
|
|
use std::sync::atomic::Ordering;
|
|
|
|
pub async fn on_msg(msg: &str, room: Room, bot: &Bot) -> anyhow::Result<()> {
|
|
let room = match room {
|
|
Room::Joined(room) => room,
|
|
_ => {
|
|
warn!(
|
|
"Received message '{}' in room {:?} that's not joined",
|
|
msg,
|
|
room.name()
|
|
);
|
|
return Ok(());
|
|
}
|
|
};
|
|
|
|
for meme in &bot.config.memes {
|
|
if meme.matches(msg) {
|
|
bot.meme_count.fetch_add(1, Ordering::SeqCst);
|
|
if bot.meme_count.load(Ordering::SeqCst) >= bot.config.clear_cache_threshold {
|
|
bot.jm_client.write().await.clear_cache().await;
|
|
bot.meme_count.store(0, Ordering::SeqCst);
|
|
}
|
|
|
|
let meme_name = &meme.keyword;
|
|
if let Some(meme) = meme.get_meme(bot).await? {
|
|
match meme.id.parse::<u32>() {
|
|
Err(e) => {
|
|
error!("Meme {:?} has invalid ID! tilera, you messed up with your stupid php again: {}", &meme, e);
|
|
}
|
|
Ok(id) => {
|
|
if let Some(ivec) = bot.memecache.get(id.to_le_bytes())? {
|
|
info!("Meme {} found in cache!", id);
|
|
let mxc = String::from_utf8(ivec.as_ref().to_vec()).context(
|
|
"Found invalid utf8 mxc url in memecache! Is the cache borked?",
|
|
)?;
|
|
|
|
send_meme(&room, mxc.into(), meme_name.clone()).await?;
|
|
} else {
|
|
info!("Meme {} not found in cache, uploading...", id);
|
|
let resp = bot
|
|
.jm_client
|
|
.read()
|
|
.await
|
|
.http
|
|
.get(&meme.link)
|
|
.send()
|
|
.await
|
|
.context("error downloading meme")?;
|
|
let resp = resp.bytes().await?;
|
|
|
|
if let Some(mime) = mime_guess::from_path(&meme.link).first() {
|
|
let create_content::Response { content_uri, .. } = bot
|
|
.client
|
|
.read()
|
|
.await
|
|
.upload(&mime, &mut Cursor::new(resp))
|
|
.await?;
|
|
|
|
bot.memecache.insert(
|
|
id.to_le_bytes(),
|
|
content_uri.to_string().into_bytes(),
|
|
)?;
|
|
|
|
send_meme(&room, content_uri, meme_name.clone()).await?;
|
|
} else {
|
|
error!(
|
|
"Couldn't guess MIME type of meme '{}', skipping.",
|
|
&meme.link
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
error!("Found meme with invalid id! {:?}", &meme);
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn send_meme(room: &Joined, mxc: MxcUri, meme_name: String) -> anyhow::Result<()> {
|
|
room.send(
|
|
AnyMessageEventContent::RoomMessage(MessageEventContent::new(MessageType::Image(
|
|
ImageMessageEventContent::plain(meme_name, mxc, None),
|
|
))),
|
|
None,
|
|
)
|
|
.await
|
|
.context("Failed to send meme")?;
|
|
|
|
Ok(())
|
|
}
|