187 lines
4.9 KiB
Rust
187 lines
4.9 KiB
Rust
|
/**
|
||
|
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<i64>,
|
||
|
// }
|
||
|
|
||
|
pub mod get_data {
|
||
|
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::{get_server_config_bulk, Config, 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<String>,
|
||
|
note: Option<String>,
|
||
|
expiry: String,
|
||
|
requested: String,
|
||
|
approved: String,
|
||
|
sitename: String,
|
||
|
domain: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, Serialize, Debug)]
|
||
|
struct WolvesResult {
|
||
|
success: i8,
|
||
|
result: Vec<WolvesResultUser>,
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, Serialize, Debug)]
|
||
|
struct WolvesResultLocal {
|
||
|
pub id_wolves: String,
|
||
|
pub email: String,
|
||
|
pub expiry: String,
|
||
|
}
|
||
|
pub async fn get_wolves_cns(ctx: &Context) {
|
||
|
let db_lock = {
|
||
|
let data_read = ctx.data.read().await;
|
||
|
data_read.get::<DataBase>().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::<Config>().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::<BTreeMap<_, _>>();
|
||
|
|
||
|
// list of users that need to be updated for this server
|
||
|
let mut user_to_update = vec![];
|
||
|
for user in get_wolves_cns_sub(&config, wolves_api).await {
|
||
|
let id = user.member_id.parse::<u64>().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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub async fn get_server_member(db: &Pool<Sqlite>, server: &GuildId) -> Vec<ServerMembersWolves> {
|
||
|
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_cns_sub(config: &Config, wolves_api: &str) -> Vec<WolvesResultUser> {
|
||
|
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<Sqlite>, 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<Sqlite>, 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|