feat: setup logique pour remonter les cronjob si l'application redemarre

This commit is contained in:
Max batleforc 2024-06-25 03:17:32 +02:00
parent ecadf7a90d
commit 9c21b0dfdf
No known key found for this signature in database
GPG Key ID: 25D243AB4B6AC9E7
5 changed files with 121 additions and 56 deletions

View File

@ -58,61 +58,67 @@ pub async fn start(ctx: Context<'_>) -> Result<(), Error> {
}
};
let (concour, success) =
match start_concour(guild.get(), ctx.channel_id().get(), &mut cron_schedule).await {
Ok(concour) => {
if concour.is_none() {
(
CreateEmbed::new()
.title("No concour created")
.color(colour::Color::RED),
let (concour, success) = match start_concour(
guild.get(),
ctx.channel_id().get(),
&mut cron_schedule,
ctx.http(),
)
.await
{
Ok(concour) => {
if concour.is_none() {
(
CreateEmbed::new()
.title("No concour created")
.color(colour::Color::RED),
false,
)
} else {
let concour = concour.unwrap();
let keyword_index = concour.index_keyword as usize;
let keyword = concour.keywords.get(keyword_index).unwrap();
let output = CreateEmbed::new()
.title(format!(
"Concour: {} Jour : {}",
concour.title,
concour.index_keyword + 1
))
.description(concour.description)
.field("Mot du jours ", keyword.to_string(), false)
.field("Good luck !", "", false)
.field(
"Vous avez jusqu'a demain 17h",
"HARD CODED FOR THE MOMENT",
false,
)
} else {
let concour = concour.unwrap();
let keyword_index = concour.index_keyword as usize;
let keyword = concour.keywords.get(keyword_index).unwrap();
let output = CreateEmbed::new()
.title(format!(
"Concour: {} Jour : {}",
concour.title,
concour.index_keyword + 1
))
.description(concour.description)
.field("Mot du jours ", keyword.to_string(), false)
.field("Good luck !", "", false)
.field(
"Vous avez jusqu'a demain 17h",
"HARD CODED FOR THE MOMENT",
false,
)
.color(colour::Color::DARK_GREEN);
(output, true)
}
.color(colour::Color::DARK_GREEN);
(output, true)
}
Err(err) => (
match err {
StartConcourError::AlreadyOnGoing => CreateEmbed::new()
.title("Concour already OnGoing")
.color(colour::Color::RED),
StartConcourError::DoesntExist => CreateEmbed::new()
.title("Concour doesn't exist")
.color(colour::Color::RED),
StartConcourError::KeyWordListEmpty => CreateEmbed::new()
.title("Keyword list empty")
.color(colour::Color::RED),
StartConcourError::FinishedKeyWordList => CreateEmbed::new()
.title("Finished keyword list, add new one")
.color(colour::Color::RED),
_ => CreateEmbed::new()
.title("Error while creating concour")
.field("Please contact your administrator", "", false)
.field("Your concour is possibly not initied correctly", "", false)
.color(colour::Color::RED),
},
false,
),
};
}
Err(err) => (
match err {
StartConcourError::AlreadyOnGoing => CreateEmbed::new()
.title("Concour already OnGoing")
.color(colour::Color::RED),
StartConcourError::DoesntExist => CreateEmbed::new()
.title("Concour doesn't exist")
.color(colour::Color::RED),
StartConcourError::KeyWordListEmpty => CreateEmbed::new()
.title("Keyword list empty")
.color(colour::Color::RED),
StartConcourError::FinishedKeyWordList => CreateEmbed::new()
.title("Finished keyword list, add new one")
.color(colour::Color::RED),
_ => CreateEmbed::new()
.title("Error while creating concour")
.field("Please contact your administrator", "", false)
.field("Your concour is possibly not initied correctly", "", false)
.color(colour::Color::RED),
},
false,
),
};
let mut builder = CreateReply::default().ephemeral(!success);
builder = builder.embed(concour.footer(footer));
match ctx.send(builder).await {

View File

@ -1,3 +1,4 @@
use poise::serenity_prelude::Http;
use serde::{Deserialize, Serialize};
use tracing::{info, instrument};
@ -16,11 +17,12 @@ pub enum StartConcourError {
UnknownError(String),
}
#[instrument(level = "info", skip(cron_scheduler))]
#[instrument(level = "info", skip(cron_scheduler, http))]
pub async fn start_concour(
server_id: u64,
channel_id: u64,
cron_scheduler: &mut ScheduleJob,
http: &Http,
) -> Result<Option<Concour>, StartConcourError> {
let concour = match Concour::find_by_server_id_channel_id(&server_id, &channel_id).await {
Ok(list_concour) => list_concour,
@ -51,7 +53,7 @@ pub async fn start_concour(
return Err(StartConcourError::AlreadyOnGoing);
}
match cron_scheduler
.add_concour_cron_job(server_id, channel_id, "*/1 * * * * *".to_string())
.add_concour_cron_job(server_id, channel_id, "*/1 * * * * *".to_string(), http)
.await
{
Ok(_) => {}

View File

@ -181,7 +181,6 @@ impl Concour {
};
Ok(Some(concour))
}
#[instrument(level = "info")]
pub async fn find_by_server_id(server_id: &u64) -> Result<Vec<Concour>, surrealdb::Error> {
let sql = format!("SELECT * FROM {} WHERE server_id = {}", CONCOUR, server_id);
let mut results = match DB.query(&sql).await {

View File

@ -1,3 +1,4 @@
use poise::serenity_prelude::Http;
use std::{
collections::HashMap,
fmt::{self, Display},
@ -8,6 +9,8 @@ use tokio_cron_scheduler::{Job, JobScheduler};
use tracing::{error, info, instrument};
use uuid::Uuid;
use crate::db::concour::{Concour, ConcourStatus};
#[derive(Debug)]
pub enum StopScheduleJob {
JobNotFound,
@ -58,6 +61,37 @@ impl ScheduleJob {
}
}
#[instrument(skip(self, http), level = "info")]
pub async fn load_all_concour_cron_job(&mut self, http: &Http) -> Result<(), bool> {
let concours = match Concour::find_by_status(&ConcourStatus::OnGoing).await {
Ok(concour) => concour,
Err(e) => {
error!("Error getting concour: {:?}", e);
return Err(true);
}
};
for concour in concours {
match self
.add_concour_cron_job(
concour.server_id,
concour.channel_id,
"0 0 17 * * *".to_string(),
http,
)
.await
{
Ok(_) => {
info!("Concour cron job added");
}
Err(_) => {
error!("Error adding concour cron job");
return Err(true);
}
}
}
Ok(())
}
#[instrument(skip(self), level = "info")]
pub async fn stop_cron_scheduler(&mut self) -> &mut Self {
let job_id = self.job_id.write().await;
@ -90,15 +124,27 @@ impl ScheduleJob {
}
}
#[instrument(skip(self), level = "info")]
#[instrument(skip(self, _http), level = "info")]
pub async fn add_concour_cron_job(
&mut self,
server_id: u64,
channel_id: u64,
cron_expression: String,
_http: &Http,
) -> Result<Uuid, ()> {
let job = match Job::new_async(cron_expression.as_str(), |uuid, _l| {
Box::pin(async move {
// Send the message to announce the end of the concour
// Get concour data
// Get All message since the announcement
// filter out the bot's message
// count the number of reactions per message
// get the user comment with the highest reaction
// announce the winner
// Give the winner the role reward
// update concour with the winner and increment the index
// Announce the next concour
// Or not if there is no more keyword
info!("Cron job fired: {:?}", uuid);
})
}) {

View File

@ -38,6 +38,18 @@ async fn main() -> std::io::Result<()> {
let (tx_bot, rx_bot) = oneshot::channel();
let http = start_bot(config.clone(), rx_bot, cron_scheduler.clone()).await;
info!("API Server started on port {}", port);
match cron_scheduler
.load_all_concour_cron_job(&http.clone())
.await
{
Ok(_) => {
info!("All concour cron job loaded");
}
Err(_) => {
println!("Error loading all concour cron job");
return Ok(());
}
};
let mut openapi = ApiDocs::openapi();
openapi.info.title = format!("{} Api", config.bot_name.clone());
openapi.info.version = env!("CARGO_PKG_VERSION").to_string();