fix: make sure that wolves data is pulled in before roles are ran
This commit is contained in:
parent
5745118ede
commit
1e486d7a57
4 changed files with 204 additions and 191 deletions
|
@ -1,8 +1,4 @@
|
||||||
use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, Config, ServerMembers, Servers, Wolves};
|
use skynet_discord_bot::{db_init, get_config, get_data::get_wolves};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serenity::model::id::GuildId;
|
|
||||||
use sqlx::{Pool, Sqlite};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
@ -15,109 +11,3 @@ async fn main() {
|
||||||
// handle wolves api here
|
// handle wolves api here
|
||||||
get_wolves(&db, &config).await;
|
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<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,
|
|
||||||
}
|
|
||||||
async fn get_wolves(db: &Pool<Sqlite>, 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<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>, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use serenity::{
|
||||||
model::gateway::{GatewayIntents, Ready},
|
model::gateway::{GatewayIntents, Ready},
|
||||||
Client,
|
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 std::{process, sync::Arc};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ use serenity::{
|
||||||
prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue},
|
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};
|
use sqlx::{Error, Pool, Sqlite};
|
||||||
|
|
||||||
pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String {
|
pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String {
|
||||||
|
@ -172,6 +173,15 @@ async fn add_server(db: &Pool<Sqlite>, ctx: &Context, server: &Servers) -> Resul
|
||||||
|
|
||||||
// update all users
|
// update all users
|
||||||
if update {
|
if update {
|
||||||
|
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;
|
||||||
|
|
||||||
|
// handle wolves api here
|
||||||
|
get_wolves(db, &config).await;
|
||||||
|
|
||||||
let mut roles_remove = vec![];
|
let mut roles_remove = vec![];
|
||||||
if current_remove {
|
if current_remove {
|
||||||
roles_remove.push(current_role)
|
roles_remove.push(current_role)
|
||||||
|
|
269
src/lib.rs
269
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()
|
thread_rng().sample_iter(&Alphanumeric).take(len).map(char::from).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_server(db: &Pool<Sqlite>, ctx: &Context, server: &Servers, remove_roles: &[Option<RoleId>]) {
|
pub mod set_roles {
|
||||||
let Servers {
|
use super::*;
|
||||||
server,
|
pub async fn update_server(db: &Pool<Sqlite>, ctx: &Context, server: &Servers, remove_roles: &[Option<RoleId>]) {
|
||||||
role_past,
|
let Servers {
|
||||||
role_current,
|
server,
|
||||||
..
|
role_past,
|
||||||
} = server;
|
role_current,
|
||||||
|
..
|
||||||
|
} = server;
|
||||||
|
|
||||||
let mut roles_set = [0, 0, 0];
|
let mut roles_set = [0, 0, 0];
|
||||||
let mut members = vec![];
|
let mut members = vec![];
|
||||||
|
|
||||||
for member in get_server_member_bulk(db, server).await {
|
for member in get_server_member_bulk(db, server).await {
|
||||||
if let Some(x) = member.discord {
|
if let Some(x) = member.discord {
|
||||||
members.push(x);
|
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 {
|
if let Ok(x) = server.members(ctx, None, None).await {
|
||||||
for mut member in x {
|
for mut member in x {
|
||||||
if members.contains(&member.user.id) {
|
if members.contains(&member.user.id) {
|
||||||
let mut roles = vec![];
|
let mut roles = vec![];
|
||||||
|
|
||||||
if let Some(role) = &role_past {
|
if let Some(role) = &role_past {
|
||||||
if !member.roles.contains(role) {
|
if !member.roles.contains(role) {
|
||||||
roles_set[0] += 1;
|
roles_set[0] += 1;
|
||||||
roles.push(role.to_owned());
|
roles.push(role.to_owned());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(role) = &role_current {
|
if let Some(role) = &role_current {
|
||||||
if !member.roles.contains(role) {
|
if !member.roles.contains(role) {
|
||||||
roles_set[1] += 1;
|
roles_set[1] += 1;
|
||||||
roles.push(role.to_owned());
|
roles.push(role.to_owned());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(e) = member.add_roles(ctx, &roles).await {
|
if let Err(e) = member.add_roles(ctx, &roles).await {
|
||||||
println!("{:?}", e);
|
println!("{:?}", e);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// old and never
|
|
||||||
|
|
||||||
if let Some(role) = &role_past {
|
|
||||||
if member.roles.contains(role) {
|
|
||||||
members_all += 1;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// old and never
|
||||||
|
|
||||||
if let Some(role) = &role_current {
|
if let Some(role) = &role_past {
|
||||||
if member.roles.contains(role) {
|
if member.roles.contains(role) {
|
||||||
roles_set[2] += 1;
|
members_all += 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_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() {
|
||||||
for role in remove_roles.iter().flatten() {
|
if let Err(e) = member.remove_role(ctx, role).await {
|
||||||
if let Err(e) = member.remove_role(ctx, role).await {
|
println!("{:?}", e);
|
||||||
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;
|
async fn get_server_member_bulk(db: &Pool<Sqlite>, server: &GuildId) -> Vec<ServerMembersWolves> {
|
||||||
|
sqlx::query_as::<_, ServerMembersWolves>(
|
||||||
// small bit of logging to note changes over time
|
r#"
|
||||||
println!("{:?} Changes: New: +{}, Current: +{}/-{}", server.as_u64(), roles_set[0], roles_set[1], roles_set[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_server_member_bulk(db: &Pool<Sqlite>, server: &GuildId) -> Vec<ServerMembersWolves> {
|
|
||||||
sqlx::query_as::<_, ServerMembersWolves>(
|
|
||||||
r#"
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM server_members
|
FROM server_members
|
||||||
JOIN wolves USING (id_wolves)
|
JOIN wolves USING (id_wolves)
|
||||||
|
@ -464,32 +466,143 @@ async fn get_server_member_bulk(db: &Pool<Sqlite>, server: &GuildId) -> Vec<Serv
|
||||||
AND expiry > ?
|
AND expiry > ?
|
||||||
)
|
)
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(*server.as_u64() as i64)
|
.bind(*server.as_u64() as i64)
|
||||||
.bind(get_now_iso(true))
|
.bind(get_now_iso(true))
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_server_numbers(db: &Pool<Sqlite>, server: &GuildId, past: i64, current: i64) {
|
async fn set_server_numbers(db: &Pool<Sqlite>, server: &GuildId, past: i64, current: i64) {
|
||||||
match sqlx::query_as::<_, Wolves>(
|
match sqlx::query_as::<_, Wolves>(
|
||||||
"
|
"
|
||||||
UPDATE servers
|
UPDATE servers
|
||||||
SET member_past = ?, member_current = ?
|
SET member_past = ?, member_current = ?
|
||||||
WHERE server = ?
|
WHERE server = ?
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.bind(past)
|
.bind(past)
|
||||||
.bind(current)
|
.bind(current)
|
||||||
.bind(*server.as_u64() as i64)
|
.bind(*server.as_u64() as i64)
|
||||||
.fetch_optional(db)
|
.fetch_optional(db)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failure to insert into {}", server.as_u64());
|
println!("Failure to insert into {}", server.as_u64());
|
||||||
println!("{:?}", e);
|
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<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(db: &Pool<Sqlite>, 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<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>, 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue