diff --git a/src/config.rs b/src/config.rs index b729cc7..6aad993 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ use crate::error::Error; use crate::imgur; use crate::imgur::Image; +use crate::models::album::AlbumConfig; use config::{Config, File}; use j_db::database::Database; use rand::prelude::SliceRandom; @@ -20,12 +21,6 @@ pub struct Args { pub cfg_path: PathBuf, } -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct AlbumConfig { - pub name: String, - pub album_id: String, -} - #[derive(Debug, Deserialize, Serialize, Clone)] pub struct MotivationConfig { pub album: Vec, @@ -43,9 +38,6 @@ pub struct BotConfig { pub db_path: PathBuf, pub admins: Vec, - #[serde(default)] - pub albums: Vec, - pub motivation: MotivationConfig, } @@ -75,10 +67,10 @@ pub struct BotState { } impl BotState { - pub async fn new(cfg: &BotConfig) -> Result { + pub async fn new(cfg: &BotConfig, db: &Database) -> Result { let mut albums: HashMap> = HashMap::new(); - for album in &cfg.albums { + for album in db.filter(|_, _: &AlbumConfig| true)? { albums.insert( album.name.clone(), imgur::get_album_images(&cfg.imgur_client_id, &album.album_id).await?, @@ -133,10 +125,11 @@ pub struct GlobalData { impl GlobalData { pub async fn new(args: Args, cfg: BotConfig) -> Result { + let db = Database::new(&cfg.db_path)?; Ok(Self { args, - bot_state: BotState::new(&cfg).await?, - db: Database::new(&cfg.db_path)?, + bot_state: BotState::new(&cfg, &db).await?, + db, cfg, }) } @@ -145,7 +138,7 @@ impl GlobalData { let cfg = BotConfig::new(&self.args.cfg_path)?; self.cfg = cfg; - self.bot_state = BotState::new(&self.cfg).await?; + self.bot_state = BotState::new(&self.cfg, &self.db).await?; Ok(()) } diff --git a/src/discord/album.rs b/src/discord/album.rs index f0d49c8..2492dfe 100644 --- a/src/discord/album.rs +++ b/src/discord/album.rs @@ -1,7 +1,8 @@ -use crate::config::AlbumConfig; use crate::error::Error; use crate::imgur::get_album_images; +use crate::models::album::AlbumConfig; use crate::{command, group, GlobalData}; +use j_db::model::JdbModel; use serenity::client::Context; use serenity::framework::standard::{Args, CommandResult}; use serenity::model::channel::Message; @@ -54,10 +55,9 @@ async fn add_album(ctx: &Context, msg: &Message, mut args: Args) -> CommandResul } }; - global_data.cfg.albums.push(AlbumConfig { - album_id, - name: album_name.clone(), - }); + global_data + .db + .insert(AlbumConfig::new(&album_name, &album_id))?; global_data .bot_state @@ -82,15 +82,25 @@ async fn remove_album(ctx: &Context, msg: &Message, args: Args) -> CommandResult let global_data = data.get_mut::().unwrap(); - global_data - .cfg - .albums - .retain(|album| !album.name.eq_ignore_ascii_case(&album_name)); + let album = AlbumConfig::get_album_by_name(&global_data.db, &album_name)?; - global_data.bot_state.albums.remove(&album_name); + match album { + None => { + msg.reply( + &ctx.http, + "I already got rid of that one, or I never had it. Who knows!", + ) + .await?; + } + Some(album) => { + global_data.bot_state.albums.remove(&album_name); - msg.reply(&ctx.http, format!("{} album removed!", album_name)) - .await?; + global_data.db.remove::(album.id().unwrap())?; + + msg.reply(&ctx.http, format!("{} album removed!", album_name)) + .await?; + } + } Ok(()) } @@ -105,10 +115,9 @@ async fn list_albums(ctx: &Context, msg: &Message, _args: Args) -> CommandResult let global_data = data.get::().unwrap(); let album_names: Vec = global_data - .cfg - .albums - .iter() - .map(|album| album.name.clone()) + .db + .filter(|_, _: &AlbumConfig| true)? + .map(|album| album.name) .collect(); if album_names.is_empty() { diff --git a/src/discord/joke.rs b/src/discord/joke.rs index e6e0151..b4bd0e7 100644 --- a/src/discord/joke.rs +++ b/src/discord/joke.rs @@ -2,6 +2,8 @@ use crate::error::Error; use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType}; use crate::models::random::RandomConfig; use crate::{command, group, GlobalData, BAD_APPLE}; +use rand::prelude::SliceRandom; +use rand::thread_rng; use reqwest::Client; use serde::{Deserialize, Serialize}; use serenity::client::Context; @@ -53,11 +55,11 @@ impl RandomCtx { pub fn new(user_name: &str, global_data: &GlobalData) -> Result { let mut random_image: HashMap = HashMap::new(); - for album in &global_data.cfg.albums { - let image = global_data.bot_state.get_image(&album.name, Vec::new())?; + for (album_name, images) in &global_data.bot_state.albums { + let image = images.choose(&mut thread_rng()); if let Some(image) = image { - random_image.insert(album.name.clone(), image.link); + random_image.insert(album_name.clone(), image.link.clone()); } } diff --git a/src/models/album.rs b/src/models/album.rs new file mode 100644 index 0000000..60b6ec6 --- /dev/null +++ b/src/models/album.rs @@ -0,0 +1,41 @@ +use crate::error::Error; +use j_db::database::Database; +use j_db::model::JdbModel; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct AlbumConfig { + id: Option, + pub name: String, + pub album_id: String, +} + +impl JdbModel for AlbumConfig { + fn id(&self) -> Option { + self.id + } + + fn set_id(&mut self, id: u64) { + self.id = Some(id) + } + + fn tree() -> String { + "Album".to_string() + } +} + +impl AlbumConfig { + pub fn new(name: &str, album_id: &str) -> AlbumConfig { + Self { + id: None, + name: name.to_string(), + album_id: album_id.to_string(), + } + } + + pub fn get_album_by_name(db: &Database, name: &str) -> Result, Error> { + Ok(db + .filter(|_, album_config: &AlbumConfig| album_config.name.eq_ignore_ascii_case(name))? + .next()) + } +} diff --git a/src/models/mod.rs b/src/models/mod.rs index 7ae479b..83742d5 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,2 +1,3 @@ +pub mod album; pub mod insult_compliment; pub mod random;