Bump the major, add the frog tips
This commit is contained in:
parent
363b4f7860
commit
19252f6e90
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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()]
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
})))
|
})))
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
pub mod fueltank;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod weather;
|
pub mod weather;
|
||||||
Loading…
Reference in New Issue