diff --git a/Cargo.lock b/Cargo.lock index a615ff6..c41772e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,15 +66,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "aho-corasick" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" -dependencies = [ - "memchr", -] - [[package]] name = "ansi_term" version = "0.12.1" @@ -141,16 +132,13 @@ dependencies = [ "clap", "futures", "matrix-sdk", - "regex", "serde", - "serde_regex", "serde_yaml", "systemd", "thiserror", "tokio", "tracing-subscriber", "url", - "void", ] [[package]] @@ -1450,10 +1438,7 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", - "thread_local", ] [[package]] @@ -1788,16 +1773,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_regex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" -dependencies = [ - "regex", - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.0" @@ -2390,12 +2365,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "want" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 8004b32..7fe7e51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,16 +10,13 @@ edition = "2018" anyhow = "1.0" clap = "3.0.0-beta.2" futures = "0.3" -regex = "1" tokio = { version = "1", features = [ "full" ] } tracing-subscriber = "0.2" url = { version = "2.2", features = [ "serde" ] } -serde_regex = "1" serde_yaml = "0.8" serde = "1.0" systemd = "0.8" thiserror = "1.0" -void = "1" [dependencies.matrix-sdk] git = "https://github.com/matrix-org/matrix-rust-sdk" diff --git a/src/bot.rs b/src/bot.rs index f95a07c..b2a6387 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -100,26 +100,15 @@ impl BadNewsBot { const KEY_MESSAGE: &str = "MESSAGE"; if let Some(unit) = record.get(KEY_UNIT) { - let unit_config = match self.config.units.iter().find(|u| &u.name == unit) { - Some(config) => config, - None => return, - }; - - let message = match record.get(KEY_MESSAGE) { - Some(msg) => msg, - None => return, - }; - - if let Some(filter) = &unit_config.filter { - if !filter.is_match(message) { - return; - } + if !self.config.units.contains(unit) { + return; } + let message = record.get(KEY_MESSAGE); let message = format!( "[{}] {}", unit.strip_suffix(".service").unwrap_or(unit), - message, + message.map(|m| m.as_ref()).unwrap_or("") ); let content = AnyMessageEventContent::RoomMessage(MessageEventContent::Text( TextMessageEventContent::plain(message), diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index ffa367b..0000000 --- a/src/config.rs +++ /dev/null @@ -1,111 +0,0 @@ -use matrix_sdk::identifiers::RoomId; -use regex::Regex; -use serde::de::{self, MapAccess, Visitor}; -use serde::{Deserialize, Deserializer}; -use std::fmt; -use std::marker::PhantomData; -use std::path::PathBuf; -use std::str::FromStr; -use url::Url; -use void::Void; - -/// Holds the configuration for the bot. -#[derive(Clone, Deserialize)] -pub struct Config { - /// The URL for the homeserver we should connect to - pub homeserver: Url, - /// The bot's account username - pub username: String, - /// The bot's account password - pub password: String, - /// Path to a directory where the bot will store Matrix state and current session information. - pub state_dir: PathBuf, - /// ID of the Matrix room where the bot should post messages. The bot will only accept - /// invitations to this room. - pub room_id: RoomId, - /// Units to watch for logs - #[serde(deserialize_with = "list_of_units")] - pub units: Vec, -} - -/// Holds a single unit's configuration. -#[derive(Clone, Debug, Deserialize)] -pub struct Unit { - /// Can be serialized from a string only instead of a map. - pub name: String, - /// Regex to filter each line read from the unit's logs. - #[serde(with = "serde_regex")] - pub filter: Option, -} - -impl PartialEq for Unit { - fn eq(&self, other: &Self) -> bool { - self.name == other.name - } -} - -impl Eq for Unit {} - -#[derive(Debug, Deserialize)] -#[serde(transparent)] -struct SerializedUnit(#[serde(deserialize_with = "unit_name_or_struct")] Unit); - -impl From for Unit { - fn from(s: SerializedUnit) -> Self { - s.0 - } -} - -impl FromStr for Unit { - type Err = Void; - - fn from_str(s: &str) -> Result { - Ok(Unit { - name: s.to_string(), - filter: None, - }) - } -} - -fn list_of_units<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let units: Vec = Deserialize::deserialize(deserializer)?; - Ok(units.into_iter().map(From::from).collect()) -} - -fn unit_name_or_struct<'de, T, D>(deserializer: D) -> Result -where - T: Deserialize<'de> + FromStr, - D: Deserializer<'de>, -{ - struct StringOrStruct(PhantomData T>); - - impl<'de, T> Visitor<'de> for StringOrStruct - where - T: Deserialize<'de> + FromStr, - { - type Value = T; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("string or map") - } - - fn visit_str(self, value: &str) -> Result - where - E: de::Error, - { - Ok(FromStr::from_str(value).unwrap()) - } - - fn visit_map(self, map: M) -> Result - where - M: MapAccess<'de>, - { - Deserialize::deserialize(de::value::MapAccessDeserializer::new(map)) - } - } - - deserializer.deserialize_any(StringOrStruct(PhantomData)) -} diff --git a/src/main.rs b/src/main.rs index 877d58e..dee3102 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,20 @@ use std::{ + collections::HashSet, fs::File, io::{self, BufReader}, path::PathBuf, }; use clap::Clap; +use matrix_sdk::identifiers::RoomId; +use serde::Deserialize; use thiserror::Error; +use url::Url; mod autojoin; mod bot; -mod config; use bot::BadNewsBot; -use config::Config; #[derive(Error, Debug)] enum BadNewsError { @@ -30,6 +32,24 @@ struct Opts { config: PathBuf, } +/// Holds the configuration for the bot. +#[derive(Clone, Deserialize)] +pub struct Config { + /// The URL for the homeserver we should connect to + homeserver: Url, + /// The bot's account username + username: String, + /// The bot's account password + password: String, + /// Path to a directory where the bot will store Matrix state and current session information. + state_dir: PathBuf, + /// ID of the Matrix room where the bot should post messages. The bot will only accept + /// invitations to this room. + room_id: RoomId, + /// Units to watch for logs + units: HashSet, +} + #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init();