diff options
author | Cara Salter <cara@devcara.com> | 2022-05-03 13:57:09 -0400 |
---|---|---|
committer | Cara Salter <cara@devcara.com> | 2022-05-03 13:57:09 -0400 |
commit | 5999e6a803a7b848acf054918fec9ee5024d5697 (patch) | |
tree | eae1f3986c41f7d7c1a956e4606a8120c6032e05 /src/commands/filters.rs | |
parent | 8f4277c55a2079edf1c9a69383c353e1cb9ef55c (diff) | |
download | glitch-ng-5999e6a803a7b848acf054918fec9ee5024d5697.tar.gz glitch-ng-5999e6a803a7b848acf054918fec9ee5024d5697.zip |
filter: Initial message filter implementation
Also a custom error type, tracing_subscriber, and unsafe impls
Diffstat (limited to 'src/commands/filters.rs')
-rw-r--r-- | src/commands/filters.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/commands/filters.rs b/src/commands/filters.rs new file mode 100644 index 0000000..35fefac --- /dev/null +++ b/src/commands/filters.rs @@ -0,0 +1,82 @@ +use crate::{Context, Error, models::{FilterAction, MessageFilter}}; +use poise::{serenity_prelude as serenity, AutocompleteChoice}; + +use std::str::FromStr; + +use futures::{Stream, StreamExt}; + +/// Base command for all filter actions +/// +/// Provides a CRUD interface for managing automatic message filters +#[poise::command(slash_command, prefix_command)] +pub async fn filter(ctx: Context<'_>) -> Result<(), Error> { + Ok(()) +} + +/// Lists message filters +/// +/// Usage: +/// filter list +#[poise::command(slash_command, ephemeral, prefix_command)] +pub async fn list(ctx: Context<'_>) -> Result<(), Error> { + let pool = ctx.data().pg.lock().unwrap().clone(); + + let filters = sqlx::query_as::<_, MessageFilter>("SELECT * FROM message_filter WHERE guild_id=$1").bind(ctx.guild().unwrap().id.0.to_string()) + .fetch_all(&pool).await?; + + let mut list = String::from(""); + if filters.len() == 0 { + list = "No filters set, try adding one with `/filter add`!".to_string(); + } else { + for f in filters { + list.push_str(&format!("{}\n", f.to_string())); + } + } + + ctx.send(|m| { + m.embed(|e| { + e.title("Message Filter List"); + e.description(list); + e + }) + }).await?; + Ok(()) +} + +/// Creates a new message filter +/// +/// Usage: +/// filter add <pattern> <action> +/// +/// Where <action> is one of "review" or "delete" +#[poise::command(slash_command, ephemeral, prefix_command)] +pub async fn add(ctx: Context<'_>, + #[description = "The regular expression to match against"] + regex: String, + #[description = "The action to take when the expression is matched"] + #[autocomplete = "ac_action"] + action: String, + ) -> Result<(), Error> { + + let pool = ctx.data().pg.lock().unwrap().clone(); + + let action = FilterAction::from_str(&action)?; + + sqlx::query("INSERT INTO message_filter (pattern, action, guild_id) VALUES ($1, $2, $3)") + .bind(regex) + .bind(action as FilterAction) + .bind(ctx.guild().unwrap().id.0.to_string()) + .execute(&pool) + .await?; + + ctx.say("Sounds good! I've written that down and will keep a close eye out").await?; + + Ok(()) +} + + +async fn ac_action(_ctx: Context<'_>, partial: String) -> impl Stream<Item = String> { + futures::stream::iter(&["review", "delete"]) + .filter(move |name| futures::future::ready(name.starts_with(&partial))) + .map(|name| name.to_string()) +} |