aboutsummaryrefslogblamecommitdiff
path: root/src/commands/pony.rs
blob: cf18cc9f7285f2e589a17d9821b3c40bb921de71 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                        
                        














                                            
                        














                                                              
                          


                                                          




                                                                       
                                        













                                                                                      

                                                                             


                    
                   
                                                    
         











                                                  





                                   
                          



                                                      

                





                                                                                              
                                        













                                                                                      

                                                                             


                    

                                                    
         

      


          

















                                                                                                  
                                                                           





                                                                                                              
                                        

























                                                                             











                                                           
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<u64>,
    pub tags: Vec<String>,
    pub sourceURL: Option<String>,
    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::<PonyResponse>()
        .await?;

    match response_msg.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 <tags>
/// 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::<PonyResponse>()
            .await?;

    match response_msg.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 <id>
#[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::<PonyResponse>().await?,
        Err(_) => {
            response_msg.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.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>) -> 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
}