142 lines
4.1 KiB
Rust
142 lines
4.1 KiB
Rust
use crate::models::motivation::{Motivation, MotivationConfig};
|
|
use crate::{command, group, GlobalData};
|
|
use magick_rust::{DrawingWand, MagickWand, PixelWand};
|
|
use serenity::builder::{CreateAttachment, CreateMessage};
|
|
use serenity::client::Context;
|
|
use serenity::framework::standard::{Args, CommandError, CommandResult};
|
|
use serenity::model::channel::Message;
|
|
use std::borrow::Cow;
|
|
|
|
#[group]
|
|
#[commands(
|
|
motivation,
|
|
motivation_add_album,
|
|
motivation_add_action,
|
|
motivation_add_goal
|
|
)]
|
|
pub struct Motivate;
|
|
|
|
pub async fn create_motivation_image(motivation: Motivation) -> Result<Vec<u8>, CommandError> {
|
|
let motivation_image_blob = tokio::fs::read(motivation.image_path).await?;
|
|
|
|
let text = format!("{} {}", motivation.action, motivation.goal);
|
|
|
|
let mut wand = MagickWand::new();
|
|
let mut border_wand = PixelWand::new();
|
|
wand.read_image_blob(motivation_image_blob)?;
|
|
|
|
border_wand.set_color(&motivation.border_color)?;
|
|
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, &text)?;
|
|
Ok(wand.write_image_blob("png")?)
|
|
}
|
|
|
|
#[command]
|
|
#[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_name = if args.is_empty() {
|
|
None
|
|
} else {
|
|
Some(args.parse::<String>()?)
|
|
};
|
|
|
|
let motivation = MotivationConfig::generate_motivation(
|
|
&global_data.db,
|
|
&global_data.cfg.img_path,
|
|
"white",
|
|
album_name,
|
|
)
|
|
.await?;
|
|
|
|
let image = create_motivation_image(motivation).await?;
|
|
|
|
msg.channel_id
|
|
.send_message(
|
|
&ctx.http,
|
|
CreateMessage::new()
|
|
.content("Today's motivation")
|
|
.add_file(CreateAttachment::bytes(
|
|
Cow::from(image),
|
|
"motivate.png".to_string(),
|
|
)),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Add imgur album to the motivation generator")]
|
|
async fn motivation_add_album(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
|
|
let album = args.parse::<String>()?;
|
|
|
|
MotivationConfig::add_album(&global_data.db, &album)?;
|
|
|
|
msg.reply(&ctx.http, "Done ;)").await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Add an action to the motivation generator")]
|
|
async fn motivation_add_action(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
|
|
let action = args.rest();
|
|
|
|
MotivationConfig::add_action(&global_data.db, action)?;
|
|
|
|
msg.reply(&ctx.http, "Done ;)").await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[command]
|
|
#[description("Add goal to the motivation generator")]
|
|
async fn motivation_add_goal(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let data = ctx.data.read().await;
|
|
let global_data = data.get::<GlobalData>().unwrap();
|
|
|
|
let goal = args.rest();
|
|
|
|
MotivationConfig::add_goal(&global_data.db, goal)?;
|
|
|
|
msg.reply(&ctx.http, "Done ;)").await?;
|
|
|
|
Ok(())
|
|
}
|