From 1e486d7a579de1289a4da58c30d23774b4027a9d Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Thu, 23 Nov 2023 21:53:27 +0000 Subject: [PATCH] fix: make sure that wolves data is pulled in before roles are ran --- src/bin/update_data.rs | 112 +-------------- src/bin/update_users.rs | 2 +- src/commands/add_server.rs | 12 +- src/lib.rs | 269 ++++++++++++++++++++++++++----------- 4 files changed, 204 insertions(+), 191 deletions(-) diff --git a/src/bin/update_data.rs b/src/bin/update_data.rs index 9db2602..08bb7a0 100644 --- a/src/bin/update_data.rs +++ b/src/bin/update_data.rs @@ -1,8 +1,4 @@ -use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, Config, ServerMembers, Servers, Wolves}; - -use serde::{Deserialize, Serialize}; -use serenity::model::id::GuildId; -use sqlx::{Pool, Sqlite}; +use skynet_discord_bot::{db_init, get_config, get_data::get_wolves}; #[tokio::main] async fn main() { @@ -15,109 +11,3 @@ async fn main() { // handle wolves api here get_wolves(&db, &config).await; } - -#[derive(Deserialize, Serialize, Debug)] -struct WolvesResultUser { - committee: String, - wolves_id: String, - first_name: String, - last_name: String, - contact_email: String, - student_id: Option, - note: Option, - expiry: String, - requested: String, - approved: String, - sitename: String, - domain: String, -} - -#[derive(Deserialize, Serialize, Debug)] -struct WolvesResult { - success: i8, - result: Vec, -} - -#[derive(Deserialize, Serialize, Debug)] -struct WolvesResultLocal { - pub id_wolves: String, - pub email: String, - pub expiry: String, -} -async fn get_wolves(db: &Pool, config: &Config) { - for server_config in get_server_config_bulk(db).await { - let Servers { - server, - wolves_api, - .. - } = server_config; - - for user in get_wolves_sub(config, &wolves_api).await { - add_users_wolves(db, &server, &user).await; - } - } -} - -async fn get_wolves_sub(config: &Config, wolves_api: &str) -> Vec { - if config.wolves_url.is_empty() { - return vec![]; - } - - // get wolves data - if let Ok(mut res) = surf::post(&config.wolves_url).header("X-AM-Identity", wolves_api).await { - if let Ok(WolvesResult { - success, - result, - }) = res.body_json().await - { - if success != 1 { - return vec![]; - } - - return result; - } - } - - vec![] -} - -async fn add_users_wolves(db: &Pool, server: &GuildId, user: &WolvesResultUser) { - // expiry - match sqlx::query_as::<_, Wolves>( - " - INSERT INTO wolves (id_wolves, email) - VALUES ($1, $2) - ON CONFLICT(id_wolves) DO UPDATE SET email = $2 - ", - ) - .bind(&user.wolves_id) - .bind(&user.contact_email) - .fetch_optional(db) - .await - { - Ok(_) => {} - Err(e) => { - println!("Failure to insert into Wolves {:?}", user); - println!("{:?}", e); - } - } - - match sqlx::query_as::<_, ServerMembers>( - " - INSERT OR REPLACE INTO server_members (server, id_wolves, expiry) - VALUES (?1, ?2, ?3) - ", - ) - .bind(*server.as_u64() as i64) - .bind(&user.wolves_id) - .bind(&user.expiry) - .fetch_optional(db) - .await - { - Ok(_) => {} - Err(e) => { - println!("Failure to insert into ServerMembers {} {:?}", server.as_u64(), user); - println!("{:?}", e); - } - } -} diff --git a/src/bin/update_users.rs b/src/bin/update_users.rs index 354ab1e..f9396e7 100644 --- a/src/bin/update_users.rs +++ b/src/bin/update_users.rs @@ -4,7 +4,7 @@ use serenity::{ model::gateway::{GatewayIntents, Ready}, Client, }; -use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, update_server, Config, DataBase}; +use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, set_roles::update_server, Config, DataBase}; use std::{process, sync::Arc}; use tokio::sync::RwLock; diff --git a/src/commands/add_server.rs b/src/commands/add_server.rs index 828a263..598c320 100644 --- a/src/commands/add_server.rs +++ b/src/commands/add_server.rs @@ -6,7 +6,8 @@ use serenity::{ prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue}, }, }; -use skynet_discord_bot::{get_server_config, update_server, DataBase, Servers}; +use skynet_discord_bot::get_data::get_wolves; +use skynet_discord_bot::{get_server_config, set_roles::update_server, Config, DataBase, Servers}; use sqlx::{Error, Pool, Sqlite}; pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String { @@ -172,6 +173,15 @@ async fn add_server(db: &Pool, ctx: &Context, server: &Servers) -> Resul // update all users if update { + let config_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Config in TypeMap.").clone() + }; + let config = config_lock.read().await; + + // handle wolves api here + get_wolves(db, &config).await; + let mut roles_remove = vec![]; if current_remove { roles_remove.push(current_role) diff --git a/src/lib.rs b/src/lib.rs index 6af97d9..59dc03c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -379,82 +379,84 @@ 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; +pub mod set_roles { + use super::*; + 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![]; + 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); + 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(); + 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 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_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 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 Err(e) = member.add_roles(ctx, &roles).await { + println!("{:?}", e); } - } + } else { + // old and never - 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); + 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); + 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]); } - 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#" + 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) @@ -464,32 +466,143 @@ async fn get_server_member_bulk(db: &Pool, server: &GuildId) -> Vec ? ) "#, - ) - .bind(*server.as_u64() as i64) - .bind(get_now_iso(true)) - .fetch_all(db) - .await - .unwrap_or_default() -} + ) + .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>( - " + 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); + ) + .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); + } + } + } +} + +pub mod get_data { + use super::*; + + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResultUser { + committee: String, + wolves_id: String, + first_name: String, + last_name: String, + contact_email: String, + student_id: Option, + note: Option, + expiry: String, + requested: String, + approved: String, + sitename: String, + domain: String, + } + + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResult { + success: i8, + result: Vec, + } + + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResultLocal { + pub id_wolves: String, + pub email: String, + pub expiry: String, + } + pub async fn get_wolves(db: &Pool, config: &Config) { + for server_config in get_server_config_bulk(db).await { + let Servers { + server, + wolves_api, + .. + } = server_config; + + for user in get_wolves_sub(config, &wolves_api).await { + add_users_wolves(db, &server, &user).await; + } + } + } + + async fn get_wolves_sub(config: &Config, wolves_api: &str) -> Vec { + if config.wolves_url.is_empty() { + return vec![]; + } + + // get wolves data + if let Ok(mut res) = surf::post(&config.wolves_url).header("X-AM-Identity", wolves_api).await { + if let Ok(WolvesResult { + success, + result, + }) = res.body_json().await + { + if success != 1 { + return vec![]; + } + + return result; + } + } + + vec![] + } + + async fn add_users_wolves(db: &Pool, server: &GuildId, user: &WolvesResultUser) { + // expiry + match sqlx::query_as::<_, Wolves>( + " + INSERT INTO wolves (id_wolves, email) + VALUES ($1, $2) + ON CONFLICT(id_wolves) DO UPDATE SET email = $2 + ", + ) + .bind(&user.wolves_id) + .bind(&user.contact_email) + .fetch_optional(db) + .await + { + Ok(_) => {} + Err(e) => { + println!("Failure to insert into Wolves {:?}", user); + println!("{:?}", e); + } + } + + match sqlx::query_as::<_, ServerMembers>( + " + INSERT OR REPLACE INTO server_members (server, id_wolves, expiry) + VALUES (?1, ?2, ?3) + ", + ) + .bind(*server.as_u64() as i64) + .bind(&user.wolves_id) + .bind(&user.expiry) + .fetch_optional(db) + .await + { + Ok(_) => {} + Err(e) => { + println!("Failure to insert into ServerMembers {} {:?}", server.as_u64(), user); + println!("{:?}", e); + } } } }