From 1b31ca39b483f35cc0633611a52d5bd9e5f9fb20 Mon Sep 17 00:00:00 2001 From: Xyon Date: Fri, 13 Jun 2025 02:26:01 +0000 Subject: [PATCH] drop locks before holding pagination timeouts --- src/badgey/commands/custom_responses.rs | 179 ++++++++++++------------ 1 file changed, 91 insertions(+), 88 deletions(-) diff --git a/src/badgey/commands/custom_responses.rs b/src/badgey/commands/custom_responses.rs index fdd3fb5..274c744 100644 --- a/src/badgey/commands/custom_responses.rs +++ b/src/badgey/commands/custom_responses.rs @@ -1,88 +1,91 @@ -use poise::serenity_prelude as serenity; - -use manifold::error::{ManifoldError, ManifoldResult}; -use manifold::{ManifoldContext, ManifoldData}; -use poise::serenity_prelude::{CreateEmbed, Mentionable}; -use url::Url; -use crate::badgey::models::custom_response::{CustomResponse, CustomResponseInserter}; - - -#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS" )] -async fn add_custom_response(ctx: ManifoldContext<'_>, target: serenity::User, trigger: String, response: String) -> ManifoldResult<()> { - let db = &ctx.data().database; - - match CustomResponseInserter::new(trigger, response, target, ctx.author().clone()).insert(db) { - Ok(_) => ctx.reply(t!("commands.custom_response.added")).await?, - Err(e) => ctx.reply(t!("commands.custom_response.added.error", error = e)).await?, - }; - - Ok(()) -} - -#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] -async fn remove_custom_response(ctx: ManifoldContext<'_>, id: i32) -> ManifoldResult<()> { - let db = &ctx.data().database; - - let mut response = CustomResponse::find_by_id(db, &id)?; - - response.deleted = Some(true); - response.insert(db)?; - - ctx.reply(t!("commands.custom_response.marked_deleted", response_id=id)).await?; - - Ok(()) -} - -#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] -async fn undelete_custom_response(ctx: ManifoldContext<'_>, id: i32) -> ManifoldResult<()> { - let db = &ctx.data().database; - - let mut response = CustomResponse::find_by_id(db, &id)?; - - if let Some(_) = response.deleted { - response.deleted = None; - response.insert(db)?; - ctx.reply(t!("commands.custom_response.marked_undeleted", response_id=id)).await?; - } else { - ctx.reply(t!("commands.custom_response.undelete_error_not_deleted", response_id=id)).await?; - } - - Ok(()) -} - -#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] -async fn list_custom_responses_for_user(ctx: ManifoldContext<'_>, target: serenity::User) -> ManifoldResult<()> { - let db = &ctx.data().database; - let userinfo = &ctx.data().user_info.lock().await; - - let reply_handle = ctx.reply("Retrieving custom responses, please stand by...".to_string()).await?; - let mut pages = Vec::::new(); - let responses = CustomResponse::find_by_user(db, &target)?; - let total = responses.len(); - - responses.iter().enumerate().for_each(|(i, f)| { - pages.push(CreateEmbed::default() - .title(format!("Custom Response {item} of {total} for user {target}", item=(i + 1), total=&total, target=target.name)) - .description(format!("Added by {added_by} on ()", added_by=userinfo.get(&(f.added_by as u64)).unwrap().username, added_on=f.added_on)) - .field("ID", format!("{id}", id=f.id), true) - .field("Deleted", format!("{deleted}", deleted=(if f.deleted.unwrap_or(false) {"yes"} else {"no"})), true) - .field("Trigger", format!("{trigger}", trigger=f.trigger), true) - .field("Response", format!("{response}", response=f.response), false) - .image(format!("{response}", response=Url::parse(&*f.response).unwrap_or("https://example.com".parse().unwrap()))) - .to_owned() - ) - }); - - if pages.len() == 0 { - ctx.reply(format!("No custom responses found for {target}", target=target.mention())).await?; - return Ok(()) - } - - manifold::helpers::paginate(ctx, reply_handle, pages, 0).await?; - - Ok(()) -} - -pub fn commands() -> [poise::Command; 4] { - [add_custom_response(), remove_custom_response(), undelete_custom_response(), list_custom_responses_for_user()] -} +use poise::serenity_prelude as serenity; + +use manifold::error::{ManifoldError, ManifoldResult}; +use manifold::{ManifoldContext, ManifoldData}; +use poise::serenity_prelude::{CreateEmbed, Mentionable}; +use url::Url; +use crate::badgey::models::custom_response::{CustomResponse, CustomResponseInserter}; + + +#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS" )] +async fn add_custom_response(ctx: ManifoldContext<'_>, target: serenity::User, trigger: String, response: String) -> ManifoldResult<()> { + let db = &ctx.data().database; + + match CustomResponseInserter::new(trigger, response, target, ctx.author().clone()).insert(db) { + Ok(_) => ctx.reply(t!("commands.custom_response.added")).await?, + Err(e) => ctx.reply(t!("commands.custom_response.added.error", error = e)).await?, + }; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] +async fn remove_custom_response(ctx: ManifoldContext<'_>, id: i32) -> ManifoldResult<()> { + let db = &ctx.data().database; + + let mut response = CustomResponse::find_by_id(db, &id)?; + + response.deleted = Some(true); + response.insert(db)?; + + ctx.reply(t!("commands.custom_response.marked_deleted", response_id=id)).await?; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] +async fn undelete_custom_response(ctx: ManifoldContext<'_>, id: i32) -> ManifoldResult<()> { + let db = &ctx.data().database; + + let mut response = CustomResponse::find_by_id(db, &id)?; + + if let Some(_) = response.deleted { + response.deleted = None; + response.insert(db)?; + ctx.reply(t!("commands.custom_response.marked_undeleted", response_id=id)).await?; + } else { + ctx.reply(t!("commands.custom_response.undelete_error_not_deleted", response_id=id)).await?; + } + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")] +async fn list_custom_responses_for_user(ctx: ManifoldContext<'_>, target: serenity::User) -> ManifoldResult<()> { + let db = &ctx.data().database; + let userinfo = &ctx.data().user_info.lock().await; + + let reply_handle = ctx.reply("Retrieving custom responses, please stand by...".to_string()).await?; + let mut pages = Vec::::new(); + let responses = CustomResponse::find_by_user(db, &target)?; + let total = responses.len(); + + responses.iter().enumerate().for_each(|(i, f)| { + pages.push(CreateEmbed::default() + .title(format!("Custom Response {item} of {total} for user {target}", item=(i + 1), total=&total, target=target.name)) + .description(format!("Added by {added_by} on ()", added_by=userinfo.get(&(f.added_by as u64)).unwrap().username, added_on=f.added_on)) + .field("ID", format!("{id}", id=f.id), true) + .field("Deleted", format!("{deleted}", deleted=(if f.deleted.unwrap_or(false) {"yes"} else {"no"})), true) + .field("Trigger", format!("{trigger}", trigger=f.trigger), true) + .field("Response", format!("{response}", response=f.response), false) + .image(format!("{response}", response=Url::parse(&*f.response).unwrap_or("https://example.com".parse().unwrap()))) + .to_owned() + ) + }); + + if pages.len() == 0 { + ctx.reply(format!("No custom responses found for {target}", target=target.mention())).await?; + return Ok(()) + } + + drop(db); + drop(userinfo); + + manifold::helpers::paginate(ctx, reply_handle, pages, 0).await?; + + Ok(()) +} + +pub fn commands() -> [poise::Command; 4] { + [add_custom_response(), remove_custom_response(), undelete_custom_response(), list_custom_responses_for_user()] +}