use crate::{Context, Error}; use poise::serenity_prelude as serenity; use serde::Deserialize; use std::collections::HashMap; #[derive(Deserialize)] pub struct PonyResponse { pub pony: Pony, } #[allow(non_snake_case)] #[derive(Deserialize)] pub struct Pony { pub id: u64, pub derpiId: Option, pub tags: Vec, pub sourceURL: Option, pub height: u64, pub width: u64, pub aspectRatio: f64, pub mimeType: String, pub originalFormat: String, pub representations: PonyRepresentation, } #[allow(non_snake_case)] #[derive(Deserialize)] pub struct PonyRepresentation { pub full: String, pub tall: String, pub large: String, pub medium: String, pub small: String, pub thumb: String, pub thumbSmall: String, pub thumbTiny: String, } /// Retrieves a random SFW pony image #[poise::command(slash_command, prefix_command)] pub async fn randpony(ctx: Context<'_>) -> Result<(), Error> { let response_msg = ctx .say("Fetching a random pony image, please wait!") .await?; let res = reqwest::get("https://theponyapi.com/api/v1/pony/random") .await? .json::() .await?; match response_msg.unwrap().message().await { Ok(mut msg) => { msg.edit(&ctx.discord(), |m| { m.content(""); m.embed(|e| { e.title("Pony!"); e.image(res.pony.representations.full.clone()); let res_tags = get_tags_as_string(res.pony.tags); e.field("Tags", format!("{:?}", res_tags), true); e.field("Image URL", res.pony.representations.full.clone(), true); if let Some(url) = res.pony.sourceURL { e.field("Source", url, true); } else { e.field("Source", "None found", true); } e.footer(|f| f.text(format!("Pony ID: {}", res.pony.id))) }) }) .await?; } Err(_) => { ctx.say("Error editing message").await?; } }; Ok(()) } /// Get a random pony image based on a set of tags /// /// Usage: /// ~tpony /// Example: /// ~tpony twilight sparkle,fluttershy #[poise::command(slash_command, prefix_command)] pub async fn tpony( ctx: Context<'_>, #[description = "List of tags"] #[rest] tags: String, ) -> Result<(), Error> { let response_msg = ctx .say(format!( "Fetching pony image based on tags: {:?}", tags.clone() )) .await?; let res = reqwest::get(format!("https://theponyapi.com/api/v1/pony/random?q={}", tags).as_str()) .await? .json::() .await?; match response_msg.unwrap().message().await { Ok(mut msg) => { msg.edit(&ctx.discord(), |m| { m.content(""); m.embed(|e| { e.title("Pony!"); e.image(res.pony.representations.full.clone()); let res_tags = get_tags_as_string(res.pony.tags); e.field("Tags", format!("{:?}", res_tags), true); e.field("Image URL", res.pony.representations.full.clone(), true); if let Some(url) = res.pony.sourceURL { e.field("Source", url, true); } else { e.field("Source", "None found", true); } e.footer(|f| f.text(format!("Pony ID: {}", res.pony.id))) }) }) .await?; } Err(e) => { ctx.say("Error editing message").await?; } }; Ok(()) } /// Gets a specific pony based on the ID /// /// Usage: /// /ponybyid #[poise::command(slash_command, prefix_command)] pub async fn ponybyid( ctx: Context<'_>, #[description = "The ID to search for"] id: String, ) -> Result<(), Error> { let response_msg = ctx .say(format!("Fetching pony based on id: {}", id)) .await?; let res = match reqwest::get(format!("https://theponyapi.com/api/v1/pony/id/{}", id).as_str()) .await { Ok(r) => r.json::().await?, Err(_) => { response_msg.unwrap().message().await.unwrap().edit(ctx.discord(), |m| { m.content("There was an error fetching that pony, please double-check your ID and try again.") }).await?; return Ok(()); } }; match response_msg.unwrap().message().await { Ok(mut msg) => { msg.edit(&ctx.discord(), |m| { m.content(""); m.embed(|e| { e.title("Pony!"); e.image(res.pony.representations.full.clone()); let res_tags = get_tags_as_string(res.pony.tags); e.field("Tags", format!("{:?}", res_tags), true); if let Some(url) = res.pony.sourceURL { e.field("Source", url, true); } else { e.field("Source", "None found", true); } e.footer(|f| f.text(format!("Pony ID: {}", res.pony.id))) }) }) .await? } Err(e) => { ctx.say("Could not edit message").await?; } }; Ok(()) } fn get_tags_as_string(tags: Vec) -> String { let mut response = String::from(tags.get(0).unwrap()); for (i, s) in tags.iter().enumerate() { if i > 0 { response.push_str(format!(", {}", s).as_str()); } else { continue; } } response }