diff --git a/libs/bot/src/trivia/config.rs b/libs/bot/src/trivia/config.rs index dabaff3..dfb670c 100644 --- a/libs/bot/src/trivia/config.rs +++ b/libs/bot/src/trivia/config.rs @@ -138,8 +138,10 @@ pub async fn config( } } - let optimize_querry = format!("OPTIMIZE TABLE {} FINAL", Trivial::table_name()); - if let Err(e) = manager.execute_with_retry(&optimize_querry).await { + if let Err(e) = manager + .execute_with_retry(&Trivial::optimize_table_sql()) + .await + { tracing::error!("Failed to optimize trivia table: {}", e); } else { info!("Trivia table optimized successfully."); diff --git a/libs/bot/src/trivia/mod.rs b/libs/bot/src/trivia/mod.rs index 3b50348..739f186 100644 --- a/libs/bot/src/trivia/mod.rs +++ b/libs/bot/src/trivia/mod.rs @@ -1,11 +1,13 @@ pub mod config; pub mod create; pub mod list; +pub mod status; use crate::{Context, Error}; use config::config; use create::create; use list::list; +use status::status; use tracing::instrument; /// Handle trivia command @@ -14,7 +16,7 @@ use tracing::instrument; slash_command, prefix_command, category = "Trivia", - subcommands("create", "list", "config"), + subcommands("create", "list", "config", "status"), guild_only = true )] pub async fn trivia(ctx: Context<'_>) -> Result<(), Error> { diff --git a/libs/bot/src/trivia/status.rs b/libs/bot/src/trivia/status.rs new file mode 100644 index 0000000..7b0c9a1 --- /dev/null +++ b/libs/bot/src/trivia/status.rs @@ -0,0 +1,126 @@ +use crate::helper::is_user_admin_right; +use crate::{Context, Error}; +use clickhouse_pool::traits::Model; +use database::trivial::{Trivial, TrivialStatus}; +use poise::serenity_prelude::Channel; +use tracing::{debug, info, instrument}; + +/// Get or set the status of an existing trivia game +#[instrument(name = "trivia_status", skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))] +#[poise::command( + prefix_command, + slash_command, + guild_only, + category = "Trivia", + check = "is_user_admin_right" +)] +pub async fn status( + ctx: Context<'_>, + #[description = "Channel of the trivia game, or current"] channel_id: Option, + #[description = "Whether to start/stop the trivia game"] enabled: Option, +) -> Result<(), Error> { + let guild_id = match ctx.guild_id() { + Some(id) => id.get(), + None => { + ctx.say("This command can only be used in a server.") + .await?; + return Ok(()); + } + }; + let channel_id = match channel_id { + Some(c) => c.id().get(), + None => { + info!("No channel specified, using current channel."); + ctx.channel_id().get() + } + }; + + let manager = ctx.data().datalake_config.clone(); + let search_query = Trivial::build_select_query( + Some(&format!( + "channel_id = {} and guild_id = {}", + channel_id, guild_id + )), + None, + None, + ); + + let mut trivia_exists: Trivial = match manager + .execute_select_with_retry::(&search_query) + .await + { + Ok(trivia) => { + if trivia.is_empty() { + ctx.say("No trivia game found in this channel. Please create one first.") + .await?; + return Ok(()); + } + trivia.into_iter().next().unwrap() + } + Err(e) => { + debug!("Error while searching for trivia game: {}", e); + ctx.say("An error occurred while searching for the trivia game.") + .await?; + return Ok(()); + } + }; + + if let Some(enabled) = enabled { + let mut inserter = match manager.get_insert::(Trivial::table_name()).await { + Ok(inserter) => inserter, + Err(e) => { + tracing::error!("Failed to create inserter for Trivial: {}", e); + ctx.say("Failed to update trivia game. Please try again later.") + .await?; + return Ok(()); + } + }; + + trivia_exists.sign = -1; // Set sign to -1 to indicate an update + inserter.write(&trivia_exists.clone()).await?; + trivia_exists.status = if enabled { + TrivialStatus::Started + } else { + TrivialStatus::Paused + }; + trivia_exists.sign = 1; // Set sign to 1 to indicate a status change + inserter.write(&trivia_exists.clone()).await?; + match inserter.end().await { + Ok(_) => { + info!( + "Trivia game '{}' updated successfully in channel <#{}>.", + trivia_exists.name, channel_id + ); + ctx.say(format!("Trivia game status updated to: {}", enabled)) + .await?; + } + Err(e) => { + tracing::error!("Failed to update trivia game: {}", e); + ctx.say("Failed to update trivia game. Please try again later.") + .await?; + return Ok(()); + } + } + + if let Err(e) = manager + .execute_with_retry(&Trivial::optimize_table_sql()) + .await + { + tracing::error!("Failed to optimize trivia table: {}", e); + } else { + info!("Trivia table optimized successfully."); + } + } else { + ctx.say(format!( + "Trivia game is currently {}.", + if trivia_exists.status == TrivialStatus::Started { + "Started" + } else { + "Paused" + } + )) + .await?; + } + + Ok(()) +}