From 6d49c9e16c7cb0677a84cf04f809fd0e6bb1d401 Mon Sep 17 00:00:00 2001 From: projectmoon Date: Sat, 26 Sep 2020 21:33:51 +0000 Subject: [PATCH] Fall back to 15 minutes if oldest message age not specified. This makes the oldest message age setting optional, in additon to the entire bot config (for now). If the oldest message age is not specified (or if the entire bot config is missing), it will default to 15 minutes. --- src/bin/dicebot.rs | 42 +++++++++++++++++++++- src/bot.rs | 86 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 11 deletions(-) diff --git a/src/bin/dicebot.rs b/src/bin/dicebot.rs index 633b647..651291d 100644 --- a/src/bin/dicebot.rs +++ b/src/bin/dicebot.rs @@ -8,12 +8,17 @@ fn read_config>(config_path: P) -> Result Result> { + let config = { toml::from_str(&contents)? }; + Ok(config) +} + #[tokio::main] async fn main() -> Result<(), Box> { env_logger::from_env(Env::default().default_filter_or("chronicle_dicebot=info")).init(); @@ -28,3 +33,38 @@ async fn main() -> Result<(), Box> { run_bot(cfg).await?; Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn deserialize_config_without_bot_section_test() { + let contents = indoc! {" + [matrix] + home_server = 'https://matrix.example.com' + username = 'username' + password = 'password' + "}; + + let cfg: Result<_, _> = deserialize_config(contents); + assert_eq!(true, cfg.is_ok()); + } + + #[test] + fn deserialize_config_without_oldest_message_setting_test() { + let contents = indoc! {" + [matrix] + home_server = 'https://matrix.example.com' + username = 'username' + password = 'password' + + [bot] + not_a_real_setting = 2 + "}; + + let cfg: Result<_, _> = deserialize_config(contents); + assert_eq!(true, cfg.is_ok()); + } +} diff --git a/src/bot.rs b/src/bot.rs index 2ab2d3f..799938f 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -32,18 +32,35 @@ pub struct MatrixConfig { pub password: String, } +const DEFAULT_OLDEST_MESSAGE: u64 = 15 * 60; + /// The "bot" section of the config file, for bot settings. #[derive(Serialize, Deserialize, Debug)] pub struct BotConfig { /// How far back from current time should we process a message? - pub oldest_message_sec: u64, + oldest_message_age: Option, +} + +impl BotConfig { + pub fn new() -> BotConfig { + BotConfig { + oldest_message_age: Some(DEFAULT_OLDEST_MESSAGE), + } + } + + pub fn oldest_message_age(&self) -> u64 { + match self.oldest_message_age { + Some(seconds) => seconds, + None => DEFAULT_OLDEST_MESSAGE, + } + } } /// Represents the toml config file for the dicebot. #[derive(Serialize, Deserialize, Debug)] pub struct Config { pub matrix: MatrixConfig, - pub bot: BotConfig, + pub bot: Option, } /// The DiceBot struct itself is the core of the program, essentially the entrypoint @@ -60,13 +77,29 @@ impl DiceBot { } } +fn get_oldest_message_age(config: &Config) -> u64 { + let none_cfg; + let bot_cfg = match &config.bot { + Some(cfg) => cfg, + None => { + none_cfg = BotConfig::new(); + &none_cfg + } + }; + + bot_cfg.oldest_message_age() +} + +/// Check if a message is recent enough to actually process. If the +/// message is within "oldest_message_age" seconds, this function +/// returns true. If it's older than that, it returns false and logs a +/// debug message. fn check_message_age( event: &SyncMessageEvent, - oldest_message_sec: u64, + oldest_message_age: u64, ) -> bool { let sending_time = event.origin_server_ts; - let now = SystemTime::now(); - let oldest_timestamp = now.sub(Duration::new(oldest_message_sec, 0)); + let oldest_timestamp = SystemTime::now().sub(Duration::new(oldest_message_age, 0)); if sending_time > oldest_timestamp { true @@ -110,24 +143,22 @@ impl EventEmitter for DiceBot { async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent) { if let SyncRoom::Joined(room) = room { - let (msg_body, sender_username, sending_time) = if let SyncMessageEvent { + let (msg_body, sender_username) = if let SyncMessageEvent { content: MessageEventContent::Text(TextMessageEventContent { body, .. }), sender, - origin_server_ts, .. } = event { ( body.clone(), format!("@{}:{}", sender.localpart(), sender.server_name()), - origin_server_ts, ) } else { - (String::new(), String::new(), &SystemTime::UNIX_EPOCH) + (String::new(), String::new()) }; //Ignore messages that are older than configured duration. - if !check_message_age(event, self.config.bot.oldest_message_sec) { + if !check_message_age(event, get_oldest_message_age(&self.config)) { return; } @@ -230,3 +261,38 @@ pub async fn run_bot(config: Config) -> Result<(), Box> { Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn oldest_message_default_no_setting_test() { + let cfg = Config { + matrix: MatrixConfig { + home_server: "".to_owned(), + username: "".to_owned(), + password: "".to_owned(), + }, + bot: Some(BotConfig { + oldest_message_age: None, + }), + }; + + assert_eq!(15 * 60, get_oldest_message_age(&cfg)); + } + + #[test] + fn oldest_message_default_no_bot_config_test() { + let cfg = Config { + matrix: MatrixConfig { + home_server: "".to_owned(), + username: "".to_owned(), + password: "".to_owned(), + }, + bot: None, + }; + + assert_eq!(15 * 60, get_oldest_message_age(&cfg)); + } +}