Skip to content

Commit

Permalink
feat: add support for !gif command (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
smolck authored May 12, 2024
1 parent 41d3bf5 commit d32fdd3
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 27 deletions.
50 changes: 41 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ lto = true

[dependencies]
ureq = "2.3.0"
serde = { version = "1.0.201", features = ["serde_derive"] }
serde_json = "1.0.69"
fancy-regex = "0.7.1" # Used over `regex` for the look-around support
pulldown-cmark = "0.9.0"
Expand Down
7 changes: 7 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub enum Command<'a> {
Help { docs: Vec<&'a str> },
Sandwich { to: &'a str },
Url { url: &'a str },
Gif { search: String },
}

pub struct CommandParser {
Expand Down Expand Up @@ -62,6 +63,12 @@ impl CommandParser {
let args = args?;
Some(Sandwich { to: args[0] })
}
"gif" => {
let args = args?;
Some(Gif {
search: args.join(" "),
})
}
x => self.url_commands_json.get(x).map(|url| Url {
url: url.as_str().unwrap(),
}),
Expand Down
140 changes: 140 additions & 0 deletions src/gif.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#![allow(unused)] // just cuz we have JSON deserialized stuff that we don't all use
// TODO(smolcK): we could do something about that idk, I like having the types
use serde::Deserialize;
use std::collections::HashMap;

#[derive(Deserialize)]
struct Response {
next: String,
results: Vec<ResponseObject>,
}

#[derive(Deserialize)]
struct ResponseObject {
created: f32,
hasaudio: bool,
id: String,
media_formats: HashMap<ContentFormat, MediaObject>,
}

#[derive(Deserialize)]
struct MediaObject {
url: String,
dims: [i32; 2], // width, height
duration: f32,
size: i32,
}

#[derive(PartialEq, Eq, Hash, Deserialize)]
#[serde(rename_all = "lowercase")]
// TODO(smolck): No idea if this is right lol
enum ContentFormat {
// Preview,
Gif,
#[serde(rename = "gifpreview")]
GifPreview,

MediumGif,
#[serde(rename = "mediumgifpreview")]
MediumGifPreview,

TinyGif,
#[serde(rename = "tinygifpreview")]
TinyGifPreview,

NanoGif,
#[serde(rename = "nanogifpreview")]
NanoGifPreview,

Mp4,
#[serde(rename = "mp4preview")]
Mp4Preview,

LoopedMp4,
#[serde(rename = "loopedmp4preview")]
LoopedMp4Preview,

TinyMp4,
#[serde(rename = "tinymp4preview")]
TinyMp4Preview,

NanoMp4,
#[serde(rename = "nanomp4preview")]
NanoMp4Preview,

Webm,
#[serde(rename = "webmpreview")]
WebmPreview,

TinyWebm,
#[serde(rename = "tinywebmpreview")]
TinyWebmPreview,

NanoWebm,
#[serde(rename = "nanowebmpreview")]
NanoWebmPreview,

#[serde(rename = "webp_transparent")]
WebpTransparent,
#[serde(rename = "webppreview_transparent")]
WebpPreviewTransparent,

#[serde(rename = "tinywebp_transparent")]
TinyWebpTransparent,
#[serde(rename = "tinywebppreview_transparent")]
TinyWebpPreviewTransparent,

#[serde(rename = "nanowebp_transparent")]
NanoWebpTransparent,
#[serde(rename = "nanowebppreview_transparent")]
NanoWebpPreviewTransparent,

#[serde(rename = "gif_transparent")]
GifTransparent,
#[serde(rename = "gifpreview_transparent")]
GifPreviewTransparent,

#[serde(rename = "tinygif_transparent")]
TinyGifTransparent,
#[serde(rename = "tinygifpreview_transparent")]
TinyGifPreviewTransparent,

#[serde(rename = "nanogif_transparent")]
NanoGifTransparent,
#[serde(rename = "nanogifpreview_transparent")]
NanoGifPreviewTransparent,
}

pub struct Gif {
pub height: i32,
pub width: i32,
pub size: i32,
pub url: String,
}

impl Gif {
pub fn search(agent: &ureq::Agent, api_key: &str, query: &str) -> Self {
let response = agent
.get("https://tenor.googleapis.com/v2/search")
.set("Accept", "application/json")
.set("Content-Type", "application/json")
.set("Charset", "utf-8")
// TODO(smolck): I hope this sanitizes this cuz it's user input lol
.query("q", query)
.query("key", api_key)
.query("limit", "1")
.call()
.unwrap();

let response: Response = serde_json::de::from_reader(&mut response.into_reader()).unwrap();
let gif_info = &response.results[0].media_formats[&ContentFormat::TinyGif];
let [width, height] = gif_info.dims;

Self {
width,
height,
size: gif_info.size,
url: gif_info.url.clone(),
}
}
}
Loading

0 comments on commit d32fdd3

Please sign in to comment.