Port sedbot (partially)

This commit is contained in:
lemonsh 2022-07-16 23:01:08 +02:00
parent dcbb530465
commit 324959faad
6 changed files with 60 additions and 78 deletions

View file

@ -21,10 +21,11 @@ serde = { version = "1.0", features = ["derive"] }
arrayvec = "0.7"
rand = "0.8"
meval = "0.2"
lazy_static = "1.4"
sedregex = "0.2"
rusqlite = { version = "0.28", features = ["bundled"] }
futures-util = "0.3"
irc = { version = "0.15", default-features = false, features = ["tls-rust"] }
async-trait = "0.1"
arg = "0.3"
[features]
# debug IRC commands
debug = []

View file

@ -1,64 +0,0 @@
use std::{error::Error, fmt::Display};
use arrayvec::{ArrayString, CapacityError};
use fancy_regex::Regex;
use lazy_static::lazy_static;
use sedregex::find_and_replace;
#[allow(clippy::module_name_repetitions)]
#[derive(Debug)]
pub enum SedError {
Capacity(CapacityError),
Regex(fancy_regex::Error),
SedRegex(sedregex::ErrorKind),
}
impl Display for SedError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Capacity(e) => e.fmt(f),
Self::Regex(e) => e.fmt(f),
Self::SedRegex(e) => e.fmt(f),
}
}
}
impl Error for SedError {}
impl<T> From<CapacityError<T>> for SedError {
fn from(e: CapacityError<T>) -> Self {
Self::Capacity(e.simplify())
}
}
impl From<fancy_regex::Error> for SedError {
fn from(e: fancy_regex::Error) -> Self {
Self::Regex(e)
}
}
impl From<sedregex::ErrorKind> for SedError {
fn from(e: sedregex::ErrorKind) -> Self {
Self::SedRegex(e)
}
}
type SedResult = Result<Option<ArrayString<512>>, SedError>;
pub fn resolve(prev_msg: &str, cmd: &str) -> SedResult {
lazy_static! {
static ref RE: Regex = Regex::new(r"^s/.*/.*").unwrap();
}
if RE.is_match(cmd)? {
return if let Some(mat) = RE.find(cmd)? {
let slice = &cmd[mat.start()..mat.end()];
let formatted = find_and_replace(prev_msg, [slice])?;
Ok(Some(ArrayString::from(&formatted)?))
} else {
Ok(None)
};
}
Ok(None)
}

View file

@ -2,11 +2,11 @@ use crate::bot::{Message, Command};
use async_trait::async_trait;
const HELP: &str = concat!(
"=- \x1d\x02Überbot\x0f ", env!("CARGO_PKG_VERSION"), " -=\n",
" * waifu <category>\n",
" * owo/mock/leet [user]\n",
" * ev <math expression>\n",
" - This bot also provides titles of URLs and details for Spotify URIs/links. It can also resolve sed expressions.\n"
"=- \x1d\x02Überbot\x0f ", env!("CARGO_PKG_VERSION"), " -=\r\n",
" * waifu <category>\r\n",
" * owo/mock/leet [user]\r\n",
" * ev <math expression>\r\n",
" - This bot also provides titles of URLs and details for Spotify URIs/links. It can also resolve sed expressions."
);
pub struct Help;

View file

@ -44,7 +44,7 @@ fn leetify(input: &str) -> ArrayString<512> {
let mut builder = ArrayString::<512>::new();
for ch in input.chars() {
builder.push(match ch {
builder.push(match ch.to_ascii_lowercase() {
'a' => '4',
'e' => '3',
'i' => '1',
@ -111,9 +111,9 @@ enum LeekCommand {
Mock,
}
fn execute_leek(cmd: LeekCommand, msg: &Message) -> anyhow::Result<String> {
async fn execute_leek(cmd: LeekCommand, msg: &Message<'_>) -> anyhow::Result<String> {
let nick = msg.content.unwrap_or(msg.author);
match msg.last_msg.get(nick) {
match msg.last_msg.read().await.get(nick) {
Some(msg) => Ok(match cmd {
LeekCommand::Owo => owoify(msg)?,
LeekCommand::Leet => leetify(msg),
@ -132,7 +132,7 @@ pub struct Mock;
impl Command for Owo {
//noinspection RsNeedlessLifetimes
async fn execute<'a>(&mut self, msg: Message<'a>) -> anyhow::Result<String> {
execute_leek(LeekCommand::Owo, &msg)
execute_leek(LeekCommand::Owo, &msg).await
}
}
@ -140,7 +140,7 @@ impl Command for Owo {
impl Command for Leet {
//noinspection RsNeedlessLifetimes
async fn execute<'a>(&mut self, msg: Message<'a>) -> anyhow::Result<String> {
execute_leek(LeekCommand::Leet, &msg)
execute_leek(LeekCommand::Leet, &msg).await
}
}
@ -148,6 +148,6 @@ impl Command for Leet {
impl Command for Mock {
//noinspection RsNeedlessLifetimes
async fn execute<'a>(&mut self, msg: Message<'a>) -> anyhow::Result<String> {
execute_leek(LeekCommand::Mock, &msg)
execute_leek(LeekCommand::Mock, &msg).await
}
}

39
src/commands/sed.rs Normal file
View file

@ -0,0 +1,39 @@
use async_trait::async_trait;
use fancy_regex::Captures;
use crate::bot::{Message, Trigger};
pub struct Sed;
#[async_trait]
impl Trigger for Sed {
async fn execute<'a>(&mut self, msg: Message<'a>, matches: Captures<'a>) -> anyhow::Result<String> {
let mut foreign_author;
let author = if let Some(author) = matches.name("u").map(|m| m.as_str()) {
foreign_author = true;
author
} else {
foreign_author = false;
msg.author
};
let lastmsg = msg.last_msg.read().await;
let message = if let Some(msg) = lastmsg.get(author) {
msg
} else {
return Ok("No previous messages found.".into());
};
if let (Some(find), Some(replace)) = (matches.name("r"), matches.name("w")) {
// TODO: karx plz add flags
//let flags = matches.name("f").map(|m| m.as_str());
let result = message.replace(find.as_str(), replace.as_str());
drop(lastmsg);
if foreign_author {
Ok(format!("(edited by {}) <{}> {}", msg.author, author, result))
} else {
msg.last_msg.write().await.insert(author.into(), result.to_string());
Ok(format!("<{}> {}", author, result))
}
} else {
Ok("Invalid usage.".into())
}
}
}

View file

@ -104,6 +104,12 @@ async fn main() -> anyhow::Result<()> {
bot.add_command("help".into(), Help);
bot.add_command("waifu".into(), Waifu);
bot.add_command("owo".into(), Owo);
bot.add_trigger(Regex::new(r"^(?:(?<u>\S+):\s+)?s/(?<r>[^/]*)/(?<w>[^/]*)(?:/(?<f>[a-z]*))?\s*")?, Sed);
#[cfg(feature = "debug")]
{
use commands::debug::*;
bot.add_command("lastmsg".into(), LastMsg);
}
let state = AppState {
client: client.clone(),