feat: now properly sets and removes roles for committee members

This commit is contained in:
silver 2025-02-18 21:14:05 +00:00
parent 4eeb7f2135
commit 1aef86ad01
Signed by: silver
GPG key ID: 36F93D61BAD3FD7D
9 changed files with 137 additions and 89 deletions

View file

@ -135,9 +135,7 @@ pub struct Servers {
pub member_past: i64,
pub member_current: i64,
pub bot_channel_id: ChannelId,
// TODO: these can be removed in teh future with an API update
pub server_name: String,
pub wolves_link: String,
}
impl<'r> FromRow<'r, SqliteRow> for Servers {
@ -175,7 +173,6 @@ impl<'r> FromRow<'r, SqliteRow> for Servers {
member_current: row.try_get("member_current")?,
bot_channel_id,
server_name: row.try_get("server_name")?,
wolves_link: row.try_get("wolves_link")?,
})
}
}

View file

@ -137,6 +137,8 @@ pub mod committee {
use serenity::client::Context;
use serenity::model::channel::ChannelType;
use serenity::model::guild::Member;
use serenity::model::id::ChannelId;
use serenity::model::prelude::RoleId;
use sqlx::{Pool, Sqlite};
use std::collections::HashMap;
use std::sync::Arc;
@ -170,6 +172,7 @@ pub mod committee {
let server = config.committee_server;
let committee_member = config.committee_role;
let committees = get_committees(db).await;
let categories = vec![config.committee_category, ChannelId(1341457244973305927), ChannelId(1341457509717639279)];
// information about the server
let roles = server.roles(&ctx).await.unwrap_or_default();
@ -185,8 +188,10 @@ pub mod committee {
for channel in channels.values() {
// we only care about teh channels in teh category
if let Some(x) = channel.parent_id {
if x.eq(&config.committee_category) {
channels_name.insert(channel.name.to_owned(), channel.to_owned());
for category in &categories {
if x.eq(category) {
channels_name.insert(channel.name.to_owned(), channel.to_owned());
}
}
}
}
@ -197,13 +202,21 @@ pub mod committee {
// a list of all the roles that can be removed from folks who should have them
let mut committee_roles = vec![committee_member];
for committee in &committees {
let mut category_index = 0;
let mut i = 0;
loop {
if i >= committees.len() {
break;
}
let committee = &committees[i];
// get the role for this committee/club/soc
let role = match roles_name.get(&committee.name_profile) {
let role = match roles_name.get(&committee.name_full) {
Some(x) => Some(x.to_owned()),
None => {
// create teh role if it does not exist
match server.create_role(&ctx, |r| r.hoist(false).mentionable(true).name(&committee.name_profile)).await {
match server.create_role(&ctx, |r| r.hoist(false).mentionable(true).name(&committee.name_full)).await {
Ok(x) => Some(x),
Err(_) => None,
}
@ -213,7 +226,7 @@ pub mod committee {
// create teh channel if it does nto exist
if !channels_name.contains_key(&committee.name_profile) {
match server
.create_channel(&ctx, |c| c.name(&committee.name_profile).kind(ChannelType::Text).category(config.committee_category))
.create_channel(&ctx, |c| c.name(&committee.name_profile).kind(ChannelType::Text).category(categories[category_index]))
.await
{
Ok(x) => {
@ -223,7 +236,14 @@ pub mod committee {
println!("Created channel: {}", &committee.name_profile);
}
Err(x) => {
dbg!("Unable to create channel: ", x);
let tmp = x.to_string();
if x.to_string().contains("Maximum number of channels in category reached (50)") {
category_index += 1;
continue;
}
dbg!("Unable to create channel: ", &tmp, &tmp.contains("Maximum number of channels in category reached (50)"));
}
}
};
@ -236,42 +256,60 @@ pub mod committee {
// ID in this is the wolves ID, so we need to get a matching discord ID (if one exists)
if let Some(x) = get_server_member_discord(db, id_wolves).await {
if let Some(member_tmp) = x.discord {
let values = users_roles.entry(member_tmp).or_insert(vec![]);
let values = users_roles.entry(member_tmp).or_insert(vec![committee_member]);
values.push(r.id);
}
}
}
}
i += 1;
}
// now we have a map of all users that should get roles time to go through all the folks on teh server
for member in members {
let roles_current = member.roles(ctx).unwrap_or_default();
let roles_required = match users_roles.get(&member.user.id) {
None => {
vec![]
}
Some(x) => {
let mut combined = x.to_owned();
// this is the main role, since it provides access to everything.
combined.push(committee_member);
combined
let mut tmp = x.to_owned();
if !tmp.is_empty() {
tmp.push(RoleId(1226602779968274573));
}
tmp
}
};
// get a list of all the roles to remove from someone
let mut roles_rem = vec![];
for role in &committee_roles {
if !roles_required.contains(role) {
roles_rem.push(role.to_owned());
let mut roles_add = vec![];
// get a list of all the roles to remove from someone
let mut roles_current_id = vec![];
for role in &roles_current {
roles_current_id.push(role.id.to_owned());
if !roles_required.contains(&role.id) {
roles_rem.push(role.id.to_owned());
}
}
for role in &roles_required {
if !roles_current_id.contains(role) {
roles_add.push(role.to_owned());
}
}
if !roles_rem.is_empty() {
member.remove_roles(&ctx, &roles_rem).await.unwrap_or_default();
}
if !roles_required.is_empty() {
if !roles_add.is_empty() {
// these roles are flavor roles, only there to make folks mentionable
member.add_roles(&ctx, &roles_required).await.unwrap_or_default();
member.add_roles(&ctx, &roles_add).await.unwrap_or_default();
} else {
member.remove_roles(&ctx, &[RoleId(1226602779968274573)]).await.unwrap_or_default();
}
}
@ -303,7 +341,7 @@ pub mod committee {
}
async fn get_committees(db: &Pool<Sqlite>) -> Vec<Committees> {
sqlx::query_as::<_, Committees>(
match sqlx::query_as::<_, Committees>(
r#"
SELECT *
FROM committees
@ -311,7 +349,13 @@ pub mod committee {
)
.fetch_all(db)
.await
.unwrap_or_default()
{
Ok(a) => a,
Err(e) => {
dbg!(e);
vec![]
}
}
}
async fn get_server_member_discord(db: &Pool<Sqlite>, user: &i64) -> Option<Wolves> {

View file

@ -87,15 +87,22 @@ pub mod cns {
server,
// this is the unique api key for each club/soc
wolves_api,
server_name,
..
} = &server_config;
// dbg!(&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![];
let mut server_name_tmp = None;
for user in wolves.get_members(wolves_api).await {
// dbg!(&user.committee);
if server_name_tmp.is_none() {
server_name_tmp = Some(user.committee.to_owned());
}
let id = user.member_id.parse::<u64>().unwrap_or_default();
match existing.get(&(id as i64)) {
None => {
@ -117,12 +124,38 @@ pub mod cns {
}
}
if let Some(name) = server_name_tmp {
if &name != server_name {
set_server_member(&db, server, &name).await;
}
}
if !user_to_update.is_empty() {
update_server(ctx, &server_config, &[], &user_to_update).await;
}
}
}
async fn set_server_member(db: &Pool<Sqlite>, server: &GuildId, name: &str) {
match sqlx::query_as::<_, Servers>(
"
UPDATE servers
SET server_name = ?
WHERE server = ?
",
)
.bind(name)
.bind(*server.as_u64() as i64)
.fetch_optional(db)
.await
{
Ok(_) => {}
Err(e) => {
println!("Failure to set server name {}", server.as_u64());
println!("{:?}", e);
}
}
}
async fn get_server_member(db: &Pool<Sqlite>, server: &GuildId) -> Vec<ServerMembersWolves> {
sqlx::query_as::<_, ServerMembersWolves>(
r#"
@ -223,7 +256,7 @@ pub mod committees {
"
INSERT INTO committees (id, name_profile, name_full, name_plain, link, committee)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT(id) DO UPDATE SET committee = $4
ON CONFLICT(id) DO UPDATE SET committee = $6
",
)
.bind(committee.id)