Bump the major, add the frog tips

This commit is contained in:
Xyon 2023-08-24 22:39:38 +01:00
parent 363b4f7860
commit 19252f6e90
Signed by: xyon
GPG Key ID: DD18155D6B18078D
6 changed files with 146 additions and 1 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "manifold" name = "manifold"
version = "1.0.0" version = "2.0.0"
authors = ["Lucy Bladen <admin@lbladen.uk>"] authors = ["Lucy Bladen <admin@lbladen.uk>"]
edition = "2021" edition = "2021"
@ -18,6 +18,7 @@ config = { version = "0.13.1", features = [ "yaml" ] }
d20 = "0.1.0" d20 = "0.1.0"
diesel = { version = "2.1.0", features = ["sqlite", "r2d2", "chrono"] } diesel = { version = "2.1.0", features = ["sqlite", "r2d2", "chrono"] }
diesel_migrations = "2.1.0" diesel_migrations = "2.1.0"
dirs = "5.0.1"
env_logger = "0.10.0" env_logger = "0.10.0"
log = "0.4.14" log = "0.4.14"
num = "0.4.1" num = "0.4.1"

23
src/commands/frog.rs Normal file
View File

@ -0,0 +1,23 @@
use crate::models::fueltank::Tip;
use crate::error::{ManifoldError, ManifoldResult};
use crate::{ManifoldContext, ManifoldData};
#[poise::command(slash_command, prefix_command, aliases("ft"))]
async fn frogtip(ctx: ManifoldContext<'_>) -> ManifoldResult<()> {
debug!("Processing tip");
let tank = ctx.data().frogtip_fueltank.lock().await;
let tip: &Tip = &tank.next_or_fill().await?;
debug!("Tip: {:?}", tip);
ctx.send(|f| f.content(format!("{}", tip)).reply(true)).await?;
Ok(())
}
pub fn commands() -> [poise::Command<ManifoldData, ManifoldError>; 1] {
[frogtip()]
}

View File

@ -1,4 +1,5 @@
mod admin; mod admin;
mod frog;
mod core; mod core;
mod weather; mod weather;
@ -7,6 +8,7 @@ use crate::ManifoldCommand;
pub fn collect_commands(injected: Vec<ManifoldCommand>) -> Vec<ManifoldCommand> { pub fn collect_commands(injected: Vec<ManifoldCommand>) -> Vec<ManifoldCommand> {
core::commands().into_iter() core::commands().into_iter()
.chain(admin::commands()) .chain(admin::commands())
.chain(frog::commands())
.chain(weather::commands()) .chain(weather::commands())
.chain(injected) .chain(injected)
.collect() .collect()

View File

@ -18,6 +18,7 @@ use crate::config::ManifoldConfig;
use crate::error::{ManifoldError, ManifoldResult}; use crate::error::{ManifoldError, ManifoldResult};
use crate::events::Handler; use crate::events::Handler;
use crate::models::user::{ManifoldUserInfo, UserInfo}; use crate::models::user::{ManifoldUserInfo, UserInfo};
use crate::models::fueltank::FuelTank;
use crate::responses::Responses; use crate::responses::Responses;
pub mod autocomplete_helpers; pub mod autocomplete_helpers;
@ -66,6 +67,7 @@ pub struct ManifoldDataInner {
responses: Responses, responses: Responses,
user_info: Mutex<ManifoldUserInfo>, user_info: Mutex<ManifoldUserInfo>,
version_string: String, version_string: String,
frogtip_fueltank: Mutex<FuelTank>,
} }
pub type ManifoldContext<'a> = poise::Context<'a, ManifoldData, ManifoldError>; pub type ManifoldContext<'a> = poise::Context<'a, ManifoldData, ManifoldError>;
@ -128,6 +130,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, inje
responses, responses,
user_info: Mutex::new(user_info), user_info: Mutex::new(user_info),
version_string: format!("{caller} (Manifold framework version {mfold_ver} built at {mfold_time} from revision {mfold_rev})", caller=caller_version_string, mfold_ver=built_info::PKG_VERSION, mfold_time=built_info::BUILT_TIME_UTC, mfold_rev=git_info), version_string: format!("{caller} (Manifold framework version {mfold_ver} built at {mfold_time} from revision {mfold_rev})", caller=caller_version_string, mfold_ver=built_info::PKG_VERSION, mfold_time=built_info::BUILT_TIME_UTC, mfold_rev=git_info),
frogtip_fueltank: Mutex::new(FuelTank::with_cache())
}))) })))
}) })
}); });

115
src/models/fueltank.rs Normal file
View File

@ -0,0 +1,115 @@
use std::fmt::{Display, Formatter};
use std::fs;
use std::path::PathBuf;
use dirs::home_dir;
use std::io::{SeekFrom, Seek};
use reqwest::Client;
use reqwest::header::CONTENT_TYPE;
use crate::error::{ManifoldError, ManifoldResult};
const CACHE_VERSION: &'static str = "1";
pub trait Pump<V> {
fn pump<F>(self) -> Result<V, ManifoldError>;
}
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
pub struct FuelTank {
mode: TankMode,
}
#[derive(Copy, Clone, Debug)]
enum TankMode {
Cache,
}
impl FuelTank {
pub fn with_cache() -> Self {
Self {
mode: TankMode::Cache,
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Tip {
pub number: i32,
pub tip: String,
}
impl Display for Tip {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "#{}: {}", self.number, self.tip)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Croak {
pub tips: Vec<Tip>,
}
pub async fn croak() -> ManifoldResult<Vec<Tip>> {
debug!("Getting new tips");
let result: Croak;
let client = Client::new();
result = client.get("https://frog.tips/api/1/tips/")
.header(CONTENT_TYPE, "application/json")
.send().await.unwrap().json().await.unwrap();
debug!("Result: {:?}", &result);
Ok(result.tips)
}
impl FuelTank {
pub async fn next_or_fill(self) -> Result<Tip, ManifoldError> {
debug!("Filling tank!");
let mut cache = {
let mut path = PathBuf::new();
path.push(home_dir().ok_or(ManifoldError::from("No home dir"))?);
path.push(".local");
path.push(format!("coffeebot-frog-cache-{}.json", CACHE_VERSION));
debug!("Cache path: {:?}", &path);
fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path)
.map_err(|e| {
error!("Error creating cache file: {}", e);
ManifoldError::from("CACHE ERROR")
})?
};
debug!("Cache: {:?}", &cache);
let json: Result<Vec<Tip>, serde_json::Error> = serde_json::from_reader(&mut cache);
debug!("Json: {:?}", &json);
let mut tips = match json {
Ok(contents) => {
match contents.len() {
0 => croak().await?,
_ => contents,
}
}
_ => croak().await?,
};
debug!("Got tips: {:?}", &tips);
let tip = tips.pop().ok_or(ManifoldError::from("FROG HAS NO TIPS FOR YOU. CROAK ERROR 12"))?;
debug!("Got single tip: {:?}", &tip);
cache
.set_len(0)
.and_then(|_| cache.seek(SeekFrom::Start(0)))?;
debug!("Writing cache");
serde_json::to_writer(cache, &tips)?;
Ok(tip)
}
}

View File

@ -1,2 +1,3 @@
pub mod fueltank;
pub mod user; pub mod user;
pub mod weather; pub mod weather;