FrenBot/src/discord/album.rs
2023-01-20 15:01:31 -07:00

164 lines
4.1 KiB
Rust

use crate::error::Error;
use crate::imgur::get_album_images;
use crate::models::album::AlbumConfig;
use crate::{command, group, GlobalData};
use j_db::model::JdbModel;
use serenity::client::Context;
use serenity::framework::standard::{Args, CommandResult};
use serenity::model::channel::Message;
#[group]
#[commands(add_album, remove_album, list_albums)]
pub struct Album;
#[command]
#[only_in(guilds)]
#[min_args(2)]
#[max_args(2)]
#[description("Add an imgur album command.")]
#[usage("<name> <album link>")]
async fn add_album(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let album_name = args.parse::<String>()?;
args.advance();
let album_id = args.parse::<String>()?;
let album_id: String = if album_id.contains("imgur") {
let parts: Vec<&str> = album_id.split("/a/").collect();
if parts.len() == 2 {
parts[1].to_string()
} else {
msg.reply(&ctx.http, "Invalid imgur album, check your link.")
.await?;
return Ok(());
}
} else {
album_id
};
let mut data = ctx.data.write().await;
let global_data = data.get_mut::<GlobalData>().unwrap();
let images = match get_album_images(&global_data.cfg.imgur_client_id, &album_id).await {
Ok(img) => img,
Err(e) => {
msg.reply(
&ctx.http,
"Error adding album, check your link and try again",
)
.await?;
println!("Error adding album: {}", e);
return Ok(());
}
};
global_data
.db
.insert(AlbumConfig::new(&album_name, &album_id))?;
global_data
.bot_state
.albums
.insert(album_name.clone(), images);
msg.reply(&ctx.http, format!("{} album added!", album_name))
.await?;
Ok(())
}
#[command]
#[only_in(guilds)]
#[max_args(1)]
#[description("Remove an imgur album command.")]
#[usage("<name>")]
async fn remove_album(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
let album_name = args.parse::<String>()?;
let mut data = ctx.data.write().await;
let global_data = data.get_mut::<GlobalData>().unwrap();
let album = AlbumConfig::get_album_by_name(&global_data.db, &album_name)?;
match album {
None => {
msg.reply(
&ctx.http,
"I already got rid of that one, or I never had it. Who knows!",
)
.await?;
}
Some(album) => {
global_data.bot_state.albums.remove(&album_name);
global_data.db.remove::<AlbumConfig>(album.id().unwrap())?;
msg.reply(&ctx.http, format!("{} album removed!", album_name))
.await?;
}
}
Ok(())
}
#[command]
#[aliases("albums")]
#[description("List all album commands.")]
#[only_in(guilds)]
async fn list_albums(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
let album_names: Vec<String> = global_data
.db
.filter(|_, _: &AlbumConfig| true)?
.map(|album| album.name)
.collect();
if album_names.is_empty() {
msg.reply(&ctx.http, "There are no albums configured!")
.await?;
} else {
msg.reply(
&ctx.http,
format!("**Albums**:\n{}", album_names.join("\n")),
)
.await?;
}
Ok(())
}
pub async fn parse_album(
ctx: &Context,
msg: &Message,
album_name: &str,
tags: Vec<&str>,
) -> Result<bool, Error> {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
let img = match global_data.bot_state.get_image(album_name, tags) {
Ok(img) => img,
Err(err) => {
return match err {
Error::NoAlbumFound => Ok(false),
_ => Err(err),
}
}
};
if let Some(img) = img {
msg.reply(&ctx.http, img.link).await?;
} else {
msg.reply(&ctx.http, "No image found :(").await?;
}
Ok(true)
}