From 683a9d94a4592cddaab3d12a87a63ad1e569e70b Mon Sep 17 00:00:00 2001 From: Max batleforc Date: Fri, 21 Jun 2024 11:13:18 +0200 Subject: [PATCH] feat: handler add_keyword, set_periode and init start/stop/end concour --- src/botv2/cmd/concour/concour.rs | 119 ++++++++++++++++++++++ src/botv2/cmd/concour/mod.rs | 1 + src/botv2/domain/concour/add_keyword.rs | 84 +++++++++++++++ src/botv2/domain/concour/end_concour.rs | 49 +++++++++ src/botv2/domain/concour/mod.rs | 5 + src/botv2/domain/concour/set_periode.rs | 47 +++++++++ src/botv2/domain/concour/start_concour.rs | 49 +++++++++ src/botv2/domain/concour/stop_concour.rs | 49 +++++++++ src/botv2/init.rs | 13 ++- 9 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 src/botv2/cmd/concour/concour.rs create mode 100644 src/botv2/domain/concour/add_keyword.rs create mode 100644 src/botv2/domain/concour/end_concour.rs create mode 100644 src/botv2/domain/concour/set_periode.rs create mode 100644 src/botv2/domain/concour/start_concour.rs create mode 100644 src/botv2/domain/concour/stop_concour.rs diff --git a/src/botv2/cmd/concour/concour.rs b/src/botv2/cmd/concour/concour.rs new file mode 100644 index 0000000..c7b4432 --- /dev/null +++ b/src/botv2/cmd/concour/concour.rs @@ -0,0 +1,119 @@ +use crate::botv2::{ + domain::concour::{ + check_if_allowed::check_if_concour_allowed, get_channel_concour::get_channel_concour, + }, + init::{Context, Error}, +}; +use poise::{ + serenity_prelude::{model::colour, CreateEmbed, CreateEmbedFooter, Mentionable, RoleId}, + CreateReply, +}; +use tracing::instrument; + +/// Show concour in the current channel (alias of get) +#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))] +#[poise::command( + slash_command, + prefix_command, + category = "concour", + subcommands("get"), + guild_only = true +)] +pub async fn concour( + ctx: Context<'_>, + #[description = "Reponse cacher ?"] ephemeral: Option, +) -> Result<(), Error> { + concour_get(ctx, ephemeral).await +} + +/// Show concour in the current channel +#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))] +#[poise::command( + slash_command, + prefix_command, + category = "server_config", + guild_only = true +)] +pub async fn get( + ctx: Context<'_>, + #[description = "Reponse cacher ?"] ephemeral: Option, +) -> Result<(), Error> { + concour_get(ctx, ephemeral).await +} + +#[instrument(skip(ctx), level = "info")] +async fn concour_get(ctx: Context<'_>, ephemeral: Option) -> Result<(), Error> { + let guild = match ctx.guild_id() { + Some(guild) => guild, + None => return Ok(()), + }; + let entity_name = ctx.data().entity_name.clone(); + let footer = CreateEmbedFooter::new(entity_name.clone()); + match check_if_concour_allowed(guild.get()).await { + Ok((ok, _)) => { + if !ok { + let embed = CreateEmbed::new() + .title("The concour feature is disabled on this server, please contact your administrator") + .color(colour::Color::RED) + .footer(footer); + if let Err(why) = ctx + .send(CreateReply::default().embed(embed).ephemeral(true)) + .await + { + tracing::error!("Error sending message: {:?}", why); + } + return Ok(()); + } + } + Err(_) => { + let embed = CreateEmbed::new() + .title("Error while fetching server config") + .field("Please contact your administrator", "", false) + .field("Your config is possibly not initied correctly", "", false) + .color(colour::Color::RED) + .footer(footer); + if let Err(why) = ctx + .send(CreateReply::default().embed(embed).ephemeral(true)) + .await + { + tracing::error!("Error sending message: {:?}", why); + } + return Ok(()); + } + }; + let concour = match get_channel_concour(guild.get(), ctx.channel_id().get()).await { + Ok(concour) => { + if let Some(concour) = concour { + CreateEmbed::new() + .title("Concour") + .field("Title", &concour.title, false) + .field("Description", &concour.description, false) + .field("Start date", &concour.start_date.to_string(), false) + .field("Periode", &concour.periode.to_string(), false) + .field( + "Role récompense", + RoleId::new(concour.role_recompense).mention().to_string(), + false, + ) + .color(colour::Color::DARK_GREEN) + } else { + CreateEmbed::new() + .title("No concour found in this channel") + .color(colour::Color::DARK_GREEN) + } + } + Err(_) => CreateEmbed::new() + .title("Error while fetching concour") + .field("Please contact your administrator", "", false) + .field("Your concour is possibly not initied correctly", "", false) + .color(colour::Color::RED), + }; + let mut builder = CreateReply::default().embed(concour.footer(footer)); + if ephemeral.unwrap_or(true) { + builder = builder.ephemeral(true); + } + if let Err(why) = ctx.send(builder).await { + tracing::error!("Error sending message: {:?}", why); + } + Ok(()) +} diff --git a/src/botv2/cmd/concour/mod.rs b/src/botv2/cmd/concour/mod.rs index e69de29..20b5f63 100644 --- a/src/botv2/cmd/concour/mod.rs +++ b/src/botv2/cmd/concour/mod.rs @@ -0,0 +1 @@ +pub mod concour; diff --git a/src/botv2/domain/concour/add_keyword.rs b/src/botv2/domain/concour/add_keyword.rs new file mode 100644 index 0000000..791cdd0 --- /dev/null +++ b/src/botv2/domain/concour/add_keyword.rs @@ -0,0 +1,84 @@ +use serde::{Deserialize, Serialize}; +use tracing::{info, instrument}; + +use crate::db::concour::Concour; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum AddKeywordConcourError { + DoesntExist, + FindError(String), + UnknownError(String), +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum KeyWordSource { + /// Fetch content from url and add to keywords, if delimiter is provided split the content with the delimiter either use \n + Url(String, Option), + /// Add text to keywords, if delimiter is provided split the content with the delimiter either use \n + Text(String, Option), +} + +/// Add keyword to concour +#[instrument(level = "info")] +pub async fn add_keyword_concour( + server_id: u64, + channel_id: u64, + keywordlist: KeyWordSource, +) -> Result, AddKeywordConcourError> { + let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await { + Ok(list_concour) => list_concour, + Err(err) => { + tracing::error!(error = err.to_string(), "Error finding concour"); + return Err(AddKeywordConcourError::UnknownError( + "Error finding concour".to_string(), + )); + } + }; + + if concour.is_none() { + info!("Concour doesn't exist"); + return Err(AddKeywordConcourError::DoesntExist); + } + + let mut concour = concour.unwrap(); + + match keywordlist { + KeyWordSource::Url(url, delimiter) => { + // Check if url is valid + // if valid fetch the content and add to keywords + match reqwest::get(url.clone()).await { + Ok(res) => { + let text = res.text().await.unwrap(); + let split_delimiter = delimiter.unwrap_or("\n".to_string()); + text.split(&split_delimiter).into_iter().for_each(|x| { + concour.keywords.push(x.to_string()); + }); + } + Err(err) => { + tracing::error!(error = err.to_string(), "Error fetching url"); + return Err(AddKeywordConcourError::UnknownError( + "Error fetching url".to_string(), + )); + } + } + concour.keywords.push(url); + } + KeyWordSource::Text(text, delimiter) => { + let split_delimiter = delimiter.unwrap_or("\n".to_string()); + text.split(&split_delimiter).into_iter().for_each(|x| { + concour.keywords.push(x.to_string()); + }); + } + } + + match concour.update().await { + Ok(_) => {} + Err(err) => { + tracing::error!(error = err.to_string(), "Error updating concour"); + return Err(AddKeywordConcourError::UnknownError( + "Error updating concour".to_string(), + )); + } + } + Ok(Some(concour)) +} diff --git a/src/botv2/domain/concour/end_concour.rs b/src/botv2/domain/concour/end_concour.rs new file mode 100644 index 0000000..aac532b --- /dev/null +++ b/src/botv2/domain/concour/end_concour.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize, Serialize}; +use tracing::{info, instrument}; + +use crate::db::concour::Concour; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum EndConcourError { + DoesntExist, + FindError(String), + UnknownError(String), +} + +#[instrument(level = "info")] +pub async fn end_concour( + server_id: u64, + channel_id: u64, +) -> Result, EndConcourError> { + let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await { + Ok(list_concour) => list_concour, + Err(err) => { + tracing::error!(error = err.to_string(), "Error finding concour"); + return Err(EndConcourError::UnknownError( + "Error finding concour".to_string(), + )); + } + }; + + if concour.is_none() { + info!("Concour doesn't exist"); + return Err(EndConcourError::DoesntExist); + } + + let mut concour = concour.unwrap(); + + // Update status to Finished + + todo!("Setup logic to end the waiting period for the concour"); + + match concour.update().await { + Ok(_) => {} + Err(err) => { + tracing::error!(error = err.to_string(), "Error updating concour"); + return Err(EndConcourError::UnknownError( + "Error updating concour".to_string(), + )); + } + } + Ok(Some(concour)) +} diff --git a/src/botv2/domain/concour/mod.rs b/src/botv2/domain/concour/mod.rs index 4e0c63a..ab97e2d 100644 --- a/src/botv2/domain/concour/mod.rs +++ b/src/botv2/domain/concour/mod.rs @@ -1,5 +1,10 @@ +pub mod add_keyword; pub mod check_if_allowed; pub mod create_concour; +pub mod end_concour; pub mod get_channel_concour; pub mod list_concour; +pub mod set_periode; +pub mod start_concour; +pub mod stop_concour; pub mod update_concour; diff --git a/src/botv2/domain/concour/set_periode.rs b/src/botv2/domain/concour/set_periode.rs new file mode 100644 index 0000000..46bdfdf --- /dev/null +++ b/src/botv2/domain/concour/set_periode.rs @@ -0,0 +1,47 @@ +use serde::{Deserialize, Serialize}; +use tracing::{info, instrument}; + +use crate::db::concour::Concour; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum SetPeriodeConcourError { + DoesntExist, + FindError(String), + UnknownError(String), +} + +#[instrument(level = "info")] +pub async fn set_periode( + server_id: u64, + channel_id: u64, + periode: time::Duration, +) -> Result, SetPeriodeConcourError> { + let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await { + Ok(list_concour) => list_concour, + Err(err) => { + tracing::error!(error = err.to_string(), "Error finding concour"); + return Err(SetPeriodeConcourError::UnknownError( + "Error finding concour".to_string(), + )); + } + }; + + if concour.is_none() { + info!("Concour doesn't exist"); + return Err(SetPeriodeConcourError::DoesntExist); + } + + let mut concour = concour.unwrap(); + concour.periode = periode; + + match concour.update().await { + Ok(_) => {} + Err(err) => { + tracing::error!(error = err.to_string(), "Error updating concour"); + return Err(SetPeriodeConcourError::UnknownError( + "Error updating concour".to_string(), + )); + } + } + Ok(Some(concour)) +} diff --git a/src/botv2/domain/concour/start_concour.rs b/src/botv2/domain/concour/start_concour.rs new file mode 100644 index 0000000..e3de29a --- /dev/null +++ b/src/botv2/domain/concour/start_concour.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize, Serialize}; +use tracing::{info, instrument}; + +use crate::db::concour::Concour; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum StartConcourError { + DoesntExist, + FindError(String), + UnknownError(String), +} + +#[instrument(level = "info")] +pub async fn start_concour( + server_id: u64, + channel_id: u64, +) -> Result, StartConcourError> { + let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await { + Ok(list_concour) => list_concour, + Err(err) => { + tracing::error!(error = err.to_string(), "Error finding concour"); + return Err(StartConcourError::UnknownError( + "Error finding concour".to_string(), + )); + } + }; + + if concour.is_none() { + info!("Concour doesn't exist"); + return Err(StartConcourError::DoesntExist); + } + + let mut concour = concour.unwrap(); + + // Update status to started + + todo!("Setup logic to start the waiting period for the concour"); + + match concour.update().await { + Ok(_) => {} + Err(err) => { + tracing::error!(error = err.to_string(), "Error updating concour"); + return Err(StartConcourError::UnknownError( + "Error updating concour".to_string(), + )); + } + } + Ok(Some(concour)) +} diff --git a/src/botv2/domain/concour/stop_concour.rs b/src/botv2/domain/concour/stop_concour.rs new file mode 100644 index 0000000..805946e --- /dev/null +++ b/src/botv2/domain/concour/stop_concour.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize, Serialize}; +use tracing::{info, instrument}; + +use crate::db::concour::Concour; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum StopConcourError { + DoesntExist, + FindError(String), + UnknownError(String), +} + +#[instrument(level = "info")] +pub async fn stop_concour( + server_id: u64, + channel_id: u64, +) -> Result, StopConcourError> { + let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await { + Ok(list_concour) => list_concour, + Err(err) => { + tracing::error!(error = err.to_string(), "Error finding concour"); + return Err(StopConcourError::UnknownError( + "Error finding concour".to_string(), + )); + } + }; + + if concour.is_none() { + info!("Concour doesn't exist"); + return Err(StopConcourError::DoesntExist); + } + + let mut concour = concour.unwrap(); + + // Update status to Paused + + todo!("Setup logic to stop the waiting period for the concour"); + + match concour.update().await { + Ok(_) => {} + Err(err) => { + tracing::error!(error = err.to_string(), "Error updating concour"); + return Err(StopConcourError::UnknownError( + "Error updating concour".to_string(), + )); + } + } + Ok(Some(concour)) +} diff --git a/src/botv2/init.rs b/src/botv2/init.rs index 7961ecf..f2bf7f9 100644 --- a/src/botv2/init.rs +++ b/src/botv2/init.rs @@ -10,6 +10,8 @@ use std::sync::Arc; use tokio::sync::oneshot; use tracing::{info, instrument}; +use super::cmd::concour::concour::concour; + pub struct Data { pub config_img: ConfigFile, pub config: Config, @@ -59,7 +61,16 @@ pub async fn start_bot(config: Config, rx: oneshot::Receiver<()>) -> Arc { let prefix = config.prefix.clone(); let framework = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![age(), ping(), help(), list(), enable(), answer(), server()], + commands: vec![ + age(), + ping(), + help(), + list(), + enable(), + answer(), + server(), + concour(), + ], prefix_options: poise::PrefixFrameworkOptions { prefix: Some(prefix), ..Default::default()