Added motivate command

+ clippy + fmt
This commit is contained in:
2023-01-01 16:47:34 -06:00
parent 35f157b42a
commit 6693cb4f98
7 changed files with 236 additions and 0 deletions
+9
View File
@@ -35,6 +35,13 @@ pub struct RandomConfig {
pub responses: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct MotivationConfig {
pub album: Vec<String>,
pub action: Vec<String>,
pub goal: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct BotConfig {
pub bot_token: String,
@@ -49,6 +56,8 @@ pub struct BotConfig {
pub wallet_manager: WalletManager,
pub motivation: MotivationConfig,
pub insults: Vec<InsultComplimentTemplate>,
pub compliments: Vec<InsultComplimentTemplate>,
+1
View File
@@ -5,6 +5,7 @@ pub mod color;
pub mod emoji_race;
pub mod fren_coin;
pub mod joke;
pub(crate) mod motivate;
pub mod story;
use crate::discord::fren_coin::give_coin;
+103
View File
@@ -0,0 +1,103 @@
use crate::imgur::{get_album_images, Image};
use crate::{command, group, GlobalData};
use magick_rust::{DrawingWand, MagickWand, PixelWand};
use rand::prelude::IteratorRandom;
use rand::thread_rng;
use serenity::client::Context;
use serenity::framework::standard::{Args, CommandResult};
use serenity::model::channel::{AttachmentType, Message};
use std::borrow::Cow;
#[group]
#[commands(motivation)]
pub struct Motivate;
#[command]
#[only_in(guilds)]
#[description("Let's give you motivation")]
async fn motivation(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
let album = &global_data
.cfg
.motivation
.album
.iter()
.choose(&mut thread_rng())
.unwrap();
let images = get_album_images(&global_data.cfg.imgur_client_id, album).await?;
let motivation_image_link: &Image = images.iter().choose(&mut thread_rng()).unwrap();
let motivation_image_blob = reqwest::get(&motivation_image_link.link)
.await?
.bytes()
.await?;
let action = global_data
.cfg
.motivation
.action
.iter()
.choose(&mut thread_rng())
.unwrap();
let goal = global_data
.cfg
.motivation
.goal
.iter()
.choose(&mut thread_rng())
.unwrap();
let motivation = format!("{} {}", action, goal);
let image = {
let mut wand = MagickWand::new();
let mut border_wand = PixelWand::new();
wand.read_image_blob(motivation_image_blob)?;
border_wand.set_color("white")?;
let width = wand.get_image_width();
let border = width / 100;
wand.border_image(
&border_wand,
border,
border,
magick_rust::bindings::CompositeOperator_OverCompositeOp,
)?;
border_wand.set_color("black")?;
let width = wand.get_image_width();
let border = width * 20 / 100;
wand.border_image(
&border_wand,
border,
border,
magick_rust::bindings::CompositeOperator_OverCompositeOp,
)?;
let text_pos_x = wand.get_image_width() as f64 / 2.0;
let text_pos_y = wand.get_image_height() as f64 - (wand.get_image_height() as f64 * 0.05);
let mut text_wand = DrawingWand::new();
let mut text_color_wand = PixelWand::new();
text_color_wand.set_color("white")?;
text_wand.set_fill_color(&text_color_wand);
text_wand.set_font_size(0.07*(wand.get_image_width() as f64));
text_wand.set_text_alignment(magick_rust::bindings::AlignType_CenterAlign);
wand.annotate_image(&text_wand, text_pos_x, text_pos_y, 0.0, &motivation)?;
wand.write_image_blob("png")?
};
msg.channel_id
.send_message(&ctx.http, |m| {
m.content("Today's motivation")
.add_file(AttachmentType::Bytes {
data: Cow::from(image),
filename: "motivate.png".to_string(),
})
})
.await?;
Ok(())
}
+2
View File
@@ -25,6 +25,8 @@ impl Display for ImgurError {
}
}
impl std::error::Error for ImgurError {}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AlbumData {
images: Option<Vec<Image>>,
+9
View File
@@ -8,13 +8,17 @@ mod wallet;
use crate::config::{Args, BotConfig, Channel, GlobalData};
use crate::discord::emoji_race::RaceMessage;
use crate::discord::unrecognised_command_hook;
use magick_rust::magick_wand_genesis;
use serenity::framework::standard::macros::{command, group, help, hook};
use serenity::framework::standard::StandardFramework;
use serenity::prelude::*;
use std::sync::Once;
use structopt::StructOpt;
const BAD_APPLE: &str = include_str!("assets/bad_apple.txt");
static START: Once = Once::new();
#[tokio::main]
async fn main() {
let args: Args = Args::from_args();
@@ -27,6 +31,10 @@ async fn main() {
}
};
START.call_once(|| {
magick_wand_genesis();
});
let global_data = match GlobalData::new(args, cfg).await {
Ok(global_data) => global_data,
Err(err) => {
@@ -45,6 +53,7 @@ async fn main() {
.group(&discord::story::STORY_GROUP)
.group(&discord::fren_coin::FRENCOIN_GROUP)
.group(&discord::emoji_race::EMOJIRACE_GROUP)
.group(&discord::motivate::MOTIVATE_GROUP)
.unrecognised_command(unrecognised_command_hook)
.bucket("bad_apple", |b| b.delay(60 * 10))
.await