titlebot/src/main.rs

75 lines
3 KiB
Rust

use std::collections::HashMap;
use futures::prelude::*;
use irc::client::prelude::*;
use regex::Regex;
use htmlescape::decode_html;
#[tokio::main]
async fn main() -> Result<(), failure::Error> {
if let Some(filename) = std::env::args().nth(1) {
let config = Config::load(filename)?;
let mut client = Client::from_config(config).await?;
client.identify()?;
println!("Connected to IRC");
let mut stream = client.stream()?;
let ure = Regex::new(r"https?://[www\.]*\w+\.\w+[/\S+]*").unwrap();
let titlefetch = Regex::new(r"<title>[\s\S]+</title>").unwrap();
let treplace = Regex::new(r"</?title>").unwrap();
let mut cache: HashMap<String, String> = HashMap::new();
while let Some(message) = stream.next().await.transpose()? {
print!("{}", message);
if let Command::PRIVMSG(channel, message) = message.command {
if message.contains(client.current_nickname()) {
client
.send_privmsg(&channel, "beep boop, i'm titlebot!")
.unwrap();
}
if ure.is_match(&message) {
if let Some(mat) = ure.find(&message) {
let slice = &message[mat.start()..mat.end()];
if let Some(entry) = cache.get(&slice.to_string()) {
let fin = format!("Title: {}", entry);
client.send_privmsg(&channel, fin)?;
} else {
let response = reqwest::get(slice).await;
if let Err(_e) = response {
client.send_privmsg(&channel, "Error: could not get title")?;
} else {
let body = response?.text().await?;
if let Some(title_mat) = titlefetch.find(&body) {
let title_raw = &body[title_mat.start()..title_mat.end()];
let result = treplace.replace_all(title_raw, "");
if let Ok(decoded) = decode_html(&result) {
let fin = format!("Title: {}", decoded.to_string());
client.send_privmsg(&channel, fin)?;
cache.insert(slice.to_string(), decoded.to_string());
} else {
// Send the raw result instead of decoding
let fin = format!("Title: {}", result.to_string());
client.send_privmsg(&channel, fin)?;
cache.insert(slice.to_string(), result.to_string());
}
}
}
}
}
}
}
}
}
Ok(())
}