diff options
| -rw-r--r-- | src/lib.rs | 40 | ||||
| -rw-r--r-- | src/main.rs | 12 | ||||
| -rw-r--r-- | src/plugin.rs | 10 | ||||
| -rw-r--r-- | src/plugins/currency.rs | 43 | ||||
| -rw-r--r-- | src/plugins/emoji.rs | 26 | ||||
| -rw-r--r-- | src/plugins/help.rs | 12 | ||||
| -rw-r--r-- | src/plugins/keepnick.rs | 42 | ||||
| -rw-r--r-- | src/plugins/url.rs | 22 |
8 files changed, 112 insertions, 95 deletions
@@ -146,7 +146,7 @@ impl Bot { let plugins = self.plugins.clone(); reactor.register_client_with_handler(client, move |client, message| { - process_msg(&client, plugins.clone(), message) + process_msg(client, plugins.clone(), message) }); Ok(()) @@ -206,23 +206,27 @@ impl ThreadedPlugins { for (name, plugin) in self.plugins.clone() { // Send the message to the plugin if the plugin needs it - if plugin.is_allowed(server, &message) { - - debug!("Executing {} with {}", - name, - message.to_string().replace("\r\n", "")); - - // Clone everything before the move - the server uses an Arc internally too - let plugin = Arc::clone(&plugin); - let message = Arc::clone(&message); - let server = server.clone(); - - // Execute the plugin in another thread - spawn(move || { - if let Err(e) = plugin.execute(&server, &message) { - error!("Error in {} - {}", name, e); - }; - }); + match plugin.execute(server, &message) { + ExecutionStatus::Done => (), + ExecutionStatus::Err(e) => error!("Error in {} - {}", name, e), + ExecutionStatus::RequiresThread => { + + debug!("Spawning thread to execute {} with {}", + name, + message.to_string().replace("\r\n", "")); + + // Clone everything before the move - the server uses an Arc internally too + let plugin = Arc::clone(&plugin); + let message = Arc::clone(&message); + let server = server.clone(); + + // Execute the plugin in another thread + spawn(move || { + if let Err(e) = plugin.execute_threaded(&server, &message) { + error!("Error in {} - {}", name, e); + }; + }); + } } } } diff --git a/src/main.rs b/src/main.rs index 21e27dc..7df8b3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +#![cfg_attr(feature="clippy", feature(plugin))] +#![cfg_attr(feature="clippy", plugin(clippy))] + extern crate frippy; extern crate time; extern crate irc; @@ -81,10 +84,10 @@ fn main() { for config in configs { let mut disabled_plugins = None; - if let &Some(ref options) = &config.options { + if let Some(ref options) = config.options { if let Some(disabled) = options.get("disabled_plugins") { disabled_plugins = Some(disabled - .split(",") + .split(',') .map(|p| p.trim()) .collect::<Vec<_>>()); } @@ -96,11 +99,12 @@ fn main() { bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::new()); + bot.add_plugin(plugins::Tell::new()); if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { - if let None = bot.remove_plugin(name) { - error!("{:?} was not found - could not disable", name); + if bot.remove_plugin(name).is_none() { + error!("\"{}\" was not found - could not disable", name); } } } diff --git a/src/plugin.rs b/src/plugin.rs index 8785708..88fe3ce 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -4,13 +4,19 @@ use std::fmt; use irc::client::prelude::*; use irc::error::IrcError; +pub enum ExecutionStatus { + Done, + Err(IrcError), + RequiresThread, +} + /// `Plugin` has to be implemented for any struct that should be usable /// as a plugin in frippy. pub trait Plugin: PluginName + Send + Sync + fmt::Debug { /// This should return true if the `Plugin` wants to do work on the message. - fn is_allowed(&self, server: &IrcClient, message: &Message) -> bool; + fn execute(&self, server: &IrcClient, message: &Message) -> ExecutionStatus; /// Handles messages which are not commands but still necessary. - fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError>; + fn execute_threaded(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError>; /// Handles any command directed at this plugin. fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError>; /// Should work like command but return a String instead of sending messages to IRC. diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 32a2506..21330a1 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -78,16 +78,15 @@ impl Currency { }) } - fn convert(&self, server: &IrcClient, command: &mut PluginCommand) -> Result<String, String> { - + fn convert(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<String, String> { if command.tokens.len() < 3 { - return Err(self.invalid_command(server)); + return Err(self.invalid_command(client)); } let request = match self.eval_command(&command.tokens) { Ok(request) => request, Err(_) => { - return Err(self.invalid_command(server)); + return Err(self.invalid_command(client)); } }; @@ -105,56 +104,56 @@ impl Currency { } } - fn help(&self, server: &IrcClient) -> String { + fn help(&self, client: &IrcClient) -> String { format!("usage: {} currency value from_currency to_currency\r\n\ - example: 1.5 eur usd\r\n\ + example: {0} currency 1.5 eur usd\r\n\ available currencies: AUD, BGN, BRL, CAD, \ CHF, CNY, CZK, DKK, GBP, HKD, HRK, HUF, \ IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, \ NZD, PHP, PLN, RON, RUB, SEK, SGD, THB, \ TRY, USD, ZAR", - server.current_nickname()) + client.current_nickname()) } - fn invalid_command(&self, server: &IrcClient) -> String { + fn invalid_command(&self, client: &IrcClient) -> String { format!("Incorrect Command. \ Send \"{} currency help\" for help.", - server.current_nickname()) + client.current_nickname()) } } impl Plugin for Currency { - fn is_allowed(&self, _: &IrcClient, _: &Message) -> bool { - false + fn execute(&self, _: &IrcClient, _: &Message) -> ExecutionStatus { + ExecutionStatus::Done } - fn execute(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { panic!("Currency does not implement the execute function!") } - fn command(&self, server: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { if command.tokens.is_empty() { - return server.send_notice(&command.source, &self.invalid_command(server)); + return client.send_notice(&command.source, &self.invalid_command(client)); } match command.tokens[0].as_ref() { - "help" => server.send_notice(&command.source, &self.help(server)), - _ => match self.convert(server, &mut command) { - Ok(msg) => server.send_privmsg(&command.target, &msg), - Err(msg) => server.send_notice(&command.source, &msg), + "help" => client.send_notice(&command.source, &self.help(client)), + _ => match self.convert(client, &mut command) { + Ok(msg) => client.send_privmsg(&command.target, &msg), + Err(msg) => client.send_notice(&command.source, &msg), } } } - fn evaluate(&self, server: &IrcClient, mut command: PluginCommand) -> Result<String, String>{ + fn evaluate(&self, client: &IrcClient, mut command: PluginCommand) -> Result<String, String>{ if command.tokens.is_empty() { - return Err(self.invalid_command(server)); + return Err(self.invalid_command(client)); } match command.tokens[0].as_ref() { - "help" => Ok(self.help(server)), - _ => self.convert(server, &mut command), + "help" => Ok(self.help(client)), + _ => self.convert(client, &mut command), } } } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index c19593d..02a31f8 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -97,25 +97,25 @@ impl Emoji { } impl Plugin for Emoji { - fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { - match message.command { - Command::PRIVMSG(_, _) => true, - _ => false, - } - } - - fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { + fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { Command::PRIVMSG(_, ref content) => { - server.send_privmsg(message.response_target().unwrap(), - &self.emoji(content)) + match client.send_privmsg(message.response_target().unwrap(), + &self.emoji(content)) { + Ok(_) => ExecutionStatus::Done, + Err(e) => ExecutionStatus::Err(e), + } } - _ => Ok(()), + _ => ExecutionStatus::Done, } } - fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + panic!("Emoji should not use threading") + } + + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + client.send_notice(&command.source, "This Plugin does not implement any commands.") } diff --git a/src/plugins/help.rs b/src/plugins/help.rs index 1bb15e1..4dd93d7 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -13,16 +13,16 @@ impl Help { } impl Plugin for Help { - fn is_allowed(&self, _: &IrcClient, _: &Message) -> bool { - false + fn execute(&self, _: &IrcClient, _: &Message) -> ExecutionStatus { + ExecutionStatus::Done } - fn execute(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { - panic!("Help does not implement the execute function!") + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + panic!("Help should not use threading") } - fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, "Help has not been added yet.") + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + client.send_notice(&command.source, "Help has not been added yet.") } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result<String, String> { diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 4a40e8f..e973769 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -11,47 +11,47 @@ impl KeepNick { KeepNick {} } - fn check_nick(&self, server: &IrcClient, leaver: &str) -> Result<(), IrcError> { - let cfg_nick = match server.config().nickname { + fn check_nick(&self, client: &IrcClient, leaver: &str) -> ExecutionStatus { + let cfg_nick = match client.config().nickname { Some(ref nick) => nick.clone(), - None => return Ok(()), + None => return ExecutionStatus::Done, }; if leaver != cfg_nick { - return Ok(()); + return ExecutionStatus::Done; } - let server_nick = server.current_nickname(); + let client_nick = client.current_nickname(); - if server_nick != cfg_nick { - info!("Trying to switch nick from {} to {}", server_nick, cfg_nick); - server.send(Command::NICK(cfg_nick)) + if client_nick != cfg_nick { + info!("Trying to switch nick from {} to {}", client_nick, cfg_nick); + match client.send(Command::NICK(cfg_nick)) { + Ok(_) => ExecutionStatus::Done, + Err(e) => ExecutionStatus::Err(e), + } } else { - Ok(()) + ExecutionStatus::Done } } } impl Plugin for KeepNick { - fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { - match message.command { - Command::QUIT(_) => true, - _ => false, - } - } - - fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { + fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { Command::QUIT(ref nick) => { - self.check_nick(server, &nick.clone().unwrap_or_else(|| String::new())) + self.check_nick(client, &nick.clone().unwrap_or_else(String::new)) } - _ => Ok(()), + _ => ExecutionStatus::Done, } } - fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + panic!("Tell should not use threading") + } + + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + client.send_notice(&command.source, "This Plugin does not implement any commands.") } diff --git a/src/plugins/url.rs b/src/plugins/url.rs index b980d3e..9ce5a6a 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -90,7 +90,7 @@ impl Url { } Err(e) => { debug!("Bad response from {:?}: ({})", url, e); - return None; + None } } } @@ -126,18 +126,22 @@ impl Url { } impl Plugin for Url { - fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { + fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { - Command::PRIVMSG(_, ref msg) => RE.is_match(msg), - _ => false, + Command::PRIVMSG(_, ref msg) => if RE.is_match(msg) { + ExecutionStatus::RequiresThread + } else { + ExecutionStatus::Done + }, + _ => ExecutionStatus::Done, } } - fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), IrcError> { match message.command { Command::PRIVMSG(_, ref content) => { match self.url(content) { - Ok(title) => server.send_privmsg(&message.response_target().unwrap(), &title), + Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), Err(_) => Ok(()), } } @@ -145,13 +149,13 @@ impl Plugin for Url { } } - fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + client.send_notice(&command.source, "This Plugin does not implement any commands.") } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result<String, String> { - self.url(&command.tokens[0]).map_err(|e| String::from(e)) + self.url(&command.tokens[0]).map_err(String::from) } } |
