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.
This commit is contained in:
projectmoon 2020-09-26 21:33:51 +00:00 committed by ProjectMoon
parent fabda911fd
commit 6d49c9e16c
2 changed files with 117 additions and 11 deletions

View File

@ -8,12 +8,17 @@ fn read_config<P: Into<PathBuf>>(config_path: P) -> Result<Config, Box<dyn std::
let config_path = config_path.into();
let config = {
let contents = fs::read_to_string(&config_path)?;
toml::from_str(&contents)?
deserialize_config(&contents)?
};
Ok(config)
}
fn deserialize_config(contents: &str) -> Result<Config, Box<dyn std::error::Error>> {
let config = { toml::from_str(&contents)? };
Ok(config)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::from_env(Env::default().default_filter_or("chronicle_dicebot=info")).init();
@ -28,3 +33,38 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
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());
}
}

View File

@ -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<u64>,
}
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<BotConfig>,
}
/// 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<MessageEventContent>,
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<MessageEventContent>) {
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<dyn std::error::Error>> {
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));
}
}