diff --git a/src/event/mod.rs b/src/event/mod.rs index eb7f6f0..e166867 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -18,50 +18,15 @@ pub enum Event { pub struct Envelope { pub from: Option, pub event: Event, - pub to: Vec, - pub tags: BTreeSet + pub to: Vec } impl Envelope { pub fn new (event: Event) -> Envelope { - let mut tags: BTreeSet = BTreeSet::new(); - - match &event { - &Event::Message { ref message } => { - tags.insert(String::from("type:message")); - tags.insert(format!("user:{:}", message.author.name)); - match message.channel { - Some(ref channel) => { - tags.insert(format!("channel:{:}", channel.name)); - }, - None => {} - } - }, - &Event::SelfJoin { ref channel } => { - tags.insert(String::from("type:selfjoin")); - tags.insert(format!("channel:{:}", channel.name)); - }, - &Event::SelfQuit { ref channel } => { - tags.insert(String::from("type:selfquit")); - tags.insert(format!("channel:{:}", channel.name)); - }, - &Event::UserJoin { ref channel, ref user } => { - tags.insert(String::from("type:userjoin")); - tags.insert(format!("channel:{:}", channel.name)); - tags.insert(format!("user:{:}", user.name)); - }, - &Event::UserQuit { ref channel, ref user } => { - tags.insert(String::from("type:userquit")); - tags.insert(format!("channel:{:}", channel.name)); - tags.insert(format!("user:{:}", user.name)); - } - } - Envelope { from: None, event: event, - to: vec![], - tags: tags + to: vec![] } } } diff --git a/src/lib.rs b/src/lib.rs index 6aea2af..af357aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ use modules::Module; use modules::loader::{ModuleLoader, ModuleLoaderError}; mod event; +use event::Event; use event::Envelope; use std::sync::Arc; @@ -75,8 +76,7 @@ impl Tenquestionmarks { Envelope { from: Some(from.clone()), event: envelope.event, - to: envelope.to, - tags: envelope.tags + to: envelope.to } }); @@ -171,21 +171,32 @@ pub trait MessageSender : Sync + Send + std::fmt::Debug { fn send_message (&self, _: &str) {} } +trait EventFilter: Sync + Send { + fn accept (&self, envelope: &Envelope) -> bool; +} + struct Subscription { pub module: Module, pub name: String, - pub filters: BTreeSet + pub filters: Vec> } impl Subscription { pub fn new (name: String, module: Module) -> Subscription { - let filters: BTreeSet = module.config.get("filters") - .and_then(|value| value.as_slice()) - .map(|value| value.to_vec()) - .unwrap_or(vec![]) - .into_iter() - .map(|value| { String::from(value.as_str().unwrap()) }) - .collect(); + let filters: Vec> = module.config.get("filters") + .and_then(|value| value.as_slice()) + .map(|value| value.to_vec()) + .unwrap_or(vec![]) + .into_iter() + .map(|value| { + match value.as_table() { + Some(table) => Some(Box::new(AttributeEventFilter::new(table)) as Box), + None => None + } + }) + .filter(|possible_filter| possible_filter.is_some()) + .map(|possible_filter| possible_filter.unwrap()) + .collect(); Subscription { module: module, @@ -208,7 +219,13 @@ impl Subscription { ); return false; } - else if !(self.filters.is_empty() || self.filters.intersection(&envelope.tags).count() > 0) { + else if !self.filters.is_empty() { + for filter in &self.filters { + if filter.accept(envelope) { + return true; + } + } + debug!( "Refusing to transmit envelope from {:?} to {:?} since envelope was filtered out", envelope.from, @@ -220,3 +237,107 @@ impl Subscription { true } } + +struct AttributeEventFilter { + // Attributes that can be filtered out + event_type: Option, + username: Option, + channel: Option, + message: Option +} + +impl AttributeEventFilter { + pub fn new (attributes: &Table) -> AttributeEventFilter { + AttributeEventFilter { + event_type: attributes.get("type").and_then(|value| value.as_str()).map(|value| String::from(value)), + message: attributes.get("message").and_then(|value| value.as_str()).map(|value| String::from(value)), + username: attributes.get("username").and_then(|value| value.as_str()).map(|value| String::from(value)), + channel: attributes.get("channel").and_then(|value| value.as_str()).map(|value| String::from(value)), + } + } +} + +impl EventFilter for AttributeEventFilter { + fn accept (&self, envelope: &Envelope) -> bool { + let mut result = true; + match &envelope.event { + &Event::Message { ref message } => { + match self.event_type { + Some(ref event_type) => result = result && event_type == "message", + None => {} + } + + match self.channel { + Some(ref channel_name) => { + match message.channel { + Some(ref channel) => result = result && channel_name == &channel.name, + None => result = false + } + }, + None => {} + } + + match self.username { + Some(ref username) => result = result && &message.author.name == username, + None => {} + } + }, + &Event::SelfJoin { ref channel } => { + match self.event_type { + Some(ref event_type) => result = result && event_type == "selfjoin", + None => {} + } + + match self.channel { + Some(ref channel_name) => result = result && channel_name == &channel.name, + None => {} + } + }, + &Event::SelfQuit { ref channel } => { + match self.event_type { + Some(ref event_type) => result = result && event_type == "selfquit", + None => {} + } + + match self.channel { + Some(ref channel_name) => result = result && channel_name == &channel.name, + None => {} + } + }, + &Event::UserJoin { ref channel, ref user } => { + match self.event_type { + Some(ref event_type) => result = result && event_type == "userjoin", + None => {} + } + + match self.channel { + Some(ref channel_name) => result = result && channel_name == &channel.name, + None => {} + } + + match self.username { + Some(ref username) => result = result && &user.name == username, + None => {} + } + }, + &Event::UserQuit { ref channel, ref user } => { + match self.event_type { + Some(ref event_type) => result = result && event_type == "userquit", + None => {} + } + + match self.channel { + Some(ref channel_name) => result = result && channel_name == &channel.name, + None => {} + } + + match self.username { + Some(ref username) => result = result && &user.name == username, + None => {} + } + } + } + + result + } +} diff --git a/tenquestionmarks.toml b/tenquestionmarks.toml index b281719..ad5c21c 100644 --- a/tenquestionmarks.toml +++ b/tenquestionmarks.toml @@ -73,7 +73,16 @@ end """ foo = "bar" +[lua2] +type = "lua" +filters = [{ username = "David" }] +code = """ +function on_message (message, reply) + reply("Lua2 says: " .. message) +end +""" + [autolink] [logger] -filters = ["user:Dave"] +filters = [{ username = "Dave" }]