From 66446e8df8d70139b1a4527acebfadcca5fc041f Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Thu, 23 Nov 2023 16:12:28 +0000 Subject: [PATCH] feat: will update users when there are changes made to teh server config --- src/bin/update_users.rs | 116 +------------------------------------ src/commands/add_server.rs | 47 +++++++++++++-- src/lib.rs | 116 +++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 118 deletions(-) diff --git a/src/bin/update_users.rs b/src/bin/update_users.rs index 6b66cfb..354ab1e 100644 --- a/src/bin/update_users.rs +++ b/src/bin/update_users.rs @@ -1,14 +1,10 @@ use serenity::{ async_trait, client::{Context, EventHandler}, - model::{ - gateway::{GatewayIntents, Ready}, - id::GuildId, - }, + model::gateway::{GatewayIntents, Ready}, Client, }; -use skynet_discord_bot::{db_init, get_config, get_now_iso, get_server_config_bulk, Config, DataBase, ServerMembersWolves, Servers, Wolves}; -use sqlx::{Pool, Sqlite}; +use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, update_server, Config, DataBase}; use std::{process, sync::Arc}; use tokio::sync::RwLock; @@ -63,112 +59,6 @@ async fn bulk_check(ctx: Arc) { let db = db_lock.read().await; for server_config in get_server_config_bulk(&db).await { - let Servers { - server, - role_past, - role_current, - .. - } = server_config; - - let mut roles_set = [0, 0, 0]; - let mut members = vec![]; - - for member in get_server_member_bulk(&db, &server).await { - if let Some(x) = member.discord { - members.push(x); - } - } - let mut members_all = members.len(); - - if let Ok(x) = server.members(&ctx, None, None).await { - for mut member in x { - if members.contains(&member.user.id) { - let mut roles = vec![]; - - if let Some(role) = &role_past { - if !member.roles.contains(role) { - roles_set[0] += 1; - roles.push(role.to_owned()); - } - } - - if let Some(role) = &role_current { - if !member.roles.contains(role) { - roles_set[1] += 1; - roles.push(role.to_owned()); - } - } - - if let Err(e) = member.add_roles(&ctx, &roles).await { - println!("{:?}", e); - } - } else { - // old and never - - if let Some(role) = &role_past { - if member.roles.contains(role) { - members_all += 1; - } - } - - if let Some(role) = &role_current { - if member.roles.contains(role) { - roles_set[2] += 1; - // if theya re not a current member and have the role then remove it - if let Err(e) = member.remove_role(&ctx, role).await { - println!("{:?}", e); - } - } - } - } - } - } - - set_server_numbers(&db, &server, members_all as i64, members.len() as i64).await; - - // small bit of logging to note changes over time - println!("{:?} Changes: New: +{}, Current: +{}/-{}", server.as_u64(), roles_set[0], roles_set[1], roles_set[2]); - } -} - -async fn get_server_member_bulk(db: &Pool, server: &GuildId) -> Vec { - sqlx::query_as::<_, ServerMembersWolves>( - r#" - SELECT * - FROM server_members - JOIN wolves USING (id_wolves) - WHERE ( - server = ? - AND discord IS NOT NULL - AND expiry > ? - ) - "#, - ) - .bind(*server.as_u64() as i64) - .bind(get_now_iso(true)) - .fetch_all(db) - .await - .unwrap_or_default() -} - -async fn set_server_numbers(db: &Pool, server: &GuildId, past: i64, current: i64) { - match sqlx::query_as::<_, Wolves>( - " - UPDATE servers - SET member_past = ?, member_current = ? - WHERE server = ? - ", - ) - .bind(past) - .bind(current) - .bind(*server.as_u64() as i64) - .fetch_optional(db) - .await - { - Ok(_) => {} - Err(e) => { - println!("Failure to insert into {}", server.as_u64()); - println!("{:?}", e); - } + update_server(&db, &ctx, &server_config, &[]).await; } } diff --git a/src/commands/add_server.rs b/src/commands/add_server.rs index 5f25646..828a263 100644 --- a/src/commands/add_server.rs +++ b/src/commands/add_server.rs @@ -6,7 +6,7 @@ use serenity::{ prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue}, }, }; -use skynet_discord_bot::{DataBase, Servers}; +use skynet_discord_bot::{get_server_config, update_server, DataBase, Servers}; use sqlx::{Error, Pool, Sqlite}; pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String { @@ -92,7 +92,7 @@ pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> Stri member_current: 0, }; - match add_server(&db, &server_data).await { + match add_server(&db, ctx, &server_data).await { Ok(_) => {} Err(e) => { println!("{:?}", e); @@ -130,11 +130,12 @@ pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicatio }) } -async fn add_server(db: &Pool, server: &Servers) -> Result, Error> { +async fn add_server(db: &Pool, ctx: &Context, server: &Servers) -> Result, Error> { + let existing = get_server_config(db, &server.server).await; let role_past = server.role_past.map(|x| *x.as_u64() as i64); let role_current = server.role_current.map(|x| *x.as_u64() as i64); - sqlx::query_as::<_, Servers>( + let insert = sqlx::query_as::<_, Servers>( " INSERT OR REPLACE INTO servers (server, wolves_api, role_past, role_current) VALUES (?1, ?2, ?3, ?4) @@ -145,5 +146,41 @@ async fn add_server(db: &Pool, server: &Servers) -> Result (true, false, None, false, None), + Some(x) => { + let mut result = (false, false, None, false, None); + if x.wolves_api != server.wolves_api { + result.0 = true; + } + if x.role_current != server.role_current { + result.0 = true; + result.1 = true; + result.2 = x.role_current; + } + if x.role_past != server.role_past { + result.0 = true; + result.3 = true; + result.4 = x.role_past; + } + result + } + }; + + // update all users + if update { + let mut roles_remove = vec![]; + if current_remove { + roles_remove.push(current_role) + } + if past_remove { + roles_remove.push(past_role) + } + update_server(db, ctx, server, &roles_remove).await; + } + + insert } diff --git a/src/lib.rs b/src/lib.rs index 24ed4d0..6af97d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ use serenity::{ use chrono::{Datelike, SecondsFormat, Utc}; use rand::{distributions::Alphanumeric, thread_rng, Rng}; +use serenity::client::Context; use serenity::model::id::UserId; use sqlx::{ sqlite::{SqliteConnectOptions, SqlitePoolOptions, SqliteRow}, @@ -377,3 +378,118 @@ pub fn get_now_iso(short: bool) -> String { pub fn random_string(len: usize) -> String { thread_rng().sample_iter(&Alphanumeric).take(len).map(char::from).collect() } + +pub async fn update_server(db: &Pool, ctx: &Context, server: &Servers, remove_roles: &[Option]) { + let Servers { + server, + role_past, + role_current, + .. + } = server; + + let mut roles_set = [0, 0, 0]; + let mut members = vec![]; + + for member in get_server_member_bulk(db, server).await { + if let Some(x) = member.discord { + members.push(x); + } + } + let mut members_all = members.len(); + + if let Ok(x) = server.members(ctx, None, None).await { + for mut member in x { + if members.contains(&member.user.id) { + let mut roles = vec![]; + + if let Some(role) = &role_past { + if !member.roles.contains(role) { + roles_set[0] += 1; + roles.push(role.to_owned()); + } + } + + if let Some(role) = &role_current { + if !member.roles.contains(role) { + roles_set[1] += 1; + roles.push(role.to_owned()); + } + } + + if let Err(e) = member.add_roles(ctx, &roles).await { + println!("{:?}", e); + } + } else { + // old and never + + if let Some(role) = &role_past { + if member.roles.contains(role) { + members_all += 1; + } + } + + if let Some(role) = &role_current { + if member.roles.contains(role) { + roles_set[2] += 1; + // if theya re not a current member and have the role then remove it + if let Err(e) = member.remove_role(ctx, role).await { + println!("{:?}", e); + } + } + } + } + for role in remove_roles.iter().flatten() { + if let Err(e) = member.remove_role(ctx, role).await { + println!("{:?}", e); + } + } + } + } + + set_server_numbers(db, server, members_all as i64, members.len() as i64).await; + + // small bit of logging to note changes over time + println!("{:?} Changes: New: +{}, Current: +{}/-{}", server.as_u64(), roles_set[0], roles_set[1], roles_set[2]); +} + +async fn get_server_member_bulk(db: &Pool, server: &GuildId) -> Vec { + sqlx::query_as::<_, ServerMembersWolves>( + r#" + SELECT * + FROM server_members + JOIN wolves USING (id_wolves) + WHERE ( + server = ? + AND discord IS NOT NULL + AND expiry > ? + ) + "#, + ) + .bind(*server.as_u64() as i64) + .bind(get_now_iso(true)) + .fetch_all(db) + .await + .unwrap_or_default() +} + +async fn set_server_numbers(db: &Pool, server: &GuildId, past: i64, current: i64) { + match sqlx::query_as::<_, Wolves>( + " + UPDATE servers + SET member_past = ?, member_current = ? + WHERE server = ? + ", + ) + .bind(past) + .bind(current) + .bind(*server.as_u64() as i64) + .fetch_optional(db) + .await + { + Ok(_) => {} + Err(e) => { + println!("Failure to insert into {}", server.as_u64()); + println!("{:?}", e); + } + } +}