From feff293043b4f2f587e9aef6475decdc5d3e87cb Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Sun, 20 Jul 2025 23:12:02 +0100 Subject: [PATCH] feat: moved the update server icon to the main thread --- Cargo.toml | 3 -- flake.nix | 3 +- src/bin/update_server-icon.rs | 78 ----------------------------------- src/commands/server_icon.rs | 2 +- src/main.rs | 40 +++++++++++++++++- 5 files changed, 40 insertions(+), 86 deletions(-) delete mode 100644 src/bin/update_server-icon.rs diff --git a/Cargo.toml b/Cargo.toml index ef48675..79ad1d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,6 @@ edition = "2021" [[bin]] name = "update_minecraft" -[[bin]] -name = "update_server-icon" - [[bin]] name = "cleanup_committee" diff --git a/flake.nix b/flake.nix index 31d6434..2dee869 100644 --- a/flake.nix +++ b/flake.nix @@ -153,9 +153,8 @@ # modify these scripts = { # minecraft stuff is updated at 5am + # this service does not depend on teh discord cache "update_minecraft" = "5:10:00"; - # server icon gets updated daily at midnight - "update_server-icon" = "0:01:00"; }; in { options.services."${package_name}" = { diff --git a/src/bin/update_server-icon.rs b/src/bin/update_server-icon.rs deleted file mode 100644 index 2c093f9..0000000 --- a/src/bin/update_server-icon.rs +++ /dev/null @@ -1,78 +0,0 @@ -use serenity::all::{ChunkGuildFilter, GuildId}; -use serenity::{ - async_trait, - client::{Context, EventHandler}, - model::gateway::{GatewayIntents, Ready}, - Client, -}; -use skynet_discord_bot::common::server_icon::{get_config_icons, update_icon}; -use skynet_discord_bot::{ - common::database::{db_init, DataBase}, - get_config, Config, -}; -use std::{process, sync::Arc}; -use tokio::sync::RwLock; - -#[tokio::main] -async fn main() { - let config = get_config(); - let db = match db_init(&config).await { - Ok(x) => x, - Err(_) => return, - }; - - // Intents are a bitflag, bitwise operations can be used to dictate which intents to use - let intents = GatewayIntents::GUILDS | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS; - // Build our client. - let mut client = Client::builder(&config.discord_token, intents) - .event_handler(Handler {}) - .cache_settings(serenity::cache::Settings::default()) - .await - .expect("Error creating client"); - - { - let mut data = client.data.write().await; - - data.insert::(Arc::new(RwLock::new(config))); - data.insert::(Arc::new(RwLock::new(db))); - } - - if let Err(why) = client.start().await { - println!("Client error: {:?}", why); - } -} - -struct Handler; -#[async_trait] -impl EventHandler for Handler { - async fn cache_ready(&self, ctx: Context, guilds: Vec) { - for guild in guilds { - ctx.shard.chunk_guild(guild, Some(2000), false, ChunkGuildFilter::None, None); - } - println!("Cache built successfully!"); - } - - async fn ready(&self, ctx: Context, ready: Ready) { - let ctx = Arc::new(ctx); - println!("{} is connected!", ready.user.name); - - let db_lock = { - let data_read = ctx.data.read().await; - data_read.get::().expect("Expected Config in TypeMap.").clone() - }; - let db = db_lock.read().await; - - let config_lock = { - let data_read = ctx.data.read().await; - data_read.get::().expect("Expected Config in TypeMap.").clone() - }; - - let config_global = config_lock.read().await; - let config_toml = get_config_icons::minimal(); - - update_icon::update_icon_main(&ctx, &db, &config_global, &config_toml).await; - - // finish up - process::exit(0); - } -} diff --git a/src/commands/server_icon.rs b/src/commands/server_icon.rs index 9c970fc..59d755f 100644 --- a/src/commands/server_icon.rs +++ b/src/commands/server_icon.rs @@ -93,7 +93,7 @@ pub(crate) mod user { } } - async fn get_current_icon(db: &Pool) -> Option { + pub async fn get_current_icon(db: &Pool) -> Option { match sqlx::query_as::<_, ServerIcons>( " SELECT * from server_icons ORDER BY id DESC LIMIT 1 diff --git a/src/main.rs b/src/main.rs index df08f6b..6e6ad8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ pub mod commands; use crate::commands::role_adder::tools::on_role_change; +use crate::commands::server_icon::user::current::icon::get_current_icon; +use chrono::{Days, SecondsFormat, TimeDelta, Utc}; use serenity::all::{ - ActivityData, Command, CommandDataOptionValue, CreateMessage, EditInteractionResponse, GuildId, GuildMemberUpdateEvent, GuildMembersChunkEvent, - Interaction, + ActivityData, Command, CommandDataOptionValue, CreateAttachment, CreateMessage, EditInteractionResponse, GuildId, GuildMemberUpdateEvent, + GuildMembersChunkEvent, Interaction, }; use serenity::{ async_trait, @@ -17,6 +19,7 @@ use serenity::{ Client, }; use skynet_discord_bot::common::database::{db_init, get_server_config, get_server_config_bulk, get_server_member, DataBase}; +use skynet_discord_bot::common::server_icon::{get_config_icons, update_icon}; use skynet_discord_bot::common::set_roles::committee::update_committees; use skynet_discord_bot::common::set_roles::{committee, normal}; use skynet_discord_bot::common::wolves::cns::get_wolves; @@ -103,6 +106,39 @@ impl EventHandler for Handler { }); } + { + // this updates teh server icon once a day + let ctx_task = Arc::clone(&ctx); + tokio::spawn(async move { + let db_lock = { + let data_read = ctx_task.data.read().await; + data_read.get::().expect("Expected Database in TypeMap.").clone() + }; + let db = db_lock.read().await; + let config_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Config in TypeMap.").clone() + }; + + let config_global = config_lock.read().await; + let config_toml = get_config_icons::minimal(); + + loop { + println!("Update - Logo - Start"); + // even though this task will run every 5 min it will only actually change the icon when its a day old + if let Some(logo) = get_current_icon(&db).await { + let now = Utc::now(); + let yesterday = now.checked_sub_days(Days::new(1)).unwrap_or_default(); + if logo.date < yesterday.to_rfc3339_opts(SecondsFormat::Millis, true) { + update_icon::update_icon_main(&ctx, &db, &config_global, &config_toml).await; + } + } + println!("Update - Logo - End"); + tokio::time::sleep(Duration::from_secs(60 * 5)).await; + } + }); + } + // Now that the loop is running, we set the bool to true self.is_loop_running.swap(true, Ordering::Relaxed); }