From fb2a38846743f4b075b5f3bf9e9130fcf2f7bfec Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 12 Feb 2018 20:44:59 +0100 Subject: Add Tell Plugin --- src/plugins/tell.rs | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/plugins/tell.rs (limited to 'src/plugins/tell.rs') diff --git a/src/plugins/tell.rs b/src/plugins/tell.rs new file mode 100644 index 0000000..07df726 --- /dev/null +++ b/src/plugins/tell.rs @@ -0,0 +1,133 @@ +use irc::client::prelude::*; +use irc::error::IrcError; + +use std::collections::HashMap; +use std::sync::Mutex; + +use plugin::*; + +macro_rules! try_lock { + ( $m:expr ) => { + match $m.lock() { + Ok(guard) => guard, + Err(poisoned) => poisoned.into_inner(), + } + } +} + +#[derive(PluginName, Default, Debug)] +pub struct Tell { + tells: Mutex>, +} + +#[derive(Default, Debug)] +struct TellMessage { + sender: String, + // TODO Add time + message: String, +} + +impl Tell { + pub fn new() -> Tell { + Tell { + tells: Mutex::new(HashMap::new()), + } + } + + fn tell_command(&self, client: &IrcClient, command: &PluginCommand) -> Result<&str, String> { + if command.tokens.len() < 2 { + return Err(self.invalid_command(client)); + } + + let receiver = command.tokens[0].to_string(); + let sender = command.source.to_owned(); + + if receiver == sender { + return Err(String::from("That's your name!")); + } + + if command.source != command.target { + if let Some(users) = client.list_users(&command.target) { + if users.iter().any(|u| u.get_nickname() == receiver) { + return Err(format!("{} is in this channel.", receiver)); + } + } + } + + let message = command.tokens[1..].join(" "); + let tell = TellMessage { + sender: sender, + message: message, + }; + + try_lock!(self.tells).insert(receiver.clone(), tell); + + Ok("Got it!") + } + + fn send_tell(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { + let mut tells = try_lock!(self.tells); + if let Some(tell) = tells.get(receiver) { + if let Err(e) = client.send_notice( + receiver, + &format!("Tell from {}: {}", tell.sender, tell.message), + ) { + return ExecutionStatus::Err(e); + } + debug!("Sent {:?} from {:?} to {:?}", tell.message, tell.sender, receiver); + } + tells.remove(receiver); + ExecutionStatus::Done + } + + fn invalid_command(&self, client: &IrcClient) -> String { + format!( + "Incorrect Command. \ + Send \"{} tell help\" for help.", + client.current_nickname() + ) + } + + fn help(&self, client: &IrcClient) -> String { + format!( + "usage: {} tell user message\r\n\ + example: {0} tell Foobar Hello!", + client.current_nickname() + ) + } +} + +impl Plugin for Tell { + fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { + match message.command { + Command::JOIN(_, _, _) => self.send_tell(client, message.source_nickname().unwrap()), + Command::PRIVMSG(_, _) => self.send_tell(client, message.source_nickname().unwrap()), + _ => ExecutionStatus::Done, + } + } + + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + panic!("Tell should not use threading") + } + + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + if command.tokens.is_empty() { + return client.send_notice(&command.source, &self.invalid_command(client)); + } + + match command.tokens[0].as_ref() { + "help" => client.send_notice(&command.source, &self.help(client)), + _ => match self.tell_command(client, &command) { + Ok(msg) => client.send_notice(&command.source, msg), + Err(msg) => client.send_notice(&command.source, &msg), + }, + } + } + + fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { + Err(String::from("This Plugin does not implement any commands.")) + } +} + +#[cfg(test)] +mod tests {} -- cgit v1.2.3-70-g09d2 From d08eb3db79e702a729324e06ed8f6ab86c8355e3 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 12 Feb 2018 21:34:08 +0100 Subject: Save multiple tells per person --- src/plugins/tell.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/plugins/tell.rs') diff --git a/src/plugins/tell.rs b/src/plugins/tell.rs index 07df726..3ec9586 100644 --- a/src/plugins/tell.rs +++ b/src/plugins/tell.rs @@ -17,7 +17,7 @@ macro_rules! try_lock { #[derive(PluginName, Default, Debug)] pub struct Tell { - tells: Mutex>, + tells: Mutex>>, } #[derive(Default, Debug)] @@ -60,21 +60,25 @@ impl Tell { message: message, }; - try_lock!(self.tells).insert(receiver.clone(), tell); + let mut tells = try_lock!(self.tells); + let tell_messages = tells.entry(receiver).or_insert(Vec::with_capacity(3)); + (*tell_messages).push(tell); Ok("Got it!") } fn send_tell(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { let mut tells = try_lock!(self.tells); - if let Some(tell) = tells.get(receiver) { - if let Err(e) = client.send_notice( - receiver, - &format!("Tell from {}: {}", tell.sender, tell.message), - ) { - return ExecutionStatus::Err(e); + if let Some(tell_messages) = tells.get_mut(receiver) { + for tell in tell_messages { + if let Err(e) = client.send_notice( + receiver, + &format!("Tell from {}: {}", tell.sender, tell.message), + ) { + return ExecutionStatus::Err(e); + } + debug!("Sent {:?} from {:?} to {:?}", tell.message, tell.sender, receiver); } - debug!("Sent {:?} from {:?} to {:?}", tell.message, tell.sender, receiver); } tells.remove(receiver); ExecutionStatus::Done -- cgit v1.2.3-70-g09d2 From 968c837365c4a332fe3c802fd4ecab2562eb4d5a Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 16:18:42 +0100 Subject: Replace try_option with ? --- src/plugins/currency.rs | 18 ++++-------------- src/plugins/tell.rs | 5 ++++- 2 files changed, 8 insertions(+), 15 deletions(-) (limited to 'src/plugins/tell.rs') diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 393df9b..958c8e2 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -23,15 +23,6 @@ struct ConvertionRequest<'a> { target: &'a str, } -macro_rules! try_option { - ($e:expr) => { - match $e { - Some(v) => v, - None => { return None; } - } - } -} - impl<'a> ConvertionRequest<'a> { fn send(&self) -> Option { let response = Client::new() @@ -43,15 +34,14 @@ impl<'a> ConvertionRequest<'a> { match response { Ok(mut response) => { let mut body = String::new(); - try_option!(response.read_to_string(&mut body).ok()); + response.read_to_string(&mut body).ok()?; let convertion_rates: Result = serde_json::from_str(&body); match convertion_rates { Ok(convertion_rates) => { - let rates: &Value = try_option!(convertion_rates.get("rates")); - let target_rate: &Value = - try_option!(rates.get(self.target.to_uppercase())); - Some(self.value * try_option!(target_rate.as_f64())) + let rates: &Value = convertion_rates.get("rates")?; + let target_rate: &Value = rates.get(self.target.to_uppercase())?; + Some(self.value * target_rate.as_f64()?) } Err(_) => None, } diff --git a/src/plugins/tell.rs b/src/plugins/tell.rs index 3ec9586..34d7cf8 100644 --- a/src/plugins/tell.rs +++ b/src/plugins/tell.rs @@ -77,7 +77,10 @@ impl Tell { ) { return ExecutionStatus::Err(e); } - debug!("Sent {:?} from {:?} to {:?}", tell.message, tell.sender, receiver); + debug!( + "Sent {:?} from {:?} to {:?}", + tell.message, tell.sender, receiver + ); } } tells.remove(receiver); -- cgit v1.2.3-70-g09d2