diff --git a/Cargo.toml b/Cargo.toml index b3f0cfe..77a6fd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "manifold" -version = "3.0.0" +version = "3.1.0" authors = ["Lucy Bladen "] edition = "2021" diff --git a/src/commands/joke.rs b/src/commands/joke.rs new file mode 100644 index 0000000..3adaa95 --- /dev/null +++ b/src/commands/joke.rs @@ -0,0 +1,26 @@ +use crate::error::{ManifoldError, ManifoldResult}; +use crate::{ManifoldContext, ManifoldData}; +use crate::models::dadjoke::{DadJoke, DadJokeWrapper}; + +#[poise::command(slash_command, prefix_command, aliases("dad"))] +async fn dad_joke(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { + + debug!("Processing tip"); + + if let Some(tank) = ctx.data().bot_config.services.get("dad_jokes") { + let tip: &DadJoke = &tank.next_or_fill::().await?; + + debug!("Tip: {:?}", tip); + + ctx.send(|f| f.content(format!("{}", tip)).reply(true)).await?; + } else { + error!("No such fuel tank dad_jokes"); + ctx.send(|f| f.content("Can't find any dad jokes. Maybe your dad isn't funny.".to_string()).reply(true)).await?; + } + + Ok(()) +} + +pub fn commands() -> [poise::Command; 1] { + [dad_joke()] +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index f284413..db683aa 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -2,6 +2,8 @@ mod admin; mod animal; mod convert; mod core; +mod joke; +mod nasa; mod weather; use crate::ManifoldCommand; @@ -11,6 +13,8 @@ pub fn collect_commands(injected: Vec) -> Vec .chain(admin::commands()) .chain(animal::commands()) .chain(convert::commands()) + .chain(joke::commands()) + .chain(nasa::commands()) .chain(weather::commands()) .chain(injected) .collect() diff --git a/src/commands/nasa.rs b/src/commands/nasa.rs new file mode 100644 index 0000000..b030716 --- /dev/null +++ b/src/commands/nasa.rs @@ -0,0 +1,35 @@ +use crate::error::{ManifoldError, ManifoldResult}; +use crate::{ManifoldContext, ManifoldData}; +use crate::models::nasa::*; + +#[poise::command(slash_command, prefix_command, aliases("apod"))] +async fn nasa_apod(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { + + debug!("Processing tip"); + + if let Some(tank) = ctx.data().bot_config.services.get("nasa_apod") { + let photo: &NasaAstroPhoto = &tank.next_or_fill::().await?; + + debug!("Tip: {:?}", photo); + + ctx.send(|f| { + f.content(format!("{}", photo)) + .reply(true) + .embed(|e| { + e.title(&photo.title); + e.description(&photo.explanation); + e.image(&photo.hdurl); + e + }) + }).await?; + } else { + error!("No such fuel tank nasa_apod"); + ctx.send(|f| f.content("The NASA Astronomy Photo of the Day was missing. Try looking up instead.".to_string()).reply(true)).await?; + } + + Ok(()) +} + +pub fn commands() -> [poise::Command; 1] { + [nasa_apod()] +} diff --git a/src/models/dadjoke.rs b/src/models/dadjoke.rs new file mode 100644 index 0000000..74f4974 --- /dev/null +++ b/src/models/dadjoke.rs @@ -0,0 +1,29 @@ +use std::fmt::{Display, Formatter}; +use crate::models::fueltank::Pump; + +#[derive(Serialize, Deserialize, Debug)] +pub struct DadJoke { + pub id: String, + pub joke: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct DadJokeWrapper { + pub results: Vec +} + +impl Display for DadJoke { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.joke) + } +} + +impl Pump for DadJokeWrapper { + fn pump(&mut self) -> Option { + self.results.pop() + } + + fn len(&self) -> usize { + self.results.len() + } +} \ No newline at end of file diff --git a/src/models/fueltank.rs b/src/models/fueltank.rs index 1cb3748..bed2f2a 100644 --- a/src/models/fueltank.rs +++ b/src/models/fueltank.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use dirs::home_dir; use std::io::{SeekFrom, Seek}; use reqwest::Client; -use reqwest::header::CONTENT_TYPE; +use reqwest::header::{ACCEPT, CONTENT_TYPE}; use serde::de::DeserializeOwned; use serde::Serialize; @@ -32,15 +32,6 @@ pub enum TankMode { } impl FuelTank { - pub fn new(source_uri: String, cache_name: Option, api_key: Option, cache_mode: TankMode) -> Self { - Self { - source_uri, - cache_name, - api_key, - cache_mode, - } - } - pub async fn next_or_fill(&self) -> ManifoldResult where T: DeserializeOwned, U: Serialize, @@ -99,10 +90,13 @@ impl FuelTank { let result: U; let mut client = Client::new().get(&self.source_uri) - .header(CONTENT_TYPE, "application/json"); + .header(CONTENT_TYPE, "application/json") + .header(ACCEPT, "application/json"); + if let Some(api_key) = &self.api_key { client = client.header("X-API-KEY", api_key); } + result = client.send().await?.json().await?; debug!("Result: {:?}", &result); diff --git a/src/models/mod.rs b/src/models/mod.rs index e7e2e2a..b02d13a 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,5 +1,7 @@ pub mod animalpics; -pub mod fueltank; +pub mod dadjoke; pub mod frogtip; +pub mod fueltank; +pub mod nasa; pub mod user; -pub mod weather; \ No newline at end of file +pub mod weather; diff --git a/src/models/nasa.rs b/src/models/nasa.rs new file mode 100644 index 0000000..31c8edc --- /dev/null +++ b/src/models/nasa.rs @@ -0,0 +1,25 @@ +use std::fmt::{Display, Formatter}; +use crate::models::fueltank::Pump; + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct NasaAstroPhoto { + pub explanation: String, + pub hdurl: String, + pub title: String +} + +impl Display for NasaAstroPhoto { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.hdurl) + } +} + +impl Pump for NasaAstroPhoto { + fn pump(&mut self) -> Option { + Some(self.clone()) + } + + fn len(&self) -> usize { + 1 + } +} \ No newline at end of file