Ported randoms to the DB
+ Also added commands for adding and listing randoms + fmt, clippy failing in a library...
This commit is contained in:
+115
-25
@@ -1,10 +1,12 @@
|
||||
use crate::error::Error;
|
||||
use crate::models::random::RandomConfig;
|
||||
use crate::{command, group, GlobalData, BAD_APPLE};
|
||||
use rand::prelude::IteratorRandom;
|
||||
use rand::thread_rng;
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serenity::client::Context;
|
||||
use serenity::constants::MESSAGE_CODE_LIMIT;
|
||||
use serenity::framework::standard::{Args, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::utils::MessageBuilder;
|
||||
@@ -12,7 +14,7 @@ use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
#[group]
|
||||
#[commands(dad_joke, roll, bad_apple, insult)]
|
||||
#[commands(dad_joke, roll, bad_apple, insult, add_random, list_random)]
|
||||
pub struct Joke;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
@@ -49,10 +51,7 @@ struct RandomCtx {
|
||||
}
|
||||
|
||||
impl RandomCtx {
|
||||
pub async fn new(
|
||||
user: serenity::model::guild::Member,
|
||||
global_data: &GlobalData,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn new(user_name: &str, global_data: &GlobalData) -> Result<Self, Error> {
|
||||
let mut random_image: HashMap<String, String> = HashMap::new();
|
||||
|
||||
for album in &global_data.cfg.albums {
|
||||
@@ -64,28 +63,42 @@ impl RandomCtx {
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
user: (*user.display_name()).clone(),
|
||||
user: user_name.to_string(),
|
||||
random_image,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_random(
|
||||
author_name: &str,
|
||||
global_data: &GlobalData,
|
||||
template: &str,
|
||||
) -> Result<String, Error> {
|
||||
let random_ctx = RandomCtx::new(author_name, global_data)?;
|
||||
|
||||
Ok(tera::Tera::one_off(
|
||||
template,
|
||||
&tera::Context::from_serialize(&random_ctx)?,
|
||||
false,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandResult {
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let templates = global_data.bot_state.templates.get(random_name);
|
||||
|
||||
let templates = if let Some(templates) = templates {
|
||||
templates
|
||||
} else {
|
||||
return Ok(());
|
||||
let random = match RandomConfig::get_random(&global_data.db, random_name)? {
|
||||
None => return Ok(()),
|
||||
Some(r) => r,
|
||||
};
|
||||
|
||||
let template = {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
templates.get_template_names().choose(&mut rng)
|
||||
let response_template_str = match random.get_response()? {
|
||||
None => {
|
||||
msg.reply(&ctx, format!("I'm all out of material for {}", random_name))
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
Some(resp) => resp,
|
||||
};
|
||||
|
||||
let guild_member = msg
|
||||
@@ -94,13 +107,11 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
||||
.member(&ctx.http, msg.author.id)
|
||||
.await?;
|
||||
|
||||
let random_ctx = RandomCtx::new(guild_member, global_data).await?;
|
||||
|
||||
let reply = if let Some(template) = template {
|
||||
templates.render(template, &tera::Context::from_serialize(&random_ctx)?)?
|
||||
} else {
|
||||
"Sorry kid, all out of messages.".to_string()
|
||||
};
|
||||
let reply = render_random(
|
||||
&guild_member.display_name(),
|
||||
global_data,
|
||||
response_template_str,
|
||||
)?;
|
||||
|
||||
msg.reply(&ctx.http, reply).await?;
|
||||
|
||||
@@ -108,7 +119,87 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[example("8ball Funny Response haha")]
|
||||
pub async fn add_random(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
if args.len() < 2 {
|
||||
msg.reply(
|
||||
&ctx.http,
|
||||
"Look kid, you need to provide both the random name and response",
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let random_name = args.parse::<String>()?;
|
||||
args.advance();
|
||||
let random_response = args.rest();
|
||||
|
||||
if let Err(err) = render_random(&msg.author.name, global_data, random_response) {
|
||||
msg.reply(
|
||||
&ctx.http,
|
||||
format!("Template failed test render, try again: {}", err),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
RandomConfig::add_random(&global_data.db, &random_name, random_response)?;
|
||||
msg.reply(&ctx.http, "New random added!").await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[example("8ball Funny Response haha")]
|
||||
pub async fn list_random(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
if args.len() < 1 {
|
||||
msg.reply(
|
||||
&ctx.http,
|
||||
"Look kid, you need to provide both the random name",
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let random_name = args.parse::<String>()?;
|
||||
|
||||
let random = RandomConfig::get_random(&global_data.db, &random_name)?;
|
||||
|
||||
if let Some(random) = random {
|
||||
let mut msg_builder = MessageBuilder::new();
|
||||
msg_builder.push_line(format!("All possible responses for {}:", random_name));
|
||||
|
||||
for resp in random.responses {
|
||||
let line_msg = format!("* {}", resp);
|
||||
|
||||
if (msg_builder.0.len() + line_msg.len()) > MESSAGE_CODE_LIMIT {
|
||||
msg.channel_id.say(&ctx.http, msg_builder.build()).await?;
|
||||
msg_builder.0.clear();
|
||||
}
|
||||
|
||||
msg_builder.push_line(line_msg);
|
||||
}
|
||||
|
||||
if !msg_builder.0.is_empty() {
|
||||
msg.channel_id.say(&ctx.http, msg_builder.build()).await?;
|
||||
}
|
||||
} else {
|
||||
msg.reply(
|
||||
&ctx.http,
|
||||
"*glances to the back room*, nope we ain't got that random",
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[aliases("roll")]
|
||||
#[description("Roll a die!")]
|
||||
async fn roll(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
@@ -168,7 +259,6 @@ async fn bad_apple(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
||||
|
||||
#[command]
|
||||
#[aliases("compliment")]
|
||||
#[only_in(guilds)]
|
||||
async fn insult(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let data = ctx.data.read().await;
|
||||
let global = data.get::<GlobalData>().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user