/** This file relates to anything that directly interacts with teh wolves API */ // #[derive(Debug, Clone, sqlx::FromRow)] // pub struct Committees { // pub id: i64, // pub name: String, // pub link: String, // pub members: Vec, // } /** This is getting data for Clubs and Socs */ pub mod cns { use crate::set_roles::update_server; use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; use serenity::client::Context; use serenity::model::id::GuildId; use sqlx::{Pool, Sqlite}; use crate::Config; use crate::common::database::{get_server_config_bulk, DataBase, ServerMembers, ServerMembersWolves, Servers, Wolves}; #[derive(Deserialize, Serialize, Debug)] struct WolvesResultUser { committee: String, member_id: String, first_name: String, last_name: String, contact_email: String, opt_in_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(ctx: &Context) { let db_lock = { let data_read = ctx.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 = config_lock.read().await; for server_config in get_server_config_bulk(&db).await { let Servers { server, wolves_api, .. } = &server_config; let existing_tmp = get_server_member(&db, server).await; let existing = existing_tmp.iter().map(|data| (data.id_wolves, data)).collect::>(); // list of users that need to be updated for this server let mut user_to_update = vec![]; for user in get_wolves_sub(&config, wolves_api).await { let id = user.member_id.parse::().unwrap_or_default(); match existing.get(&(id as i64)) { None => { // user does not exist already, add everything add_users_wolves(&db, &user).await; add_users_server_members(&db, server, &user).await; } Some(old) => { // always update wolves table, in case data has changed add_users_wolves(&db, &user).await; if old.expiry != user.expiry { add_users_server_members(&db, server, &user).await; if let Some(discord_id) = old.discord { user_to_update.push(discord_id); } } } } } if !user_to_update.is_empty() { update_server(ctx, &server_config, &[], &user_to_update).await; } } } async fn get_server_member(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 ) "#, ) .bind(*server.as_u64() as i64) .fetch_all(db) .await .unwrap_or_default() } 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, 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.member_id) .bind(&user.contact_email) .fetch_optional(db) .await { Ok(_) => {} Err(e) => { println!("Failure to insert into Wolves {:?}", user); println!("{:?}", e); } } } async fn add_users_server_members(db: &Pool, server: &GuildId, user: &WolvesResultUser) { 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.member_id) .bind(&user.expiry) .fetch_optional(db) .await { Ok(_) => {} Err(e) => { println!("Failure to insert into ServerMembers {} {:?}", server.as_u64(), user); println!("{:?}", e); } } } } /** Get and store the data on C&S committees */ pub mod committees {} /** get the data for an individual user */ pub mod individual {}