discord-bot/src/commands/count.rs

257 lines
6.7 KiB
Rust
Raw Normal View History

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::<DataBase>().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")
2025-02-28 10:58:44 +00:00
// 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
2025-03-14 04:03:20 +00:00
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;
2025-03-14 04:03:20 +00:00
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::<DataBase>().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()));
}
}
2025-03-14 04:03:20 +00:00
// 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")));
2025-03-14 04:03:20 +00:00
// 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")));
2025-03-14 04:03:20 +00:00
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")
}
2025-03-14 04:03:20 +00:00
#[derive(Debug, Clone, Deserialize, Serialize, sqlx::FromRow)]
pub struct Count {
pub count: i64,
}
async fn get_wolves_total(db: &Pool<Sqlite>) -> (i64, i64, i64) {
let current = match sqlx::query_as::<_, Count>(
2025-03-14 04:03:20 +00:00
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 > ?
)
2025-03-14 04:03:20 +00:00
"#,
)
.bind(get_now_iso(true))
2025-03-14 04:03:20 +00:00
.fetch_one(db)
.await
{
Ok(res) => res.count,
Err(e) => {
dbg!(e);
0
}
};
let cns = match sqlx::query_as::<_, Count>(
2025-03-14 04:03:20 +00:00
r#"
SELECT COUNT(DISTINCT id_wolves) as count
FROM server_members
JOIN wolves USING (id_wolves)
WHERE wolves.discord IS NOT NULL
2025-03-14 04:03:20 +00:00
"#,
)
.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)
2025-03-14 04:03:20 +00:00
}
async fn get_wolves_committee(db: &Pool<Sqlite>) -> 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"))
}
}