pub mod committee { // get the list of all the current clubs/socs members use serenity::all::{ CommandDataOption, CommandDataOptionValue, CommandInteraction, CommandOptionType, Context, CreateCommand, CreateCommandOption, }; use skynet_discord_bot::common::database::DataBase; use skynet_discord_bot::common::set_roles::committee::db_roles_get; pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { let sub_options = if let Some(CommandDataOption { value: CommandDataOptionValue::SubCommand(key), .. }) = command.data.options.first() { key } else { return "Please provide a wolves API key".to_string(); }; let all = if let Some(x) = sub_options.first() { match x.value { CommandDataOptionValue::Boolean(y) => y, _ => false, } } else { false }; let db_lock = { let data_read = ctx.data.read().await; data_read.get::().expect("Expected Databse in TypeMap.").clone() }; let db = db_lock.read().await; let mut cs = vec![]; // pull it from a DB for committee in db_roles_get(&db).await { if !all && committee.count == 0 { continue; } cs.push((committee.count, committee.name_role.to_owned())); } cs.sort_by_key(|(count, _)| *count); cs.reverse(); // msg can be a max 2000 chars long let mut limit = 2000 - 3; let mut response = vec!["```".to_string()]; for (count, name) in cs { let leading = if count < 10 { " " } else { "" }; let line = format!("{}{} {}", leading, count, name); let length = line.len() + 1; if length < (limit + 3) { response.push(line); limit -= length; } else { break; } } response.push("```".to_string()); response.join("\n") } pub fn register() -> CreateCommand { CreateCommand::new("count") .description("Count Committee Members") // All Committee members are able to add reactions to posts .default_member_permissions(serenity::model::Permissions::ADD_REACTIONS) .add_option( CreateCommandOption::new(CommandOptionType::SubCommand, "committee", "List out the Committee Roles Numbers") .add_sub_option(CreateCommandOption::new(CommandOptionType::Boolean, "all", "List out all the Committee Roles Numbers").required(false)), ) } } pub mod servers { // get the list of all the current clubs/socs use serde::{Deserialize, Serialize}; use serenity::all::{CommandInteraction, CommandOptionType, Context, CreateCommand, CreateCommandOption}; use skynet_discord_bot::common::database::{get_server_config_bulk, DataBase}; use skynet_discord_bot::common::set_roles::committee::get_committees; use skynet_discord_bot::get_now_iso; use sqlx::{Pool, Sqlite}; use std::collections::HashMap; pub async fn run(_command: &CommandInteraction, ctx: &Context) -> String { let db_lock = { let data_read = ctx.data.read().await; data_read.get::().expect("Expected Databse in TypeMap.").clone() }; let db = db_lock.read().await; let mut committees = HashMap::new(); for committee in get_committees(&db).await { committees.insert(committee.id, committee.to_owned()); } let mut cs = vec![]; // pull it from a DB for server_config in get_server_config_bulk(&db).await { if let Some(x) = committees.get(&server_config.wolves_id) { cs.push((server_config.member_current, server_config.member_past, x.name_full.to_owned())); } } // get all members let (wolves_current, wolves_past, total) = get_wolves_total(&db).await; cs.push((total, total, String::from("Skynet Network"))); cs.push((wolves_current, wolves_past, String::from("Clubs/Socs Servers"))); // treat teh committee server as its own thing let committee_current = get_wolves_committee(&db).await; cs.push((committee_current, committee_current, String::from("Committee Server"))); cs.sort_by_key(|(current, _, _)| *current); cs.reverse(); // msg can be a max 2000 chars long let mut limit = 2000 - 3; let mut response = vec!["```".to_string()]; for (current, past, name) in cs { let current_leading = if current < 10 { " " } else if current < 100 { " " } else { "" }; let past_leading = if past < 10 { " " } else if past < 100 { " " } else { "" }; let line = format!("{}{} {}{} {}", current_leading, current, past_leading, past, name); let length = line.len() + 1; // +3 is to account for the closing fense if length < (limit + 3) { response.push(line); limit -= length; } else { break; } } response.push("```".to_string()); response.join("\n") } #[derive(Debug, Clone, Deserialize, Serialize, sqlx::FromRow)] pub struct Count { pub count: i64, } async fn get_wolves_total(db: &Pool) -> (i64, i64, i64) { let current = match sqlx::query_as::<_, Count>( r#" SELECT COUNT(DISTINCT id_wolves) as count FROM server_members JOIN wolves USING (id_wolves) WHERE ( wolves.discord IS NOT NULL AND server_members.expiry > ? ) "#, ) .bind(get_now_iso(true)) .fetch_one(db) .await { Ok(res) => res.count, Err(e) => { dbg!(e); 0 } }; let cns = match sqlx::query_as::<_, Count>( r#" SELECT COUNT(DISTINCT id_wolves) as count FROM server_members JOIN wolves USING (id_wolves) WHERE wolves.discord IS NOT NULL "#, ) .bind(get_now_iso(true)) .fetch_one(db) .await { Ok(res) => res.count, Err(e) => { dbg!(e); 0 } }; let total = match sqlx::query_as::<_, Count>( r#" SELECT COUNT(DISTINCT id_wolves) as count FROM wolves WHERE discord IS NOT NULL "#, ) .fetch_one(db) .await { Ok(res) => res.count, Err(e) => { dbg!(e); 0 } }; (current, cns, total) } async fn get_wolves_committee(db: &Pool) -> i64 { // expiry match sqlx::query_as::<_, Count>( " SELECT count FROM committee_roles WHERE id_wolves = '0' ", ) .fetch_one(db) .await { Ok(res) => res.count, Err(e) => { dbg!(e); 0 } } } pub fn register() -> CreateCommand { CreateCommand::new("count") .description("Count the servers") .default_member_permissions(serenity::model::Permissions::MANAGE_GUILD) .add_option(CreateCommandOption::new(CommandOptionType::SubCommand, "servers", "List out all servers using the skynet bot")) } }