Files
ByteDiceAssistant/src/cmds/reddit/top.rs
T

77 lines
2.2 KiB
Rust

use std::collections::HashMap;
use crate::{Context, Error, db::{generic::get_json_mutex, reddit::POSTS_KEY}, re_cmds::generic_fns::send_embed_for_post};
#[derive(poise::ChoiceParameter, PartialEq)]
enum TopCategory {
Upvotes,
ModVotes,
Oldest,
Newest
}
#[poise::command(
slash_command,
prefix_command,
rename = "re_topposts",
category = "re",
required_bot_permissions = "SEND_MESSAGES | VIEW_CHANNEL | EMBED_LINKS"
)]
/// Shows the top N (up to 10, default is 3) posts within a certain category, such as upvotes.
pub async fn cmd(
ctx: Context<'_>,
#[description = "The sorting criteria, such as upvotes."]
category: TopCategory,
#[description = "The amount of posts to show (max 10, default is 3)."]
#[min = 1]
#[max = 10]
amount: Option<u8>
) -> Result<(), Error>
{
let mut all: HashMap<&str, i32> = HashMap::new();
let posts = &get_json_mutex(&ctx.data().reddit_data).await?[POSTS_KEY];
let posts_u = posts.as_object().unwrap();
for (url, dat) in posts_u {
if dat["removed"]["removed"].as_bool().unwrap() { continue; }
let val: i32 = match category {
TopCategory::Upvotes => dat["post_data"]["upvotes"].as_i64().unwrap() as i32,
TopCategory::ModVotes => dat["votes"]["mod_voters"].as_array().unwrap().len() as i32,
TopCategory::Oldest
| TopCategory::Newest => dat["post_data"]["date_unix"].as_i64().unwrap() as i32,
};
all.insert(url, val);
}
let amount_u = amount.unwrap_or(3);
let amount_clamped = amount_u.clamp(1, 10);
let top =
if category != TopCategory::Oldest
{ largest_n (&all, amount_clamped as usize) }
else { smallest_n(&all, amount_clamped as usize) };
for post in top {
let url = post.0;
let _ = send_embed_for_post(ctx, posts_u[url].clone(), url).await;
}
return Ok(());
}
fn largest_n<'a>(map: &'a HashMap<&'a str, i32>, n: usize) -> Vec<(&'a str, i32)> {
let mut vec: Vec<_> = map.iter().collect();
vec.sort_unstable_by(|a, b| b.1.cmp(a.1));
vec.into_iter().take(n).map(|(&k, &v)| (k, v)).collect()
}
fn smallest_n<'a>(map: &'a HashMap<&'a str, i32>, n: usize) -> Vec<(&'a str, i32)> {
let mut vec: Vec<_> = map.iter().collect();
vec.sort_unstable_by(|a, b| a.1.cmp(b.1));
vec.into_iter().take(n).map(|(&k, &v)| (k, v)).collect()
}