Move to poise, add slash commands

This commit is contained in:
Elnu 2022-11-14 23:05:17 -08:00
parent d397bb7117
commit 9e9eb48025
8 changed files with 385 additions and 404 deletions

View file

@ -1,9 +1,6 @@
use rand::seq::IteratorRandom;
use serde_json::Map;
use serde_json::Value;
use serenity::framework::standard::{Args, CommandResult};
use serenity::model::prelude::*;
use serenity::prelude::*;
use std::collections::HashMap;
use std::env;
use std::fs;
@ -12,6 +9,9 @@ use std::fs::OpenOptions;
use std::io::Read;
use std::io::Write;
use std::process::Command;
use crate::serenity;
use crate::Error;
use crate::{Context, PrefixContext};
pub fn get_challenge_number() -> i32 {
let challenge_dir = format!("{}/content/challenges", env::var("HUGO").unwrap());
@ -90,8 +90,8 @@ pub fn set_submission_data(submission_data: Vec<Value>) {
.unwrap();
}
pub fn is_matching_submission(submission: &Value, msg: &Message) -> bool {
submission["id"].as_str().unwrap() == msg.author.id.as_u64().to_string()
pub fn is_matching_submission(submission: &Value, author: &serenity::User) -> bool {
submission["id"].as_str().unwrap() == author.id.as_u64().to_string()
}
pub fn to_fullwidth(string: &str) -> String {
@ -153,12 +153,11 @@ pub fn set_guild_data(guild_data: Map<String, Value>) {
}
pub async fn send(
ctx: &Context,
msg: &Message,
ctx: Context<'_>,
message: &str,
ping: bool,
pin: bool,
) -> CommandResult {
) -> Result<(), Error> {
let guild_data = get_guild_data();
let mut announcements_count = 0;
for (_guild, data) in guild_data.iter() {
@ -166,7 +165,7 @@ pub async fn send(
if !data.contains_key("submissionChannel") {
continue;
}
let channel = ChannelId(
let channel = serenity::ChannelId(
data["submissionChannel"]
.as_str()
.unwrap()
@ -181,6 +180,7 @@ pub async fn send(
));
}
message_to_send.push_str(message);
let ctx = ctx.discord();
let sent_message = channel
.send_message(&ctx.http, |e| {
e.content(message_to_send);
@ -198,8 +198,7 @@ pub async fn send(
}
announcements_count += 1;
}
msg.reply(
&ctx.http,
ctx.say(
format!(
"Announced to {} server{}!",
announcements_count,
@ -222,21 +221,20 @@ pub fn get_so_diagram(kanji: char) -> String {
}
pub async fn display_kanji(
ctx: &Context,
msg: &Message,
ctx: Context<'_>,
kanji: char,
comment: &str,
) -> CommandResult {
msg.reply(&ctx.http, format!("{}{}", kanji, comment))
) -> Result<(), Error> {
ctx.say(format!("{}{}", kanji, comment))
.await?;
let url = get_so_diagram(kanji);
let client = reqwest::Client::new();
let request = client.head(&url).build().unwrap();
let response = client.execute(request).await?.status();
let link_validated = response != reqwest::StatusCode::NOT_FOUND;
msg.channel_id
ctx.channel_id()
.say(
&ctx.http,
&ctx.discord().http,
if link_validated {
&url
} else {
@ -301,10 +299,9 @@ pub fn get_kanji_info(kanji: char) -> String {
pub async fn random_kanji(
category: &str,
ctx: &Context,
msg: &Message,
mut args: Args,
) -> CommandResult {
ctx: Context<'_>,
subcategory: Option<String>,
) -> Result<(), Error> {
let lists_data = get_lists_data();
let category = &lists_data[category];
let default_version = category["default"].as_str().unwrap();
@ -312,10 +309,9 @@ pub async fn random_kanji(
match list.as_str() {
Some(string) => {
let kanji = random_from_string(string);
display_kanji(&ctx, &msg, kanji, "").await?;
display_kanji(ctx, kanji, "").await?;
}
None => {
let subcategory = args.single::<String>();
let subcategories = list.as_object().unwrap();
let subcategory_list = {
let mut string = String::from("\n");
@ -335,49 +331,40 @@ pub async fn random_kanji(
));
string
};
match subcategory {
Ok(string) => {
let string = string.to_uppercase();
if string == "ALL" {
let subcategory_key = subcategories
.keys()
.choose(&mut rand::thread_rng())
.unwrap();
let list = subcategories[subcategory_key].as_str().unwrap();
let kanji = random_from_string(&list);
display_kanji(&ctx, &msg, kanji, &format!(", **{}**", subcategory_key))
.await?;
} else if subcategories.contains_key(&string) {
let list = list[&string].as_str().unwrap();
let kanji = random_from_string(&list);
display_kanji(&ctx, &msg, kanji, "").await?;
} else {
let message = format!(
"That is an invalid subcategory. Please use {}.",
&subcategory_list
);
msg.reply(&ctx.http, message).await?;
}
}
Err(_) => {
let mut message = String::from("Please specify a subcategory: ");
message.push_str(&subcategory_list);
msg.reply(&ctx.http, message).await?;
}
let subcategory = subcategory.unwrap().to_uppercase();
if subcategory == "ALL" {
let subcategory_key = subcategories
.keys()
.choose(&mut rand::thread_rng())
.unwrap();
let list = subcategories[subcategory_key].as_str().unwrap();
let kanji = random_from_string(&list);
display_kanji(ctx, kanji, &format!(", **{}**", subcategory_key))
.await?;
} else if subcategories.contains_key(&subcategory) {
let list = list[&subcategory].as_str().unwrap();
let kanji = random_from_string(&list);
display_kanji(ctx, kanji, "").await?;
} else {
let message = format!(
"That is an invalid subcategory. Please use {}.",
&subcategory_list
);
ctx.say(message).await?;
}
}
}
Ok(())
}
pub fn get_avatar(user: &User) -> String {
pub fn get_avatar(user: &serenity::User) -> String {
match user.avatar_url() {
Some(avatar_url) => avatar_url,
None => user.default_avatar_url(),
}
}
pub async fn leaderboard(ctx: &Context) -> CommandResult {
pub async fn leaderboard(ctx: &PrefixContext<'_>) -> Result<(), Error> {
const LENGTH: usize = 10;
let mut submission_counts: HashMap<String, u32> = HashMap::new();
for challenge in 1..get_challenge_number() + 1 {
@ -396,12 +383,10 @@ pub async fn leaderboard(ctx: &Context) -> CommandResult {
let mut leaderboard_html = String::from("<table id=\"leaderboard\">");
for (i, (id, count)) in top_submitters[0..LENGTH].iter().enumerate() {
let place = i + 1;
let user = UserId(id.parse::<u64>().unwrap())
.to_user(&ctx.http)
.await?;
let user = &ctx.msg.author;
let avatar = get_avatar(&user);
let profile = format!("https://discord.com/users/{id}");
let name = user.name;
let name = &user.name;
let discriminator = user.discriminator;
leaderboard_html.push_str(&format!("<tr><td>{place}</td><td><a href=\"{profile}\" target=\"_blank\" class=\"no-underline\"><img src=\"{avatar}\" alt=\"avatar\"> <span class=\"underline\">{name}<span class=\"muted\">#{:0>4}</span></span></a></td><td>{count}</td></tr>", discriminator));
}