diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3ad93ca --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tenor-v2"] + path = tenor-v2 + url = ssh://git@forgejo.djkato.net:222/HLadislav/tenor-v2.git diff --git a/Cargo.toml b/Cargo.toml index 84a692b..4b1081e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ sqlx = {version="0.8.2", features=["runtime-tokio", "sqlite"]} json = "0.12.4" reqwest = "0.12.7" form_urlencoded = "1.2.1" +tenorv2 = { path = "./tenor-v2/tenorv2" } [features] DEBUG = [] diff --git a/src/other/mod.rs b/src/other/mod.rs index 992a442..97abf42 100644 --- a/src/other/mod.rs +++ b/src/other/mod.rs @@ -1,4 +1 @@ -pub mod notice; -pub mod tenor_builder; -pub mod tenor_types; -pub mod tenor; \ No newline at end of file +pub mod notice; \ No newline at end of file diff --git a/src/other/notice.rs b/src/other/notice.rs index 09a94a5..3b07c4c 100644 --- a/src/other/notice.rs +++ b/src/other/notice.rs @@ -12,7 +12,7 @@ use crate::util::utilities; use std::sync::Arc; -use super::{tenor, tenor_builder::Tenor, tenor_types::{ContentFilter, MediaFilter}}; +use tenorv2::{tenor, tenor_builder::Tenor, tenor_types::{ContentFilter, MediaFilter}}; // pub async fn notice_wrapper(http: Arc) { pub async fn notice_wrapper(ctx: Context) { @@ -48,10 +48,12 @@ async fn announce_event(guild_id: GuildId, name: &str, special_message: &str, ht } async fn celebrate_birthday(guild_id: GuildId, user_id: UserId, nick: &str, http: Arc) -> anyhow::Result<()> { - + use anyhow::Context; + const LIMIT: u8 = 20; let tenor_response = Tenor::new() + .key(dotenv_var("TENORV2").context("TENORV2 key not found in the .env")?) .random(true) .contentfilter(ContentFilter::low) .add_media_filter(MediaFilter::gif) diff --git a/src/other/tenor.rs b/src/other/tenor.rs deleted file mode 100644 index 6ac9049..0000000 --- a/src/other/tenor.rs +++ /dev/null @@ -1,17 +0,0 @@ -use super::tenor_types::MediaFilter; - -use json::JsonValue; - -pub fn get_gif_url(filter: MediaFilter, tenor_response: JsonValue) -> anyhow::Result> { - use anyhow::Context; - - let mut urls: Vec = Vec::new(); - let results = tenor_response["results"].members(); - - for result in results { - let url = result["media_formats"][filter.to_string()]["url"].as_str().context("Value not found in Json")?; - urls.push(url.to_string()); - } - - Ok(urls) -} \ No newline at end of file diff --git a/src/other/tenor_builder.rs b/src/other/tenor_builder.rs deleted file mode 100644 index 4f0de5a..0000000 --- a/src/other/tenor_builder.rs +++ /dev/null @@ -1,171 +0,0 @@ -use json::JsonValue; - -use std::collections::HashSet; - -use anyhow::Error; - -use crate::util::security::dotenv_var; - -use super::tenor_types::{ContentFilter, ArRange, MediaFilter}; - -pub struct Tenor { - /// Specify the country of origin for the request. To do so, provide its two-letter ISO 3166-1 country code. - country: Option, - /// Specify the default language to interpret the search string using ISO 639-1 language code + optional two-letter ISO 3166-1 country code. - /// You can use the country code that you provide in locale to differentiate between dialects of the given language. - locale: Option, - /// Specify the content safety filter level - /// The default value is off - contentfilter: Option, - /// Set of GIF formats to filter - /// By default returns all formats - media_filter: Option>, - /// Filter to only include GIFS with the aspect ratios that fit within range - /// Default value is all - /// wide: 0.42 <= aspect ratio <= 2.36 - /// standard: 0.56 <= aspect ratio <= 1.78 - ar_range: Option, - /// Whether to randomly order the response - /// Default value is false - random: Option, - /// Fetch up to the specified number of results - /// Default value (for Tenor) is 20 and maximum is 50 - /// if smaller or greater values is provided, the value is clamped to the min/max - limit: Option, - /// Retrieve results that start at the position - /// Use a non-zero, non-empty value from next, returned by the API response, to get the next set of results - pos: Option -} - -impl Tenor { - pub fn new() -> Self { - Tenor { - country: None, - locale: None, - contentfilter: None, - media_filter: None, - ar_range: None, - random: None, - limit: None, - pos: None - } - } - - /// Replaces current country with the passed one - pub fn country(mut self, country: String) -> Self { - self.country = Some(country); - self - } - - /// Replaces current locale with the passed one - pub fn locale(mut self, locale: String) -> Self { - self.locale = Some(locale); - self - } - - /// Replaces current media_filter with the passed one - pub fn media_filter(mut self, filter: HashSet) -> Self { - self.media_filter = Some(filter); - self - } - - /// Replaces current contentfilter with the passed one - pub fn contentfilter(mut self, filter: ContentFilter) -> Self { - self.contentfilter = Some(filter); - self - } - - /// Replaces current media_filter with the passed one - pub fn add_media_filter(mut self, filter: MediaFilter) -> Self { - if self.media_filter.is_none() { - let mut set = HashSet::new(); - set.insert(filter); - self.media_filter = Some(set); - } - else { - self.media_filter.as_mut().unwrap().insert(filter); - } - self - } - - pub fn ar_range(mut self, range: ArRange) -> Self { - self.ar_range = Some(range); - self - } - - pub fn random(mut self, random: bool) -> Self { - self.random = Some(random); - self - } - - pub fn limit(mut self, mut limit: u8) -> Self { - if limit < 20 { - limit = 20; - } - else if limit > 50 { - limit = 50; - } - - self.limit = Some(limit); - self - } - - pub fn pos(mut self, pos: String) -> Self { - self.pos = Some(pos); - self - } - - pub async fn search(self, query: &str) -> Result { - use anyhow::Context; - - let q: String = form_urlencoded::byte_serialize(query.as_bytes()).collect(); - - let base_url = "https://tenor.googleapis.com/v2/search?"; - let api_key = dotenv_var("TENORV2").context("TENORV2 key not found in the .env")?; - - let mut request = format!("{base_url}q={q}&key={api_key}"); - - if self.country.is_some() { - request.push_str(&format!("&country={}", self.country.unwrap())); - } - - if self.locale.is_some() { - request.push_str(&format!("&locale={}", self.locale.unwrap())); - } - - if self.contentfilter.is_some() { - request.push_str(&format!("&contentfilter={}", self.contentfilter.unwrap())) - } - - if self.media_filter.is_some() && self.media_filter.as_ref().unwrap().len() > 0 { - request.push_str( - format!("&media_filter={}", - self.media_filter.unwrap() - .iter() - .map(|e| e.to_string()) - .collect::>() - .join(",") - .as_str() - ).as_str() - ); - } - - if self.ar_range.is_some() { - request.push_str(&format!("&ar_range={}", self.ar_range.unwrap())); - } - - if self.random.is_some() { - request.push_str(&format!("&random={}", self.random.unwrap())); - } - - if self.limit.is_some() { - request.push_str(&format!("&limit={}", self.limit.unwrap())); - } - - let response = reqwest::get(request).await?.text().await?; - - let response_json = json::parse(&response)?; - - Ok(response_json) - } -} \ No newline at end of file diff --git a/src/other/tenor_types.rs b/src/other/tenor_types.rs deleted file mode 100644 index 91620e5..0000000 --- a/src/other/tenor_types.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow(non_camel_case_types)] - -use std::fmt; - -#[derive(Debug)] -pub enum ContentFilter { - off, - low, - medium, - high -} - -impl fmt::Display for ContentFilter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -/// More information here https://developers.google.com/tenor/guides/response-objects-and-errors#media-object -#[derive(Debug, PartialEq, Eq, Hash)] -pub enum MediaFilter { - preview, - gif, - mediumgif, - tinygif, - nanogif, - - mp4, - loopedmp4, - tinymp4, - nanomp4, - - webm, - tinywebm, - nanowebm, - - webp_transparent, - tinywebp_transparent, - nanowebp_transparent, - - gif_transparent, - tinygif_transparent, - nanogif_transparent -} - -impl fmt::Display for MediaFilter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -#[derive(Debug)] -pub enum ArRange { - all, - wide, - standard -} - -impl fmt::Display for ArRange { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} \ No newline at end of file diff --git a/tenor-v2 b/tenor-v2 new file mode 160000 index 0000000..dc1ddc7 --- /dev/null +++ b/tenor-v2 @@ -0,0 +1 @@ +Subproject commit dc1ddc798ca6b211d8cfb3c4da73d3ca2a5a559b