From 09113bf4fa8cb8a42adb72533c3c76279e090978 Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 28 Nov 2017 03:12:48 +0100 Subject: Let users of the library define their own plugins This means that: - run() is now part of a Bot struct - Plugins the bot should use have to be added before calling run() - The Plugin trait and all of the included plugins are now public --- bin/main.rs | 10 ++- src/lib.rs | 269 ++++++++++++++++++++++++++++++++++++++++++++-------------- src/plugin.rs | 120 ++++++-------------------- 3 files changed, 238 insertions(+), 161 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index 86910c0..f6a9418 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -4,6 +4,8 @@ extern crate time; use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; +use frippy::plugins; + struct Logger; impl log::Log for Logger { @@ -43,5 +45,11 @@ fn main() { }) .unwrap(); - frippy::run(); + let mut bot = frippy::Bot::new(); + + bot.add_plugin(plugins::Help::new()); + bot.add_plugin(plugins::Emoji::new()); + bot.add_plugin(plugins::Currency::new()); + + bot.run(); } diff --git a/src/lib.rs b/src/lib.rs index 324e273..9613160 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,11 +4,17 @@ //! Frippy is an IRC bot that runs plugins on each message //! received. //! -//! ## Example +//! ## Examples //! ```no_run -//! extern crate frippy; +//! use frippy::plugins; //! -//! frippy::run(); +//! let mut bot = frippy::Bot::new(); +//! +//! bot.add_plugin(plugins::Help::new()); +//! bot.add_plugin(plugins::Emoji::new()); +//! bot.add_plugin(plugins::Currency::new()); +//! +//! bot.run(); //! ``` //! //! # Logging @@ -25,9 +31,12 @@ extern crate tokio_core; extern crate futures; extern crate glob; -mod plugin; -mod plugins; +pub mod plugin; +pub mod plugins; +use std::fmt; +use std::collections::HashMap; +use std::thread::spawn; use std::sync::Arc; use irc::client::prelude::*; @@ -39,75 +48,114 @@ use glob::glob; use plugin::*; -/// Runs the bot -/// -/// # Remarks -/// -/// This blocks the current thread while the bot is running -pub fn run() { - - // Load all toml files in the configs directory - let mut configs = Vec::new(); - for toml in glob("configs/*.toml").unwrap() { - match toml { - Ok(path) => { - info!("Loading {}", path.to_str().unwrap()); - match Config::load(path) { - Ok(v) => configs.push(v), - Err(e) => error!("Incorrect config file {}", e), - } - } - Err(e) => error!("Failed to read path {}", e), - } +pub struct Bot { + plugins: ThreadedPlugins, +} + +impl Bot { + /// Creates a `Bot`. + /// By itself the bot only responds to a few simple ctcp commands + /// defined per config file. + /// Any other functionality has to be provided by plugins + /// which need to implement [`Plugin`](plugin/trait.Plugin.html). + /// + /// # Examples + /// ``` + /// use frippy::Bot; + /// let mut bot = Bot::new(); + /// ``` + pub fn new() -> Bot { + Bot { plugins: ThreadedPlugins::new() } } - // Without configs the bot would just idle - if configs.is_empty() { - error!("No config file found"); - return; + /// Add plugins which should evaluate incoming messages from IRC. + /// + /// # Examples + /// ``` + /// use frippy::{plugins, Bot}; + /// + /// let mut bot = frippy::Bot::new(); + /// bot.add_plugin(plugins::Help::new()); + /// ``` + pub fn add_plugin(&mut self, plugin: T) { + self.plugins.add(plugin); } - // The list of plugins in use - let mut plugins = ThreadedPlugins::new(); - plugins.add(plugins::Help::new()); - plugins.add(plugins::Emoji::new()); - plugins.add(plugins::Currency::new()); - info!("Plugins loaded: {}", plugins); - - // Create an event loop to run the connections on. - let mut reactor = Core::new().unwrap(); - - // Open a connection and add work for each config - for config in configs { - let server = - match IrcServer::new_future(reactor.handle(), &config).and_then(|f| reactor.run(f)) { - Ok(v) => v, - Err(e) => { - error!("Failed to connect: {}", e); - return; + /// This starts the `Bot` which means that it tries + /// to create one connection for each toml file + /// found in the `configs` directory. + /// + /// Then it waits for incoming messages and sends them to the plugins. + /// This blocks the current thread until the `Bot` is shut down. + /// + /// # Examples + /// ```no_run + /// use frippy::{plugins, Bot}; + /// + /// let mut bot = Bot::new(); + /// bot.run(); + /// ``` + pub fn run(self) { + info!("Plugins loaded: {}", self.plugins); + + // Load all toml files in the configs directory + let mut configs = Vec::new(); + for toml in glob("configs/*.toml").unwrap() { + match toml { + Ok(path) => { + info!("Loading {}", path.to_str().unwrap()); + match Config::load(path) { + Ok(v) => configs.push(v), + Err(e) => error!("Incorrect config file {}", e), + } } - }; + Err(e) => error!("Failed to read path {}", e), + } + } - info!("Connected to server"); + // Without configs the bot would just idle + if configs.is_empty() { + error!("No config file found"); + return; + } - match server.identify() { - Ok(_) => info!("Identified"), - Err(e) => error!("Failed to identify: {}", e), - }; + // Create an event loop to run the connections on. + let mut reactor = Core::new().unwrap(); - // TODO Verify if we actually need to clone plugins twice - let plugins = plugins.clone(); + // Open a connection and add work for each config + for config in configs { + let server = + match IrcServer::new_future(reactor.handle(), &config).and_then(|f| { + reactor.run(f) + }) { + Ok(v) => v, + Err(e) => { + error!("Failed to connect: {}", e); + return; + } + }; - let task = server - .stream() - .for_each(move |message| process_msg(&server, plugins.clone(), message)) - .map_err(|e| error!("Failed to process message: {}", e)); + info!("Connected to server"); - reactor.handle().spawn(task); - } + match server.identify() { + Ok(_) => info!("Identified"), + Err(e) => error!("Failed to identify: {}", e), + }; + + // TODO Verify if we actually need to clone plugins twice + let plugins = self.plugins.clone(); + + let task = server + .stream() + .for_each(move |message| process_msg(&server, plugins.clone(), message)) + .map_err(|e| error!("Failed to process message: {}", e)); - // Run the main loop forever - reactor.run(future::empty::<(), ()>()).unwrap(); + reactor.handle().spawn(task); + } + + // Run the main loop forever + reactor.run(future::empty::<(), ()>()).unwrap(); + } } fn process_msg(server: &IrcServer, @@ -115,6 +163,7 @@ fn process_msg(server: &IrcServer, message: Message) -> Result<(), IrcError> { + // Log any channels we join if let Command::JOIN(ref channel, _, _) = message.command { if message.source_nickname().unwrap() == server.current_nickname() { info!("Joined {}", channel); @@ -124,7 +173,6 @@ fn process_msg(server: &IrcServer, // Check for possible command and save the result for later let command = PluginCommand::from(&server.current_nickname().to_lowercase(), &message); - let message = Arc::new(message); plugins.execute_plugins(server, message); // If the message contained a command, handle it @@ -137,6 +185,99 @@ fn process_msg(server: &IrcServer, Ok(()) } +#[derive(Clone, Debug)] +struct ThreadedPlugins { + plugins: HashMap>, +} + +impl ThreadedPlugins { + pub fn new() -> ThreadedPlugins { + ThreadedPlugins { plugins: HashMap::new() } + } + + pub fn add(&mut self, plugin: T) { + let name = plugin.name().to_lowercase(); + let safe_plugin = Arc::new(plugin); + + self.plugins.insert(name, safe_plugin); + } + + pub fn execute_plugins(&mut self, server: &IrcServer, message: Message) { + let message = Arc::new(message); + + 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); + }; + }); + } + } + } + + pub fn handle_command(&mut self, + server: &IrcServer, + mut command: PluginCommand) + -> Result<(), IrcError> { + + if !command.tokens.iter().any(|s| !s.is_empty()) { + let help = format!("Use \"{} help\" to get help", server.current_nickname()); + return server.send_notice(&command.source, &help); + } + + // Check if the command is for this plugin + if let Some(plugin) = self.plugins.get(&command.tokens[0].to_lowercase()) { + + // The first token contains the name of the plugin + let name = command.tokens.remove(0); + + debug!("Sending command \"{:?}\" to {}", command, name); + + // Clone for the move - the server uses an Arc internally + let server = server.clone(); + let plugin = Arc::clone(plugin); + spawn(move || { + if let Err(e) = plugin.command(&server, command) { + error!("Error in {} command - {}", name, e); + }; + }); + + Ok(()) + + } else { + let help = format!("\"{} {}\" is not a command, \ + try \"{0} help\" instead.", + server.current_nickname(), + command.tokens[0]); + + server.send_notice(&command.source, &help) + } + } +} + +impl fmt::Display for ThreadedPlugins { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let plugin_names = self.plugins + .iter() + .map(|(_, p)| p.name().to_string()) + .collect::>(); + write!(f, "{}", plugin_names.join(", ")) + } +} #[cfg(test)] mod tests {} diff --git a/src/plugin.rs b/src/plugin.rs index d1f849a..0287989 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -1,29 +1,50 @@ use std::fmt; -use std::collections::HashMap; -use std::thread::spawn; -use std::sync::Arc; use irc::client::prelude::*; use irc::error::Error as IrcError; +/// `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: &IrcServer, message: &Message) -> bool; + /// Handles messages which are not commands but still necessary. fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError>; + /// Handles any command directed at this plugina. fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError>; } +/// `PluginName` is required by `Plugin`. +/// To implement it simply add `#[derive(PluginName)]` +/// above the definition of the struct. +/// +/// # Examples +/// ```ignore +/// #[macro_use] extern crate plugin_derive; +/// +/// #[derive(PluginName)] +/// struct Foo; +/// ``` pub trait PluginName: Send + Sync + fmt::Debug { + /// Returns the name of the plugin. fn name(&self) -> &str; } +/// Represents a command sent by a user to the bot. #[derive(Clone, Debug)] pub struct PluginCommand { + /// The sender of the command. pub source: String, + /// If the command was sent to a channel, this will be that channel + /// otherwise it is the same as `source`. pub target: String, + /// The remaining part of the message that has not been processed yet - split by spaces. pub tokens: Vec, } impl PluginCommand { + /// Creates a `PluginCommand` from `Message` if it is a `PRIVMSG` + /// that starts with the provided `nick`. pub fn from(nick: &str, message: &Message) -> Option { // Get the actual message out of PRIVMSG @@ -64,96 +85,3 @@ impl PluginCommand { } } } - -#[derive(Clone, Debug)] -pub struct ThreadedPlugins { - plugins: HashMap>, -} - -impl ThreadedPlugins { - pub fn new() -> ThreadedPlugins { - ThreadedPlugins { plugins: HashMap::new() } - } - - pub fn add(&mut self, plugin: T) { - let name = plugin.name().to_lowercase(); - let safe_plugin = Arc::new(plugin); - - self.plugins.insert(name, safe_plugin); - } - - pub fn execute_plugins(&mut self, server: &IrcServer, message: Arc) { - - 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); - }; - }); - } - } - } - - pub fn handle_command(&mut self, - server: &IrcServer, - mut command: PluginCommand) - -> Result<(), IrcError> { - - if !command.tokens.iter().any(|s| !s.is_empty()) { - let help = format!("Use \"{} help\" to get help", server.current_nickname()); - return server.send_notice(&command.source, &help); - } - - // Check if the command is for this plugin - if let Some(plugin) = self.plugins.get(&command.tokens[0].to_lowercase()) { - - // The first token contains the name of the plugin - let name = command.tokens.remove(0); - - debug!("Sending command \"{:?}\" to {}", command, name); - - // Clone for the move - the server uses an Arc internally - let server = server.clone(); - let plugin = Arc::clone(plugin); - spawn(move || { - if let Err(e) = plugin.command(&server, command) { - error!("Error in {} command - {}", name, e); - }; - }); - - Ok(()) - - } else { - let help = format!("\"{} {}\" is not a command, \ - try \"{0} help\" instead.", - server.current_nickname(), - command.tokens[0]); - - server.send_notice(&command.source, &help) - } - } -} - -impl fmt::Display for ThreadedPlugins { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let plugin_names = self.plugins - .iter() - .map(|(_, p)| p.name().to_string()) - .collect::>(); - write!(f, "{}", plugin_names.join(", ")) - } -} -- cgit v1.2.3-70-g09d2 From 5501fdf4042db1abf82d8e791b47d1802e710f9a Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 28 Nov 2017 03:52:13 +0100 Subject: Update dependencies to remove deprecated syntax --- Cargo.lock | 305 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 150 insertions(+), 155 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a721a1d..bbba229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,14 +22,14 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -39,8 +39,8 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -91,14 +91,14 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -117,30 +117,32 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.166" +version = "0.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.166" +version = "0.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -149,7 +151,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -157,23 +159,17 @@ name = "core-foundation-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crc" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crc-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crc-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crypt32-sys" version = "0.2.0" @@ -199,7 +195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "either" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -264,29 +260,37 @@ name = "error-chain" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "foreign-types" -version = "0.2.0" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "foreign-types-shared 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "frippy" version = "0.3.1" dependencies = [ - "clippy 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "plugin_derive 0.1.0", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", @@ -310,7 +314,7 @@ dependencies = [ [[package]] name = "futures" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -318,7 +322,7 @@ name = "futures-cpupool" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -339,25 +343,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -365,11 +369,11 @@ name = "hyper-tls" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -384,12 +388,17 @@ dependencies = [ "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "if_chain" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "iovec" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -403,13 +412,13 @@ dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -421,7 +430,7 @@ name = "itertools" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -445,7 +454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -455,7 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -465,7 +474,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -483,7 +492,7 @@ name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -491,12 +500,12 @@ name = "mime" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mime_guess" -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -515,7 +524,7 @@ dependencies = [ "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", @@ -539,7 +548,7 @@ name = "native-tls" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -553,7 +562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -595,35 +604,35 @@ name = "num_cpus" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "percent-encoding" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -649,7 +658,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -695,11 +704,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -729,29 +738,29 @@ name = "relay" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "reqwest" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -760,14 +769,6 @@ name = "rustc-demangle" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc_version" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "safemem" version = "0.2.0" @@ -781,7 +782,7 @@ dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -808,7 +809,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -818,14 +819,9 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "semver" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "semver" version = "0.6.0" @@ -841,22 +837,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.16" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.16" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -865,13 +861,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -881,8 +877,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -933,7 +929,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -941,7 +937,7 @@ name = "thread_local" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -951,7 +947,7 @@ version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -962,22 +958,22 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -986,8 +982,8 @@ name = "tokio-mockstream" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -995,15 +991,15 @@ name = "tokio-proto" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1012,7 +1008,7 @@ name = "tokio-service" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1020,7 +1016,7 @@ name = "tokio-timer" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1029,10 +1025,10 @@ name = "tokio-tls" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1040,7 +1036,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1053,10 +1049,10 @@ dependencies = [ [[package]] name = "unicase" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1080,7 +1076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode_names" version = "0.1.7" -source = "git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode#6f3ad8f563cbd9a29c2857a451f1bf8cc0e105ee" +source = "git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode#d97b80c3c35b9f1d04085409087ef113c94cde17" [[package]] name = "unreachable" @@ -1092,12 +1088,12 @@ dependencies = [ [[package]] name = "url" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1110,7 +1106,7 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1151,7 +1147,7 @@ dependencies = [ "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" -"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983" +"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" @@ -1161,19 +1157,18 @@ dependencies = [ "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" -"checksum cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4019bdb99c0c1ddd56c12c2f507c174d729c6915eca6bd9d27c42f3d93b0f4" +"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clippy 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)" = "86c1e9a7fd08987104fcca0ce1ab0a627006ed955ce14a87ffa32754c947fccb" -"checksum clippy_lints 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)" = "cbde64e1942d299a8ebe242d54567654db22aa06bdaae7aa3eb392db275172e0" +"checksum clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)" = "1b03ded6eba74b16dbeb598be58e874bc72f6cf12f7ccc577b328091e1d4392a" +"checksum clippy_lints 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)" = "9b8e508648d6d41040e0061f45fc5562b3af5c8a7d67853f15841fb531c8e984" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum crc 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fba69ea0e15e720f7e1cfe1cf3bc55007fbd41e32b8ae11cfa343e7e5961e79a" -"checksum crc-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "003d1170779d405378223470f5864b41b79a91969be1260e4de7b4ec069af69c" +"checksum crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d4a687c40efbc7d376958117b34d5f1cece11709110a742405bf58e7a34f00" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum either 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e311a7479512fbdf858fb54d91ec59f3b9f85bc0113659f46bba12b199d273ce" +"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -1182,32 +1177,34 @@ dependencies = [ "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" -"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" +"checksum foreign-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00a47bdf90d10e6ceae97fb92c1b05461461e53c89cedd455a943f0e0e1f7404" +"checksum foreign-types-shared 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baa1839fc3c5487b5e129ea4f774e3fd84e6c4607127315521bc014a722ebc9e" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" -"checksum futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "05a23db7bd162d4e8265968602930c476f688f0c180b44bdaf55e0cb2c687558" +"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b45eac8b696d59491b079bd04fcb0f3488c0f6ed62dcb36bcfea8a543e9cdc3" +"checksum hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4959ca95f55df4265bff2ad63066147255e6fa733682cf6d1cb5eaff6e53324b" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" +"checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" "checksum irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)" = "484fea2147dd042cdb3dd9e707af9cc9d8f46a4adc04e553ff985203a955ed6e" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "56cce3130fd040c28df6f495c8492e5ec5808fb4c9093c310df02b0c8f030148" +"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" "checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" -"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae" +"checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" "checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" @@ -1217,9 +1214,9 @@ dependencies = [ "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum openssl 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf434ff6117485dc16478d77a4f5c84eccc9c3645c4da8323b287ad6a15a638" -"checksum openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad395f1cee51b64a8d07cc8063498dc7554db62d5f3ca87a67f4eed2791d0c8" -"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "2225c305d8f57001a0d34263e046794aa251695f20773102fbbfeb1e7b189955" +"checksum openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "92867746af30eea7a89feade385f7f5366776f1c52ec6f0de81360373fa88363" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" @@ -1228,27 +1225,25 @@ dependencies = [ "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae" +"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" -"checksum reqwest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194fe0d39dea7f89738707bf70e9f3ed47e8aca47d4b2eeaad6ac7831d2d390b" +"checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7554288337c1110e34d7a2433518d889374c1de1a45f856b7bcddb03702131fc" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e11a631f964d4e6572712ea12075fb1d65eeef42b0058884195b430ac1e26809" -"checksum serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1a51d54c805fbc8e12b603d1ba51eaed3195862976be468888ab0e4995d0000e" -"checksum serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd381f6d01a6616cdba8530492d453b7761b456ba974e98768a18cad2cd76f58" -"checksum serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee28c1d94a7745259b767ca9e5b95d55bafbd3205ca3acb978cad84a6ed6bc62" +"checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e" +"checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" +"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" +"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" @@ -1261,7 +1256,7 @@ dependencies = [ "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" -"checksum tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ab83e7adb5677e42e405fa4ceff75659d93c4d7d7dd22f52fcec59ee9f02af" +"checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41bfc436ef8b7f60c19adf3df086330ae9992385e4d8c53b17a323cad288e155" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" @@ -1269,13 +1264,13 @@ dependencies = [ "checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80" +"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)" = "" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27" +"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" -- cgit v1.2.3-70-g09d2 From 413f5d96e9fe4e990e5cd485abe828e0fb5c7ed4 Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 30 Nov 2017 15:28:05 +0100 Subject: Rename plugin_derive to frippy_derive --- .gitignore | 4 +- Cargo.lock | 144 +++++++++++++++++++++++------------------------ Cargo.toml | 2 +- frippy_derive/Cargo.toml | 11 ++++ frippy_derive/src/lib.rs | 27 +++++++++ plugin_derive/Cargo.toml | 11 ---- plugin_derive/src/lib.rs | 27 --------- src/lib.rs | 2 +- src/plugin.rs | 2 +- 9 files changed, 115 insertions(+), 115 deletions(-) create mode 100644 frippy_derive/Cargo.toml create mode 100644 frippy_derive/src/lib.rs delete mode 100644 plugin_derive/Cargo.toml delete mode 100644 plugin_derive/src/lib.rs diff --git a/.gitignore b/.gitignore index fdcd3a6..f6ed057 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ # Generated by Cargo # will have compiled files and executables /target/ -/plugin_derive/target/ +/frippy_derive/target/ # The top level Cargo.lock should handle everything -/plugin_derive/Cargo.lock +/frippy_derive/Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock index bbba229..aae3b22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,10 +14,10 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -29,7 +29,7 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -40,7 +40,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -48,7 +48,7 @@ name = "base64" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -82,7 +82,7 @@ name = "bytes" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -91,8 +91,8 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -122,7 +122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -138,8 +138,8 @@ dependencies = [ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -151,7 +151,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -159,7 +159,7 @@ name = "core-foundation-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -265,15 +265,15 @@ dependencies = [ [[package]] name = "foreign-types" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "foreign-types-shared 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "foreign-types-shared" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -281,21 +281,29 @@ name = "frippy" version = "0.3.1" dependencies = [ "clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", + "frippy_derive 0.1.0", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "plugin_derive 0.1.0", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", ] +[[package]] +name = "frippy_derive" +version = "0.1.0" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-zircon" version = "0.2.1" @@ -398,7 +406,7 @@ name = "iovec" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -414,8 +422,8 @@ dependencies = [ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -464,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -473,7 +481,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -489,10 +497,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "1.0.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -524,7 +532,7 @@ dependencies = [ "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", @@ -548,7 +556,7 @@ name = "native-tls" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -562,7 +570,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -604,28 +612,28 @@ name = "num_cpus" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl" -version = "0.9.21" +version = "0.9.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.21" +version = "0.9.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -675,14 +683,6 @@ name = "pkg-config" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "plugin_derive" -version = "0.1.0" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pulldown-cmark" version = "0.0.15" @@ -708,21 +708,21 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -754,7 +754,7 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -809,7 +809,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -819,7 +819,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -837,12 +837,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -867,7 +867,7 @@ dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -877,7 +877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -947,8 +947,8 @@ version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1036,7 +1036,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1146,7 +1146,7 @@ dependencies = [ [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" -"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" @@ -1154,7 +1154,7 @@ dependencies = [ "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9" -"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" +"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" @@ -1177,8 +1177,8 @@ dependencies = [ "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" -"checksum foreign-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00a47bdf90d10e6ceae97fb92c1b05461461e53c89cedd455a943f0e0e1f7404" -"checksum foreign-types-shared 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baa1839fc3c5487b5e129ea4f774e3fd84e6c4607127315521bc014a722ebc9e" +"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" @@ -1198,11 +1198,11 @@ dependencies = [ "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" +"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" "checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" "checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" @@ -1214,8 +1214,8 @@ dependencies = [ "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "2225c305d8f57001a0d34263e046794aa251695f20773102fbbfeb1e7b189955" -"checksum openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "92867746af30eea7a89feade385f7f5366776f1c52ec6f0de81360373fa88363" +"checksum openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "419ef26bb651d72b6c5a603bcc4e4856a362460e62352dfffa53de91d2e81181" +"checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" @@ -1226,8 +1226,8 @@ dependencies = [ "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" -"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" -"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" +"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" +"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" @@ -1240,8 +1240,8 @@ dependencies = [ "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e" -"checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" +"checksum serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c37d7f192f00041e8a613e936717923a71bc0c9051fc4425a49b104140f05" +"checksum serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "0672de7300b02bac3f3689f8faea813c4a1ea9fe0cb49e80f714231d267518a2" "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" "checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" diff --git a/Cargo.toml b/Cargo.toml index eecfa86..2eae2bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ serde = "1.0.15" serde_json = "1.0.3" glob = "0.2" -plugin_derive = { path = "plugin_derive" } +frippy_derive = { path = "frippy_derive" } unicode_names = { git = 'https://github.com/Jokler/unicode_names', branch = 'update-to-latest-unicode' } clippy = {version = "*", optional = true} diff --git a/frippy_derive/Cargo.toml b/frippy_derive/Cargo.toml new file mode 100644 index 0000000..937afba --- /dev/null +++ b/frippy_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "frippy_derive" +version = "0.1.0" +authors = ["Jokler "] + +[lib] +proc-macro = true + +[dependencies] +syn = "0.11.11" +quote = "0.3.15" diff --git a/frippy_derive/src/lib.rs b/frippy_derive/src/lib.rs new file mode 100644 index 0000000..704d6ef --- /dev/null +++ b/frippy_derive/src/lib.rs @@ -0,0 +1,27 @@ + +//! Provides the plugin derive macro + +extern crate proc_macro; +extern crate syn; +#[macro_use] +extern crate quote; + +use proc_macro::TokenStream; + +#[proc_macro_derive(PluginName)] +pub fn derive_plugin(data: TokenStream) -> TokenStream { + let ast = syn::parse_derive_input(&data.to_string()).unwrap(); + let gen = expand_plugin(&ast); + gen.parse().unwrap() +} + +fn expand_plugin(ast: &syn::DeriveInput) -> quote::Tokens { + let name = &ast.ident; + quote! { + impl PluginName for #name { + fn name(&self) -> &str { + stringify!(#name) + } + } + } +} diff --git a/plugin_derive/Cargo.toml b/plugin_derive/Cargo.toml deleted file mode 100644 index 0b62f9f..0000000 --- a/plugin_derive/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "plugin_derive" -version = "0.1.0" -authors = ["Jokler "] - -[lib] -proc-macro = true - -[dependencies] -syn = "0.11.11" -quote = "0.3.15" diff --git a/plugin_derive/src/lib.rs b/plugin_derive/src/lib.rs deleted file mode 100644 index 704d6ef..0000000 --- a/plugin_derive/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ - -//! Provides the plugin derive macro - -extern crate proc_macro; -extern crate syn; -#[macro_use] -extern crate quote; - -use proc_macro::TokenStream; - -#[proc_macro_derive(PluginName)] -pub fn derive_plugin(data: TokenStream) -> TokenStream { - let ast = syn::parse_derive_input(&data.to_string()).unwrap(); - let gen = expand_plugin(&ast); - gen.parse().unwrap() -} - -fn expand_plugin(ast: &syn::DeriveInput) -> quote::Tokens { - let name = &ast.ident; - quote! { - impl PluginName for #name { - fn name(&self) -> &str { - stringify!(#name) - } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 9613160..eef6914 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,7 @@ #[macro_use] extern crate log; #[macro_use] -extern crate plugin_derive; +extern crate frippy_derive; extern crate irc; extern crate tokio_core; diff --git a/src/plugin.rs b/src/plugin.rs index 0287989..fb01168 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -20,7 +20,7 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { /// /// # Examples /// ```ignore -/// #[macro_use] extern crate plugin_derive; +/// #[macro_use] extern crate frippy_derive; /// /// #[derive(PluginName)] /// struct Foo; -- cgit v1.2.3-70-g09d2 From f716ecd319977aea7773dc689592fc8193c609f1 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 6 Dec 2017 03:45:10 +0100 Subject: Add KeepNick plugin --- bin/main.rs | 1 + src/plugins/keepnick.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ src/plugins/mod.rs | 2 ++ 3 files changed, 54 insertions(+) create mode 100644 src/plugins/keepnick.rs diff --git a/bin/main.rs b/bin/main.rs index f6a9418..614bffe 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -50,6 +50,7 @@ fn main() { bot.add_plugin(plugins::Help::new()); bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); + bot.add_plugin(plugins::KeepNick::new()); bot.run(); } diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs new file mode 100644 index 0000000..5f5d92c --- /dev/null +++ b/src/plugins/keepnick.rs @@ -0,0 +1,51 @@ +use irc::client::prelude::*; +use irc::error::Error as IrcError; + +use plugin::*; + +#[derive(PluginName, Debug)] +pub struct KeepNick; + +impl KeepNick { + pub fn new() -> KeepNick { + KeepNick {} + } + + fn check_nick(&self, server: &IrcServer) -> Result<(), IrcError> { + let cfg_nick = match server.config().nickname { + Some(ref nick) => nick.clone(), + None => return Ok(()), + }; + + let server_nick = server.current_nickname(); + + if server_nick != cfg_nick { + info!("Trying to switch nick from {} to {}", server_nick, cfg_nick); + server.send(Command::NICK(cfg_nick)) + + } else { + Ok(()) + } + } +} + +impl Plugin for KeepNick { + fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + match message.command { + Command::QUIT(_) => true, + _ => false, + } + } + + fn execute(&self, server: &IrcServer, _: &Message) -> Result<(), IrcError> { + self.check_nick(server) + } + + fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + server.send_notice(&command.source, + "This Plugin does not implement any commands.") + } +} + +#[cfg(test)] +mod tests {} diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 0dea596..5bcb6ed 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,7 +1,9 @@ mod help; mod emoji; mod currency; +mod keepnick; pub use self::help::Help; pub use self::emoji::Emoji; pub use self::currency::Currency; +pub use self::keepnick::KeepNick; -- cgit v1.2.3-70-g09d2 From 6ba6651cdda7528e39a94c596b5137ec4f8d32e6 Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 7 Dec 2017 14:25:39 +0100 Subject: Check who left before trying to get the nick --- src/plugins/keepnick.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 5f5d92c..afe12f8 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -11,12 +11,16 @@ impl KeepNick { KeepNick {} } - fn check_nick(&self, server: &IrcServer) -> Result<(), IrcError> { + fn check_nick(&self, server: &IrcServer, leaver: &str) -> Result<(), IrcError> { let cfg_nick = match server.config().nickname { Some(ref nick) => nick.clone(), None => return Ok(()), }; + if leaver != cfg_nick { + return Ok(()); + } + let server_nick = server.current_nickname(); if server_nick != cfg_nick { @@ -37,8 +41,13 @@ impl Plugin for KeepNick { } } - fn execute(&self, server: &IrcServer, _: &Message) -> Result<(), IrcError> { - self.check_nick(server) + fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + match message.command { + Command::QUIT(ref nick) => { + self.check_nick(server, &nick.clone().unwrap_or(String::from(""))) + } + _ => Ok(()), + } } fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { -- cgit v1.2.3-70-g09d2 From ab70f0e6dff916638edfc95d406922b3fd15df7d Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 11 Dec 2017 01:49:09 +0100 Subject: Move Config logic out of the library --- bin/main.rs | 53 ++++++++++++++++++++++---- src/lib.rs | 125 ++++++++++++++++++++++++++---------------------------------- 2 files changed, 100 insertions(+), 78 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index 614bffe..b220b0c 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -1,10 +1,20 @@ extern crate frippy; -extern crate log; extern crate time; +extern crate tokio_core; +extern crate glob; +extern crate futures; + +#[macro_use] +extern crate log; use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; +use tokio_core::reactor::Core; +use futures::future; +use glob::glob; + use frippy::plugins; +use frippy::Config; struct Logger; @@ -45,12 +55,41 @@ fn main() { }) .unwrap(); - let mut bot = frippy::Bot::new(); + // Load all toml files in the configs directory + let mut configs = Vec::new(); + for toml in glob("configs/*.toml").unwrap() { + match toml { + Ok(path) => { + info!("Loading {}", path.to_str().unwrap()); + match Config::load(path) { + Ok(v) => configs.push(v), + Err(e) => error!("Incorrect config file {}", e), + } + } + Err(e) => error!("Failed to read path {}", e), + } + } + + // Without configs the bot would just idle + if configs.is_empty() { + error!("No config file found"); + return; + } + + // Create an event loop to run the connections on. + let mut reactor = Core::new().unwrap(); + + // Open a connection and add work for each config + for config in configs { + let mut bot = frippy::Bot::new(); + bot.add_plugin(plugins::Help::new()); + bot.add_plugin(plugins::Emoji::new()); + bot.add_plugin(plugins::Currency::new()); + bot.add_plugin(plugins::KeepNick::new()); - bot.add_plugin(plugins::Help::new()); - bot.add_plugin(plugins::Emoji::new()); - bot.add_plugin(plugins::Currency::new()); - bot.add_plugin(plugins::KeepNick::new()); + bot.connect(&mut reactor, &config); + } - bot.run(); + // Run the main loop forever + reactor.run(future::empty::<(), ()>()).unwrap(); } diff --git a/src/lib.rs b/src/lib.rs index eef6914..da1a278 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,15 +6,25 @@ //! //! ## Examples //! ```no_run -//! use frippy::plugins; +//! # extern crate tokio_core; +//! # extern crate futures; +//! # extern crate frippy; +//! # fn main() { +//! use frippy::{plugins, Config, Bot}; +//! use tokio_core::reactor::Core; +//! use futures::future; //! -//! let mut bot = frippy::Bot::new(); +//! let config = Config::load("config.toml").unwrap(); +//! let mut reactor = Core::new().unwrap(); +//! let mut bot = Bot::new(); //! //! bot.add_plugin(plugins::Help::new()); //! bot.add_plugin(plugins::Emoji::new()); //! bot.add_plugin(plugins::Currency::new()); //! -//! bot.run(); +//! bot.connect(&mut reactor, &config); +//! reactor.run(future::empty::<(), ()>()).unwrap(); +//! # } //! ``` //! //! # Logging @@ -27,9 +37,8 @@ extern crate log; extern crate frippy_derive; extern crate irc; -extern crate tokio_core; extern crate futures; -extern crate glob; +extern crate tokio_core; pub mod plugin; pub mod plugins; @@ -39,12 +48,9 @@ use std::collections::HashMap; use std::thread::spawn; use std::sync::Arc; -use irc::client::prelude::*; -use irc::error::Error as IrcError; - use tokio_core::reactor::Core; -use futures::future; -use glob::glob; +pub use irc::client::prelude::*; +pub use irc::error::Error as IrcError; use plugin::*; @@ -81,80 +87,58 @@ impl Bot { self.plugins.add(plugin); } - /// This starts the `Bot` which means that it tries - /// to create one connection for each toml file - /// found in the `configs` directory. + /// This connects the `Bot` to IRC and adds a task + /// to the Core that was supplied. /// - /// Then it waits for incoming messages and sends them to the plugins. - /// This blocks the current thread until the `Bot` is shut down. + /// You need to run the core, so that frippy + /// can do its work. /// /// # Examples /// ```no_run - /// use frippy::{plugins, Bot}; + /// # extern crate tokio_core; + /// # extern crate futures; + /// # extern crate frippy; + /// # fn main() { + /// use frippy::{Config, Bot}; + /// use tokio_core::reactor::Core; + /// use futures::future; /// + /// let config = Config::load("config.toml").unwrap(); + /// let mut reactor = Core::new().unwrap(); /// let mut bot = Bot::new(); - /// bot.run(); + /// + /// bot.connect(&mut reactor, &config); + /// reactor.run(future::empty::<(), ()>()).unwrap(); + /// # } /// ``` - pub fn run(self) { + pub fn connect(&self, reactor: &mut Core, config: &Config) { info!("Plugins loaded: {}", self.plugins); - // Load all toml files in the configs directory - let mut configs = Vec::new(); - for toml in glob("configs/*.toml").unwrap() { - match toml { - Ok(path) => { - info!("Loading {}", path.to_str().unwrap()); - match Config::load(path) { - Ok(v) => configs.push(v), - Err(e) => error!("Incorrect config file {}", e), - } + let server = + match IrcServer::new_future(reactor.handle(), config).and_then(|f| {reactor.run(f)}) { + Ok(v) => v, + Err(e) => { + error!("Failed to connect: {}", e); + return; } - Err(e) => error!("Failed to read path {}", e), - } - } - - // Without configs the bot would just idle - if configs.is_empty() { - error!("No config file found"); - return; - } - - // Create an event loop to run the connections on. - let mut reactor = Core::new().unwrap(); - - // Open a connection and add work for each config - for config in configs { - let server = - match IrcServer::new_future(reactor.handle(), &config).and_then(|f| { - reactor.run(f) - }) { - Ok(v) => v, - Err(e) => { - error!("Failed to connect: {}", e); - return; - } - }; - - info!("Connected to server"); - - match server.identify() { - Ok(_) => info!("Identified"), - Err(e) => error!("Failed to identify: {}", e), }; - // TODO Verify if we actually need to clone plugins twice - let plugins = self.plugins.clone(); + info!("Connected to server"); - let task = server - .stream() - .for_each(move |message| process_msg(&server, plugins.clone(), message)) - .map_err(|e| error!("Failed to process message: {}", e)); + match server.identify() { + Ok(_) => info!("Identified"), + Err(e) => error!("Failed to identify: {}", e), + }; - reactor.handle().spawn(task); - } + // TODO Verify if we actually need to clone plugins twice + let plugins = self.plugins.clone(); + + let task = server + .stream() + .for_each(move |message| process_msg(&server, plugins.clone(), message)) + .map_err(|e| error!("Failed to process message: {}", e)); - // Run the main loop forever - reactor.run(future::empty::<(), ()>()).unwrap(); + reactor.handle().spawn(task); } } @@ -213,8 +197,7 @@ impl ThreadedPlugins { name, message.to_string().replace("\r\n", "")); - // Clone everything before the move - // The server uses an Arc internally too + // 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(); -- cgit v1.2.3-70-g09d2 From 6c3060994a3e04a59caeae7221650d0eec5e49fa Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 11 Dec 2017 03:35:05 +0100 Subject: Add Url Plugin --- Cargo.lock | 280 +++++++++++++++++++++++++++++++++++++++++------------ Cargo.toml | 1 + bin/main.rs | 1 + src/lib.rs | 2 + src/plugins/mod.rs | 2 + src/plugins/url.rs | 146 ++++++++++++++++++++++++++++ 6 files changed, 371 insertions(+), 61 deletions(-) create mode 100644 src/plugins/url.rs diff --git a/Cargo.lock b/Cargo.lock index aae3b22..16aaef5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,13 +45,26 @@ dependencies = [ [[package]] name = "base64" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bit-set" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-vec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "0.7.0" @@ -91,9 +104,9 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -111,23 +124,23 @@ name = "chrono" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy" -version = "0.0.174" +version = "0.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.174" +version = "0.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -138,8 +151,8 @@ dependencies = [ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -188,6 +201,14 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "debug_unreachable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -280,7 +301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "frippy" version = "0.3.1" dependencies = [ - "clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -289,8 +310,9 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", @@ -320,6 +342,15 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "futf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "futures" version = "0.1.17" @@ -344,6 +375,18 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "html5ever" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.2.3" @@ -351,10 +394,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -378,7 +421,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -422,9 +465,9 @@ dependencies = [ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -465,6 +508,11 @@ name = "lazy_static" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazycell" version = "0.5.1" @@ -490,6 +538,24 @@ name = "log" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "markup5ever" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "matches" version = "0.1.6" @@ -556,8 +622,8 @@ name = "native-tls" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -577,12 +643,12 @@ dependencies = [ [[package]] name = "num" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -590,7 +656,7 @@ name = "num-integer" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -599,12 +665,12 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -617,19 +683,19 @@ dependencies = [ [[package]] name = "openssl" -version = "0.9.22" +version = "0.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.22" +version = "0.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -683,6 +749,11 @@ name = "pkg-config" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pulldown-cmark" version = "0.0.15" @@ -724,7 +795,7 @@ dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -748,14 +819,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -769,6 +840,11 @@ name = "rustc-demangle" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "safemem" version = "0.2.0" @@ -776,13 +852,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "schannel" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -822,6 +898,15 @@ dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "select" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "semver" version = "0.6.0" @@ -837,22 +922,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -861,13 +946,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -877,7 +962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -901,6 +986,36 @@ name = "smallvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "string_cache" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string_cache_codegen" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string_cache_shared" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.11.11" @@ -932,12 +1047,22 @@ dependencies = [ "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tendril" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1036,7 +1161,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1078,6 +1203,14 @@ name = "unicode_names" version = "0.1.7" source = "git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode#d97b80c3c35b9f1d04085409087ef113c94cde17" +[[package]] +name = "unreachable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unreachable" version = "1.0.0" @@ -1096,6 +1229,14 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "utf-8" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1149,7 +1290,9 @@ dependencies = [ "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" +"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" +"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" @@ -1160,13 +1303,14 @@ dependencies = [ "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)" = "1b03ded6eba74b16dbeb598be58e874bc72f6cf12f7ccc577b328091e1d4392a" -"checksum clippy_lints 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)" = "9b8e508648d6d41040e0061f45fc5562b3af5c8a7d67853f15841fb531c8e984" +"checksum clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "2dae056aaec8acd5fc26722234cc9fa03b969a860d9aef0da6c5e5c996ce66ae" +"checksum clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "d04f24bc10870e19880865d8f206168993bfc6df9cc7335c0692cad98378a4b6" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d4a687c40efbc7d376958117b34d5f1cece11709110a742405bf58e7a34f00" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" @@ -1181,12 +1325,14 @@ dependencies = [ "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" +"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4959ca95f55df4265bff2ad63066147255e6fa733682cf6d1cb5eaff6e53324b" +"checksum hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e0594792d2109069d0caffd176f674d770a84adf024c5bb48e686b1ee5ac7659" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" @@ -1197,10 +1343,13 @@ dependencies = [ "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" "checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" +"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +"checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" @@ -1209,19 +1358,20 @@ dependencies = [ "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" -"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525" +"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" +"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "419ef26bb651d72b6c5a603bcc4e4856a362460e62352dfffa53de91d2e81181" -"checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7" +"checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" +"checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" @@ -1232,28 +1382,34 @@ dependencies = [ "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7554288337c1110e34d7a2433518d889374c1de1a45f856b7bcddb03702131fc" +"checksum schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4330c2e874379fbd28fa67ba43239dbe8c7fb00662ceb1078bd37474f08bf5ce" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" +"checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c37d7f192f00041e8a613e936717923a71bc0c9051fc4425a49b104140f05" -"checksum serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "0672de7300b02bac3f3689f8faea813c4a1ea9fe0cb49e80f714231d267518a2" -"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" -"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" +"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" +"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce" +"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603" +"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" +"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" +"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" +"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" -"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" @@ -1269,8 +1425,10 @@ dependencies = [ "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)" = "" +"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" +"checksum utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f923c601c7ac48ef1d66f7d5b5b2d9a7ba9c51333ab75a3ddf8d0309185a56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" diff --git a/Cargo.toml b/Cargo.toml index 2eae2bb..3218e65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ futures = "0.1.16" log = "0.3.8" time = "0.1" reqwest = "0.8.0" +select = "0.4.2" regex = "0.2.2" lazy_static = "0.2.9" serde = "1.0.15" diff --git a/bin/main.rs b/bin/main.rs index b220b0c..08787ff 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -83,6 +83,7 @@ fn main() { for config in configs { let mut bot = frippy::Bot::new(); bot.add_plugin(plugins::Help::new()); + bot.add_plugin(plugins::Url::new(1024)); bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::new()); diff --git a/src/lib.rs b/src/lib.rs index da1a278..badf578 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,8 @@ #[macro_use] extern crate log; #[macro_use] +extern crate lazy_static; +#[macro_use] extern crate frippy_derive; extern crate irc; diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 5bcb6ed..3eb7db4 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,9 +1,11 @@ mod help; +mod url; mod emoji; mod currency; mod keepnick; pub use self::help::Help; +pub use self::url::Url; pub use self::emoji::Emoji; pub use self::currency::Currency; pub use self::keepnick::KeepNick; diff --git a/src/plugins/url.rs b/src/plugins/url.rs new file mode 100644 index 0000000..ec146a0 --- /dev/null +++ b/src/plugins/url.rs @@ -0,0 +1,146 @@ +extern crate regex; +extern crate reqwest; +extern crate select; + +use irc::client::prelude::*; +use irc::error::Error as IrcError; + +use self::regex::Regex; + +use std::str; +use std::io::{self, Read}; +use self::reqwest::Client; +use self::reqwest::header::Connection; + +use self::select::document::Document; +use self::select::predicate::Name; + +use plugin::*; + +lazy_static! { + static ref RE: Regex = Regex::new(r"http(s)?://(\S+)").unwrap(); +} + +#[derive(PluginName, Debug)] +pub struct Url { + max_kib: usize, +} + +impl Url { + /// If a file is larger than `max_kib` KiB the download is stopped + pub fn new(max_kib: usize) -> Url { + Url {max_kib: max_kib} + } + + fn grep_url(&self, msg: &str) -> Option { + match RE.captures(msg) { + Some(captures) => { + debug!("Url captures: {:?}", captures); + + Some(captures.get(0).unwrap().as_str().to_string()) + } + None => None, + } + } + + fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { + let url = match self.grep_url(message) { + Some(url) => url, + None => { + return Ok(()); + } + }; + + let response = Client::new() + .get(&url) + .header(Connection::close()) + .send(); + + match response { + Ok(mut response) => { + let mut body = String::new(); + + // 500 kilobyte buffer + let mut buf = [0; 500 * 1000]; + let mut written = 0; + // Read until we reach EOF or max_kib KiB + loop { + let len = match response.read(&mut buf) { + Ok(0) => break, + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => { + debug!("Download from \"{}\" failed: {}", url, e); + return Ok(()) + } + }; + + let slice = match str::from_utf8(&buf[..len]) { + Ok(slice) => slice, + Err(e) => { + debug!("Failed to read bytes from \"{}\" as UTF8: {}", url, e); + return Ok(()); + } + }; + + body.push_str(slice); + written += len; + + // Check if the file is too large to download + if written > self.max_kib * 1024 { + debug!("Stopping download - File from \"{}\" is larger than {} KiB", url, self.max_kib); + return Ok(()); + } + } + + // let mut body = String::new(); + // if let Err(e) = response.read_to_string(&mut body) { + // error!("Failed to read string from \"{}\": {}", url, e); + // return Ok(()); + // } + // let doc = Document::from(body.as_ref()); + + let doc = Document::from(body.as_ref()); + if let Some(title) = doc.find(Name("title")).next() { + let text = title.children().next().unwrap(); + debug!("Title: {:?}", text); + + server.send_privmsg(target, text.as_text().unwrap()) + + } else { + Ok(()) + } + } + Err(e) => { + debug!("Bad response from \"{}\": ({})", url, e); + Ok(()) + } + } + } +} + +impl Plugin for Url { + fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + match message.command { + Command::PRIVMSG(_, ref msg) => RE.is_match(msg), + _ => false, + } + } + + fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + match message.command { + Command::PRIVMSG(_, ref content) => { + self.url(server, content, message.response_target().unwrap()) + } + _ => Ok(()), + } + } + + fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + server.send_notice(&command.source, + "This Plugin does not implement any commands.") + } +} + +#[cfg(test)] +mod tests {} -- cgit v1.2.3-70-g09d2 From df4d91e5a4b5cca1757d4cfac8849e7cd6b5524d Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 11 Dec 2017 03:41:27 +0100 Subject: Derive defaults where possible --- src/lib.rs | 3 ++- src/plugins/currency.rs | 2 +- src/plugins/emoji.rs | 2 +- src/plugins/help.rs | 2 +- src/plugins/keepnick.rs | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index badf578..4a511c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,6 +56,7 @@ pub use irc::error::Error as IrcError; use plugin::*; +#[derive(Default)] pub struct Bot { plugins: ThreadedPlugins, } @@ -171,7 +172,7 @@ fn process_msg(server: &IrcServer, Ok(()) } -#[derive(Clone, Debug)] +#[derive(Clone, Default, Debug)] struct ThreadedPlugins { plugins: HashMap>, } diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index d6cf928..634faa2 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -14,7 +14,7 @@ use self::serde_json::Value; use plugin::*; -#[derive(PluginName, Debug)] +#[derive(PluginName, Default, Debug)] pub struct Currency; struct ConvertionRequest<'a> { diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 1bb714c..59e2fdd 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -28,7 +28,7 @@ impl fmt::Display for EmojiHandle { } } -#[derive(PluginName, Debug)] +#[derive(PluginName, Default, Debug)] pub struct Emoji; impl Emoji { diff --git a/src/plugins/help.rs b/src/plugins/help.rs index 8f3fb4d..7b987d4 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -3,7 +3,7 @@ use irc::error::Error as IrcError; use plugin::*; -#[derive(PluginName, Debug)] +#[derive(PluginName, Default, Debug)] pub struct Help; impl Help { diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index afe12f8..0d12110 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -3,7 +3,7 @@ use irc::error::Error as IrcError; use plugin::*; -#[derive(PluginName, Debug)] +#[derive(PluginName, Default, Debug)] pub struct KeepNick; impl KeepNick { -- cgit v1.2.3-70-g09d2 From be3661ca2115ab704697b45628ed9984b924ad76 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 11 Dec 2017 03:51:57 +0100 Subject: Remove needless allocation & fix typo --- src/plugin.rs | 2 +- src/plugins/keepnick.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin.rs b/src/plugin.rs index fb01168..d2338f9 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -10,7 +10,7 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { fn is_allowed(&self, server: &IrcServer, message: &Message) -> bool; /// Handles messages which are not commands but still necessary. fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError>; - /// Handles any command directed at this plugina. + /// Handles any command directed at this plugin. fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError>; } diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 0d12110..1d4627d 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -44,7 +44,7 @@ impl Plugin for KeepNick { fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { match message.command { Command::QUIT(ref nick) => { - self.check_nick(server, &nick.clone().unwrap_or(String::from(""))) + self.check_nick(server, &nick.clone().unwrap_or_else(|| String::new())) } _ => Ok(()), } -- cgit v1.2.3-70-g09d2 From 57a6791edcfe0fb508a88ef2c7255ecd7c3142fb Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 12 Dec 2017 00:10:25 +0100 Subject: Only match urls which start with http --- src/plugins/url.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/url.rs b/src/plugins/url.rs index ec146a0..e954638 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -18,7 +18,7 @@ use self::select::predicate::Name; use plugin::*; lazy_static! { - static ref RE: Regex = Regex::new(r"http(s)?://(\S+)").unwrap(); + static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap(); } #[derive(PluginName, Debug)] @@ -37,7 +37,7 @@ impl Url { Some(captures) => { debug!("Url captures: {:?}", captures); - Some(captures.get(0).unwrap().as_str().to_string()) + Some(captures.get(2).unwrap().as_str().to_string()) } None => None, } -- cgit v1.2.3-70-g09d2 From 709a293da674c5682bada5bd2b8fad0967e8080c Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 12 Dec 2017 00:32:59 +0100 Subject: Remove unused code --- src/plugins/url.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/url.rs b/src/plugins/url.rs index e954638..f1f6828 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -93,13 +93,6 @@ impl Url { } } - // let mut body = String::new(); - // if let Err(e) = response.read_to_string(&mut body) { - // error!("Failed to read string from \"{}\": {}", url, e); - // return Ok(()); - // } - // let doc = Document::from(body.as_ref()); - let doc = Document::from(body.as_ref()); if let Some(title) = doc.find(Name("title")).next() { let text = title.children().next().unwrap(); -- cgit v1.2.3-70-g09d2 From d0a417cd9569d135a1dab0d49fe2f5dfbc65bad3 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 13 Dec 2017 18:37:53 +0100 Subject: Trim url titles and move downloading into a function --- src/plugins/url.rs | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/plugins/url.rs b/src/plugins/url.rs index f1f6828..f6e06f3 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -43,16 +43,9 @@ impl Url { } } - fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { - let url = match self.grep_url(message) { - Some(url) => url, - None => { - return Ok(()); - } - }; - + fn download(&self, url: &str) -> Option { let response = Client::new() - .get(&url) + .get(url) .header(Connection::close()) .send(); @@ -70,16 +63,16 @@ impl Url { Ok(len) => len, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, Err(e) => { - debug!("Download from \"{}\" failed: {}", url, e); - return Ok(()) + debug!("Download from {:?} failed: {}", url, e); + return None; } }; let slice = match str::from_utf8(&buf[..len]) { Ok(slice) => slice, Err(e) => { - debug!("Failed to read bytes from \"{}\" as UTF8: {}", url, e); - return Ok(()); + debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); + return None; } }; @@ -88,26 +81,46 @@ impl Url { // Check if the file is too large to download if written > self.max_kib * 1024 { - debug!("Stopping download - File from \"{}\" is larger than {} KiB", url, self.max_kib); - return Ok(()); + debug!("Stopping download - File from {:?} is larger than {} KiB", url, self.max_kib); + return None; } + } + Some(body) // once told me + } + Err(e) => { + debug!("Bad response from {:?}: ({})", url, e); + return None; + } + } + } + + fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { + let url = match self.grep_url(message) { + Some(url) => url, + None => { + return Ok(()); + } + }; + + + match self.download(&url) { + Some(body) => { let doc = Document::from(body.as_ref()); if let Some(title) = doc.find(Name("title")).next() { let text = title.children().next().unwrap(); + let message = text.as_text().unwrap().trim().replace("\n", "|"); debug!("Title: {:?}", text); + debug!("Message: {:?}", message); - server.send_privmsg(target, text.as_text().unwrap()) + server.send_privmsg(target, &message) } else { Ok(()) } } - Err(e) => { - debug!("Bad response from \"{}\": ({})", url, e); - Ok(()) - } + None => Ok(()), } } } -- cgit v1.2.3-70-g09d2 From b4c1722bbee9fa822a6063cbb0540c0a7fb2e430 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 15 Dec 2017 19:27:43 +0100 Subject: Add option for disabled plugins in the toml files --- bin/main.rs | 16 ++++++++++++++++ configs/config.toml | 3 +++ src/lib.rs | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/bin/main.rs b/bin/main.rs index 08787ff..420e016 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -81,6 +81,14 @@ fn main() { // Open a connection and add work for each config for config in configs { + + let mut disabled_plugins = None; + if let &Some(ref options) = &config.options { + if let Some(disabled) = options.get("disabled_plugins") { + disabled_plugins = Some(disabled.split(",").map(|p| p.trim()).collect::>()); + } + } + let mut bot = frippy::Bot::new(); bot.add_plugin(plugins::Help::new()); bot.add_plugin(plugins::Url::new(1024)); @@ -88,6 +96,14 @@ fn main() { bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::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); + } + } + } + bot.connect(&mut reactor, &config); } diff --git a/configs/config.toml b/configs/config.toml index 5ad66e2..02f86fd 100644 --- a/configs/config.toml +++ b/configs/config.toml @@ -23,3 +23,6 @@ source = "https://github.com/Mavulp/frippy" #[channel_keys] #"#frippy" = "" + +#[options] +#disabled_plugins = "Url" diff --git a/src/lib.rs b/src/lib.rs index 4a511c3..d34a728 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,6 +90,22 @@ impl Bot { self.plugins.add(plugin); } + /// Removes a plugin based on its name. + /// The binary currently uses this to disable plugins + /// based on user configuration. + /// + /// # Examples + /// ``` + /// use frippy::{plugins, Bot}; + /// + /// let mut bot = frippy::Bot::new(); + /// bot.add_plugin(plugins::Help::new()); + /// bot.remove_plugin("Help"); + /// ``` + pub fn remove_plugin(&mut self, name: &str) -> Option<()> { + self.plugins.remove(name) + } + /// This connects the `Bot` to IRC and adds a task /// to the Core that was supplied. /// @@ -189,6 +205,10 @@ impl ThreadedPlugins { self.plugins.insert(name, safe_plugin); } + pub fn remove(&mut self, name: &str) -> Option<()> { + self.plugins.remove(&name.to_lowercase()).map(|_| ()) + } + pub fn execute_plugins(&mut self, server: &IrcServer, message: Message) { let message = Arc::new(message); -- cgit v1.2.3-70-g09d2 From 92ea5a1c2e0b7ddaa102d6b602d180e84964c3be Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 15 Dec 2017 19:29:40 +0100 Subject: Adjust documentation --- src/lib.rs | 4 +++- src/plugin.rs | 4 +++- src/plugins/mod.rs | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d34a728..5d15802 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,6 +56,7 @@ pub use irc::error::Error as IrcError; use plugin::*; +/// The bot which contains the main logic. #[derive(Default)] pub struct Bot { plugins: ThreadedPlugins, @@ -77,7 +78,8 @@ impl Bot { Bot { plugins: ThreadedPlugins::new() } } - /// Add plugins which should evaluate incoming messages from IRC. + /// Adds the plugin. + /// These plugins will be used to evaluate incoming messages from IRC. /// /// # Examples /// ``` diff --git a/src/plugin.rs b/src/plugin.rs index d2338f9..d14c129 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -1,3 +1,4 @@ +//! Definitions required for every `Plugin` use std::fmt; use irc::client::prelude::*; @@ -14,7 +15,8 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError>; } -/// `PluginName` is required by `Plugin`. +/// `PluginName` is required by `Plugin`. +/// /// To implement it simply add `#[derive(PluginName)]` /// above the definition of the struct. /// diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 3eb7db4..e8c4622 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,3 +1,4 @@ +//! Collection of plugins included mod help; mod url; mod emoji; -- cgit v1.2.3-70-g09d2 From 7905adee9fc5a9664560de9500c18bb2ec5ca060 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 13 Oct 2017 17:15:50 +0200 Subject: First prototype for the Factoids plugin --- bin/main.rs | 1 + src/plugins/factoids.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ src/plugins/mod.rs | 2 + 3 files changed, 111 insertions(+) create mode 100644 src/plugins/factoids.rs diff --git a/bin/main.rs b/bin/main.rs index 420e016..e8cf790 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -95,6 +95,7 @@ fn main() { bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::new()); + bot.add_plugin(plugins::Factoids::new()); if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { diff --git a/src/plugins/factoids.rs b/src/plugins/factoids.rs new file mode 100644 index 0000000..f13cada --- /dev/null +++ b/src/plugins/factoids.rs @@ -0,0 +1,108 @@ + +use irc::client::prelude::*; +use irc::error::Error as IrcError; +use std::collections::HashMap; +use std::sync::Mutex; + +use plugin::*; + +#[derive(PluginName, Debug)] +pub struct Factoids { + factoids: Mutex>, +} + +macro_rules! try_lock { + ( $m:expr ) => { + match $m.lock() { + Ok(guard) => guard, + Err(poisoned) => poisoned.into_inner(), + } + } +} + +impl Factoids { + pub fn new() -> Factoids { + Factoids { factoids: Mutex::new(HashMap::new()) } + } + + fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { + + if command.tokens.len() < 2 { + return self.invalid_command(server, command); + } + + let name = command.tokens.remove(0); + + try_lock!(self.factoids) + .insert(name, command.tokens.join(" ")); + + server.send_notice(&command.source, "Successfully added") + } + + fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + if command.tokens.len() < 1 { + self.invalid_command(server, command) + + } else { + let factoids = try_lock!(self.factoids); + let factoid = match factoids.get(&command.tokens[0]) { + Some(v) => v, + None => return self.invalid_command(server, command), + }; + + server.send_privmsg(&command.target, factoid) + } + } + + fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + server.send_notice(&command.source, "Invalid Command") + } +} + +impl Plugin for Factoids { + fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + match message.command { + Command::PRIVMSG(_, ref content) => content.starts_with('!'), + _ => false, + } + } + + fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + if let Command::PRIVMSG(_, mut content) = message.command.clone() { + content.remove(0); + + let t: Vec = content + .split(' ') + .map(ToOwned::to_owned) + .collect(); + + let c = PluginCommand { + source: message.source_nickname().unwrap().to_string(), + target: message.response_target().unwrap().to_string(), + tokens: t, + }; + + self.get(server, &c) + + } else { + Ok(()) + } + } + + fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { + if command.tokens.is_empty() { + self.invalid_command(server, &command) + + } else if command.tokens[0].to_lowercase() == "add" { + command.tokens.remove(0); + self.add(server, &mut command) + + } else if command.tokens[0].to_lowercase() == "get" { + command.tokens.remove(0); + self.get(server, &command) + + } else { + self.invalid_command(server, &command) + } + } +} diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index e8c4622..f860d88 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -3,10 +3,12 @@ mod help; mod url; mod emoji; mod currency; +mod factoids; mod keepnick; pub use self::help::Help; pub use self::url::Url; pub use self::emoji::Emoji; pub use self::currency::Currency; +pub use self::factoids::Factoids; pub use self::keepnick::KeepNick; -- cgit v1.2.3-70-g09d2 From 11593a68b0ea23ed55f867e70df6a2bb947951fd Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 14 Oct 2017 04:26:00 +0200 Subject: Run factoids in Lua --- Cargo.lock | 62 ++++++++++++++++++++++++++--------------- Cargo.toml | 1 + src/plugins/factoids.rs | 73 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16aaef5..3466ce6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,22 +130,22 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.175" +version = "0.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.175" +version = "0.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -301,20 +301,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "frippy" version = "0.3.1" dependencies = [ - "clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", + "irc 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", ] @@ -365,6 +366,11 @@ dependencies = [ "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "getopts" version = "0.2.15" @@ -408,7 +414,7 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -423,7 +429,7 @@ dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -455,7 +461,7 @@ dependencies = [ [[package]] name = "irc" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -464,11 +470,12 @@ dependencies = [ "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -814,7 +821,7 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -828,13 +835,22 @@ dependencies = [ "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rlua" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.5" @@ -1079,7 +1095,7 @@ dependencies = [ [[package]] name = "tokio-core" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1123,7 +1139,7 @@ dependencies = [ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1152,7 +1168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1303,8 +1319,8 @@ dependencies = [ "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "2dae056aaec8acd5fc26722234cc9fa03b969a860d9aef0da6c5e5c996ce66ae" -"checksum clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "d04f24bc10870e19880865d8f206168993bfc6df9cc7335c0692cad98378a4b6" +"checksum clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)" = "131acb21874af5ec9a2ed5b3945edd9961b260735ba0d6879357a924a77be66b" +"checksum clippy_lints 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)" = "e5ad86d7ff55bf5461ed84388c445ecba69badb2805a5e4750bd57ee12a0f8a2" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d4a687c40efbc7d376958117b34d5f1cece11709110a742405bf58e7a34f00" @@ -1328,6 +1344,7 @@ dependencies = [ "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" @@ -1337,7 +1354,7 @@ dependencies = [ "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" -"checksum irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)" = "484fea2147dd042cdb3dd9e707af9cc9d8f46a4adc04e553ff985203a955ed6e" +"checksum irc 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c5053c25509042e963baa67d0d648add9f72b7487784505a5d5a3054d136a615" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -1380,7 +1397,8 @@ dependencies = [ "checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" -"checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" +"checksum reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3161ca63fd11ce36c7718af239e6492a25a3dbfcec54240f959b9d816cf42413" +"checksum rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7eec2f28b4812553f10b2e69888a5a674b2e761f5a39731c14541c32bdb6d8" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" @@ -1411,7 +1429,7 @@ dependencies = [ "checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" +"checksum tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c87c27560184212c9dc45cd8f38623f37918248aad5b58fb65303b5d07a98c6e" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41bfc436ef8b7f60c19adf3df086330ae9992385e4d8c53b17a323cad288e155" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" diff --git a/Cargo.toml b/Cargo.toml index 3218e65..87c9052 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ tokio-core = "0.1.10" futures = "0.1.16" log = "0.3.8" time = "0.1" +rlua = "0.9.2" reqwest = "0.8.0" select = "0.4.2" regex = "0.2.2" diff --git a/src/plugins/factoids.rs b/src/plugins/factoids.rs index f13cada..b3a4446 100644 --- a/src/plugins/factoids.rs +++ b/src/plugins/factoids.rs @@ -1,6 +1,9 @@ +extern crate rlua; use irc::client::prelude::*; use irc::error::Error as IrcError; +use self::rlua::Lua; + use std::collections::HashMap; use std::sync::Mutex; @@ -40,20 +43,50 @@ impl Factoids { } fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + if command.tokens.len() < 1 { self.invalid_command(server, command) } else { + let name = &command.tokens[0]; let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(&command.tokens[0]) { + let factoid = match factoids.get(name) { Some(v) => v, None => return self.invalid_command(server, command), }; - server.send_privmsg(&command.target, factoid) + server.send_privmsg(&command.target, &format!("{}: {}", name, factoid)) } } + fn exec(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + + if command.tokens.len() < 1 { + self.invalid_command(server, command) + + } else { + let name = &command.tokens[0]; + + let factoids = try_lock!(self.factoids); + let factoid = match factoids.get(name) { + Some(v) => v, + None => return self.invalid_command(server, command), + }; + + let value = match self.run_lua(name, factoid) { + Ok(v) => v, + Err(e) => format!("{}", e), + }; + + server.send_privmsg(&command.target, &value) + } + } + + fn run_lua(&self, name: &str, code: &str) -> Result { + let lua = Lua::new(); + lua.eval::(code, Some(name)) + } + fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { server.send_notice(&command.source, "Invalid Command") } @@ -61,28 +94,25 @@ impl Factoids { impl Plugin for Factoids { fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { - match message.command { - Command::PRIVMSG(_, ref content) => content.starts_with('!'), - _ => false, - } + match message.command { + Command::PRIVMSG(_, ref content) => content.starts_with('!'), + _ => false, + } } fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { if let Command::PRIVMSG(_, mut content) = message.command.clone() { content.remove(0); - let t: Vec = content - .split(' ') - .map(ToOwned::to_owned) - .collect(); + let t: Vec = content.split(' ').map(ToOwned::to_owned).collect(); - let c = PluginCommand { + let mut c = PluginCommand { source: message.source_nickname().unwrap().to_string(), target: message.response_target().unwrap().to_string(), tokens: t, }; - self.get(server, &c) + self.exec(server, &mut c) } else { Ok(()) @@ -91,18 +121,15 @@ impl Plugin for Factoids { fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { if command.tokens.is_empty() { - self.invalid_command(server, &command) - - } else if command.tokens[0].to_lowercase() == "add" { - command.tokens.remove(0); - self.add(server, &mut command) - - } else if command.tokens[0].to_lowercase() == "get" { - command.tokens.remove(0); - self.get(server, &command) + return self.invalid_command(server, &command); + } - } else { - self.invalid_command(server, &command) + let sub_command = command.tokens.remove(0); + match sub_command.as_ref() { + "add" => self.add(server, &mut command), + "get" => self.get(server, &mut command), + "exec" => self.exec(server, &mut command), + _ => self.invalid_command(server, &command), } } } -- cgit v1.2.3-70-g09d2 From 5f1b2465080b7343869256c09ceda8025b30f3fa Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 15 Oct 2017 05:08:43 +0200 Subject: Prepare environment for the Sandbox --- src/plugins/factoids.rs | 52 ++++++++++++++++++++++++++++++++++++------------- src/plugins/sandbox.lua | 1 + 2 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 src/plugins/sandbox.lua diff --git a/src/plugins/factoids.rs b/src/plugins/factoids.rs index b3a4446..a6cb5c3 100644 --- a/src/plugins/factoids.rs +++ b/src/plugins/factoids.rs @@ -1,8 +1,8 @@ extern crate rlua; +use self::rlua::prelude::*; use irc::client::prelude::*; use irc::error::Error as IrcError; -use self::rlua::Lua; use std::collections::HashMap; use std::sync::Mutex; @@ -23,6 +23,8 @@ macro_rules! try_lock { } } +static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); + impl Factoids { pub fn new() -> Factoids { Factoids { factoids: Mutex::new(HashMap::new()) } @@ -59,21 +61,21 @@ impl Factoids { } } - fn exec(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { if command.tokens.len() < 1 { - self.invalid_command(server, command) + self.invalid_command(server, &command) } else { - let name = &command.tokens[0]; + let name = command.tokens.remove(0); let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(name) { + let factoid = match factoids.get(&name) { Some(v) => v, - None => return self.invalid_command(server, command), + None => return self.invalid_command(server, &command), }; - let value = match self.run_lua(name, factoid) { + let value = match self.run_lua(&name, factoid, &command) { Ok(v) => v, Err(e) => format!("{}", e), }; @@ -82,9 +84,33 @@ impl Factoids { } } - fn run_lua(&self, name: &str, code: &str) -> Result { + fn run_lua(&self, + name: &str, + code: &str, + command: &PluginCommand) + -> Result { + + let args = command + .tokens + .iter() + .filter(|x| !x.is_empty()) + .map(ToOwned::to_owned) + .collect::>(); + let lua = Lua::new(); - lua.eval::(code, Some(name)) + let globals = lua.globals(); + + globals.set("factoid", lua.load(code, Some(name))?)?; + globals.set("args", args)?; + globals.set("input", command.tokens.join(" "))?; + globals.set("user", command.source.clone())?; + globals.set("channel", command.target.clone())?; + globals.set("output", lua.create_table())?; + + lua.exec::<()>(LUA_SANDBOX, Some(name))?; + let output: Vec = globals.get::<_, Vec>("output")?; + + Ok(output.join("|")) } fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { @@ -106,13 +132,13 @@ impl Plugin for Factoids { let t: Vec = content.split(' ').map(ToOwned::to_owned).collect(); - let mut c = PluginCommand { + let c = PluginCommand { source: message.source_nickname().unwrap().to_string(), target: message.response_target().unwrap().to_string(), tokens: t, }; - self.exec(server, &mut c) + self.exec(server, c) } else { Ok(()) @@ -127,8 +153,8 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); match sub_command.as_ref() { "add" => self.add(server, &mut command), - "get" => self.get(server, &mut command), - "exec" => self.exec(server, &mut command), + "get" => self.get(server, &command), + "exec" => self.exec(server, command), _ => self.invalid_command(server, &command), } } diff --git a/src/plugins/sandbox.lua b/src/plugins/sandbox.lua new file mode 100644 index 0000000..9b4f52e --- /dev/null +++ b/src/plugins/sandbox.lua @@ -0,0 +1 @@ +factoid() -- cgit v1.2.3-70-g09d2 From e8b4f54ef9910f733f5d4785a906fc6ca185167b Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 20 Oct 2017 01:07:48 +0200 Subject: Move the Factoids plugin into a subfolder --- src/plugins/factoids.rs | 161 --------------------------------------- src/plugins/factoids/mod.rs | 161 +++++++++++++++++++++++++++++++++++++++ src/plugins/factoids/sandbox.lua | 1 + src/plugins/sandbox.lua | 1 - 4 files changed, 162 insertions(+), 162 deletions(-) delete mode 100644 src/plugins/factoids.rs create mode 100644 src/plugins/factoids/mod.rs create mode 100644 src/plugins/factoids/sandbox.lua delete mode 100644 src/plugins/sandbox.lua diff --git a/src/plugins/factoids.rs b/src/plugins/factoids.rs deleted file mode 100644 index a6cb5c3..0000000 --- a/src/plugins/factoids.rs +++ /dev/null @@ -1,161 +0,0 @@ -extern crate rlua; - -use self::rlua::prelude::*; -use irc::client::prelude::*; -use irc::error::Error as IrcError; - -use std::collections::HashMap; -use std::sync::Mutex; - -use plugin::*; - -#[derive(PluginName, Debug)] -pub struct Factoids { - factoids: Mutex>, -} - -macro_rules! try_lock { - ( $m:expr ) => { - match $m.lock() { - Ok(guard) => guard, - Err(poisoned) => poisoned.into_inner(), - } - } -} - -static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); - -impl Factoids { - pub fn new() -> Factoids { - Factoids { factoids: Mutex::new(HashMap::new()) } - } - - fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { - - if command.tokens.len() < 2 { - return self.invalid_command(server, command); - } - - let name = command.tokens.remove(0); - - try_lock!(self.factoids) - .insert(name, command.tokens.join(" ")); - - server.send_notice(&command.source, "Successfully added") - } - - fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { - - if command.tokens.len() < 1 { - self.invalid_command(server, command) - - } else { - let name = &command.tokens[0]; - let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(name) { - Some(v) => v, - None => return self.invalid_command(server, command), - }; - - server.send_privmsg(&command.target, &format!("{}: {}", name, factoid)) - } - } - - fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { - - if command.tokens.len() < 1 { - self.invalid_command(server, &command) - - } else { - let name = command.tokens.remove(0); - - let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(&name) { - Some(v) => v, - None => return self.invalid_command(server, &command), - }; - - let value = match self.run_lua(&name, factoid, &command) { - Ok(v) => v, - Err(e) => format!("{}", e), - }; - - server.send_privmsg(&command.target, &value) - } - } - - fn run_lua(&self, - name: &str, - code: &str, - command: &PluginCommand) - -> Result { - - let args = command - .tokens - .iter() - .filter(|x| !x.is_empty()) - .map(ToOwned::to_owned) - .collect::>(); - - let lua = Lua::new(); - let globals = lua.globals(); - - globals.set("factoid", lua.load(code, Some(name))?)?; - globals.set("args", args)?; - globals.set("input", command.tokens.join(" "))?; - globals.set("user", command.source.clone())?; - globals.set("channel", command.target.clone())?; - globals.set("output", lua.create_table())?; - - lua.exec::<()>(LUA_SANDBOX, Some(name))?; - let output: Vec = globals.get::<_, Vec>("output")?; - - Ok(output.join("|")) - } - - fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, "Invalid Command") - } -} - -impl Plugin for Factoids { - fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { - match message.command { - Command::PRIVMSG(_, ref content) => content.starts_with('!'), - _ => false, - } - } - - fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { - if let Command::PRIVMSG(_, mut content) = message.command.clone() { - content.remove(0); - - let t: Vec = content.split(' ').map(ToOwned::to_owned).collect(); - - let c = PluginCommand { - source: message.source_nickname().unwrap().to_string(), - target: message.response_target().unwrap().to_string(), - tokens: t, - }; - - self.exec(server, c) - - } else { - Ok(()) - } - } - - fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { - if command.tokens.is_empty() { - return self.invalid_command(server, &command); - } - - let sub_command = command.tokens.remove(0); - match sub_command.as_ref() { - "add" => self.add(server, &mut command), - "get" => self.get(server, &command), - "exec" => self.exec(server, command), - _ => self.invalid_command(server, &command), - } - } -} diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs new file mode 100644 index 0000000..a6cb5c3 --- /dev/null +++ b/src/plugins/factoids/mod.rs @@ -0,0 +1,161 @@ +extern crate rlua; + +use self::rlua::prelude::*; +use irc::client::prelude::*; +use irc::error::Error as IrcError; + +use std::collections::HashMap; +use std::sync::Mutex; + +use plugin::*; + +#[derive(PluginName, Debug)] +pub struct Factoids { + factoids: Mutex>, +} + +macro_rules! try_lock { + ( $m:expr ) => { + match $m.lock() { + Ok(guard) => guard, + Err(poisoned) => poisoned.into_inner(), + } + } +} + +static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); + +impl Factoids { + pub fn new() -> Factoids { + Factoids { factoids: Mutex::new(HashMap::new()) } + } + + fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { + + if command.tokens.len() < 2 { + return self.invalid_command(server, command); + } + + let name = command.tokens.remove(0); + + try_lock!(self.factoids) + .insert(name, command.tokens.join(" ")); + + server.send_notice(&command.source, "Successfully added") + } + + fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + + if command.tokens.len() < 1 { + self.invalid_command(server, command) + + } else { + let name = &command.tokens[0]; + let factoids = try_lock!(self.factoids); + let factoid = match factoids.get(name) { + Some(v) => v, + None => return self.invalid_command(server, command), + }; + + server.send_privmsg(&command.target, &format!("{}: {}", name, factoid)) + } + } + + fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { + + if command.tokens.len() < 1 { + self.invalid_command(server, &command) + + } else { + let name = command.tokens.remove(0); + + let factoids = try_lock!(self.factoids); + let factoid = match factoids.get(&name) { + Some(v) => v, + None => return self.invalid_command(server, &command), + }; + + let value = match self.run_lua(&name, factoid, &command) { + Ok(v) => v, + Err(e) => format!("{}", e), + }; + + server.send_privmsg(&command.target, &value) + } + } + + fn run_lua(&self, + name: &str, + code: &str, + command: &PluginCommand) + -> Result { + + let args = command + .tokens + .iter() + .filter(|x| !x.is_empty()) + .map(ToOwned::to_owned) + .collect::>(); + + let lua = Lua::new(); + let globals = lua.globals(); + + globals.set("factoid", lua.load(code, Some(name))?)?; + globals.set("args", args)?; + globals.set("input", command.tokens.join(" "))?; + globals.set("user", command.source.clone())?; + globals.set("channel", command.target.clone())?; + globals.set("output", lua.create_table())?; + + lua.exec::<()>(LUA_SANDBOX, Some(name))?; + let output: Vec = globals.get::<_, Vec>("output")?; + + Ok(output.join("|")) + } + + fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + server.send_notice(&command.source, "Invalid Command") + } +} + +impl Plugin for Factoids { + fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + match message.command { + Command::PRIVMSG(_, ref content) => content.starts_with('!'), + _ => false, + } + } + + fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + if let Command::PRIVMSG(_, mut content) = message.command.clone() { + content.remove(0); + + let t: Vec = content.split(' ').map(ToOwned::to_owned).collect(); + + let c = PluginCommand { + source: message.source_nickname().unwrap().to_string(), + target: message.response_target().unwrap().to_string(), + tokens: t, + }; + + self.exec(server, c) + + } else { + Ok(()) + } + } + + fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { + if command.tokens.is_empty() { + return self.invalid_command(server, &command); + } + + let sub_command = command.tokens.remove(0); + match sub_command.as_ref() { + "add" => self.add(server, &mut command), + "get" => self.get(server, &command), + "exec" => self.exec(server, command), + _ => self.invalid_command(server, &command), + } + } +} diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua new file mode 100644 index 0000000..9b4f52e --- /dev/null +++ b/src/plugins/factoids/sandbox.lua @@ -0,0 +1 @@ +factoid() diff --git a/src/plugins/sandbox.lua b/src/plugins/sandbox.lua deleted file mode 100644 index 9b4f52e..0000000 --- a/src/plugins/sandbox.lua +++ /dev/null @@ -1 +0,0 @@ -factoid() -- cgit v1.2.3-70-g09d2 From fee0ea52e7300042f4baaf2419be344dbc643fb8 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 20 Oct 2017 05:24:11 +0200 Subject: Do not allow factoids to send newlines --- src/plugins/factoids/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index a6cb5c3..68b02e3 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -110,7 +110,7 @@ impl Factoids { lua.exec::<()>(LUA_SANDBOX, Some(name))?; let output: Vec = globals.get::<_, Vec>("output")?; - Ok(output.join("|")) + Ok(output.join("|").replace("\n", "|")) } fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { -- cgit v1.2.3-70-g09d2 From aa2e6dc0103c303aac0dd688d90c8547b22f8a47 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 29 Oct 2017 17:00:58 +0100 Subject: Add non Lua factoids Only factoids prefixed with '>' are run as Lua now. To escape the '>' just add another one. --- src/plugins/factoids/mod.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 68b02e3..c69042f 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -9,6 +9,8 @@ use std::sync::Mutex; use plugin::*; +static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); + #[derive(PluginName, Debug)] pub struct Factoids { factoids: Mutex>, @@ -23,8 +25,6 @@ macro_rules! try_lock { } } -static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); - impl Factoids { pub fn new() -> Factoids { Factoids { factoids: Mutex::new(HashMap::new()) } @@ -75,9 +75,19 @@ impl Factoids { None => return self.invalid_command(server, &command), }; - let value = match self.run_lua(&name, factoid, &command) { - Ok(v) => v, - Err(e) => format!("{}", e), + let value = if factoid.starts_with(">") { + let factoid = String::from(&factoid[1..]); + + if factoid.starts_with(">") { + factoid + } else { + match self.run_lua(&name, &factoid, &command) { + Ok(v) => v, + Err(e) => format!("{}", e), + } + } + } else { + String::from(factoid) }; server.send_privmsg(&command.target, &value) -- cgit v1.2.3-70-g09d2 From f3d679da59a64711ef96042668b26dffd1e662d5 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 29 Oct 2017 17:09:04 +0100 Subject: Add Database trait to be used by the Factoids plugin --- bin/main.rs | 4 +++- frippy_derive/src/lib.rs | 4 +++- src/plugins/factoids/database.rs | 18 ++++++++++++++++++ src/plugins/factoids/mod.rs | 15 ++++++++------- 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/plugins/factoids/database.rs diff --git a/bin/main.rs b/bin/main.rs index e8cf790..1597a70 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -7,6 +7,8 @@ extern crate futures; #[macro_use] extern crate log; +use std::collections::HashMap; + use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; use tokio_core::reactor::Core; @@ -95,7 +97,7 @@ fn main() { bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::new()); - bot.add_plugin(plugins::Factoids::new()); + bot.add_plugin(plugins::Factoids::new(HashMap::new())); if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { diff --git a/frippy_derive/src/lib.rs b/frippy_derive/src/lib.rs index 704d6ef..2622f0b 100644 --- a/frippy_derive/src/lib.rs +++ b/frippy_derive/src/lib.rs @@ -17,8 +17,10 @@ pub fn derive_plugin(data: TokenStream) -> TokenStream { fn expand_plugin(ast: &syn::DeriveInput) -> quote::Tokens { let name = &ast.ident; + let generics = &ast.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); quote! { - impl PluginName for #name { + impl #impl_generics PluginName for #name #ty_generics #where_clause { fn name(&self) -> &str { stringify!(#name) } diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs new file mode 100644 index 0000000..7a6f568 --- /dev/null +++ b/src/plugins/factoids/database.rs @@ -0,0 +1,18 @@ +use std::fmt; + +use std::collections::HashMap; + +pub trait Database: Send + Sync + fmt::Debug { + fn insert(&mut self, name: String, content: String) -> Option; + fn get(&self, name: &str) -> Option<&str>; +} + +impl Database for HashMap { + fn insert(&mut self, name: String, content: String) -> Option { + self.insert(name, content) + } + + fn get(&self, name: &str) -> Option<&str> { + self.get(name).map(String::as_str) + } +} diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index c69042f..a13bba6 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -4,16 +4,17 @@ use self::rlua::prelude::*; use irc::client::prelude::*; use irc::error::Error as IrcError; -use std::collections::HashMap; use std::sync::Mutex; use plugin::*; +mod database; +use self::database::*; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); #[derive(PluginName, Debug)] -pub struct Factoids { - factoids: Mutex>, +pub struct Factoids { + factoids: Mutex, } macro_rules! try_lock { @@ -25,9 +26,9 @@ macro_rules! try_lock { } } -impl Factoids { - pub fn new() -> Factoids { - Factoids { factoids: Mutex::new(HashMap::new()) } +impl Factoids { + pub fn new(db: T) -> Factoids { + Factoids { factoids: Mutex::new(db) } } fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { @@ -128,7 +129,7 @@ impl Factoids { } } -impl Plugin for Factoids { +impl Plugin for Factoids { fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { match message.command { Command::PRIVMSG(_, ref content) => content.starts_with('!'), -- cgit v1.2.3-70-g09d2 From 5928afc3bf83661cd3b11130a31a2d97ef135a9e Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 4 Nov 2017 22:46:39 +0100 Subject: Add MySql as a possible database for the Factoids plugin --- Cargo.lock | 67 ++++++++++++++++++++ Cargo.toml | 26 +++++++- migrations/.gitkeep | 0 .../2017-11-03-164322_create_factoids/down.sql | 1 + .../2017-11-03-164322_create_factoids/up.sql | 4 ++ src/lib.rs | 7 +++ src/plugins/factoids/database.rs | 72 +++++++++++++++++++--- src/plugins/factoids/mod.rs | 16 +++-- 8 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 migrations/.gitkeep create mode 100644 migrations/2017-11-03-164322_create_factoids/down.sql create mode 100644 migrations/2017-11-03-164322_create_factoids/up.sql diff --git a/Cargo.lock b/Cargo.lock index 3466ce6..91693d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,6 +209,55 @@ dependencies = [ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "derive-error-chain" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_codegen" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_infer_schema" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dotenv" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -302,6 +351,9 @@ name = "frippy" version = "0.3.1" dependencies = [ "clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -624,6 +676,15 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mysqlclient-sys" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "native-tls" version = "0.1.4" @@ -1327,6 +1388,11 @@ dependencies = [ "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" +"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" +"checksum diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "304226fa7a3982b0405f6bb95dd9c10c3e2000709f194038a60ec2c277150951" +"checksum diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a42ca5c9b660add51d58bc5a50a87123380e1e458069c5504528a851ed7384" +"checksum diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1957ff5cd3b04772e43c162c2f69c2aa918080ff9b020276792d236be8be52" +"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" @@ -1373,6 +1439,7 @@ dependencies = [ "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" "checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "879ce08e38739c54d87b7f8332a476004fe2a095f40a142a36f889779d9942b7" "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" diff --git a/Cargo.toml b/Cargo.toml index 87c9052..5ff779f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,9 @@ name = "frippy" path = "bin/main.rs" doc = false +[features] +mysql = ["diesel", "diesel_codegen", "dotenv"] + [dependencies] irc = "0.12.5" tokio-core = "0.1.10" @@ -34,6 +37,25 @@ serde_json = "1.0.3" glob = "0.2" frippy_derive = { path = "frippy_derive" } -unicode_names = { git = 'https://github.com/Jokler/unicode_names', branch = 'update-to-latest-unicode' } -clippy = {version = "*", optional = true} +[dependencies.unicode_names] +git = 'https://github.com/Jokler/unicode_names' +branch = 'update-to-latest-unicode' + +[dependencies.diesel] +version = "0.16.0" +optional = true +features = ["mysql"] + +[dependencies.diesel_codegen] +version = "0.16.0" +optional = true +features = ["mysql"] + +[dependencies.dotenv] +version = "0.10.1" +optional = true + +[dependencies.clippy] +version = "*" +optional = true \ No newline at end of file diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/2017-11-03-164322_create_factoids/down.sql b/migrations/2017-11-03-164322_create_factoids/down.sql new file mode 100644 index 0000000..58c2110 --- /dev/null +++ b/migrations/2017-11-03-164322_create_factoids/down.sql @@ -0,0 +1 @@ +DROP TABLE factoids diff --git a/migrations/2017-11-03-164322_create_factoids/up.sql b/migrations/2017-11-03-164322_create_factoids/up.sql new file mode 100644 index 0000000..84e9f9d --- /dev/null +++ b/migrations/2017-11-03-164322_create_factoids/up.sql @@ -0,0 +1,4 @@ +CREATE TABLE factoids ( + name VARCHAR(32) PRIMARY KEY, + content VARCHAR(5000) NOT NULL +) diff --git a/src/lib.rs b/src/lib.rs index 5d15802..1f5514e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,13 @@ //! Frippy uses the [log](https://docs.rs/log) crate so you can log events //! which might be of interest. +#[cfg(feature = "mysql")] +#[macro_use] +extern crate diesel; +#[cfg(feature = "mysql")] +#[macro_use] +extern crate diesel_codegen; + #[macro_use] extern crate log; #[macro_use] diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 7a6f568..dbf136c 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -1,18 +1,74 @@ -use std::fmt; +#[cfg(feature = "mysql")] +extern crate dotenv; use std::collections::HashMap; -pub trait Database: Send + Sync + fmt::Debug { - fn insert(&mut self, name: String, content: String) -> Option; - fn get(&self, name: &str) -> Option<&str>; +#[cfg(feature = "mysql")] +use diesel::prelude::*; + +#[cfg(feature = "mysql")] +use diesel::mysql::MysqlConnection; + +pub trait Database: Send { + fn insert(&mut self, name: &str, content: &str) -> Option<()>; + fn get(&self, name: &str) -> Option; } impl Database for HashMap { - fn insert(&mut self, name: String, content: String) -> Option { - self.insert(name, content) + fn insert(&mut self, name: &str, content: &str) -> Option<()> { + self.insert(String::from(name), String::from(content)).map(|_| ()) + } + + fn get(&self, name: &str) -> Option { + self.get(name).cloned() + } +} + +#[cfg(feature = "mysql")] +#[derive(Queryable)] +struct Factoid { + pub name: String, + pub content: String, +} + +#[cfg(feature = "mysql")] +table! { + factoids (name) { + name -> Varchar, + content -> Varchar, + } +} + +#[cfg(feature = "mysql")] +#[derive(Insertable)] +#[table_name="factoids"] +struct NewFactoid<'a> { + pub name: &'a str, + pub content: &'a str, +} + + +#[cfg(feature = "mysql")] +impl Database for MysqlConnection { + fn insert(&mut self, name: &str, content: &str) -> Option<()> { + let factoid = NewFactoid { + name: name, + content: content, + }; + + ::diesel::insert(&factoid) + .into(factoids::table) + .execute(self) + .ok() + .map(|_| ()) } - fn get(&self, name: &str) -> Option<&str> { - self.get(name).map(String::as_str) + fn get(&self, name: &str) -> Option { + factoids::table + .filter(factoids::columns::name.eq(name)) + .limit(1) + .load::(self) + .ok() + .and_then(|v| v.first().map(|f| f.content.clone())) } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index a13bba6..5f9f99a 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -1,5 +1,6 @@ extern crate rlua; +use std::fmt; use self::rlua::prelude::*; use irc::client::prelude::*; use irc::error::Error as IrcError; @@ -8,11 +9,11 @@ use std::sync::Mutex; use plugin::*; mod database; -use self::database::*; +use self::database::Database; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); -#[derive(PluginName, Debug)] +#[derive(PluginName)] pub struct Factoids { factoids: Mutex, } @@ -40,7 +41,7 @@ impl Factoids { let name = command.tokens.remove(0); try_lock!(self.factoids) - .insert(name, command.tokens.join(" ")); + .insert(&name, &command.tokens.join(" ")); server.send_notice(&command.source, "Successfully added") } @@ -63,7 +64,6 @@ impl Factoids { } fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { - if command.tokens.len() < 1 { self.invalid_command(server, &command) @@ -88,7 +88,7 @@ impl Factoids { } } } else { - String::from(factoid) + factoid }; server.send_privmsg(&command.target, &value) @@ -170,3 +170,9 @@ impl Plugin for Factoids { } } } + +impl fmt::Debug for Factoids { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Factoids {{ ... }}") + } +} -- cgit v1.2.3-70-g09d2 From 4b5693d3c6781a5ca4ef32f43f3994a65020c933 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 16 Dec 2017 18:13:02 +0100 Subject: Add more info to factoids and save old versions --- Cargo.lock | 78 +++++++++-- Cargo.toml | 19 ++- bin/main.rs | 30 ++++- migrations/.gitkeep | 0 .../2017-11-03-164322_create_factoids/up.sql | 8 +- src/lib.rs | 9 +- src/plugins/factoids/database.rs | 120 +++++++++++------ src/plugins/factoids/mod.rs | 146 +++++++++++++++++---- 8 files changed, 322 insertions(+), 88 deletions(-) delete mode 100644 migrations/.gitkeep diff --git a/Cargo.lock b/Cargo.lock index 91693d5..936d8a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,32 +220,40 @@ dependencies = [ [[package]] name = "diesel" -version = "0.16.0" +version = "1.0.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_derives 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", "mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "diesel_codegen" -version = "0.16.0" +name = "diesel_derives" +version = "1.0.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "diesel_infer_schema" -version = "0.16.0" +version = "1.0.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "infer_schema_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_migrations" +version = "1.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", + "migrations_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -350,9 +358,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "frippy" version = "0.3.1" dependencies = [ + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.177 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_infer_schema 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_migrations 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -502,6 +512,25 @@ name = "if_chain" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "infer_schema_internals" +version = "1.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "infer_schema_macros" +version = "1.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "infer_schema_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.1" @@ -628,6 +657,24 @@ dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "migrations_internals" +version = "1.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "migrations_macros" +version = "1.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.3.5" @@ -1389,9 +1436,10 @@ dependencies = [ "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" -"checksum diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "304226fa7a3982b0405f6bb95dd9c10c3e2000709f194038a60ec2c277150951" -"checksum diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a42ca5c9b660add51d58bc5a50a87123380e1e458069c5504528a851ed7384" -"checksum diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1957ff5cd3b04772e43c162c2f69c2aa918080ff9b020276792d236be8be52" +"checksum diesel 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b9e512c7fbcc7240848252ff620ed5f0e996e25d5c694b2b535d27db7465c6" +"checksum diesel_derives 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "a631faea061a7b5ab85e842866da57dbc31cc5fe715397a5e5a5b0effd7146b9" +"checksum diesel_infer_schema 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cee2c5104f0258a4461c4c8694e870161cb974f4de8609fae3d496e26336590" +"checksum diesel_migrations 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "e1fd168d237ae0bd9e8bfdcb82ba87a4b72e4c1d9edd864242a67149c7f3c960" "checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" @@ -1419,6 +1467,8 @@ dependencies = [ "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" +"checksum infer_schema_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2af8e23352c51aff14633500bfff361e9ea310375044b40dd8939e2defccd5c" +"checksum infer_schema_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa05e92983b3f9af1e7508f7d4981452542d505640d1b328fe74f4466c82b953" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" "checksum irc 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c5053c25509042e963baa67d0d648add9f72b7487784505a5d5a3054d136a615" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" @@ -1435,6 +1485,8 @@ dependencies = [ "checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum migrations_internals 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "c39531d07a48b5920d19310f9ba644667aac56edd933a6e7649893551756ad50" +"checksum migrations_macros 1.0.0-rc1 (registry+https://github.com/rust-lang/crates.io-index)" = "12d6c72b7dae5fb40009c6313ef5a2075aa25f479a8a51f6a487abef887a7a2c" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" "checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" diff --git a/Cargo.toml b/Cargo.toml index 5ff779f..5f535e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "bin/main.rs" doc = false [features] -mysql = ["diesel", "diesel_codegen", "dotenv"] +mysql = ["diesel", "diesel_infer_schema", "diesel_migrations", "dotenv"] [dependencies] irc = "0.12.5" @@ -27,13 +27,14 @@ tokio-core = "0.1.10" futures = "0.1.16" log = "0.3.8" time = "0.1" -rlua = "0.9.2" +rlua = "0.9.3" reqwest = "0.8.0" select = "0.4.2" regex = "0.2.2" lazy_static = "0.2.9" serde = "1.0.15" serde_json = "1.0.3" +chrono = "0.4.0" glob = "0.2" frippy_derive = { path = "frippy_derive" } @@ -42,13 +43,19 @@ frippy_derive = { path = "frippy_derive" } git = 'https://github.com/Jokler/unicode_names' branch = 'update-to-latest-unicode' + [dependencies.diesel] -version = "0.16.0" +version = "1.0.0-beta1" +optional = true +features = ["mysql", "chrono"] + +[dependencies.diesel_infer_schema] +version = "1.0.0-beta1" optional = true features = ["mysql"] -[dependencies.diesel_codegen] -version = "0.16.0" +[dependencies.diesel_migrations] +version = "1.0.0-beta1" optional = true features = ["mysql"] @@ -58,4 +65,4 @@ optional = true [dependencies.clippy] version = "*" -optional = true \ No newline at end of file +optional = true diff --git a/bin/main.rs b/bin/main.rs index 1597a70..7869548 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -4,9 +4,16 @@ extern crate tokio_core; extern crate glob; extern crate futures; +#[cfg(feature = "mysql")] +#[macro_use] +extern crate diesel_migrations; +#[cfg(feature = "mysql")] +extern crate diesel; + #[macro_use] extern crate log; +#[cfg(not(feature = "mysql"))] use std::collections::HashMap; use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; @@ -18,6 +25,9 @@ use glob::glob; use frippy::plugins; use frippy::Config; +#[cfg(feature = "mysql")] +embed_migrations!(); + struct Logger; impl log::Log for Logger { @@ -44,7 +54,6 @@ impl log::Log for Logger { } fn main() { - let log_level = if cfg!(debug_assertions) { LogLevelFilter::Debug } else { @@ -87,7 +96,10 @@ fn main() { let mut disabled_plugins = None; if let &Some(ref options) = &config.options { if let Some(disabled) = options.get("disabled_plugins") { - disabled_plugins = Some(disabled.split(",").map(|p| p.trim()).collect::>()); + disabled_plugins = Some(disabled + .split(",") + .map(|p| p.trim()) + .collect::>()); } } @@ -97,8 +109,22 @@ fn main() { bot.add_plugin(plugins::Emoji::new()); bot.add_plugin(plugins::Currency::new()); bot.add_plugin(plugins::KeepNick::new()); + #[cfg(feature = "mysql")] + { + use diesel; + use diesel::Connection; + match diesel::mysql::MysqlConnection::establish("mysql://user:password@address/db") { + Ok(conn) => { + embedded_migrations::run(&conn).unwrap(); + bot.add_plugin(plugins::Factoids::new(conn)); + } + Err(e) => error!("Failed to connect to database: {}", e), + } + } + #[cfg(not(feature = "mysql"))] bot.add_plugin(plugins::Factoids::new(HashMap::new())); + if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { if let None = bot.remove_plugin(name) { diff --git a/migrations/.gitkeep b/migrations/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/migrations/2017-11-03-164322_create_factoids/up.sql b/migrations/2017-11-03-164322_create_factoids/up.sql index 84e9f9d..784a3f4 100644 --- a/migrations/2017-11-03-164322_create_factoids/up.sql +++ b/migrations/2017-11-03-164322_create_factoids/up.sql @@ -1,4 +1,8 @@ CREATE TABLE factoids ( - name VARCHAR(32) PRIMARY KEY, - content VARCHAR(5000) NOT NULL + name VARCHAR(32) NOT NULL, + idx INTEGER NOT NULL, + content TEXT NOT NULL, + author VARCHAR(32) NOT NULL, + created TIMESTAMP NOT NULL, + PRIMARY KEY (name, idx) ) diff --git a/src/lib.rs b/src/lib.rs index 1f5514e..4407e6a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,8 +35,10 @@ #[macro_use] extern crate diesel; #[cfg(feature = "mysql")] +extern crate diesel_infer_schema; +#[cfg(feature = "mysql")] #[macro_use] -extern crate diesel_codegen; +extern crate diesel_migrations; #[macro_use] extern crate log; @@ -48,12 +50,15 @@ extern crate frippy_derive; extern crate irc; extern crate futures; extern crate tokio_core; +extern crate regex; +extern crate chrono; +extern crate time; pub mod plugin; pub mod plugins; -use std::fmt; use std::collections::HashMap; +use std::fmt; use std::thread::spawn; use std::sync::Arc; diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index dbf136c..522c9d0 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -9,66 +9,112 @@ use diesel::prelude::*; #[cfg(feature = "mysql")] use diesel::mysql::MysqlConnection; +use chrono::NaiveDateTime; + +pub enum DbResponse { + Success, + Failed(&'static str), +} + +#[cfg_attr(feature = "mysql", derive(Queryable))] +#[derive(Clone, Debug)] +pub struct Factoid { + pub name: String, + pub idx: i32, + pub content: String, + pub author: String, + pub created: NaiveDateTime, +} + +#[cfg_attr(feature = "mysql", derive(Insertable))] +#[cfg_attr(feature = "mysql", table_name="factoids")] +pub struct NewFactoid<'a> { + pub name: &'a str, + pub idx: i32, + pub content: &'a str, + pub author: &'a str, + pub created: NaiveDateTime, +} + + pub trait Database: Send { - fn insert(&mut self, name: &str, content: &str) -> Option<()>; - fn get(&self, name: &str) -> Option; + fn insert(&mut self, factoid: &NewFactoid) -> DbResponse; + fn get(&self, name: &str, idx: i32) -> Option; + fn count(&self, name: &str) -> Result; } -impl Database for HashMap { - fn insert(&mut self, name: &str, content: &str) -> Option<()> { - self.insert(String::from(name), String::from(content)).map(|_| ()) +// HashMap +impl Database for HashMap<(String, i32), Factoid> { + fn insert(&mut self, factoid: &NewFactoid) -> DbResponse { + let factoid = Factoid { + name: String::from(factoid.name), + idx: factoid.idx, + content: factoid.content.to_string(), + author: factoid.author.to_string(), + created: factoid.created, + }; + + let name = String::from(factoid.name.clone()); + match self.insert((name, factoid.idx), factoid) { + None => DbResponse::Success, + Some(_) => DbResponse::Failed("Factoid was overwritten"), + } } - fn get(&self, name: &str) -> Option { - self.get(name).cloned() + fn get(&self, name: &str, idx: i32) -> Option { + self.get(&(String::from(name), idx)).map(|f| f.clone()) } -} -#[cfg(feature = "mysql")] -#[derive(Queryable)] -struct Factoid { - pub name: String, - pub content: String, + fn count(&self, name: &str) -> Result { + Ok(self.iter() + .filter(|&(&(ref n, _), _)| n == name) + .count() as i32) + } } +// MySql #[cfg(feature = "mysql")] table! { - factoids (name) { + factoids (name, idx) { name -> Varchar, - content -> Varchar, + idx -> Integer, + content -> Text, + author -> Varchar, + created -> Timestamp, } } -#[cfg(feature = "mysql")] -#[derive(Insertable)] -#[table_name="factoids"] -struct NewFactoid<'a> { - pub name: &'a str, - pub content: &'a str, -} - - #[cfg(feature = "mysql")] impl Database for MysqlConnection { - fn insert(&mut self, name: &str, content: &str) -> Option<()> { - let factoid = NewFactoid { - name: name, - content: content, - }; + fn insert(&mut self, factoid: &NewFactoid) -> DbResponse { + use diesel; - ::diesel::insert(&factoid) - .into(factoids::table) - .execute(self) - .ok() - .map(|_| ()) + match diesel::insert_into(factoids::table) + .values(factoid) + .execute(self) { + Ok(_) => DbResponse::Success, + Err(_) => DbResponse::Failed("Database error - possible duplicate"), + } } - fn get(&self, name: &str) -> Option { + fn get(&self, name: &str, idx: i32) -> Option { factoids::table - .filter(factoids::columns::name.eq(name)) + .find((name, idx)) .limit(1) .load::(self) .ok() - .and_then(|v| v.first().map(|f| f.content.clone())) + .and_then(|v| v.into_iter().next()) + } + + fn count(&self, name: &str) -> Result { + let count: Result = factoids::table + .filter(factoids::columns::name.eq(name)) + .count() + .first(self); + + match count { + Ok(c) => Ok(c as i32), + Err(_) => Err("Database Error"), + } } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 5f9f99a..bb83700 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -1,15 +1,18 @@ extern crate rlua; use std::fmt; +use std::str::FromStr; +use std::sync::Mutex; use self::rlua::prelude::*; use irc::client::prelude::*; use irc::error::Error as IrcError; -use std::sync::Mutex; +use time; +use chrono::NaiveDateTime; use plugin::*; mod database; -use self::database::Database; +use self::database::{Database, DbResponse}; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); @@ -33,50 +36,140 @@ impl Factoids { } fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { - if command.tokens.len() < 2 { return self.invalid_command(server, command); } let name = command.tokens.remove(0); - - try_lock!(self.factoids) - .insert(&name, &command.tokens.join(" ")); - - server.send_notice(&command.source, "Successfully added") + let content = command.tokens.join(" "); + let count = match try_lock!(self.factoids).count(&name) { + Ok(c) => c, + Err(e) => return server.send_notice(&command.source, e), + }; + + let tm = time::now().to_timespec(); + + let factoid = database::NewFactoid { + name: &name, + idx: count, + content: &content, + author: &command.source, + created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), + }; + + match try_lock!(self.factoids).insert(&factoid) { + DbResponse::Success => server.send_notice(&command.source, "Successfully added"), + DbResponse::Failed(e) => server.send_notice(&command.source, &e), + } } fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { - if command.tokens.len() < 1 { - self.invalid_command(server, command) + let (name, idx) = match command.tokens.len() { + 0 => return self.invalid_command(server, command), + 1 => { + let name = &command.tokens[0]; + let count = match try_lock!(self.factoids).count(name) { + Ok(c) => c, + Err(e) => return server.send_notice(&command.source, e), + }; + + if count < 1 { + return server.send_notice(&command.source, &format!("{} does not exist", name)); + } - } else { - let name = &command.tokens[0]; - let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(name) { - Some(v) => v, - None => return self.invalid_command(server, command), - }; + (name, count - 1) + } + _ => { + let name = &command.tokens[0]; + let idx = match i32::from_str(&command.tokens[1]) { + Ok(i) => i, + Err(_) => return server.send_notice(&command.source, "Invalid index"), + }; + + (name, idx) + } + }; + + let factoid = match try_lock!(self.factoids).get(name, idx) { + Some(v) => v, + None => return server.send_notice(&command.source, &format!("{}~{} does not exist", name, idx)), + }; + + server.send_privmsg(&command.target, + &format!("{}: {}", factoid.name, factoid.content)) + } + + fn info(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { + + match command.tokens.len() { + 0 => self.invalid_command(server, command), + 1 => { + let name = &command.tokens[0]; + let count = match try_lock!(self.factoids).count(name) { + Ok(c) => c, + Err(e) => return server.send_notice(&command.source, e), + }; + + match count { + 0 => server.send_notice(&command.source, &format!("{} does not exist", name)), + 1 => { + server.send_privmsg(&command.target, + &format!("There is 1 version of {}", name)) + } + _ => { + server.send_privmsg(&command.target, + &format!("There are {} versions of {}", count, name)) + } + } + } + _ => { + let name = &command.tokens[0]; + let idx = match i32::from_str(&command.tokens[1]) { + Ok(i) => i, + Err(_) => return server.send_notice(&command.source, "Invalid index"), + }; + + let factoid = match try_lock!(self.factoids).get(name, idx) { + Some(v) => v, + None => { + return server.send_notice(&command.source, + &format!("{}~{} does not exist", name, idx)) + } + }; + + server.send_privmsg(&command.target, + &format!("{}: Added by {} at {} UTC", + name, + factoid.author, + factoid.created)) + } - server.send_privmsg(&command.target, &format!("{}: {}", name, factoid)) } } - fn exec(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { + fn exec(&self, + server: &IrcServer, + mut command: PluginCommand, + error: bool) + -> Result<(), IrcError> { if command.tokens.len() < 1 { self.invalid_command(server, &command) } else { let name = command.tokens.remove(0); + let count = match try_lock!(self.factoids).count(&name) { + Ok(c) => c, + Err(e) => return server.send_notice(&command.source, e), + }; - let factoids = try_lock!(self.factoids); - let factoid = match factoids.get(&name) { - Some(v) => v, - None => return self.invalid_command(server, &command), + let factoid = match try_lock!(self.factoids).get(&name, count - 1) { + Some(v) => v.content, + None if error => return self.invalid_command(server, &command), + None => return Ok(()), }; - let value = if factoid.starts_with(">") { + let value = &if factoid.starts_with(">") { let factoid = String::from(&factoid[1..]); if factoid.starts_with(">") { @@ -149,7 +242,7 @@ impl Plugin for Factoids { tokens: t, }; - self.exec(server, c) + self.exec(server, c, false) } else { Ok(()) @@ -165,7 +258,8 @@ impl Plugin for Factoids { match sub_command.as_ref() { "add" => self.add(server, &mut command), "get" => self.get(server, &command), - "exec" => self.exec(server, command), + "info" => self.info(server, &command), + "exec" => self.exec(server, command, true), _ => self.invalid_command(server, &command), } } -- cgit v1.2.3-70-g09d2 From 5fdb7198bc73035cf5621ded8183000c3fcbbe29 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 02:00:00 +0100 Subject: Add 'remove' command to Factoids and make the Database trait public --- src/lib.rs | 5 ---- src/plugins/factoids/database.rs | 57 +++++++++++++++++++++++++++++----------- src/plugins/factoids/mod.rs | 20 +++++++++++++- src/plugins/mod.rs | 1 + 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4407e6a..8b55dab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,11 +34,6 @@ #[cfg(feature = "mysql")] #[macro_use] extern crate diesel; -#[cfg(feature = "mysql")] -extern crate diesel_infer_schema; -#[cfg(feature = "mysql")] -#[macro_use] -extern crate diesel_migrations; #[macro_use] extern crate log; diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 522c9d0..1af586e 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -26,6 +26,8 @@ pub struct Factoid { pub created: NaiveDateTime, } +#[cfg(feature = "mysql")] +use self::mysql::factoids; #[cfg_attr(feature = "mysql", derive(Insertable))] #[cfg_attr(feature = "mysql", table_name="factoids")] pub struct NewFactoid<'a> { @@ -40,6 +42,7 @@ pub struct NewFactoid<'a> { pub trait Database: Send { fn insert(&mut self, factoid: &NewFactoid) -> DbResponse; fn get(&self, name: &str, idx: i32) -> Option; + fn delete(&mut self, name: &str, idx: i32) -> DbResponse; fn count(&self, name: &str) -> Result; } @@ -65,6 +68,13 @@ impl Database for HashMap<(String, i32), Factoid> { self.get(&(String::from(name), idx)).map(|f| f.clone()) } + fn delete(&mut self, name: &str, idx: i32) -> DbResponse { + match self.remove(&(String::from(name), idx)) { + Some(_) => DbResponse::Success, + None => DbResponse::Failed("Factoid not found"), + } + } + fn count(&self, name: &str) -> Result { Ok(self.iter() .filter(|&(&(ref n, _), _)| n == name) @@ -72,15 +82,18 @@ impl Database for HashMap<(String, i32), Factoid> { } } -// MySql +// Diesel automatically define the factoids module as public. +// For now this is how we keep it private. #[cfg(feature = "mysql")] -table! { - factoids (name, idx) { - name -> Varchar, - idx -> Integer, - content -> Text, - author -> Varchar, - created -> Timestamp, +mod mysql { + table! { + factoids (name, idx) { + name -> Varchar, + idx -> Integer, + content -> Text, + author -> Varchar, + created -> Timestamp, + } } } @@ -88,22 +101,34 @@ table! { impl Database for MysqlConnection { fn insert(&mut self, factoid: &NewFactoid) -> DbResponse { use diesel; - match diesel::insert_into(factoids::table) .values(factoid) .execute(self) { Ok(_) => DbResponse::Success, - Err(_) => DbResponse::Failed("Database error - possible duplicate"), + Err(e) => { + debug!("DB Insertion Error: {:?}", e); + DbResponse::Failed("Database error - possible duplicate") + } } } fn get(&self, name: &str, idx: i32) -> Option { - factoids::table - .find((name, idx)) - .limit(1) - .load::(self) - .ok() - .and_then(|v| v.into_iter().next()) + factoids::table.find((name, idx)).first(self).ok() + } + + fn delete(&mut self, name: &str, idx: i32) -> DbResponse { + use diesel; + use self::factoids::columns; + match diesel::delete(factoids::table + .filter(columns::name.eq(name)) + .filter(columns::idx.eq(idx))) + .execute(self) { + Ok(_) => DbResponse::Success, + Err(e) => { + debug!("DB Deletion Error: {:?}", e); + DbResponse::Failed("Failed to delete factoid") + } + } } fn count(&self, name: &str) -> Result { diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index bb83700..fcbbb79 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -11,7 +11,7 @@ use time; use chrono::NaiveDateTime; use plugin::*; -mod database; +pub mod database; use self::database::{Database, DbResponse}; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); @@ -63,6 +63,23 @@ impl Factoids { } } + fn remove(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { + if command.tokens.len() < 1 { + return self.invalid_command(server, command); + } + + let name = command.tokens.remove(0); + let count = match try_lock!(self.factoids).count(&name) { + Ok(c) => c, + Err(e) => return server.send_notice(&command.source, e), + }; + + match try_lock!(self.factoids).delete(&name, count - 1) { + DbResponse::Success => server.send_notice(&command.source, "Successfully removed"), + DbResponse::Failed(e) => server.send_notice(&command.source, &e), + } + } + fn get(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { let (name, idx) = match command.tokens.len() { @@ -257,6 +274,7 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); match sub_command.as_ref() { "add" => self.add(server, &mut command), + "remove" => self.remove(server, &mut command), "get" => self.get(server, &command), "info" => self.info(server, &command), "exec" => self.exec(server, command, true), diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index f860d88..2e85932 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -11,4 +11,5 @@ pub use self::url::Url; pub use self::emoji::Emoji; pub use self::currency::Currency; pub use self::factoids::Factoids; +pub use self::factoids::database; pub use self::keepnick::KeepNick; -- cgit v1.2.3-70-g09d2 From b98d1ce014eb6b502601547d46fc522ed6a4b416 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 14:46:48 +0100 Subject: Add mysql_url option to the toml files --- bin/main.rs | 29 ++++++++++++++++++++--------- configs/config.toml | 4 +++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index 7869548..8f1877a 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -13,7 +13,6 @@ extern crate diesel; #[macro_use] extern crate log; -#[cfg(not(feature = "mysql"))] use std::collections::HashMap; use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; @@ -94,6 +93,7 @@ fn main() { for config in configs { let mut disabled_plugins = None; + let mut mysql_url = None; if let &Some(ref options) = &config.options { if let Some(disabled) = options.get("disabled_plugins") { disabled_plugins = Some(disabled @@ -101,6 +101,8 @@ fn main() { .map(|p| p.trim()) .collect::>()); } + + mysql_url = options.get("mysql_url"); } let mut bot = frippy::Bot::new(); @@ -111,18 +113,27 @@ fn main() { bot.add_plugin(plugins::KeepNick::new()); #[cfg(feature = "mysql")] { - use diesel; - use diesel::Connection; - match diesel::mysql::MysqlConnection::establish("mysql://user:password@address/db") { - Ok(conn) => { - embedded_migrations::run(&conn).unwrap(); - bot.add_plugin(plugins::Factoids::new(conn)); + if let Some(url) = mysql_url { + use diesel; + use diesel::Connection; + match diesel::mysql::MysqlConnection::establish(url) { + Ok(conn) => { + embedded_migrations::run(&conn).unwrap(); + bot.add_plugin(plugins::Factoids::new(conn)); + } + Err(e) => error!("Failed to connect to database: {}", e), } - Err(e) => error!("Failed to connect to database: {}", e), + } else { + bot.add_plugin(plugins::Factoids::new(HashMap::new())); } } #[cfg(not(feature = "mysql"))] - bot.add_plugin(plugins::Factoids::new(HashMap::new())); + { + if let Some(_) = mysql_url { + error!("frippy was not built with the mysql feature") + } + bot.add_plugin(plugins::Factoids::new(HashMap::new())); + } if let Some(disabled_plugins) = disabled_plugins { diff --git a/configs/config.toml b/configs/config.toml index 02f86fd..56e5240 100644 --- a/configs/config.toml +++ b/configs/config.toml @@ -24,5 +24,7 @@ source = "https://github.com/Mavulp/frippy" #[channel_keys] #"#frippy" = "" -#[options] +[options] #disabled_plugins = "Url" +# If no database url is set a HashMap is used +#mysql_url = "mysql://user:password@address/db" -- cgit v1.2.3-70-g09d2 From 4a8e69f7f3069f8d059d0f88fba72e03712fd591 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 15:22:29 +0100 Subject: Log database errors and send a notice if no factoid was deleted --- src/plugins/factoids/database.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 1af586e..cb6f422 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -106,8 +106,8 @@ impl Database for MysqlConnection { .execute(self) { Ok(_) => DbResponse::Success, Err(e) => { - debug!("DB Insertion Error: {:?}", e); - DbResponse::Failed("Database error - possible duplicate") + error!("DB Insertion Error: {:?}", e); + DbResponse::Failed("Failed to add factoid") } } } @@ -123,9 +123,15 @@ impl Database for MysqlConnection { .filter(columns::name.eq(name)) .filter(columns::idx.eq(idx))) .execute(self) { - Ok(_) => DbResponse::Success, + Ok(v) => { + if v > 0 { + DbResponse::Success + } else { + DbResponse::Failed("Could not find any factoid with that name") + } + } Err(e) => { - debug!("DB Deletion Error: {:?}", e); + error!("DB Deletion Error: {:?}", e); DbResponse::Failed("Failed to delete factoid") } } -- cgit v1.2.3-70-g09d2 From 32e870aeefee587d6eabdfa08cf27b3cf9a46f15 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 15:27:14 +0100 Subject: Exit if no bot connected successfully --- bin/main.rs | 9 ++++++--- src/lib.rs | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index 420e016..c9749b6 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -78,6 +78,7 @@ fn main() { // Create an event loop to run the connections on. let mut reactor = Core::new().unwrap(); + let mut task = false; // Open a connection and add work for each config for config in configs { @@ -104,9 +105,11 @@ fn main() { } } - bot.connect(&mut reactor, &config); + bot.connect(&mut reactor, &config).map(|_| task = true); } - // Run the main loop forever - reactor.run(future::empty::<(), ()>()).unwrap(); + if task { + // Run the main loop forever + reactor.run(future::empty::<(), ()>()).unwrap(); + } } diff --git a/src/lib.rs b/src/lib.rs index 5d15802..5592da7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,7 +132,7 @@ impl Bot { /// reactor.run(future::empty::<(), ()>()).unwrap(); /// # } /// ``` - pub fn connect(&self, reactor: &mut Core, config: &Config) { + pub fn connect(&self, reactor: &mut Core, config: &Config) -> Option<()> { info!("Plugins loaded: {}", self.plugins); let server = @@ -140,7 +140,7 @@ impl Bot { Ok(v) => v, Err(e) => { error!("Failed to connect: {}", e); - return; + return None; } }; @@ -148,7 +148,10 @@ impl Bot { match server.identify() { Ok(_) => info!("Identified"), - Err(e) => error!("Failed to identify: {}", e), + Err(e) => { + error!("Failed to identify: {}", e); + return None; + } }; // TODO Verify if we actually need to clone plugins twice @@ -160,6 +163,7 @@ impl Bot { .map_err(|e| error!("Failed to process message: {}", e)); reactor.handle().spawn(task); + Some(()) } } -- cgit v1.2.3-70-g09d2 From c0f68f11396713ffc1ec99ee49b9c16ff55f6824 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 15:55:01 +0100 Subject: Update diesel --- Cargo.lock | 38 +++++++++++++++++++------------------- Cargo.toml | 6 +++--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 936d8a4..6b471e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,8 +104,8 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -151,8 +151,8 @@ dependencies = [ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -374,7 +374,7 @@ dependencies = [ "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -553,8 +553,8 @@ dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -940,7 +940,7 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1046,22 +1046,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1076,7 +1076,7 @@ dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1086,7 +1086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1119,7 +1119,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1285,7 +1285,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1529,9 +1529,9 @@ dependencies = [ "checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" -"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce" -"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603" +"checksum serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "386122ba68c214599c44587e0c0b411e8d90894503a95425b4f9508e4317901f" +"checksum serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "ec0bfa6c5784e7d110514448da0e1dbad41ea5514c3e68be755b23858b83a399" +"checksum serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "730fe9f29fe8db69a601837f416e46cba07792031ed6b27557a43e49d62d89ae" "checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" diff --git a/Cargo.toml b/Cargo.toml index 5f535e4..1775455 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,17 +45,17 @@ branch = 'update-to-latest-unicode' [dependencies.diesel] -version = "1.0.0-beta1" +version = "1.0.0-rc1" optional = true features = ["mysql", "chrono"] [dependencies.diesel_infer_schema] -version = "1.0.0-beta1" +version = "1.0.0-rc1" optional = true features = ["mysql"] [dependencies.diesel_migrations] -version = "1.0.0-beta1" +version = "1.0.0-rc1" optional = true features = ["mysql"] -- cgit v1.2.3-70-g09d2 From 3d28c4e4bcff399e294a507187e051839f74ee87 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 24 Dec 2017 15:55:13 +0100 Subject: Switch to HashMap if the migrations failed to run --- bin/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index 8f1877a..9373afd 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -118,8 +118,13 @@ fn main() { use diesel::Connection; match diesel::mysql::MysqlConnection::establish(url) { Ok(conn) => { - embedded_migrations::run(&conn).unwrap(); - bot.add_plugin(plugins::Factoids::new(conn)); + match embedded_migrations::run(&conn) { + Ok(_) => bot.add_plugin(plugins::Factoids::new(conn)), + Err(e) => { + bot.add_plugin(plugins::Factoids::new(HashMap::new())); + error!("Failed to run migrations: {}", e); + } + } } Err(e) => error!("Failed to connect to database: {}", e), } -- cgit v1.2.3-70-g09d2 From 046a0114f0e23be258cbb6834c286153b758ecaf Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 25 Dec 2017 15:38:32 +0100 Subject: Send all factoid info responses to the channel instead of the user --- src/plugins/factoids/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index fcbbb79..aeb83b0 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -129,7 +129,7 @@ impl Factoids { }; match count { - 0 => server.send_notice(&command.source, &format!("{} does not exist", name)), + 0 => server.send_privmsg(&command.target, &format!("{} does not exist", name)), 1 => { server.send_privmsg(&command.target, &format!("There is 1 version of {}", name)) -- cgit v1.2.3-70-g09d2 From 37056a823a574add2cd452a97f328bb170400a0b Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 4 Jan 2018 19:12:01 +0100 Subject: Return the future on connect instead of adding it to the reactor --- bin/main.rs | 10 ++++------ src/lib.rs | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index c9749b6..ac25a93 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -78,7 +78,7 @@ fn main() { // Create an event loop to run the connections on. let mut reactor = Core::new().unwrap(); - let mut task = false; + let mut futures = Vec::new(); // Open a connection and add work for each config for config in configs { @@ -105,11 +105,9 @@ fn main() { } } - bot.connect(&mut reactor, &config).map(|_| task = true); + futures.push(bot.connect(&mut reactor, &config)); } - if task { - // Run the main loop forever - reactor.run(future::empty::<(), ()>()).unwrap(); - } + // Run the bots until they throw an error + reactor.run(future::join_all(futures)).unwrap(); } diff --git a/src/lib.rs b/src/lib.rs index 5592da7..d769075 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,11 +108,12 @@ impl Bot { self.plugins.remove(name) } - /// This connects the `Bot` to IRC and adds a task - /// to the Core that was supplied. + /// This connects the `Bot` to IRC and returns a `Future` + /// which represents the bots work. + /// This `Future` will run forever unless it returns an error. /// - /// You need to run the core, so that frippy - /// can do its work. + /// You need to run the `Future`, so that the `Bot` + /// can actually do its work. /// /// # Examples /// ```no_run @@ -128,11 +129,11 @@ impl Bot { /// let mut reactor = Core::new().unwrap(); /// let mut bot = Bot::new(); /// - /// bot.connect(&mut reactor, &config); - /// reactor.run(future::empty::<(), ()>()).unwrap(); + /// let future = bot.connect(&mut reactor, &config); + /// reactor.run(future).unwrap(); /// # } /// ``` - pub fn connect(&self, reactor: &mut Core, config: &Config) -> Option<()> { + pub fn connect(&self, reactor: &mut Core, config: &Config) -> Option>> { info!("Plugins loaded: {}", self.plugins); let server = @@ -157,13 +158,12 @@ impl Bot { // TODO Verify if we actually need to clone plugins twice let plugins = self.plugins.clone(); - let task = server + let future = server .stream() .for_each(move |message| process_msg(&server, plugins.clone(), message)) .map_err(|e| error!("Failed to process message: {}", e)); - reactor.handle().spawn(task); - Some(()) + Some(Box::new(future)) } } -- cgit v1.2.3-70-g09d2 From 1f69bfef7f2fd5fdc8787485d81461d68aa2d3ba Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 28 Jan 2018 05:28:32 +0100 Subject: Update dependencies --- Cargo.lock | 496 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 240 insertions(+), 256 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16aaef5..61717a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,15 +3,6 @@ name = "adler32" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "advapi32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aho-corasick" version = "0.6.4" @@ -22,16 +13,14 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -39,13 +28,13 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "base64" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -67,12 +56,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "0.7.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "0.9.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -92,11 +81,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -104,14 +93,14 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -125,34 +114,34 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy" -version = "0.0.175" +version = "0.0.182" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.175" +version = "0.0.182" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -164,7 +153,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -172,35 +161,17 @@ name = "core-foundation-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crc" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crypt32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dbghelp-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "debug_unreachable" version = "0.1.1" @@ -281,7 +252,7 @@ name = "error-chain" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -301,20 +272,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "frippy" version = "0.3.1" dependencies = [ - "clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", + "irc 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", ] @@ -328,19 +299,17 @@ dependencies = [ [[package]] name = "fuchsia-zircon" -version = "0.2.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-zircon-sys" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "futf" @@ -353,21 +322,21 @@ dependencies = [ [[package]] name = "futures" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-cpupool" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getopts" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -380,7 +349,7 @@ name = "html5ever" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -389,26 +358,26 @@ dependencies = [ [[package]] name = "httparse" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.9" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -420,13 +389,13 @@ name = "hyper-tls" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -446,33 +415,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "iovec" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "irc" -version = "0.12.5" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -515,28 +485,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazycell" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.34" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libflate" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.3.8" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "mac" @@ -566,7 +547,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -590,16 +571,16 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -619,11 +600,13 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -636,7 +619,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -648,7 +631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -656,7 +639,7 @@ name = "num-integer" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -665,20 +648,20 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -689,17 +672,17 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.23" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -732,7 +715,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -760,7 +743,7 @@ version = "0.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -775,33 +758,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.32" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -809,28 +792,28 @@ name = "relay" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "reqwest" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -852,16 +835,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "schannel" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -869,15 +847,6 @@ name = "scoped-tls" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "secur32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "security-framework" version = "0.1.16" @@ -885,7 +854,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -895,7 +864,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -922,22 +891,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -946,13 +915,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -962,7 +931,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -995,7 +964,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1044,7 +1013,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1054,7 +1023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1068,25 +1037,24 @@ dependencies = [ [[package]] name = "time" -version = "0.1.38" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-core" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1097,9 +1065,9 @@ name = "tokio-io" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1107,7 +1075,7 @@ name = "tokio-mockstream" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1116,14 +1084,14 @@ name = "tokio-proto" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1133,7 +1101,7 @@ name = "tokio-service" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1141,18 +1109,18 @@ name = "tokio-timer" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-tls" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1161,7 +1129,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1231,11 +1199,8 @@ dependencies = [ [[package]] name = "utf-8" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "utf8-ranges" @@ -1247,7 +1212,7 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1270,11 +1235,30 @@ name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1286,30 +1270,27 @@ dependencies = [ [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" -"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" +"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" +"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" +"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" -"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clippy 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "2dae056aaec8acd5fc26722234cc9fa03b969a860d9aef0da6c5e5c996ce66ae" -"checksum clippy_lints 0.0.175 (registry+https://github.com/rust-lang/crates.io-index)" = "d04f24bc10870e19880865d8f206168993bfc6df9cc7335c0692cad98378a4b6" +"checksum clippy 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5d02da768264b4faa1494aad322c4537f3f9855349ef704077064a246248e3" +"checksum clippy_lints 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)" = "e60c2e0439117abddf18407165aeb46b0e9a59d3a441b323ac176d2894f2adde" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d4a687c40efbc7d376958117b34d5f1cece11709110a742405bf58e7a34f00" -"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" -"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" @@ -1323,48 +1304,49 @@ dependencies = [ "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" -"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" -"checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" -"checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" +"checksum futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0bab5b5e94f5c31fc764ba5dd9ad16568aae5d4825538c01d6bca680c9bf94a7" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" -"checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e0594792d2109069d0caffd176f674d770a84adf024c5bb48e686b1ee5ac7659" +"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" +"checksum hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6105c5eeb03068b10ff34475a0d166964f98e7b9777cc34b342a225af9b87c" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" -"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" -"checksum irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)" = "484fea2147dd042cdb3dd9e707af9cc9d8f46a4adc04e553ff985203a955ed6e" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum irc 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf1f0b1ab53de0a7c48591d681ba5e39db83884fc4c1f37e2617fc7c7373cc5" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" -"checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67" -"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" +"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" +"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" +"checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" -"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" +"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" +"checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" -"checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" +"checksum openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "14ba54ac7d5a4eabd1d5f2c1fdeb7e7c14debfa669d94b983d01b465e767ba9e" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" @@ -1375,27 +1357,26 @@ dependencies = [ "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" -"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" -"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" -"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" -"checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" +"checksum reqwest 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "449c45f593ce9af9417c91e22f274fb8cea013bcf3d37ec1b5fb534b623bc708" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4330c2e874379fbd28fa67ba43239dbe8c7fb00662ceb1078bd37474f08bf5ce" +"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" -"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" -"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce" -"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603" -"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" +"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" @@ -1410,14 +1391,14 @@ dependencies = [ "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" +"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41bfc436ef8b7f60c19adf3df086330ae9992385e4d8c53b17a323cad288e155" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc" -"checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13" +"checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" @@ -1428,12 +1409,15 @@ dependencies = [ "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" -"checksum utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f923c601c7ac48ef1d66f7d5b5b2d9a7ba9c51333ab75a3ddf8d0309185a56" +"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -- cgit v1.2.3-70-g09d2 From 2ba26a37d27a637b7c0e02970419342a6f83462b Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Feb 2018 14:13:07 +0100 Subject: Add evaluate function to plugins This allows plugins to be used in combination with each other. --- src/plugin.rs | 2 ++ src/plugins/currency.rs | 58 +++++++++++++++++++++++++++++-------------------- src/plugins/emoji.rs | 21 +++++++++++++----- src/plugins/help.rs | 10 ++++----- src/plugins/keepnick.rs | 4 ++++ src/plugins/url.rs | 29 +++++++++++++++---------- 6 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/plugin.rs b/src/plugin.rs index d14c129..63d3530 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -13,6 +13,8 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError>; /// Handles any command directed at this plugin. fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError>; + /// Should work like command but return a String instead of sending messages to IRC. + fn evaluate(&self, server: &IrcServer, command: PluginCommand) -> Result; } /// `PluginName` is required by `Plugin`. diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 634faa2..4d44d9a 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -68,24 +68,26 @@ impl Currency { Currency {} } - fn eval_command<'a>(&self, tokens: &'a [String]) -> Result, ParseFloatError> { + fn eval_command<'a>(&self, + tokens: &'a [String]) + -> Result, ParseFloatError> { Ok(ConvertionRequest { - value: tokens[0].parse()?, - source: &tokens[1], - target: &tokens[2], - }) + value: tokens[0].parse()?, + source: &tokens[1], + target: &tokens[2], + }) } - fn convert(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + fn convert(&self, server: &IrcServer, command: &mut PluginCommand) -> Result { if command.tokens.len() < 3 { - return self.invalid_command(server, &command); + return Err(self.invalid_command(server)); } let request = match self.eval_command(&command.tokens) { Ok(request) => request, Err(_) => { - return self.invalid_command(server, &command); + return Err(self.invalid_command(server)); } }; @@ -97,31 +99,27 @@ impl Currency { response / 1.00000000, request.target.to_lowercase()); - server.send_privmsg(&command.target, &response) + Ok(response) } - None => server.send_notice(&command.source, "Error while converting given currency"), + None => Err(String::from("An error occured during the conversion of the given currency")), } } - fn help(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { - let help = format!("usage: {} currency value from_currency to_currency\r\n\ + fn help(&self, server: &IrcServer) -> String { + format!("usage: {} currency value from_currency to_currency\r\n\ example: 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()); - - server.send_notice(&command.source, &help) + server.current_nickname()) } - fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { - let help = format!("Incorrect Command. \ + fn invalid_command(&self, server: &IrcServer) -> String { + format!("Incorrect Command. \ Send \"{} currency help\" for help.", - server.current_nickname()); - - server.send_notice(&command.source, &help) + server.current_nickname()) } } @@ -137,12 +135,26 @@ impl Plugin for Currency { fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { if command.tokens.is_empty() { - return self.invalid_command(server, &command); + return server.send_notice(&command.source, &self.invalid_command(server)); + } + + 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), + } + } + } + + fn evaluate(&self, server: &IrcServer, mut command: PluginCommand) -> Result{ + if command.tokens.is_empty() { + return Err(self.invalid_command(server)); } match command.tokens[0].as_ref() { - "help" => self.help(server, &mut command), - _ => self.convert(server, command), + "help" => Ok(self.help(server)), + _ => self.convert(server, &mut command), } } } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 59e2fdd..512a62e 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -36,13 +36,12 @@ impl Emoji { Emoji {} } - fn emoji(&self, server: &IrcServer, content: &str, target: &str) -> Result<(), IrcError> { - let names = self.return_emojis(content) + fn emoji(&self, content: &str) -> String { + self.return_emojis(content) .iter() .map(|e| e.to_string()) - .collect::>(); - - server.send_privmsg(target, &names.join(", ")) + .collect::>() + .join(", ") } fn return_emojis(&self, string: &str) -> Vec { @@ -108,7 +107,8 @@ impl Plugin for Emoji { fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { match message.command { Command::PRIVMSG(_, ref content) => { - self.emoji(server, content, message.response_target().unwrap()) + server.send_privmsg(message.response_target().unwrap(), + &self.emoji(content)) } _ => Ok(()), } @@ -118,6 +118,15 @@ impl Plugin for Emoji { server.send_notice(&command.source, "This Plugin does not implement any commands.") } + + fn evaluate(&self, _: &IrcServer, command: PluginCommand) -> Result { + let emojis = self.emoji(&command.tokens[0]); + if emojis.is_empty() { + Ok(emojis) + } else { + Err(String::from("No emojis were found.")) + } + } } #[cfg(test)] diff --git a/src/plugins/help.rs b/src/plugins/help.rs index 7b987d4..cea325f 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -10,10 +10,6 @@ impl Help { pub fn new() -> Help { Help {} } - - fn help(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { - server.send_notice(&command.source, "Help has not been added yet.") - } } impl Plugin for Help { @@ -26,7 +22,11 @@ impl Plugin for Help { } fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { - self.help(server, command) + server.send_notice(&command.source, "Help has not been added yet.") + } + + fn evaluate(&self, _: &IrcServer, _: PluginCommand) -> Result { + Err(String::from("Help has not been added yet.")) } } diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 1d4627d..2970857 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -54,6 +54,10 @@ impl Plugin for KeepNick { server.send_notice(&command.source, "This Plugin does not implement any commands.") } + + fn evaluate(&self, _: &IrcServer, _: PluginCommand) -> Result { + Err(String::from("This Plugin does not implement any commands.")) + } } #[cfg(test)] diff --git a/src/plugins/url.rs b/src/plugins/url.rs index f6e06f3..ab36833 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -95,11 +95,11 @@ impl Url { } } - fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { - let url = match self.grep_url(message) { + fn url(&self, text: &str) -> Result { + let url = match self.grep_url(text) { Some(url) => url, None => { - return Ok(()); + return Err("No Url was found.") } }; @@ -109,18 +109,18 @@ impl Url { let doc = Document::from(body.as_ref()); if let Some(title) = doc.find(Name("title")).next() { - let text = title.children().next().unwrap(); - let message = text.as_text().unwrap().trim().replace("\n", "|"); - debug!("Title: {:?}", text); - debug!("Message: {:?}", message); + let title = title.children().next().unwrap(); + let title_text = title.as_text().unwrap().trim().replace("\n", "|"); + debug!("Title: {:?}", title); + debug!("Text: {:?}", title_text); - server.send_privmsg(target, &message) + Ok(title_text) } else { - Ok(()) + Err("No title was found.") } } - None => Ok(()), + None => Err("Failed to download document.") } } } @@ -136,7 +136,10 @@ impl Plugin for Url { fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { match message.command { Command::PRIVMSG(_, ref content) => { - self.url(server, content, message.response_target().unwrap()) + match self.url(content) { + Ok(title) => server.send_privmsg(&message.response_target().unwrap(), &title), + Err(_) => Ok(()), + } } _ => Ok(()), } @@ -146,6 +149,10 @@ impl Plugin for Url { server.send_notice(&command.source, "This Plugin does not implement any commands.") } + + fn evaluate(&self, _: &IrcServer, command: PluginCommand) -> Result { + self.url(&command.tokens[0]).map_err(|e| String::from(e)) + } } #[cfg(test)] -- cgit v1.2.3-70-g09d2 From 2c10ee57bbefde948b401c36fc50209bc34a99ad Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Feb 2018 15:25:01 +0100 Subject: Upgrade dependencies --- Cargo.lock | 188 ++++++++++++++++++++++++++++++------------------ Cargo.toml | 20 +++--- bin/main.rs | 48 ++++++------- src/lib.rs | 74 ++++++++----------- src/plugin.rs | 10 +-- src/plugins/currency.rs | 16 ++--- src/plugins/emoji.rs | 10 +-- src/plugins/help.rs | 10 +-- src/plugins/keepnick.rs | 12 ++-- src/plugins/url.rs | 10 +-- 10 files changed, 217 insertions(+), 181 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61717a6..ab10e52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,23 +113,23 @@ name = "chrono" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy" -version = "0.0.182" +version = "0.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.182" +version = "0.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -248,11 +248,22 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "error-chain" -version = "0.10.0" +name = "failure" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -272,20 +283,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "frippy" version = "0.3.1" dependencies = [ - "clippy 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", - "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "irc 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "irc 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)", ] @@ -363,7 +372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.15" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -371,14 +380,15 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -390,10 +400,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -424,22 +434,21 @@ dependencies = [ [[package]] name = "irc" -version = "0.12.8" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -571,7 +580,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -609,7 +618,7 @@ dependencies = [ "schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -626,34 +635,42 @@ dependencies = [ [[package]] name = "num" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-iter" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.42" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -715,7 +732,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -758,11 +775,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.20" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -772,7 +800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -789,12 +817,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "relay" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "remove_dir_all" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "reqwest" version = "0.8.4" @@ -802,7 +839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -812,7 +849,7 @@ dependencies = [ "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -920,7 +957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1003,6 +1040,15 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "take" version = "0.1.0" @@ -1010,10 +1056,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tempdir" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1054,20 +1101,20 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1076,7 +1123,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1087,12 +1134,12 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1121,7 +1168,7 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1212,7 +1259,7 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1286,8 +1333,8 @@ dependencies = [ "checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clippy 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5d02da768264b4faa1494aad322c4537f3f9855349ef704077064a246248e3" -"checksum clippy_lints 0.0.182 (registry+https://github.com/rust-lang/crates.io-index)" = "e60c2e0439117abddf18407165aeb46b0e9a59d3a441b323ac176d2894f2adde" +"checksum clippy 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7b79c57f831e752f3667ae6115d02ed2d9e97a986ff76e5f04d613a8c0842a" +"checksum clippy_lints 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)" = "a3864104a4e6092e644b985dd7543e5f24e99aa7262f5ee400bcb17cfeec1bf5" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" @@ -1301,7 +1348,8 @@ dependencies = [ "checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" @@ -1313,12 +1361,12 @@ dependencies = [ "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" -"checksum hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6105c5eeb03068b10ff34475a0d166964f98e7b9777cc34b342a225af9b87c" +"checksum hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)" = "c4f9b276c87e3fc1902a8bdfcce264c3f7c8a1c35e5e0c946062739f55026664" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum irc 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf1f0b1ab53de0a7c48591d681ba5e39db83884fc4c1f37e2617fc7c7373cc5" +"checksum irc 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf38b935ba382932a429f918888568d1f94c24e2d6d2289b96b817085624a39d" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -1336,14 +1384,15 @@ dependencies = [ "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" -"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" +"checksum mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7da01a5e23070d92d99b1ecd1cd0af36447c6fd44b0fe283c2db199fa136724f" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017" +"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" +"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +"checksum num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7de20f146db9d920c45ee8ed8f71681fd9ade71909b48c3acbd766aa504cf10" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" "checksum openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "14ba54ac7d5a4eabd1d5f2c1fdeb7e7c14debfa669d94b983d01b465e767ba9e" @@ -1357,11 +1406,13 @@ dependencies = [ "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5be5347bde0c48cfd8c3fdc0766cdfe9d8a755ef84d620d6794c778c91de8b2b" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" -"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" +"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" +"checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum reqwest 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "449c45f593ce9af9417c91e22f274fb8cea013bcf3d37ec1b5fb534b623bc708" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" @@ -1387,13 +1438,14 @@ dependencies = [ "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" -"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" +"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" "checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" -"checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" +"checksum tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9532748772222bf70297ec0e2ad0f17213b4a7dd0e6afb68e0a0768f69f4e4f" "checksum tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41bfc436ef8b7f60c19adf3df086330ae9992385e4d8c53b17a323cad288e155" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" diff --git a/Cargo.toml b/Cargo.toml index 3218e65..bbaa28d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,18 +19,16 @@ path = "bin/main.rs" doc = false [dependencies] -irc = "0.12.5" -tokio-core = "0.1.10" -futures = "0.1.16" -log = "0.3.8" -time = "0.1" -reqwest = "0.8.0" +irc = "0.13.2" +log = "0.4.1" +time = "0.1.39" +reqwest = "0.8.4" select = "0.4.2" -regex = "0.2.2" -lazy_static = "0.2.9" -serde = "1.0.15" -serde_json = "1.0.3" -glob = "0.2" +regex = "0.2.6" +lazy_static = "1.0.0" +serde = "1.0.27" +serde_json = "1.0.9" +glob = "0.2.11" frippy_derive = { path = "frippy_derive" } unicode_names = { git = 'https://github.com/Jokler/unicode_names', branch = 'update-to-latest-unicode' } diff --git a/bin/main.rs b/bin/main.rs index ac25a93..21e27dc 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -1,16 +1,14 @@ extern crate frippy; extern crate time; -extern crate tokio_core; +extern crate irc; extern crate glob; -extern crate futures; #[macro_use] extern crate log; -use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata}; +use log::{Record, Level, LevelFilter, Metadata}; -use tokio_core::reactor::Core; -use futures::future; +use irc::client::reactor::IrcReactor; use glob::glob; use frippy::plugins; @@ -19,13 +17,13 @@ use frippy::Config; struct Logger; impl log::Log for Logger { - fn enabled(&self, metadata: &LogMetadata) -> bool { + fn enabled(&self, metadata: &Metadata) -> bool { metadata.target().contains("frippy") } - fn log(&self, record: &LogRecord) { + fn log(&self, record: &Record) { if self.enabled(record.metadata()) { - if record.metadata().level() >= LogLevel::Debug { + if record.metadata().level() >= Level::Debug { println!("[{}]({}) {} -> {}", time::now().rfc822(), record.level(), @@ -39,21 +37,21 @@ impl log::Log for Logger { } } } + + fn flush(&self) {} } +static LOGGER: Logger = Logger; + fn main() { - let log_level = if cfg!(debug_assertions) { - LogLevelFilter::Debug - } else { - LogLevelFilter::Info - }; + log::set_max_level(if cfg!(debug_assertions) { + LevelFilter::Debug + } else { + LevelFilter::Info + }); - log::set_logger(|max_log_level| { - max_log_level.set(log_level); - Box::new(Logger) - }) - .unwrap(); + log::set_logger(&LOGGER).unwrap(); // Load all toml files in the configs directory let mut configs = Vec::new(); @@ -77,8 +75,7 @@ fn main() { } // Create an event loop to run the connections on. - let mut reactor = Core::new().unwrap(); - let mut futures = Vec::new(); + let mut reactor = IrcReactor::new().unwrap(); // Open a connection and add work for each config for config in configs { @@ -86,7 +83,10 @@ fn main() { let mut disabled_plugins = None; if let &Some(ref options) = &config.options { if let Some(disabled) = options.get("disabled_plugins") { - disabled_plugins = Some(disabled.split(",").map(|p| p.trim()).collect::>()); + disabled_plugins = Some(disabled + .split(",") + .map(|p| p.trim()) + .collect::>()); } } @@ -105,9 +105,9 @@ fn main() { } } - futures.push(bot.connect(&mut reactor, &config)); + bot.connect(&mut reactor, &config).expect("Failed to connect"); } - // Run the bots until they throw an error - reactor.run(future::join_all(futures)).unwrap(); + // Run the bots until they throw an error - an error could be loss of connection + reactor.run().unwrap(); } diff --git a/src/lib.rs b/src/lib.rs index d769075..3e47c8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,24 +6,22 @@ //! //! ## Examples //! ```no_run -//! # extern crate tokio_core; -//! # extern crate futures; +//! # extern crate irc; //! # extern crate frippy; //! # fn main() { //! use frippy::{plugins, Config, Bot}; -//! use tokio_core::reactor::Core; -//! use futures::future; +//! use irc::client::reactor::IrcReactor; //! //! let config = Config::load("config.toml").unwrap(); -//! let mut reactor = Core::new().unwrap(); +//! let mut reactor = IrcReactor::new().unwrap(); //! let mut bot = Bot::new(); //! //! bot.add_plugin(plugins::Help::new()); //! bot.add_plugin(plugins::Emoji::new()); //! bot.add_plugin(plugins::Currency::new()); //! -//! bot.connect(&mut reactor, &config); -//! reactor.run(future::empty::<(), ()>()).unwrap(); +//! bot.connect(&mut reactor, &config).unwrap(); +//! reactor.run().unwrap(); //! # } //! ``` //! @@ -39,8 +37,6 @@ extern crate lazy_static; extern crate frippy_derive; extern crate irc; -extern crate futures; -extern crate tokio_core; pub mod plugin; pub mod plugins; @@ -50,9 +46,8 @@ use std::collections::HashMap; use std::thread::spawn; use std::sync::Arc; -use tokio_core::reactor::Core; pub use irc::client::prelude::*; -pub use irc::error::Error as IrcError; +pub use irc::error::IrcError; use plugin::*; @@ -108,66 +103,57 @@ impl Bot { self.plugins.remove(name) } - /// This connects the `Bot` to IRC and returns a `Future` - /// which represents the bots work. - /// This `Future` will run forever unless it returns an error. + /// This connects the `Bot` to IRC and creates a task on the `IrcReactor` + /// which returns an Ok if the connection was cleanly closed and an Err + /// if the connection was lostwhich returns an Ok if the connection was cleanly closed and an Err + /// if the connection was lost. /// - /// You need to run the `Future`, so that the `Bot` + /// You need to run the `IrcReactor`, so that the `Bot` /// can actually do its work. /// /// # Examples /// ```no_run - /// # extern crate tokio_core; - /// # extern crate futures; + /// # extern crate irc; /// # extern crate frippy; /// # fn main() { /// use frippy::{Config, Bot}; - /// use tokio_core::reactor::Core; - /// use futures::future; + /// use irc::client::reactor::IrcReactor; /// /// let config = Config::load("config.toml").unwrap(); - /// let mut reactor = Core::new().unwrap(); + /// let mut reactor = IrcReactor::new().unwrap(); /// let mut bot = Bot::new(); /// - /// let future = bot.connect(&mut reactor, &config); - /// reactor.run(future).unwrap(); + /// bot.connect(&mut reactor, &config).unwrap(); + /// reactor.run().unwrap(); /// # } /// ``` - pub fn connect(&self, reactor: &mut Core, config: &Config) -> Option>> { + pub fn connect(&self, reactor: &mut IrcReactor, config: &Config) -> Result<(), String> { info!("Plugins loaded: {}", self.plugins); - let server = - match IrcServer::new_future(reactor.handle(), config).and_then(|f| {reactor.run(f)}) { - Ok(v) => v, - Err(e) => { - error!("Failed to connect: {}", e); - return None; - } - }; + let client = match reactor.prepare_client_and_connect(config) { + Ok(v) => v, + Err(e) => return Err(format!("Failed to connect: {}", e)), + }; info!("Connected to server"); - match server.identify() { + match client.identify() { Ok(_) => info!("Identified"), - Err(e) => { - error!("Failed to identify: {}", e); - return None; - } + Err(e) => return Err(format!("Failed to identify: {}", e)), }; // TODO Verify if we actually need to clone plugins twice let plugins = self.plugins.clone(); - let future = server - .stream() - .for_each(move |message| process_msg(&server, plugins.clone(), message)) - .map_err(|e| error!("Failed to process message: {}", e)); + reactor.register_client_with_handler(client, move |client, message| { + process_msg(&client, plugins.clone(), message) + }); - Some(Box::new(future)) + Ok(()) } } -fn process_msg(server: &IrcServer, +fn process_msg(server: &IrcClient, mut plugins: ThreadedPlugins, message: Message) -> Result<(), IrcError> { @@ -215,7 +201,7 @@ impl ThreadedPlugins { self.plugins.remove(&name.to_lowercase()).map(|_| ()) } - pub fn execute_plugins(&mut self, server: &IrcServer, message: Message) { + pub fn execute_plugins(&mut self, server: &IrcClient, message: Message) { let message = Arc::new(message); for (name, plugin) in self.plugins.clone() { @@ -242,7 +228,7 @@ impl ThreadedPlugins { } pub fn handle_command(&mut self, - server: &IrcServer, + server: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { diff --git a/src/plugin.rs b/src/plugin.rs index 63d3530..8785708 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -2,19 +2,19 @@ use std::fmt; use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; /// `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: &IrcServer, message: &Message) -> bool; + fn is_allowed(&self, server: &IrcClient, message: &Message) -> bool; /// Handles messages which are not commands but still necessary. - fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError>; + fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError>; /// Handles any command directed at this plugin. - fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError>; + fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError>; /// Should work like command but return a String instead of sending messages to IRC. - fn evaluate(&self, server: &IrcServer, command: PluginCommand) -> Result; + fn evaluate(&self, server: &IrcClient, command: PluginCommand) -> Result; } /// `PluginName` is required by `Plugin`. diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 4d44d9a..32a2506 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -6,7 +6,7 @@ use std::io::Read; use std::num::ParseFloatError; use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; use self::reqwest::Client; use self::reqwest::header::Connection; @@ -78,7 +78,7 @@ impl Currency { }) } - fn convert(&self, server: &IrcServer, command: &mut PluginCommand) -> Result { + fn convert(&self, server: &IrcClient, command: &mut PluginCommand) -> Result { if command.tokens.len() < 3 { return Err(self.invalid_command(server)); @@ -105,7 +105,7 @@ impl Currency { } } - fn help(&self, server: &IrcServer) -> String { + fn help(&self, server: &IrcClient) -> String { format!("usage: {} currency value from_currency to_currency\r\n\ example: 1.5 eur usd\r\n\ available currencies: AUD, BGN, BRL, CAD, \ @@ -116,7 +116,7 @@ impl Currency { server.current_nickname()) } - fn invalid_command(&self, server: &IrcServer) -> String { + fn invalid_command(&self, server: &IrcClient) -> String { format!("Incorrect Command. \ Send \"{} currency help\" for help.", server.current_nickname()) @@ -124,15 +124,15 @@ impl Currency { } impl Plugin for Currency { - fn is_allowed(&self, _: &IrcServer, _: &Message) -> bool { + fn is_allowed(&self, _: &IrcClient, _: &Message) -> bool { false } - fn execute(&self, _: &IrcServer, _: &Message) -> Result<(), IrcError> { + fn execute(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { panic!("Currency does not implement the execute function!") } - fn command(&self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, server: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { if command.tokens.is_empty() { return server.send_notice(&command.source, &self.invalid_command(server)); @@ -147,7 +147,7 @@ impl Plugin for Currency { } } - fn evaluate(&self, server: &IrcServer, mut command: PluginCommand) -> Result{ + fn evaluate(&self, server: &IrcClient, mut command: PluginCommand) -> Result{ if command.tokens.is_empty() { return Err(self.invalid_command(server)); } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 512a62e..c19593d 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -3,7 +3,7 @@ extern crate unicode_names; use std::fmt; use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; use plugin::*; @@ -97,14 +97,14 @@ impl Emoji { } impl Plugin for Emoji { - fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { match message.command { Command::PRIVMSG(_, _) => true, _ => false, } } - fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { match message.command { Command::PRIVMSG(_, ref content) => { server.send_privmsg(message.response_target().unwrap(), @@ -114,12 +114,12 @@ impl Plugin for Emoji { } } - fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { server.send_notice(&command.source, "This Plugin does not implement any commands.") } - fn evaluate(&self, _: &IrcServer, command: PluginCommand) -> Result { + fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { let emojis = self.emoji(&command.tokens[0]); if emojis.is_empty() { Ok(emojis) diff --git a/src/plugins/help.rs b/src/plugins/help.rs index cea325f..1bb15e1 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -1,5 +1,5 @@ use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; use plugin::*; @@ -13,19 +13,19 @@ impl Help { } impl Plugin for Help { - fn is_allowed(&self, _: &IrcServer, _: &Message) -> bool { + fn is_allowed(&self, _: &IrcClient, _: &Message) -> bool { false } - fn execute(&self, _: &IrcServer, _: &Message) -> Result<(), IrcError> { + fn execute(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { panic!("Help does not implement the execute function!") } - fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { server.send_notice(&command.source, "Help has not been added yet.") } - fn evaluate(&self, _: &IrcServer, _: PluginCommand) -> Result { + fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { Err(String::from("Help has not been added yet.")) } } diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 2970857..4a40e8f 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -1,5 +1,5 @@ use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; use plugin::*; @@ -11,7 +11,7 @@ impl KeepNick { KeepNick {} } - fn check_nick(&self, server: &IrcServer, leaver: &str) -> Result<(), IrcError> { + fn check_nick(&self, server: &IrcClient, leaver: &str) -> Result<(), IrcError> { let cfg_nick = match server.config().nickname { Some(ref nick) => nick.clone(), None => return Ok(()), @@ -34,14 +34,14 @@ impl KeepNick { } impl Plugin for KeepNick { - fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { match message.command { Command::QUIT(_) => true, _ => false, } } - fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { match message.command { Command::QUIT(ref nick) => { self.check_nick(server, &nick.clone().unwrap_or_else(|| String::new())) @@ -50,12 +50,12 @@ impl Plugin for KeepNick { } } - fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { server.send_notice(&command.source, "This Plugin does not implement any commands.") } - fn evaluate(&self, _: &IrcServer, _: PluginCommand) -> Result { + fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { Err(String::from("This Plugin does not implement any commands.")) } } diff --git a/src/plugins/url.rs b/src/plugins/url.rs index ab36833..b980d3e 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -3,7 +3,7 @@ extern crate reqwest; extern crate select; use irc::client::prelude::*; -use irc::error::Error as IrcError; +use irc::error::IrcError; use self::regex::Regex; @@ -126,14 +126,14 @@ impl Url { } impl Plugin for Url { - fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + fn is_allowed(&self, _: &IrcClient, message: &Message) -> bool { match message.command { Command::PRIVMSG(_, ref msg) => RE.is_match(msg), _ => false, } } - fn execute(&self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + fn execute(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError> { match message.command { Command::PRIVMSG(_, ref content) => { match self.url(content) { @@ -145,12 +145,12 @@ impl Plugin for Url { } } - fn command(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { server.send_notice(&command.source, "This Plugin does not implement any commands.") } - fn evaluate(&self, _: &IrcServer, command: PluginCommand) -> Result { + fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { self.url(&command.tokens[0]).map_err(|e| String::from(e)) } } -- cgit v1.2.3-70-g09d2 From 54558758735bb2a5057c67f5296d3ac4be0e56f6 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Feb 2018 15:38:08 +0100 Subject: Update Readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0376967..4caa6e9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ -# frippy -IRC Bot +# frippy [![Build Status](https://travis-ci.org/Mavulp/frippy.svg?branch=master)](https://travis-ci.org/Mavulp/frippy) +Frippy is an IRC bot which sends emojis used to the channel they were received from, +lets you convert from one currency to another and checks the title of html pages +linked in the channel. + +Check the config.toml file to get an idea of of how to set the bot up. -- cgit v1.2.3-70-g09d2 From 2b7c31a05684511918afbe1954fc3a6e282d13f3 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Feb 2018 15:40:14 +0100 Subject: Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4caa6e9..0f76302 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ Frippy is an IRC bot which sends emojis used to the channel they were received f lets you convert from one currency to another and checks the title of html pages linked in the channel. -Check the config.toml file to get an idea of of how to set the bot up. +Check the config.toml file to get an idea of how to set the bot up. -- cgit v1.2.3-70-g09d2 From ddf42bc0292b0befe2b2f47f3284d9ffeaf6f4b4 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Feb 2018 21:00:51 +0100 Subject: Move main file into the src directory --- Cargo.toml | 5 --- bin/main.rs | 113 ------------------------------------------------------------ src/main.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 118 deletions(-) delete mode 100644 bin/main.rs create mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml index bbaa28d..e320c55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,8 @@ keywords = ["irc", "bot"] categories = ["network-programming"] description = "An IRC Bot" -[lib] -name = "frippy" -path = "src/lib.rs" - [[bin]] name = "frippy" -path = "bin/main.rs" doc = false [dependencies] diff --git a/bin/main.rs b/bin/main.rs deleted file mode 100644 index 21e27dc..0000000 --- a/bin/main.rs +++ /dev/null @@ -1,113 +0,0 @@ -extern crate frippy; -extern crate time; -extern crate irc; -extern crate glob; - -#[macro_use] -extern crate log; - -use log::{Record, Level, LevelFilter, Metadata}; - -use irc::client::reactor::IrcReactor; -use glob::glob; - -use frippy::plugins; -use frippy::Config; - -struct Logger; - -impl log::Log for Logger { - fn enabled(&self, metadata: &Metadata) -> bool { - metadata.target().contains("frippy") - } - - fn log(&self, record: &Record) { - if self.enabled(record.metadata()) { - if record.metadata().level() >= Level::Debug { - println!("[{}]({}) {} -> {}", - time::now().rfc822(), - record.level(), - record.target(), - record.args()); - } else { - println!("[{}]({}) {}", - time::now().rfc822(), - record.level(), - record.args()); - } - } - } - - fn flush(&self) {} -} - -static LOGGER: Logger = Logger; - -fn main() { - - log::set_max_level(if cfg!(debug_assertions) { - LevelFilter::Debug - } else { - LevelFilter::Info - }); - - log::set_logger(&LOGGER).unwrap(); - - // Load all toml files in the configs directory - let mut configs = Vec::new(); - for toml in glob("configs/*.toml").unwrap() { - match toml { - Ok(path) => { - info!("Loading {}", path.to_str().unwrap()); - match Config::load(path) { - Ok(v) => configs.push(v), - Err(e) => error!("Incorrect config file {}", e), - } - } - Err(e) => error!("Failed to read path {}", e), - } - } - - // Without configs the bot would just idle - if configs.is_empty() { - error!("No config file found"); - return; - } - - // Create an event loop to run the connections on. - let mut reactor = IrcReactor::new().unwrap(); - - // Open a connection and add work for each config - for config in configs { - - let mut disabled_plugins = None; - if let &Some(ref options) = &config.options { - if let Some(disabled) = options.get("disabled_plugins") { - disabled_plugins = Some(disabled - .split(",") - .map(|p| p.trim()) - .collect::>()); - } - } - - let mut bot = frippy::Bot::new(); - bot.add_plugin(plugins::Help::new()); - bot.add_plugin(plugins::Url::new(1024)); - bot.add_plugin(plugins::Emoji::new()); - bot.add_plugin(plugins::Currency::new()); - bot.add_plugin(plugins::KeepNick::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); - } - } - } - - bot.connect(&mut reactor, &config).expect("Failed to connect"); - } - - // Run the bots until they throw an error - an error could be loss of connection - reactor.run().unwrap(); -} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..21e27dc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,113 @@ +extern crate frippy; +extern crate time; +extern crate irc; +extern crate glob; + +#[macro_use] +extern crate log; + +use log::{Record, Level, LevelFilter, Metadata}; + +use irc::client::reactor::IrcReactor; +use glob::glob; + +use frippy::plugins; +use frippy::Config; + +struct Logger; + +impl log::Log for Logger { + fn enabled(&self, metadata: &Metadata) -> bool { + metadata.target().contains("frippy") + } + + fn log(&self, record: &Record) { + if self.enabled(record.metadata()) { + if record.metadata().level() >= Level::Debug { + println!("[{}]({}) {} -> {}", + time::now().rfc822(), + record.level(), + record.target(), + record.args()); + } else { + println!("[{}]({}) {}", + time::now().rfc822(), + record.level(), + record.args()); + } + } + } + + fn flush(&self) {} +} + +static LOGGER: Logger = Logger; + +fn main() { + + log::set_max_level(if cfg!(debug_assertions) { + LevelFilter::Debug + } else { + LevelFilter::Info + }); + + log::set_logger(&LOGGER).unwrap(); + + // Load all toml files in the configs directory + let mut configs = Vec::new(); + for toml in glob("configs/*.toml").unwrap() { + match toml { + Ok(path) => { + info!("Loading {}", path.to_str().unwrap()); + match Config::load(path) { + Ok(v) => configs.push(v), + Err(e) => error!("Incorrect config file {}", e), + } + } + Err(e) => error!("Failed to read path {}", e), + } + } + + // Without configs the bot would just idle + if configs.is_empty() { + error!("No config file found"); + return; + } + + // Create an event loop to run the connections on. + let mut reactor = IrcReactor::new().unwrap(); + + // Open a connection and add work for each config + for config in configs { + + let mut disabled_plugins = None; + if let &Some(ref options) = &config.options { + if let Some(disabled) = options.get("disabled_plugins") { + disabled_plugins = Some(disabled + .split(",") + .map(|p| p.trim()) + .collect::>()); + } + } + + let mut bot = frippy::Bot::new(); + bot.add_plugin(plugins::Help::new()); + bot.add_plugin(plugins::Url::new(1024)); + bot.add_plugin(plugins::Emoji::new()); + bot.add_plugin(plugins::Currency::new()); + bot.add_plugin(plugins::KeepNick::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); + } + } + } + + bot.connect(&mut reactor, &config).expect("Failed to connect"); + } + + // Run the bots until they throw an error - an error could be loss of connection + reactor.run().unwrap(); +} -- cgit v1.2.3-70-g09d2 From da5c2c8e4893bfb095a8e2122b943c4dca61c41d Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 12 Feb 2018 19:16:59 +0100 Subject: Replace is_allowed with a single-threaded execute function The old execute got renamed to exeute_threaded. --- src/lib.rs | 40 ++++++++++++++++++++++------------------ src/main.rs | 12 ++++++++---- src/plugin.rs | 10 ++++++++-- src/plugins/currency.rs | 43 +++++++++++++++++++++---------------------- src/plugins/emoji.rs | 26 +++++++++++++------------- src/plugins/help.rs | 12 ++++++------ src/plugins/keepnick.rs | 42 +++++++++++++++++++++--------------------- src/plugins/url.rs | 22 +++++++++++++--------- 8 files changed, 112 insertions(+), 95 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3e47c8c..8a3a0d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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::>()); } @@ -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 { - + fn convert(&self, client: &IrcClient, command: &mut PluginCommand) -> Result { 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{ + fn evaluate(&self, client: &IrcClient, mut command: PluginCommand) -> Result{ 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 { 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 { - self.url(&command.tokens[0]).map_err(|e| String::from(e)) + self.url(&command.tokens[0]).map_err(String::from) } } -- cgit v1.2.3-70-g09d2 From d761a8ad9650b4797a673230c2cc924235aafc98 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 12 Feb 2018 20:14:46 +0100 Subject: Improve documentation --- src/lib.rs | 14 ++++++-------- src/plugin.rs | 22 +++++++++++++++------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8a3a0d1..87c06c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ pub struct Bot { impl Bot { /// Creates a `Bot`. - /// By itself the bot only responds to a few simple ctcp commands + /// By itself the bot only responds to a few simple CTCP commands /// defined per config file. /// Any other functionality has to be provided by plugins /// which need to implement [`Plugin`](plugin/trait.Plugin.html). @@ -73,7 +73,7 @@ impl Bot { Bot { plugins: ThreadedPlugins::new() } } - /// Adds the plugin. + /// Adds the [`Plugin`](plugin/trait.Plugin.html). /// These plugins will be used to evaluate incoming messages from IRC. /// /// # Examples @@ -87,7 +87,7 @@ impl Bot { self.plugins.add(plugin); } - /// Removes a plugin based on its name. + /// Removes a [`Plugin`](plugin/trait.Plugin.html) based on its name. /// The binary currently uses this to disable plugins /// based on user configuration. /// @@ -103,12 +103,10 @@ impl Bot { self.plugins.remove(name) } - /// This connects the `Bot` to IRC and creates a task on the `IrcReactor` - /// which returns an Ok if the connection was cleanly closed and an Err - /// if the connection was lostwhich returns an Ok if the connection was cleanly closed and an Err - /// if the connection was lost. + /// This connects the `Bot` to IRC and creates a task on the [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html) + /// which returns an Ok if the connection was cleanly closed and an Err if the connection was lost. /// - /// You need to run the `IrcReactor`, so that the `Bot` + /// You need to run the [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html), so that the `Bot` /// can actually do its work. /// /// # Examples diff --git a/src/plugin.rs b/src/plugin.rs index 88fe3ce..e343a2c 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -4,26 +4,33 @@ use std::fmt; use irc::client::prelude::*; use irc::error::IrcError; +/// Describes if a [`Plugin`](trait.Plugin.html) is done working on a +/// [`Message`](../../irc/proto/message/struct.Message.html) or if another thread is required. +#[derive(Debug)] pub enum ExecutionStatus { + /// The [`Plugin`](trait.Plugin.html) does not need to do any more work on this [`Message`](../../irc/proto/message/struct.Message.html). Done, + /// An error occured during the execution. Err(IrcError), + /// The execution needs to be done by [`execute_threaded()`](trait.Plugin.html#tymethod.execute_threaded). RequiresThread, } /// `Plugin` has to be implemented for any struct that should be usable -/// as a plugin in frippy. +/// 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. + /// Handles messages which are not commands or returns [`RequiresThread`](enum.ExecutionStatus.html#variant.RequiresThread) + /// if [`execute_threaded()`](trait.Plugin.html#tymethod.execute_threaded) should be used instead. fn execute(&self, server: &IrcClient, message: &Message) -> ExecutionStatus; - /// Handles messages which are not commands but still necessary. + /// Handles messages which are not commands in a new thread. 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. + /// Similar to [`command()`](trait.Plugin.html#tymethod.command) but return a String instead of sending messages directly to IRC. fn evaluate(&self, server: &IrcClient, command: PluginCommand) -> Result; } -/// `PluginName` is required by `Plugin`. +/// `PluginName` is required by [`Plugin`](trait.Plugin.html). /// /// To implement it simply add `#[derive(PluginName)]` /// above the definition of the struct. @@ -36,7 +43,7 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { /// struct Foo; /// ``` pub trait PluginName: Send + Sync + fmt::Debug { - /// Returns the name of the plugin. + /// Returns the name of the `Plugin`. fn name(&self) -> &str; } @@ -53,7 +60,8 @@ pub struct PluginCommand { } impl PluginCommand { - /// Creates a `PluginCommand` from `Message` if it is a `PRIVMSG` + /// Creates a `PluginCommand` from [`Message`](../../irc/proto/message/struct.Message.html) + /// if it contains a [`PRIVMSG`](../../irc/proto/command/enum.Command.html#variant.PRIVMSG) /// that starts with the provided `nick`. pub fn from(nick: &str, message: &Message) -> Option { -- cgit v1.2.3-70-g09d2 From 72f1411f1c72a9271c7d3993a3e307050e8d1b31 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 12 Feb 2018 20:31:56 +0100 Subject: Run latest rustfmt --- src/lib.rs | 74 +++++++++++++++++++++++++++---------------------- src/main.rs | 50 ++++++++++++++++----------------- src/plugin.rs | 18 ++++-------- src/plugins/currency.rs | 64 +++++++++++++++++++++++------------------- src/plugins/emoji.rs | 22 +++++++-------- src/plugins/keepnick.rs | 7 +++-- src/plugins/url.rs | 38 +++++++++++-------------- 7 files changed, 137 insertions(+), 136 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 87c06c3..da14277 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] //! Frippy is an IRC bot that runs plugins on each message //! received. @@ -30,11 +30,11 @@ //! which might be of interest. #[macro_use] -extern crate log; +extern crate frippy_derive; #[macro_use] extern crate lazy_static; #[macro_use] -extern crate frippy_derive; +extern crate log; extern crate irc; @@ -70,7 +70,9 @@ impl Bot { /// let mut bot = Bot::new(); /// ``` pub fn new() -> Bot { - Bot { plugins: ThreadedPlugins::new() } + Bot { + plugins: ThreadedPlugins::new(), + } } /// Adds the [`Plugin`](plugin/trait.Plugin.html). @@ -103,10 +105,13 @@ impl Bot { self.plugins.remove(name) } - /// This connects the `Bot` to IRC and creates a task on the [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html) - /// which returns an Ok if the connection was cleanly closed and an Err if the connection was lost. + /// This connects the `Bot` to IRC and creates a task on the + /// [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html) + /// which returns an Ok if the connection was cleanly closed and + /// an Err if the connection was lost. /// - /// You need to run the [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html), so that the `Bot` + /// You need to run the [`IrcReactor`](../irc/client/reactor/struct.IrcReactor.html), + /// so that the `Bot` /// can actually do its work. /// /// # Examples @@ -151,11 +156,11 @@ impl Bot { } } -fn process_msg(server: &IrcClient, - mut plugins: ThreadedPlugins, - message: Message) - -> Result<(), IrcError> { - +fn process_msg( + server: &IrcClient, + mut plugins: ThreadedPlugins, + message: Message, +) -> Result<(), IrcError> { // Log any channels we join if let Command::JOIN(ref channel, _, _) = message.command { if message.source_nickname().unwrap() == server.current_nickname() { @@ -185,7 +190,9 @@ struct ThreadedPlugins { impl ThreadedPlugins { pub fn new() -> ThreadedPlugins { - ThreadedPlugins { plugins: HashMap::new() } + ThreadedPlugins { + plugins: HashMap::new(), + } } pub fn add(&mut self, plugin: T) { @@ -208,10 +215,11 @@ impl ThreadedPlugins { 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", "")); + 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); @@ -229,11 +237,11 @@ impl ThreadedPlugins { } } - pub fn handle_command(&mut self, - server: &IrcClient, - mut command: PluginCommand) - -> Result<(), IrcError> { - + pub fn handle_command( + &mut self, + server: &IrcClient, + mut command: PluginCommand, + ) -> Result<(), IrcError> { if !command.tokens.iter().any(|s| !s.is_empty()) { let help = format!("Use \"{} help\" to get help", server.current_nickname()); return server.send_notice(&command.source, &help); @@ -241,7 +249,6 @@ impl ThreadedPlugins { // Check if the command is for this plugin if let Some(plugin) = self.plugins.get(&command.tokens[0].to_lowercase()) { - // The first token contains the name of the plugin let name = command.tokens.remove(0); @@ -251,18 +258,19 @@ impl ThreadedPlugins { let server = server.clone(); let plugin = Arc::clone(plugin); spawn(move || { - if let Err(e) = plugin.command(&server, command) { - error!("Error in {} command - {}", name, e); - }; - }); + if let Err(e) = plugin.command(&server, command) { + error!("Error in {} command - {}", name, e); + }; + }); Ok(()) - } else { - let help = format!("\"{} {}\" is not a command, \ - try \"{0} help\" instead.", - server.current_nickname(), - command.tokens[0]); + let help = format!( + "\"{} {}\" is not a command, \ + try \"{0} help\" instead.", + server.current_nickname(), + command.tokens[0] + ); server.send_notice(&command.source, &help) } diff --git a/src/main.rs b/src/main.rs index 7df8b3b..9a96791 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,15 @@ -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] extern crate frippy; -extern crate time; -extern crate irc; extern crate glob; +extern crate irc; +extern crate time; #[macro_use] extern crate log; -use log::{Record, Level, LevelFilter, Metadata}; +use log::{Level, LevelFilter, Metadata, Record}; use irc::client::reactor::IrcReactor; use glob::glob; @@ -27,16 +27,20 @@ impl log::Log for Logger { fn log(&self, record: &Record) { if self.enabled(record.metadata()) { if record.metadata().level() >= Level::Debug { - println!("[{}]({}) {} -> {}", - time::now().rfc822(), - record.level(), - record.target(), - record.args()); + println!( + "[{}]({}) {} -> {}", + time::now().rfc822(), + record.level(), + record.target(), + record.args() + ); } else { - println!("[{}]({}) {}", - time::now().rfc822(), - record.level(), - record.args()); + println!( + "[{}]({}) {}", + time::now().rfc822(), + record.level(), + record.args() + ); } } } @@ -47,12 +51,11 @@ impl log::Log for Logger { static LOGGER: Logger = Logger; fn main() { - log::set_max_level(if cfg!(debug_assertions) { - LevelFilter::Debug - } else { - LevelFilter::Info - }); + LevelFilter::Debug + } else { + LevelFilter::Info + }); log::set_logger(&LOGGER).unwrap(); @@ -82,14 +85,10 @@ fn main() { // Open a connection and add work for each config for config in configs { - let mut disabled_plugins = None; if let Some(ref options) = config.options { if let Some(disabled) = options.get("disabled_plugins") { - disabled_plugins = Some(disabled - .split(',') - .map(|p| p.trim()) - .collect::>()); + disabled_plugins = Some(disabled.split(',').map(|p| p.trim()).collect::>()); } } @@ -109,7 +108,8 @@ fn main() { } } - bot.connect(&mut reactor, &config).expect("Failed to connect"); + bot.connect(&mut reactor, &config) + .expect("Failed to connect"); } // Run the bots until they throw an error - an error could be loss of connection diff --git a/src/plugin.rs b/src/plugin.rs index e343a2c..a67d68f 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -30,7 +30,7 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { fn evaluate(&self, server: &IrcClient, command: PluginCommand) -> Result; } -/// `PluginName` is required by [`Plugin`](trait.Plugin.html). +/// `PluginName` is required by [`Plugin`](trait.Plugin.html). /// /// To implement it simply add `#[derive(PluginName)]` /// above the definition of the struct. @@ -64,25 +64,19 @@ impl PluginCommand { /// if it contains a [`PRIVMSG`](../../irc/proto/command/enum.Command.html#variant.PRIVMSG) /// that starts with the provided `nick`. pub fn from(nick: &str, message: &Message) -> Option { - // Get the actual message out of PRIVMSG if let Command::PRIVMSG(_, ref content) = message.command { - // Split content by spaces and filter empty tokens let mut tokens: Vec = content.split(' ').map(ToOwned::to_owned).collect(); // Commands start with our name if tokens[0].to_lowercase().starts_with(nick) { - // Remove the bot's name from the first token tokens[0].drain(..nick.len()); // We assume that only ':' and ',' are used as suffixes on IRC // If there are any other chars we assume that it is not ment for the bot - tokens[0] = tokens[0] - .chars() - .filter(|&c| !":,".contains(c)) - .collect(); + tokens[0] = tokens[0].chars().filter(|&c| !":,".contains(c)).collect(); if !tokens[0].is_empty() { return None; } @@ -91,10 +85,10 @@ impl PluginCommand { tokens.remove(0); Some(PluginCommand { - source: message.source_nickname().unwrap().to_string(), - target: message.response_target().unwrap().to_string(), - tokens: tokens, - }) + source: message.source_nickname().unwrap().to_string(), + target: message.response_target().unwrap().to_string(), + tokens: tokens, + }) } else { None } diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 21330a1..393df9b 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -34,7 +34,6 @@ macro_rules! try_option { impl<'a> ConvertionRequest<'a> { fn send(&self) -> Option { - let response = Client::new() .get("https://api.fixer.io/latest") .form(&[("base", self.source)]) @@ -49,7 +48,6 @@ impl<'a> ConvertionRequest<'a> { 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())); @@ -68,14 +66,15 @@ impl Currency { Currency {} } - fn eval_command<'a>(&self, - tokens: &'a [String]) - -> Result, ParseFloatError> { + fn eval_command<'a>( + &self, + tokens: &'a [String], + ) -> Result, ParseFloatError> { Ok(ConvertionRequest { - value: tokens[0].parse()?, - source: &tokens[1], - target: &tokens[2], - }) + value: tokens[0].parse()?, + source: &tokens[1], + target: &tokens[2], + }) } fn convert(&self, client: &IrcClient, command: &mut PluginCommand) -> Result { @@ -92,33 +91,41 @@ impl Currency { match request.send() { Some(response) => { - let response = format!("{} {} => {:.4} {}", - request.value, - request.source.to_lowercase(), - response / 1.00000000, - request.target.to_lowercase()); + let response = format!( + "{} {} => {:.4} {}", + request.value, + request.source.to_lowercase(), + response / 1.00000000, + request.target.to_lowercase() + ); Ok(response) } - None => Err(String::from("An error occured during the conversion of the given currency")), + None => Err(String::from( + "An error occured during the conversion of the given currency", + )), } } fn help(&self, client: &IrcClient) -> String { - format!("usage: {} currency value from_currency to_currency\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", - client.current_nickname()) + format!( + "usage: {} currency value from_currency to_currency\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", + client.current_nickname() + ) } fn invalid_command(&self, client: &IrcClient) -> String { - format!("Incorrect Command. \ - Send \"{} currency help\" for help.", - client.current_nickname()) + format!( + "Incorrect Command. \ + Send \"{} currency help\" for help.", + client.current_nickname() + ) } } @@ -132,7 +139,6 @@ impl Plugin for Currency { } fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { - if command.tokens.is_empty() { return client.send_notice(&command.source, &self.invalid_command(client)); } @@ -142,11 +148,11 @@ impl Plugin for Currency { _ => 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, client: &IrcClient, mut command: PluginCommand) -> Result{ + fn evaluate(&self, client: &IrcClient, mut command: PluginCommand) -> Result { if command.tokens.is_empty() { return Err(self.invalid_command(client)); } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 02a31f8..fcb04d1 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -14,7 +14,6 @@ struct EmojiHandle { impl fmt::Display for EmojiHandle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let name = match unicode_names::name(self.symbol) { Some(sym) => sym.to_string().to_lowercase(), None => String::from("UNKNOWN"), @@ -52,7 +51,6 @@ impl Emoji { count: 0, }; - for c in string.chars() { if !self.is_emoji(&c) { continue; @@ -60,7 +58,6 @@ impl Emoji { if current.symbol == c { current.count += 1; - } else { if current.count > 0 { emojis.push(current); @@ -99,13 +96,12 @@ impl Emoji { impl Plugin for Emoji { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { - Command::PRIVMSG(_, ref content) => { - match client.send_privmsg(message.response_target().unwrap(), - &self.emoji(content)) { - Ok(_) => ExecutionStatus::Done, - Err(e) => ExecutionStatus::Err(e), - } - } + Command::PRIVMSG(_, ref content) => match client + .send_privmsg(message.response_target().unwrap(), &self.emoji(content)) + { + Ok(_) => ExecutionStatus::Done, + Err(e) => ExecutionStatus::Err(e), + }, _ => ExecutionStatus::Done, } } @@ -115,8 +111,10 @@ impl Plugin for Emoji { } fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - client.send_notice(&command.source, - "This Plugin does not implement any commands.") + client.send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index e973769..73f4893 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -29,7 +29,6 @@ impl KeepNick { Ok(_) => ExecutionStatus::Done, Err(e) => ExecutionStatus::Err(e), } - } else { ExecutionStatus::Done } @@ -51,8 +50,10 @@ impl Plugin for KeepNick { } fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - client.send_notice(&command.source, - "This Plugin does not implement any commands.") + client.send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { diff --git a/src/plugins/url.rs b/src/plugins/url.rs index 9ce5a6a..455aa4e 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -29,7 +29,7 @@ pub struct Url { impl Url { /// If a file is larger than `max_kib` KiB the download is stopped pub fn new(max_kib: usize) -> Url { - Url {max_kib: max_kib} + Url { max_kib: max_kib } } fn grep_url(&self, msg: &str) -> Option { @@ -44,10 +44,7 @@ impl Url { } fn download(&self, url: &str) -> Option { - let response = Client::new() - .get(url) - .header(Connection::close()) - .send(); + let response = Client::new().get(url).header(Connection::close()).send(); match response { Ok(mut response) => { @@ -81,10 +78,12 @@ impl Url { // Check if the file is too large to download if written > self.max_kib * 1024 { - debug!("Stopping download - File from {:?} is larger than {} KiB", url, self.max_kib); + debug!( + "Stopping download - File from {:?} is larger than {} KiB", + url, self.max_kib + ); return None; } - } Some(body) // once told me } @@ -98,15 +97,11 @@ impl Url { fn url(&self, text: &str) -> Result { let url = match self.grep_url(text) { Some(url) => url, - None => { - return Err("No Url was found.") - } + None => return Err("No Url was found."), }; - match self.download(&url) { Some(body) => { - let doc = Document::from(body.as_ref()); if let Some(title) = doc.find(Name("title")).next() { let title = title.children().next().unwrap(); @@ -115,12 +110,11 @@ impl Url { debug!("Text: {:?}", title_text); Ok(title_text) - } else { Err("No title was found.") } } - None => Err("Failed to download document.") + None => Err("Failed to download document."), } } } @@ -139,19 +133,19 @@ impl Plugin for Url { fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), IrcError> { match message.command { - Command::PRIVMSG(_, ref content) => { - match self.url(content) { - Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), - Err(_) => Ok(()), - } - } + Command::PRIVMSG(_, ref content) => match self.url(content) { + Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), + Err(_) => Ok(()), + }, _ => Ok(()), } } fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - client.send_notice(&command.source, - "This Plugin does not implement any commands.") + client.send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { -- cgit v1.2.3-70-g09d2 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/mod.rs | 2 + src/plugins/tell.rs | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 src/plugins/tell.rs diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index e8c4622..834e5b1 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -2,11 +2,13 @@ mod help; mod url; mod emoji; +mod tell; mod currency; mod keepnick; pub use self::help::Help; pub use self::url::Url; pub use self::emoji::Emoji; +pub use self::tell::Tell; pub use self::currency::Currency; pub use self::keepnick::KeepNick; 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(-) 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 048f5f048456b4537b1067273b89d5192c65fb21 Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 15:35:03 +0100 Subject: Add some sandboxing --- src/plugins/factoids/mod.rs | 6 +++--- src/plugins/factoids/sandbox.lua | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index aeb83b0..d67416f 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -201,7 +201,7 @@ impl Factoids { factoid }; - server.send_privmsg(&command.target, &value) + server.send_privmsg(&command.target, &value.replace("\n", "|").replace("\r", "")) } } @@ -221,7 +221,7 @@ impl Factoids { let lua = Lua::new(); let globals = lua.globals(); - globals.set("factoid", lua.load(code, Some(name))?)?; + globals.set("factoid", code)?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; @@ -231,7 +231,7 @@ impl Factoids { lua.exec::<()>(LUA_SANDBOX, Some(name))?; let output: Vec = globals.get::<_, Vec>("output")?; - Ok(output.join("|").replace("\n", "|")) + Ok(output.join("|")) } fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 9b4f52e..4e6b53e 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -1 +1,27 @@ -factoid() +function send(text) + len = #output + if len < 1 then + output = { text } + else + output[len] = output[len] .. text + end +end + +function sendln(text) + sendtoirc(text) + table.insert(output, "") +end + +local env = { print = send, + println = sendln, + args = args, + input = input, + user = user, + channel = channel, + pairs = pairs, + table = table, + string = string, + tostring = tostring, + math = math } + +load(factoid, nil, nil, env)() -- cgit v1.2.3-70-g09d2 From 2c6351d2c8dea5b782b2e6b52b8847426722a60a Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 15:39:05 +0100 Subject: Fix function call in lua --- src/plugins/factoids/sandbox.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 4e6b53e..2fff150 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -8,7 +8,7 @@ function send(text) end function sendln(text) - sendtoirc(text) + send(text) table.insert(output, "") end -- 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(-) 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 From 32e59aa3cc6567b909ab995a4e69beb12bdf0322 Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 21:37:58 +0100 Subject: Add download function & fromurl command --- bin/main.rs | 2 +- src/lib.rs | 1 + src/plugins/factoids/database.rs | 4 +-- src/plugins/factoids/mod.rs | 63 +++++++++++++++++++++++++++++----------- src/plugins/factoids/sandbox.lua | 1 + src/plugins/factoids/utils.rs | 13 +++++++++ src/plugins/url.rs | 61 ++------------------------------------ src/utils.rs | 59 +++++++++++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+), 79 deletions(-) create mode 100644 src/plugins/factoids/utils.rs create mode 100644 src/utils.rs diff --git a/bin/main.rs b/bin/main.rs index 9373afd..fd0b4ab 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -144,7 +144,7 @@ fn main() { 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); + error!("\"{}\" was not found - could not disable", name); } } } diff --git a/src/lib.rs b/src/lib.rs index 8b55dab..186d35c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,7 @@ extern crate time; pub mod plugin; pub mod plugins; +pub mod utils; use std::collections::HashMap; use std::fmt; diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index cb6f422..b612d6f 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -106,7 +106,7 @@ impl Database for MysqlConnection { .execute(self) { Ok(_) => DbResponse::Success, Err(e) => { - error!("DB Insertion Error: {:?}", e); + error!("DB Insertion Error: \"{}\"", e); DbResponse::Failed("Failed to add factoid") } } @@ -131,7 +131,7 @@ impl Database for MysqlConnection { } } Err(e) => { - error!("DB Deletion Error: {:?}", e); + error!("DB Deletion Error: \"{}\"", e); DbResponse::Failed("Failed to delete factoid") } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index d67416f..f857f85 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -14,6 +14,9 @@ use plugin::*; pub mod database; use self::database::{Database, DbResponse}; +mod utils; +use self::utils::download; + static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); #[derive(PluginName)] @@ -35,6 +38,24 @@ impl Factoids { Factoids { factoids: Mutex::new(db) } } + fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, &str> { + let count = try_lock!(self.factoids).count(&name)?; + let tm = time::now().to_timespec(); + + let factoid = database::NewFactoid { + name: name, + idx: count, + content: content, + author: author, + created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), + }; + + match try_lock!(self.factoids).insert(&factoid) { + DbResponse::Success => Ok("Successfully added"), + DbResponse::Failed(e) => Err(e), + } + } + fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { if command.tokens.len() < 2 { return self.invalid_command(server, command); @@ -42,24 +63,27 @@ impl Factoids { let name = command.tokens.remove(0); let content = command.tokens.join(" "); - let count = match try_lock!(self.factoids).count(&name) { - Ok(c) => c, - Err(e) => return server.send_notice(&command.source, e), - }; - let tm = time::now().to_timespec(); + match self.create_factoid(&name, &content, &command.source) { + Ok(v) => server.send_notice(&command.source, v), + Err(e) => server.send_notice(&command.source, e), + } + } - let factoid = database::NewFactoid { - name: &name, - idx: count, - content: &content, - author: &command.source, - created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), - }; + fn from_url(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { + if command.tokens.len() < 2 { + return self.invalid_command(server, command); + } - match try_lock!(self.factoids).insert(&factoid) { - DbResponse::Success => server.send_notice(&command.source, "Successfully added"), - DbResponse::Failed(e) => server.send_notice(&command.source, &e), + let name = command.tokens.remove(0); + let url = &command.tokens[0]; + if let Some(content) = ::utils::download(1024, url) { + match self.create_factoid(&name, &content, &command.source) { + Ok(v) => server.send_notice(&command.source, v), + Err(e) => server.send_notice(&command.source, e), + } + } else { + server.send_notice(&command.source, "Failed to download.") } } @@ -110,7 +134,10 @@ impl Factoids { let factoid = match try_lock!(self.factoids).get(name, idx) { Some(v) => v, - None => return server.send_notice(&command.source, &format!("{}~{} does not exist", name, idx)), + None => { + return server.send_notice(&command.source, + &format!("{}~{} does not exist", name, idx)) + } }; server.send_privmsg(&command.target, @@ -194,7 +221,7 @@ impl Factoids { } else { match self.run_lua(&name, &factoid, &command) { Ok(v) => v, - Err(e) => format!("{}", e), + Err(e) => format!("\"{}\"", e), } } } else { @@ -222,6 +249,7 @@ impl Factoids { let globals = lua.globals(); globals.set("factoid", code)?; + globals.set("download", lua.create_function(download))?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; @@ -274,6 +302,7 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); match sub_command.as_ref() { "add" => self.add(server, &mut command), + "fromurl" => self.from_url(server, &mut command), "remove" => self.remove(server, &mut command), "get" => self.get(server, &command), "info" => self.info(server, &command), diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 2fff150..282a903 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -18,6 +18,7 @@ local env = { print = send, input = input, user = user, channel = channel, + request = download, pairs = pairs, table = table, string = string, diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs new file mode 100644 index 0000000..ad25eef --- /dev/null +++ b/src/plugins/factoids/utils.rs @@ -0,0 +1,13 @@ +extern crate reqwest; + +use utils; +use super::rlua::prelude::*; + +use self::LuaError::RuntimeError; + +pub fn download(_: &Lua, url: String) -> Result { + match utils::download(1024, &url) { + Some(v) => Ok(v), + None => Err(RuntimeError(format!("Failed to download {}", url))), + } +} diff --git a/src/plugins/url.rs b/src/plugins/url.rs index f6e06f3..6f4a68f 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -1,5 +1,4 @@ extern crate regex; -extern crate reqwest; extern crate select; use irc::client::prelude::*; @@ -7,15 +6,11 @@ use irc::error::Error as IrcError; use self::regex::Regex; -use std::str; -use std::io::{self, Read}; -use self::reqwest::Client; -use self::reqwest::header::Connection; - use self::select::document::Document; use self::select::predicate::Name; use plugin::*; +use utils; lazy_static! { static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap(); @@ -43,58 +38,6 @@ impl Url { } } - fn download(&self, url: &str) -> Option { - let response = Client::new() - .get(url) - .header(Connection::close()) - .send(); - - match response { - Ok(mut response) => { - let mut body = String::new(); - - // 500 kilobyte buffer - let mut buf = [0; 500 * 1000]; - let mut written = 0; - // Read until we reach EOF or max_kib KiB - loop { - let len = match response.read(&mut buf) { - Ok(0) => break, - Ok(len) => len, - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, - Err(e) => { - debug!("Download from {:?} failed: {}", url, e); - return None; - } - }; - - let slice = match str::from_utf8(&buf[..len]) { - Ok(slice) => slice, - Err(e) => { - debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); - return None; - } - }; - - body.push_str(slice); - written += len; - - // Check if the file is too large to download - if written > self.max_kib * 1024 { - debug!("Stopping download - File from {:?} is larger than {} KiB", url, self.max_kib); - return None; - } - - } - Some(body) // once told me - } - Err(e) => { - debug!("Bad response from {:?}: ({})", url, e); - return None; - } - } - } - fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { let url = match self.grep_url(message) { Some(url) => url, @@ -104,7 +47,7 @@ impl Url { }; - match self.download(&url) { + match utils::download(self.max_kib, &url) { Some(body) => { let doc = Document::from(body.as_ref()); diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..59a5a54 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,59 @@ +extern crate reqwest; + +use std::str; +use std::io::{self, Read}; + +use self::reqwest::Client; +use self::reqwest::header::Connection; + +pub fn download(max_kib: usize, url: &str) -> Option { + let response = Client::new() + .get(url) + .header(Connection::close()) + .send(); + + match response { + Ok(mut response) => { + let mut body = String::new(); + + // 500 kilobyte buffer + let mut buf = [0; 500 * 1000]; + let mut written = 0; + // Read until we reach EOF or max_kib KiB + loop { + let len = match response.read(&mut buf) { + Ok(0) => break, + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => { + debug!("Download from {:?} failed: {}", url, e); + return None; + } + }; + + let slice = match str::from_utf8(&buf[..len]) { + Ok(slice) => slice, + Err(e) => { + debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); + return None; + } + }; + + body.push_str(slice); + written += len; + + // Check if the file is too large to download + if written > max_kib * 1024 { + debug!("Stopping download - File from {:?} is larger than {} KiB", url, max_kib); + return None; + } + + } + Some(body) + } + Err(e) => { + debug!("Bad response from {:?}: ({})", url, e); + return None; + } + } +} -- cgit v1.2.3-70-g09d2 From 0892425bf833c03765e2edba8d6fdb338ae68ed5 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 17 Feb 2018 23:24:13 +0100 Subject: Improve startup logs --- bin/main.rs | 5 ++++- src/lib.rs | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/main.rs b/bin/main.rs index fd0b4ab..88f3809 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -119,7 +119,10 @@ fn main() { match diesel::mysql::MysqlConnection::establish(url) { Ok(conn) => { match embedded_migrations::run(&conn) { - Ok(_) => bot.add_plugin(plugins::Factoids::new(conn)), + Ok(_) => { + bot.add_plugin(plugins::Factoids::new(conn)); + info!("Connected to MySQL server") + } Err(e) => { bot.add_plugin(plugins::Factoids::new(HashMap::new())); error!("Failed to run migrations: {}", e); diff --git a/src/lib.rs b/src/lib.rs index 186d35c..54c672e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -147,12 +147,12 @@ impl Bot { match IrcServer::new_future(reactor.handle(), config).and_then(|f| {reactor.run(f)}) { Ok(v) => v, Err(e) => { - error!("Failed to connect: {}", e); + error!("Failed to connect to IRC server: {}", e); return; } }; - info!("Connected to server"); + info!("Connected to IRC server"); match server.identify() { Ok(_) => info!("Identified"), -- cgit v1.2.3-70-g09d2 From 806614b5bf00581c9a564fcda4ecb760b6d27c6a Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 17 Feb 2018 23:25:38 +0100 Subject: Improve factoid error handling --- src/plugins/factoids/mod.rs | 6 ++++-- src/plugins/factoids/sandbox.lua | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index f857f85..252ba83 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -140,8 +140,10 @@ impl Factoids { } }; + let message = factoid.content.replace("\n", "|").replace("\r", ""); + server.send_privmsg(&command.target, - &format!("{}: {}", factoid.name, factoid.content)) + &format!("{}: {}", factoid.name, message)) } fn info(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { @@ -156,7 +158,7 @@ impl Factoids { }; match count { - 0 => server.send_privmsg(&command.target, &format!("{} does not exist", name)), + 0 => server.send_notice(&command.source, &format!("{} does not exist", name)), 1 => { server.send_privmsg(&command.target, &format!("There is 1 version of {}", name)) diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 282a903..8ebf518 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -1,5 +1,6 @@ function send(text) - len = #output + local text = tostring(text) + local len = #output if len < 1 then output = { text } else @@ -25,4 +26,9 @@ local env = { print = send, tostring = tostring, math = math } -load(factoid, nil, nil, env)() +local f, e = load(factoid, nil, nil, env) +if f then + f() +else + error(e) +end -- cgit v1.2.3-70-g09d2 From 297ceaa0899a6228f47f1f14e4bd261ec4cc6619 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 23 Feb 2018 18:29:20 +0100 Subject: Add possibly unsafe timeout hook to factoids --- Cargo.lock | 38 +++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- src/plugins/factoids/mod.rs | 9 +++++---- src/plugins/factoids/sandbox.lua | 17 +++++++++++++++++ src/plugins/factoids/utils.rs | 8 ++++++++ 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b471e8..118e68f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,6 +341,25 @@ dependencies = [ "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "failure" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "foreign-types" version = "0.3.2" @@ -372,7 +391,7 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -952,9 +971,10 @@ dependencies = [ [[package]] name = "rlua" -version = "0.9.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1158,6 +1178,15 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "take" version = "0.1.0" @@ -1451,6 +1480,8 @@ dependencies = [ "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" @@ -1517,7 +1548,7 @@ dependencies = [ "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3161ca63fd11ce36c7718af239e6492a25a3dbfcec54240f959b9d816cf42413" -"checksum rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7eec2f28b4812553f10b2e69888a5a674b2e761f5a39731c14541c32bdb6d8" +"checksum rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6a9d2d1da31dd5cb4878789b924e46a600bdca4895b30f2efd6370d0dfc80e" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" @@ -1543,6 +1574,7 @@ dependencies = [ "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" diff --git a/Cargo.toml b/Cargo.toml index 1775455..aadd44c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ tokio-core = "0.1.10" futures = "0.1.16" log = "0.3.8" time = "0.1" -rlua = "0.9.3" +rlua = "0.12.2" reqwest = "0.8.0" select = "0.4.2" regex = "0.2.2" diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 252ba83..08e8f12 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -15,7 +15,7 @@ pub mod database; use self::database::{Database, DbResponse}; mod utils; -use self::utils::download; +use self::utils::*; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); @@ -247,16 +247,17 @@ impl Factoids { .map(ToOwned::to_owned) .collect::>(); - let lua = Lua::new(); + let lua = unsafe { Lua::new_with_debug() }; let globals = lua.globals(); globals.set("factoid", code)?; - globals.set("download", lua.create_function(download))?; + globals.set("download", lua.create_function(download)?)?; + globals.set("sleep", lua.create_function(sleep)?)?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; globals.set("channel", command.target.clone())?; - globals.set("output", lua.create_table())?; + globals.set("output", lua.create_table()?)?; lua.exec::<()>(LUA_SANDBOX, Some(name))?; let output: Vec = globals.get::<_, Vec>("output")?; diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 8ebf518..3fde65e 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -24,9 +24,26 @@ local env = { print = send, table = table, string = string, tostring = tostring, + tonumber = tonumber, math = math } local f, e = load(factoid, nil, nil, env) + +-- Check if the factoid timed out +function checktime(event, line) + if os.time() - time >= timeout then + error("Timed out after " .. timeout .. " seconds", 0) + else + -- Limit the cpu usage of factoids + sleep(1) + end +end + +-- Add timeout hook +time = os.time() +timeout = 30 +debug.sethook(checktime, "l") + if f then f() else diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs index ad25eef..fc86fb3 100644 --- a/src/plugins/factoids/utils.rs +++ b/src/plugins/factoids/utils.rs @@ -1,5 +1,8 @@ extern crate reqwest; +use std::thread; +use std::time::Duration; + use utils; use super::rlua::prelude::*; @@ -11,3 +14,8 @@ pub fn download(_: &Lua, url: String) -> Result { None => Err(RuntimeError(format!("Failed to download {}", url))), } } + +pub fn sleep(_: &Lua, dur: u64) -> Result<(), LuaError> { + thread::sleep(Duration::from_millis(dur)); + Ok(()) +} -- cgit v1.2.3-70-g09d2 From 5e309d4d58735e2ccc34542564265ace3cf1856e Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 15:06:43 +0100 Subject: Log all database errors --- src/plugins/factoids/database.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index b612d6f..53efe6a 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -106,14 +106,20 @@ impl Database for MysqlConnection { .execute(self) { Ok(_) => DbResponse::Success, Err(e) => { - error!("DB Insertion Error: \"{}\"", e); + error!("DB Insertion Error: {}", e); DbResponse::Failed("Failed to add factoid") } } } fn get(&self, name: &str, idx: i32) -> Option { - factoids::table.find((name, idx)).first(self).ok() + match factoids::table.find((name, idx)).first(self) { + Ok(f) => Ok(f), + Err(e) => { + error!("DB Count Error: {}", e); + None + }, + } } fn delete(&mut self, name: &str, idx: i32) -> DbResponse { @@ -131,7 +137,7 @@ impl Database for MysqlConnection { } } Err(e) => { - error!("DB Deletion Error: \"{}\"", e); + error!("DB Deletion Error: {}", e); DbResponse::Failed("Failed to delete factoid") } } @@ -145,7 +151,10 @@ impl Database for MysqlConnection { match count { Ok(c) => Ok(c as i32), - Err(_) => Err("Database Error"), + Err(e) => { + error!("DB Count Error: {}", e); + Err("Database Error") + }, } } } -- cgit v1.2.3-70-g09d2 From 4e6c31fada410d6a156970a99c31760633d1b544 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 15:10:54 +0100 Subject: Use correct return type --- src/plugins/factoids/database.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 53efe6a..cb5ef29 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -114,7 +114,7 @@ impl Database for MysqlConnection { fn get(&self, name: &str, idx: i32) -> Option { match factoids::table.find((name, idx)).first(self) { - Ok(f) => Ok(f), + Ok(f) => Some(f), Err(e) => { error!("DB Count Error: {}", e); None -- cgit v1.2.3-70-g09d2 From 288eadd3c42352deba28cfe062e79e673cb5d577 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 15:35:37 +0100 Subject: Update dependencies --- Cargo.lock | 31 +++++++++++++++++++++++++++++-- Cargo.toml | 14 +++++++------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09eb74a..e2a0350 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,6 +189,15 @@ dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "derive-error-chain" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diesel" version = "1.1.1" @@ -237,6 +246,16 @@ dependencies = [ "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dotenv" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive-error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -316,6 +335,11 @@ dependencies = [ name = "error-chain" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "error-chain" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -361,11 +385,11 @@ dependencies = [ "diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_infer_schema 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "irc 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1481,11 +1505,13 @@ dependencies = [ "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" +"checksum derive-error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92183014af72c63aea490e66526c712bf1066ac50f66c9f34824f02483ec1d98" "checksum diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925325c57038f2f14c0413bdf6a92ca72acff644959d0a1a9ebf8d19be7e9c01" "checksum diesel_derives 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28e2b2605ac6a3b9a586383f5f8b2b5f1108f07a421ade965b266289d2805e79" "checksum diesel_infer_schema 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd41decf55679a8486a3ea5e5de20e8f2a48c76d57177cd05f37f4d166f48647" "checksum diesel_migrations 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0928a7d6f27c849954185416bd59439837de55fbc89e2985b0e46e756ae4e3da" "checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3" +"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" @@ -1497,6 +1523,7 @@ dependencies = [ "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" diff --git a/Cargo.toml b/Cargo.toml index 44f70d7..bc49f61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,14 +17,14 @@ doc = false mysql = ["diesel", "diesel_infer_schema", "diesel_migrations", "dotenv"] [dependencies] -irc = "0.13.2" +irc = "0.13.4" log = "0.4.1" time = "0.1.39" rlua = "0.12.2" -reqwest = "0.8.4" +reqwest = "0.8.5" select = "0.4.2" regex = "0.2.6" -lazy_static = "0.2.9" +lazy_static = "1.0.0" serde = "1.0.27" serde_json = "1.0.9" chrono = "0.4.0" @@ -38,22 +38,22 @@ branch = 'update-to-latest-unicode' [dependencies.diesel] -version = "1.0.0-rc1" +version = "1.1.1" optional = true features = ["mysql", "chrono"] [dependencies.diesel_infer_schema] -version = "1.0.0-rc1" +version = "1.1.0" optional = true features = ["mysql"] [dependencies.diesel_migrations] -version = "1.0.0-rc1" +version = "1.1.0" optional = true features = ["mysql"] [dependencies.dotenv] -version = "0.10.1" +version = "0.11.0" optional = true [dependencies.clippy] -- cgit v1.2.3-70-g09d2 From db0f14a163a087261db7360a90d6ac70fb92e884 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 17:18:09 +0100 Subject: Use r2d2 as a ConnectionPool for diesel --- Cargo.lock | 38 +++++++++++++++++++++++++++++++++ Cargo.toml | 17 ++++++++++++++- src/lib.rs | 4 ++++ src/main.rs | 19 +++++++++++------ src/plugins/factoids/database.rs | 46 ++++++++++++++++++++++++---------------- src/plugins/factoids/mod.rs | 20 ++++++++--------- 6 files changed, 109 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2a0350..d36e32e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,11 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "antidote" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" version = "0.3.5" @@ -391,6 +396,8 @@ dependencies = [ "irc 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -927,6 +934,25 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "r2d2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "r2d2-diesel" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.22" @@ -1044,6 +1070,14 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scoped-tls" version = "0.1.0" @@ -1483,6 +1517,7 @@ dependencies = [ [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" @@ -1588,6 +1623,8 @@ dependencies = [ "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" +"checksum r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9c29bad92da76d02bc2c020452ebc3a3fe6fa74cfab91e711c43116e4fb1a3" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" @@ -1601,6 +1638,7 @@ dependencies = [ "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" +"checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" diff --git a/Cargo.toml b/Cargo.toml index bc49f61..7b7c6f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,14 @@ name = "frippy" doc = false [features] -mysql = ["diesel", "diesel_infer_schema", "diesel_migrations", "dotenv"] +mysql = [ + "diesel", + "diesel_infer_schema", + "diesel_migrations", + "dotenv", + "r2d2", + "r2d2-diesel" +] [dependencies] irc = "0.13.4" @@ -52,6 +59,14 @@ version = "1.1.0" optional = true features = ["mysql"] +[dependencies.r2d2] +version = "0.8.2" +optional = true + +[dependencies.r2d2-diesel] +version = "1.0.0" +optional = true + [dependencies.dotenv] version = "0.11.0" optional = true diff --git a/src/lib.rs b/src/lib.rs index bd2e302..aeead16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,10 @@ #[cfg(feature = "mysql")] #[macro_use] extern crate diesel; +#[cfg(feature = "mysql")] +extern crate r2d2; +#[cfg(feature = "mysql")] +extern crate r2d2_diesel; #[macro_use] extern crate frippy_derive; diff --git a/src/main.rs b/src/main.rs index cb4e384..6605693 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,10 @@ extern crate time; extern crate diesel_migrations; #[cfg(feature = "mysql")] extern crate diesel; +#[cfg(feature = "mysql")] +extern crate r2d2; +#[cfg(feature = "mysql")] +extern crate r2d2_diesel; #[macro_use] extern crate log; @@ -119,13 +123,16 @@ fn main() { #[cfg(feature = "mysql")] { if let Some(url) = mysql_url { - use diesel; - use diesel::Connection; - match diesel::mysql::MysqlConnection::establish(url) { - Ok(conn) => { - match embedded_migrations::run(&conn) { + use diesel::MysqlConnection; + use r2d2; + use r2d2_diesel::ConnectionManager; + + let manager = ConnectionManager::::new(url.clone()); + match r2d2::Pool::builder().build(manager) { + Ok(pool) => { + match embedded_migrations::run(&*pool.get().expect("Failed to get connection")) { Ok(_) => { - bot.add_plugin(plugins::Factoids::new(conn)); + bot.add_plugin(plugins::Factoids::new(pool)); info!("Connected to MySQL server") } Err(e) => { diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index cb5ef29..f003419 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -5,9 +5,12 @@ use std::collections::HashMap; #[cfg(feature = "mysql")] use diesel::prelude::*; - #[cfg(feature = "mysql")] use diesel::mysql::MysqlConnection; +#[cfg(feature = "mysql")] +use r2d2::Pool; +#[cfg(feature = "mysql")] +use r2d2_diesel::ConnectionManager; use chrono::NaiveDateTime; @@ -40,15 +43,15 @@ pub struct NewFactoid<'a> { pub trait Database: Send { - fn insert(&mut self, factoid: &NewFactoid) -> DbResponse; - fn get(&self, name: &str, idx: i32) -> Option; - fn delete(&mut self, name: &str, idx: i32) -> DbResponse; - fn count(&self, name: &str) -> Result; + fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse; + fn get_factoid(&self, name: &str, idx: i32) -> Option; + fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse; + fn count_factoids(&self, name: &str) -> Result; } // HashMap impl Database for HashMap<(String, i32), Factoid> { - fn insert(&mut self, factoid: &NewFactoid) -> DbResponse { + fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse { let factoid = Factoid { name: String::from(factoid.name), idx: factoid.idx, @@ -64,18 +67,18 @@ impl Database for HashMap<(String, i32), Factoid> { } } - fn get(&self, name: &str, idx: i32) -> Option { + fn get_factoid(&self, name: &str, idx: i32) -> Option { self.get(&(String::from(name), idx)).map(|f| f.clone()) } - fn delete(&mut self, name: &str, idx: i32) -> DbResponse { + fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse { match self.remove(&(String::from(name), idx)) { Some(_) => DbResponse::Success, None => DbResponse::Failed("Factoid not found"), } } - fn count(&self, name: &str) -> Result { + fn count_factoids(&self, name: &str) -> Result { Ok(self.iter() .filter(|&(&(ref n, _), _)| n == name) .count() as i32) @@ -98,12 +101,14 @@ mod mysql { } #[cfg(feature = "mysql")] -impl Database for MysqlConnection { - fn insert(&mut self, factoid: &NewFactoid) -> DbResponse { +impl Database for Pool> { + fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse { use diesel; + + let conn = &*self.get().expect("Failed to get connection"); match diesel::insert_into(factoids::table) .values(factoid) - .execute(self) { + .execute(conn) { Ok(_) => DbResponse::Success, Err(e) => { error!("DB Insertion Error: {}", e); @@ -112,8 +117,9 @@ impl Database for MysqlConnection { } } - fn get(&self, name: &str, idx: i32) -> Option { - match factoids::table.find((name, idx)).first(self) { + fn get_factoid(&self, name: &str, idx: i32) -> Option { + let conn = &*self.get().expect("Failed to get connection"); + match factoids::table.find((name, idx)).first(conn) { Ok(f) => Some(f), Err(e) => { error!("DB Count Error: {}", e); @@ -122,13 +128,15 @@ impl Database for MysqlConnection { } } - fn delete(&mut self, name: &str, idx: i32) -> DbResponse { + fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse { use diesel; use self::factoids::columns; + + let conn = &*self.get().expect("Failed to get connection"); match diesel::delete(factoids::table .filter(columns::name.eq(name)) .filter(columns::idx.eq(idx))) - .execute(self) { + .execute(conn) { Ok(v) => { if v > 0 { DbResponse::Success @@ -143,11 +151,13 @@ impl Database for MysqlConnection { } } - fn count(&self, name: &str) -> Result { + fn count_factoids(&self, name: &str) -> Result { + + let conn = &*self.get().expect("Failed to get connection"); let count: Result = factoids::table .filter(factoids::columns::name.eq(name)) .count() - .first(self); + .first(conn); match count { Ok(c) => Ok(c as i32), diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 49ace10..b662d22 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -39,7 +39,7 @@ impl Factoids { } fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, &str> { - let count = try_lock!(self.factoids).count(&name)?; + let count = try_lock!(self.factoids).count_factoids(&name)?; let tm = time::now().to_timespec(); let factoid = database::NewFactoid { @@ -50,7 +50,7 @@ impl Factoids { created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), }; - match try_lock!(self.factoids).insert(&factoid) { + match try_lock!(self.factoids).insert_factoid(&factoid) { DbResponse::Success => Ok("Successfully added"), DbResponse::Failed(e) => Err(e), } @@ -93,12 +93,12 @@ impl Factoids { } let name = command.tokens.remove(0); - let count = match try_lock!(self.factoids).count(&name) { + let count = match try_lock!(self.factoids).count_factoids(&name) { Ok(c) => c, Err(e) => return client.send_notice(&command.source, e), }; - match try_lock!(self.factoids).delete(&name, count - 1) { + match try_lock!(self.factoids).delete_factoid(&name, count - 1) { DbResponse::Success => client.send_notice(&command.source, "Successfully removed"), DbResponse::Failed(e) => client.send_notice(&command.source, &e), } @@ -110,7 +110,7 @@ impl Factoids { 0 => return self.invalid_command(client, command), 1 => { let name = &command.tokens[0]; - let count = match try_lock!(self.factoids).count(name) { + let count = match try_lock!(self.factoids).count_factoids(name) { Ok(c) => c, Err(e) => return client.send_notice(&command.source, e), }; @@ -132,7 +132,7 @@ impl Factoids { } }; - let factoid = match try_lock!(self.factoids).get(name, idx) { + let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, None => { return client.send_notice(&command.source, @@ -152,7 +152,7 @@ impl Factoids { 0 => self.invalid_command(client, command), 1 => { let name = &command.tokens[0]; - let count = match try_lock!(self.factoids).count(name) { + let count = match try_lock!(self.factoids).count_factoids(name) { Ok(c) => c, Err(e) => return client.send_notice(&command.source, e), }; @@ -176,7 +176,7 @@ impl Factoids { Err(_) => return client.send_notice(&command.source, "Invalid index"), }; - let factoid = match try_lock!(self.factoids).get(name, idx) { + let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, None => { return client.send_notice(&command.source, @@ -204,12 +204,12 @@ impl Factoids { } else { let name = command.tokens.remove(0); - let count = match try_lock!(self.factoids).count(&name) { + let count = match try_lock!(self.factoids).count_factoids(&name) { Ok(c) => c, Err(e) => return client.send_notice(&command.source, e), }; - let factoid = match try_lock!(self.factoids).get(&name, count - 1) { + let factoid = match try_lock!(self.factoids).get_factoid(&name, count - 1) { Some(v) => v.content, None if error => return self.invalid_command(client, &command), None => return Ok(()), -- cgit v1.2.3-70-g09d2 From 886bd6d4d77a941946bec0d7f8b5c422d206feea Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 18:49:57 +0100 Subject: Extend Lua sandbox --- src/plugins/factoids/sandbox.lua | 52 ++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 3fde65e..31ef5cb 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -13,21 +13,43 @@ function sendln(text) table.insert(output, "") end -local env = { print = send, - println = sendln, - args = args, - input = input, - user = user, - channel = channel, - request = download, - pairs = pairs, - table = table, - string = string, - tostring = tostring, - tonumber = tonumber, - math = math } - -local f, e = load(factoid, nil, nil, env) +local sandbox_env = { + print = send, + println = sendln, + args = args, + input = input, + user = user, + channel = channel, + request = download, + string = string, + math = math, + table = table, + pairs = pairs, + ipairs = ipairs, + next = next, + select = select, + unpack = unpack, + tostring = tostring, + tonumber = tonumber, + type = type, + assert = assert, + error = error, + pcall = pcall, + xpcall = xpcall, + _VERSION = _VERSION +} + +sandbox_env.os = { + clock = os.clock, + time = os.time, + difftime = os.difftime +} + +sandbox_env.string.rep = nil +sandbox_env.string.dump = nil +sandbox_env.math.randomseed = nil + +local f, e = load(factoid, nil, nil, sandbox_env) -- Check if the factoid timed out function checktime(event, line) -- cgit v1.2.3-70-g09d2 From f24da1f5090d71a4963e05c5a76dad2eccac15bd Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 19:26:26 +0100 Subject: Add temporary eval function to factoids --- src/plugins/factoids/sandbox.lua | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 31ef5cb..3fc74cd 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -16,6 +16,7 @@ end local sandbox_env = { print = send, println = sendln, + eval = nil, args = args, input = input, user = user, @@ -49,18 +50,30 @@ sandbox_env.string.rep = nil sandbox_env.string.dump = nil sandbox_env.math.randomseed = nil -local f, e = load(factoid, nil, nil, sandbox_env) +-- Temporary evaluation function +function eval(code) + local c, e = load(code, nil, nil, sandbox_env) + if c then + return c() + else + error(e) + end +end + +sandbox_env.eval = eval -- Check if the factoid timed out function checktime(event, line) - if os.time() - time >= timeout then - error("Timed out after " .. timeout .. " seconds", 0) - else - -- Limit the cpu usage of factoids - sleep(1) - end + if os.time() - time >= timeout then + error("Timed out after " .. timeout .. " seconds", 0) + else + -- Limit the cpu usage of factoids + sleep(1) + end end +local f, e = load(factoid, nil, nil, sandbox_env) + -- Add timeout hook time = os.time() timeout = 30 -- cgit v1.2.3-70-g09d2 From ce2db228aac1c0114bcac30bb6c01212faca025a Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 20:13:32 +0100 Subject: Run rustfmt and clippy --- Cargo.lock | 6 +- src/lib.rs | 2 +- src/main.rs | 34 +++++------- src/plugin.rs | 2 +- src/plugins/emoji.rs | 2 +- src/plugins/factoids/database.rs | 31 +++++------ src/plugins/factoids/mod.rs | 117 ++++++++++++++++++++------------------- src/plugins/keepnick.rs | 2 +- src/plugins/tell.rs | 11 ++-- src/plugins/url.rs | 1 - src/utils.rs | 13 ++--- 11 files changed, 111 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d36e32e..92cf4ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "mime_guess" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1024,7 +1024,7 @@ dependencies = [ "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1599,7 +1599,7 @@ dependencies = [ "checksum migrations_internals 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd916de6df9ac7e811e7e1ac28e0abfebe5205f3b29a7bda9ec8a41ee980a4eb" "checksum migrations_macros 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a550cfd76f6cfdf15a7b541893d7c79b68277b0b309f12179211a373a56e617" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" -"checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" +"checksum mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130ea3c9c1b65dba905ab5a4d9ac59234a9585c24d135f264e187fe7336febbd" "checksum mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7da01a5e23070d92d99b1ecd1cd0af36447c6fd44b0fe283c2db199fa136724f" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "879ce08e38739c54d87b7f8332a476004fe2a095f40a142a36f889779d9942b7" diff --git a/src/lib.rs b/src/lib.rs index aeead16..cc6e921 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,8 +44,8 @@ extern crate lazy_static; #[macro_use] extern crate log; -extern crate irc; extern crate chrono; +extern crate irc; extern crate time; pub mod plugin; diff --git a/src/main.rs b/src/main.rs index 6605693..511fe09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,12 +6,12 @@ extern crate glob; extern crate irc; extern crate time; +#[cfg(feature = "mysql")] +extern crate diesel; #[cfg(feature = "mysql")] #[macro_use] extern crate diesel_migrations; #[cfg(feature = "mysql")] -extern crate diesel; -#[cfg(feature = "mysql")] extern crate r2d2; #[cfg(feature = "mysql")] extern crate r2d2_diesel; @@ -103,10 +103,7 @@ fn main() { let mut mysql_url = None; if let Some(ref options) = config.options { if let Some(disabled) = options.get("disabled_plugins") { - disabled_plugins = Some(disabled - .split(",") - .map(|p| p.trim()) - .collect::>()); + disabled_plugins = Some(disabled.split(',').map(|p| p.trim()).collect::>()); } mysql_url = options.get("mysql_url"); @@ -129,18 +126,18 @@ fn main() { let manager = ConnectionManager::::new(url.clone()); match r2d2::Pool::builder().build(manager) { - Ok(pool) => { - match embedded_migrations::run(&*pool.get().expect("Failed to get connection")) { - Ok(_) => { - bot.add_plugin(plugins::Factoids::new(pool)); - info!("Connected to MySQL server") - } - Err(e) => { - bot.add_plugin(plugins::Factoids::new(HashMap::new())); - error!("Failed to run migrations: {}", e); - } + Ok(pool) => match embedded_migrations::run(&*pool.get() + .expect("Failed to get connection")) + { + Ok(_) => { + bot.add_plugin(plugins::Factoids::new(pool)); + info!("Connected to MySQL server") + } + Err(e) => { + bot.add_plugin(plugins::Factoids::new(HashMap::new())); + error!("Failed to run migrations: {}", e); } - } + }, Err(e) => error!("Failed to connect to database: {}", e), } } else { @@ -149,13 +146,12 @@ fn main() { } #[cfg(not(feature = "mysql"))] { - if let Some(_) = mysql_url { + if mysql_url.is_some() { error!("frippy was not built with the mysql feature") } bot.add_plugin(plugins::Factoids::new(HashMap::new())); } - if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { if bot.remove_plugin(name).is_none() { diff --git a/src/plugin.rs b/src/plugin.rs index a67d68f..f33fa80 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -11,7 +11,7 @@ pub enum ExecutionStatus { /// The [`Plugin`](trait.Plugin.html) does not need to do any more work on this [`Message`](../../irc/proto/message/struct.Message.html). Done, /// An error occured during the execution. - Err(IrcError), + Err(Box), /// The execution needs to be done by [`execute_threaded()`](trait.Plugin.html#tymethod.execute_threaded). RequiresThread, } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index fcb04d1..a4276f4 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -100,7 +100,7 @@ impl Plugin for Emoji { .send_privmsg(message.response_target().unwrap(), &self.emoji(content)) { Ok(_) => ExecutionStatus::Done, - Err(e) => ExecutionStatus::Err(e), + Err(e) => ExecutionStatus::Err(Box::new(e)), }, _ => ExecutionStatus::Done, } diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index f003419..ccebfee 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -32,7 +32,7 @@ pub struct Factoid { #[cfg(feature = "mysql")] use self::mysql::factoids; #[cfg_attr(feature = "mysql", derive(Insertable))] -#[cfg_attr(feature = "mysql", table_name="factoids")] +#[cfg_attr(feature = "mysql", table_name = "factoids")] pub struct NewFactoid<'a> { pub name: &'a str, pub idx: i32, @@ -41,7 +41,6 @@ pub struct NewFactoid<'a> { pub created: NaiveDateTime, } - pub trait Database: Send { fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse; fn get_factoid(&self, name: &str, idx: i32) -> Option; @@ -60,7 +59,7 @@ impl Database for HashMap<(String, i32), Factoid> { created: factoid.created, }; - let name = String::from(factoid.name.clone()); + let name = factoid.name.clone(); match self.insert((name, factoid.idx), factoid) { None => DbResponse::Success, Some(_) => DbResponse::Failed("Factoid was overwritten"), @@ -68,7 +67,7 @@ impl Database for HashMap<(String, i32), Factoid> { } fn get_factoid(&self, name: &str, idx: i32) -> Option { - self.get(&(String::from(name), idx)).map(|f| f.clone()) + self.get(&(String::from(name), idx)).cloned() } fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse { @@ -79,9 +78,7 @@ impl Database for HashMap<(String, i32), Factoid> { } fn count_factoids(&self, name: &str) -> Result { - Ok(self.iter() - .filter(|&(&(ref n, _), _)| n == name) - .count() as i32) + Ok(self.iter().filter(|&(&(ref n, _), _)| n == name).count() as i32) } } @@ -107,8 +104,9 @@ impl Database for Pool> { let conn = &*self.get().expect("Failed to get connection"); match diesel::insert_into(factoids::table) - .values(factoid) - .execute(conn) { + .values(factoid) + .execute(conn) + { Ok(_) => DbResponse::Success, Err(e) => { error!("DB Insertion Error: {}", e); @@ -124,7 +122,7 @@ impl Database for Pool> { Err(e) => { error!("DB Count Error: {}", e); None - }, + } } } @@ -133,10 +131,12 @@ impl Database for Pool> { use self::factoids::columns; let conn = &*self.get().expect("Failed to get connection"); - match diesel::delete(factoids::table - .filter(columns::name.eq(name)) - .filter(columns::idx.eq(idx))) - .execute(conn) { + match diesel::delete( + factoids::table + .filter(columns::name.eq(name)) + .filter(columns::idx.eq(idx)), + ).execute(conn) + { Ok(v) => { if v > 0 { DbResponse::Success @@ -152,7 +152,6 @@ impl Database for Pool> { } fn count_factoids(&self, name: &str) -> Result { - let conn = &*self.get().expect("Failed to get connection"); let count: Result = factoids::table .filter(factoids::columns::name.eq(name)) @@ -164,7 +163,7 @@ impl Database for Pool> { Err(e) => { error!("DB Count Error: {}", e); Err("Database Error") - }, + } } } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index b662d22..c3d19b0 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -35,25 +35,27 @@ macro_rules! try_lock { impl Factoids { pub fn new(db: T) -> Factoids { - Factoids { factoids: Mutex::new(db) } + Factoids { + factoids: Mutex::new(db), + } } fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, &str> { - let count = try_lock!(self.factoids).count_factoids(&name)?; - let tm = time::now().to_timespec(); - - let factoid = database::NewFactoid { - name: name, - idx: count, - content: content, - author: author, - created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), - }; + let count = try_lock!(self.factoids).count_factoids(name)?; + let tm = time::now().to_timespec(); + + let factoid = database::NewFactoid { + name: name, + idx: count, + content: content, + author: author, + created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), + }; - match try_lock!(self.factoids).insert_factoid(&factoid) { - DbResponse::Success => Ok("Successfully added"), - DbResponse::Failed(e) => Err(e), - } + match try_lock!(self.factoids).insert_factoid(&factoid) { + DbResponse::Success => Ok("Successfully added"), + DbResponse::Failed(e) => Err(e), + } } fn add(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<(), IrcError> { @@ -70,7 +72,11 @@ impl Factoids { } } - fn from_url(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<(), IrcError> { + fn save_from_url( + &self, + client: &IrcClient, + command: &mut PluginCommand, + ) -> Result<(), IrcError> { if command.tokens.len() < 2 { return self.invalid_command(client, command); } @@ -100,12 +106,11 @@ impl Factoids { match try_lock!(self.factoids).delete_factoid(&name, count - 1) { DbResponse::Success => client.send_notice(&command.source, "Successfully removed"), - DbResponse::Failed(e) => client.send_notice(&command.source, &e), + DbResponse::Failed(e) => client.send_notice(&command.source, e), } } fn get(&self, client: &IrcClient, command: &PluginCommand) -> Result<(), IrcError> { - let (name, idx) = match command.tokens.len() { 0 => return self.invalid_command(client, command), 1 => { @@ -135,19 +140,17 @@ impl Factoids { let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, None => { - return client.send_notice(&command.source, - &format!("{}~{} does not exist", name, idx)) + return client + .send_notice(&command.source, &format!("{}~{} does not exist", name, idx)) } }; let message = factoid.content.replace("\n", "|").replace("\r", ""); - client.send_privmsg(&command.target, - &format!("{}: {}", factoid.name, message)) + client.send_privmsg(&command.target, &format!("{}: {}", factoid.name, message)) } fn info(&self, client: &IrcClient, command: &PluginCommand) -> Result<(), IrcError> { - match command.tokens.len() { 0 => self.invalid_command(client, command), 1 => { @@ -159,14 +162,12 @@ impl Factoids { match count { 0 => client.send_notice(&command.source, &format!("{} does not exist", name)), - 1 => { - client.send_privmsg(&command.target, - &format!("There is 1 version of {}", name)) - } - _ => { - client.send_privmsg(&command.target, - &format!("There are {} versions of {}", count, name)) - } + 1 => client + .send_privmsg(&command.target, &format!("There is 1 version of {}", name)), + _ => client.send_privmsg( + &command.target, + &format!("There are {} versions of {}", count, name), + ), } } _ => { @@ -179,29 +180,32 @@ impl Factoids { let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, None => { - return client.send_notice(&command.source, - &format!("{}~{} does not exist", name, idx)) + return client.send_notice( + &command.source, + &format!("{}~{} does not exist", name, idx), + ) } }; - client.send_privmsg(&command.target, - &format!("{}: Added by {} at {} UTC", - name, - factoid.author, - factoid.created)) + client.send_privmsg( + &command.target, + &format!( + "{}: Added by {} at {} UTC", + name, factoid.author, factoid.created + ), + ) } - } } - fn exec(&self, - client: &IrcClient, - mut command: PluginCommand, - error: bool) - -> Result<(), IrcError> { + fn exec( + &self, + client: &IrcClient, + mut command: PluginCommand, + error: bool, + ) -> Result<(), IrcError> { if command.tokens.len() < 1 { self.invalid_command(client, &command) - } else { let name = command.tokens.remove(0); let count = match try_lock!(self.factoids).count_factoids(&name) { @@ -215,10 +219,10 @@ impl Factoids { None => return Ok(()), }; - let value = &if factoid.starts_with(">") { + let value = &if factoid.starts_with('>') { let factoid = String::from(&factoid[1..]); - if factoid.starts_with(">") { + if factoid.starts_with('>') { factoid } else { match self.run_lua(&name, &factoid, &command) { @@ -234,12 +238,12 @@ impl Factoids { } } - fn run_lua(&self, - name: &str, - code: &str, - command: &PluginCommand) - -> Result { - + fn run_lua( + &self, + name: &str, + code: &str, + command: &PluginCommand, + ) -> Result { let args = command .tokens .iter() @@ -295,7 +299,6 @@ impl Plugin for Factoids { }; self.exec(client, c, false) - } else { Ok(()) } @@ -309,7 +312,7 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); match sub_command.as_ref() { "add" => self.add(client, &mut command), - "fromurl" => self.from_url(client, &mut command), + "fromurl" => self.save_from_url(client, &mut command), "remove" => self.remove(client, &mut command), "get" => self.get(client, &command), "info" => self.info(client, &command), @@ -319,7 +322,9 @@ impl Plugin for Factoids { } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { - Err(String::from("Evaluation of commands is not implemented for Factoids at this time")) + Err(String::from( + "Evaluation of commands is not implemented for Factoids at this time", + )) } } diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index 73f4893..bdabd90 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -27,7 +27,7 @@ impl KeepNick { 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), + Err(e) => ExecutionStatus::Err(Box::new(e)), } } else { ExecutionStatus::Done diff --git a/src/plugins/tell.rs b/src/plugins/tell.rs index 34d7cf8..89d91f2 100644 --- a/src/plugins/tell.rs +++ b/src/plugins/tell.rs @@ -61,7 +61,9 @@ impl Tell { }; let mut tells = try_lock!(self.tells); - let tell_messages = tells.entry(receiver).or_insert(Vec::with_capacity(3)); + let tell_messages = tells + .entry(receiver) + .or_insert_with(|| Vec::with_capacity(3)); (*tell_messages).push(tell); Ok("Got it!") @@ -75,7 +77,7 @@ impl Tell { receiver, &format!("Tell from {}: {}", tell.sender, tell.message), ) { - return ExecutionStatus::Err(e); + return ExecutionStatus::Err(Box::new(e)); } debug!( "Sent {:?} from {:?} to {:?}", @@ -107,8 +109,9 @@ impl Tell { 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()), + Command::JOIN(_, _, _) | Command::PRIVMSG(_, _) => { + self.send_tell(client, message.source_nickname().unwrap()) + } _ => ExecutionStatus::Done, } } diff --git a/src/plugins/url.rs b/src/plugins/url.rs index df4fdf2..52f92d8 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -44,7 +44,6 @@ impl Url { None => return Err("No Url was found."), }; - match utils::download(self.max_kib, &url) { Some(body) => { let doc = Document::from(body.as_ref()); diff --git a/src/utils.rs b/src/utils.rs index 59a5a54..0b965c8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -7,10 +7,7 @@ use self::reqwest::Client; use self::reqwest::header::Connection; pub fn download(max_kib: usize, url: &str) -> Option { - let response = Client::new() - .get(url) - .header(Connection::close()) - .send(); + let response = Client::new().get(url).header(Connection::close()).send(); match response { Ok(mut response) => { @@ -44,16 +41,18 @@ pub fn download(max_kib: usize, url: &str) -> Option { // Check if the file is too large to download if written > max_kib * 1024 { - debug!("Stopping download - File from {:?} is larger than {} KiB", url, max_kib); + debug!( + "Stopping download - File from {:?} is larger than {} KiB", + url, max_kib + ); return None; } - } Some(body) } Err(e) => { debug!("Bad response from {:?}: ({})", url, e); - return None; + None } } } -- cgit v1.2.3-70-g09d2 From ac1afe4c7b0f62160f62b848d7f747cb7be74bbd Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 25 Feb 2018 01:30:17 +0100 Subject: Return zero if count_factoids could not find the factoid --- src/plugins/factoids/database.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index ccebfee..386d3f7 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -152,14 +152,17 @@ impl Database for Pool> { } fn count_factoids(&self, name: &str) -> Result { + use diesel; + let conn = &*self.get().expect("Failed to get connection"); let count: Result = factoids::table .filter(factoids::columns::name.eq(name)) .count() - .first(conn); + .get_result(conn); match count { Ok(c) => Ok(c as i32), + Err(diesel::NotFound) => Ok(0), Err(e) => { error!("DB Count Error: {}", e); Err("Database Error") -- cgit v1.2.3-70-g09d2 From 76461addd2fb7ec383123b1efc4368b7662eea04 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 25 Feb 2018 02:30:53 +0100 Subject: Remove unwraps from the Url plugin --- src/plugins/url.rs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/plugins/url.rs b/src/plugins/url.rs index 52f92d8..b19d4e5 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -32,12 +32,23 @@ impl Url { Some(captures) => { debug!("Url captures: {:?}", captures); - Some(captures.get(2).unwrap().as_str().to_string()) + Some(captures.get(2)?.as_str().to_string()) } None => None, } } + fn get_title(&self, body: &str) -> Option { + let doc = Document::from(body.as_ref()); + let title = doc.find(Name("title")).next()?; + let title = title.children().next()?; + let title_text = title.as_text()?.trim().replace("\n", "|"); + debug!("Title: {:?}", title); + debug!("Text: {:?}", title_text); + + Some(title_text) + } + fn url(&self, text: &str) -> Result { let url = match self.grep_url(text) { Some(url) => url, @@ -46,16 +57,9 @@ impl Url { match utils::download(self.max_kib, &url) { Some(body) => { - let doc = Document::from(body.as_ref()); - if let Some(title) = doc.find(Name("title")).next() { - let title = title.children().next().unwrap(); - let title_text = title.as_text().unwrap().trim().replace("\n", "|"); - debug!("Title: {:?}", title); - debug!("Text: {:?}", title_text); - - Ok(title_text) - } else { - Err("No title was found.") + match self.get_title(&body) { + Some(title) => Ok(title), + None => Err("No title was found.") } } None => Err("Failed to download document."), @@ -79,7 +83,10 @@ impl Plugin for Url { match message.command { Command::PRIVMSG(_, ref content) => match self.url(content) { Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), - Err(_) => Ok(()), + Err(e) => { + error!("Url plugin error: {}", e); + Ok(()) + }, }, _ => Ok(()), } -- cgit v1.2.3-70-g09d2 From 92668ad4c53edcc1a317a16aa5ea30ca502f54ee Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 25 Feb 2018 18:54:16 +0100 Subject: Add Mysql as a possible database to the Tell plugin --- migrations/2018-02-25-154922_create_tells/down.sql | 1 + migrations/2018-02-25-154922_create_tells/up.sql | 7 + src/main.rs | 10 +- src/plugins/factoids/database.rs | 15 ++- src/plugins/factoids/mod.rs | 2 +- src/plugins/tell.rs | 143 -------------------- src/plugins/tell/database.rs | 143 ++++++++++++++++++++ src/plugins/tell/mod.rs | 144 +++++++++++++++++++++ 8 files changed, 313 insertions(+), 152 deletions(-) create mode 100644 migrations/2018-02-25-154922_create_tells/down.sql create mode 100644 migrations/2018-02-25-154922_create_tells/up.sql delete mode 100644 src/plugins/tell.rs create mode 100644 src/plugins/tell/database.rs create mode 100644 src/plugins/tell/mod.rs diff --git a/migrations/2018-02-25-154922_create_tells/down.sql b/migrations/2018-02-25-154922_create_tells/down.sql new file mode 100644 index 0000000..73c9b9b --- /dev/null +++ b/migrations/2018-02-25-154922_create_tells/down.sql @@ -0,0 +1 @@ +DROP TABLE tells diff --git a/migrations/2018-02-25-154922_create_tells/up.sql b/migrations/2018-02-25-154922_create_tells/up.sql new file mode 100644 index 0000000..9de037c --- /dev/null +++ b/migrations/2018-02-25-154922_create_tells/up.sql @@ -0,0 +1,7 @@ +CREATE TABLE tells ( + id SERIAL PRIMARY KEY, + sender VARCHAR(32) NOT NULL, + receiver VARCHAR(32) NOT NULL, + time TIMESTAMP NOT NULL, + message VARCHAR(512) NOT NULL +) diff --git a/src/main.rs b/src/main.rs index 511fe09..ec04d33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ extern crate r2d2_diesel; #[macro_use] extern crate log; +#[cfg(feature = "mysql")] +use std::sync::Arc; use std::collections::HashMap; use log::{Level, LevelFilter, Metadata, Record}; @@ -115,7 +117,6 @@ 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()); #[cfg(feature = "mysql")] { @@ -130,11 +131,14 @@ fn main() { .expect("Failed to get connection")) { Ok(_) => { - bot.add_plugin(plugins::Factoids::new(pool)); + let pool = Arc::new(pool); + bot.add_plugin(plugins::Factoids::new(pool.clone())); + bot.add_plugin(plugins::Tell::new(pool.clone())); info!("Connected to MySQL server") } Err(e) => { bot.add_plugin(plugins::Factoids::new(HashMap::new())); + bot.add_plugin(plugins::Tell::new(HashMap::new())); error!("Failed to run migrations: {}", e); } }, @@ -142,6 +146,7 @@ fn main() { } } else { bot.add_plugin(plugins::Factoids::new(HashMap::new())); + bot.add_plugin(plugins::Tell::new(HashMap::new())); } } #[cfg(not(feature = "mysql"))] @@ -150,6 +155,7 @@ fn main() { error!("frippy was not built with the mysql feature") } bot.add_plugin(plugins::Factoids::new(HashMap::new())); + bot.add_plugin(plugins::Tell::new(HashMap::new())); } if let Some(disabled_plugins) = disabled_plugins { diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 386d3f7..88aa0fd 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -1,6 +1,8 @@ #[cfg(feature = "mysql")] extern crate dotenv; +#[cfg(feature = "mysql")] +use std::sync::Arc; use std::collections::HashMap; #[cfg(feature = "mysql")] @@ -29,8 +31,6 @@ pub struct Factoid { pub created: NaiveDateTime, } -#[cfg(feature = "mysql")] -use self::mysql::factoids; #[cfg_attr(feature = "mysql", derive(Insertable))] #[cfg_attr(feature = "mysql", table_name = "factoids")] pub struct NewFactoid<'a> { @@ -82,10 +82,10 @@ impl Database for HashMap<(String, i32), Factoid> { } } -// Diesel automatically define the factoids module as public. -// For now this is how we keep it private. +// Diesel automatically defines the factoids module as public. +// We create a schema module to keep it private. #[cfg(feature = "mysql")] -mod mysql { +mod schema { table! { factoids (name, idx) { name -> Varchar, @@ -98,7 +98,10 @@ mod mysql { } #[cfg(feature = "mysql")] -impl Database for Pool> { +use self::schema::factoids; + +#[cfg(feature = "mysql")] +impl Database for Arc>> { fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse { use diesel; diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index c3d19b0..d6abb1d 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -49,7 +49,7 @@ impl Factoids { idx: count, content: content, author: author, - created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), + created: NaiveDateTime::from_timestamp(tm.sec, 0u32), }; match try_lock!(self.factoids).insert_factoid(&factoid) { diff --git a/src/plugins/tell.rs b/src/plugins/tell.rs deleted file mode 100644 index 89d91f2..0000000 --- a/src/plugins/tell.rs +++ /dev/null @@ -1,143 +0,0 @@ -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, - }; - - let mut tells = try_lock!(self.tells); - let tell_messages = tells - .entry(receiver) - .or_insert_with(|| 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_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(Box::new(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(_, _, _) | 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 {} diff --git a/src/plugins/tell/database.rs b/src/plugins/tell/database.rs new file mode 100644 index 0000000..277847e --- /dev/null +++ b/src/plugins/tell/database.rs @@ -0,0 +1,143 @@ +#[cfg(feature = "mysql")] +extern crate dotenv; + +#[cfg(feature = "mysql")] +use std::sync::Arc; +use std::collections::HashMap; + +#[cfg(feature = "mysql")] +use diesel::prelude::*; +#[cfg(feature = "mysql")] +use diesel::mysql::MysqlConnection; +#[cfg(feature = "mysql")] +use r2d2::Pool; +#[cfg(feature = "mysql")] +use r2d2_diesel::ConnectionManager; + +use chrono::NaiveDateTime; + +pub enum DbResponse { + Success, + Failed(&'static str), +} + +#[cfg_attr(feature = "mysql", derive(Queryable))] +#[derive(PartialEq, Clone, Debug)] +pub struct TellMessage { + pub id: i64, + pub sender: String, + pub receiver: String, + pub time: NaiveDateTime, + pub message: String, +} + +#[cfg_attr(feature = "mysql", derive(Insertable))] +#[cfg_attr(feature = "mysql", table_name = "tells")] +pub struct NewTellMessage<'a> { + pub sender: &'a str, + pub receiver: &'a str, + pub time: NaiveDateTime, + pub message: &'a str, +} + +pub trait Database: Send { + fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse; + fn get_tells(&self, receiver: &str) -> Option>; + fn delete_tells(&mut self, receiver: &str) -> DbResponse; +} + +// HashMap +impl Database for HashMap> { + fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse { + let tell = TellMessage { + id: 0, + sender: tell.sender.to_string(), + receiver: tell.receiver.to_string(), + time: tell.time, + message: tell.message.to_string(), + }; + + let receiver = tell.receiver.clone(); + let tell_messages = self.entry(receiver) + .or_insert_with(|| Vec::with_capacity(3)); + (*tell_messages).push(tell); + + DbResponse::Success + } + + fn get_tells(&self, receiver: &str) -> Option> { + self.get(receiver).cloned() + } + + fn delete_tells(&mut self, receiver: &str) -> DbResponse { + match self.remove(receiver) { + Some(_) => DbResponse::Success, + None => DbResponse::Failed("Tells not found"), + } + } +} + +// Diesel automatically defines the tells module as public. +// We create a schema module to keep it private. +#[cfg(feature = "mysql")] +mod schema { + table! { + tells (id) { + id -> Bigint, + sender -> Varchar, + receiver -> Varchar, + time -> Timestamp, + message -> Varchar, + } + } +} + +#[cfg(feature = "mysql")] +use self::schema::tells; + +#[cfg(feature = "mysql")] +impl Database for Arc>> { + fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse { + use diesel; + + let conn = &*self.get().expect("Failed to get connection"); + match diesel::insert_into(tells::table).values(tell).execute(conn) { + Ok(_) => DbResponse::Success, + Err(e) => { + error!("DB failed to insert tell: {}", e); + DbResponse::Failed("Failed to save Tell") + } + } + } + + fn get_tells(&self, receiver: &str) -> Option> { + use self::tells::columns; + + let conn = &*self.get().expect("Failed to get connection"); + match tells::table + .filter(columns::receiver.eq(receiver)) + .order(columns::time.asc()) + .load::(conn) + { + Ok(f) => Some(f), + Err(e) => { + error!("DB failed to get tells: {}", e); + None + } + } + } + + fn delete_tells(&mut self, receiver: &str) -> DbResponse { + use diesel; + use self::tells::columns; + + let conn = &*self.get().expect("Failed to get connection"); + match diesel::delete(tells::table.filter(columns::receiver.eq(receiver))).execute(conn) { + Ok(_) => DbResponse::Success, + Err(e) => { + error!("DB failed to delete tells: {}", e); + DbResponse::Failed("Failed to delete tells") + } + } + } +} diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs new file mode 100644 index 0000000..1a1bef1 --- /dev/null +++ b/src/plugins/tell/mod.rs @@ -0,0 +1,144 @@ +use irc::client::prelude::*; +use irc::error::IrcError; + +use time; +use chrono::NaiveDateTime; +use std::sync::Mutex; + +use plugin::*; + +pub mod database; +use self::database::{Database, DbResponse}; + +macro_rules! try_lock { + ( $m:expr ) => { + match $m.lock() { + Ok(guard) => guard, + Err(poisoned) => poisoned.into_inner(), + } + } +} + +#[derive(PluginName, Default)] +pub struct Tell { + tells: Mutex, +} + +impl Tell { + pub fn new(db: T) -> Tell { + Tell { + tells: Mutex::new(db), + } + } + + 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 tm = time::now().to_timespec(); + let message = command.tokens[1..].join(" "); + let tell = database::NewTellMessage { + sender: &sender, + receiver: &receiver, + time: NaiveDateTime::from_timestamp(tm.sec, 0u32), + message: &message, + }; + + match try_lock!(self.tells).insert_tell(&tell) { + DbResponse::Success => Ok("Got it!"), + DbResponse::Failed(e) => Err(e.to_string()), + } + } + + fn send_tell(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { + let mut tells = try_lock!(self.tells); + if let Some(tell_messages) = tells.get_tells(receiver) { + for tell in tell_messages { + if let Err(e) = client.send_notice( + receiver, + &format!("Tell from {}: {}", tell.sender, tell.message), + ) { + return ExecutionStatus::Err(Box::new(e)); + } + debug!( + "Sent {:?} from {:?} to {:?}", + tell.message, tell.sender, receiver + ); + } + } + tells.delete_tells(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(_, _, _) | 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.")) + } +} + +use std::fmt; +impl fmt::Debug for Tell { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Tell {{ ... }}") + } +} -- cgit v1.2.3-70-g09d2 From 5c7f882a0ed10153b1bd2dd8c796a168059e2c37 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 26 Feb 2018 18:09:57 +0100 Subject: Add time passed to tells --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 1 + src/lib.rs | 1 + src/plugins/tell/mod.rs | 18 ++++++++++++++---- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92cf4ee..d823d90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,6 +393,7 @@ dependencies = [ "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "irc 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -485,6 +486,14 @@ name = "httparse" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "humantime" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper" version = "0.11.19" @@ -924,6 +933,11 @@ dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quine-mc_cluskey" version = "0.2.4" @@ -1573,6 +1587,7 @@ dependencies = [ "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" +"checksum humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5369e01a05e3404c421b5d6dcfea6ecf7d5e65eba8a275948151358cd8282042" "checksum hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)" = "47659bb1cb7ef3cd7b4f9bd2a11349b8d92097d34f9597a3c09e9bcefaf92b61" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" @@ -1621,6 +1636,7 @@ dependencies = [ "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" +"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" diff --git a/Cargo.toml b/Cargo.toml index 7b7c6f3..961ffb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ mysql = [ irc = "0.13.4" log = "0.4.1" time = "0.1.39" +humantime = "1.1.0" rlua = "0.12.2" reqwest = "0.8.5" select = "0.4.2" diff --git a/src/lib.rs b/src/lib.rs index cc6e921..657b0eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ extern crate lazy_static; extern crate log; extern crate chrono; +extern crate humantime; extern crate irc; extern crate time; diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index 1a1bef1..a2c49f2 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -1,9 +1,12 @@ use irc::client::prelude::*; use irc::error::IrcError; +use std::time::Duration; +use std::sync::Mutex; + use time; use chrono::NaiveDateTime; -use std::sync::Mutex; +use humantime::format_duration; use plugin::*; @@ -40,13 +43,13 @@ impl Tell { let sender = command.source.to_owned(); if receiver == sender { - return Err(String::from("That's your name!")); + //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)); + //return Err(format!("{} is in this channel.", receiver)); } } } @@ -70,9 +73,16 @@ impl Tell { let mut tells = try_lock!(self.tells); if let Some(tell_messages) = tells.get_tells(receiver) { for tell in tell_messages { + let now = Duration::new(time::now().to_timespec().sec as u64, 0); + let dur = now - Duration::new(tell.time.timestamp() as u64, 0); + let human_dur = format_duration(dur); + if let Err(e) = client.send_notice( receiver, - &format!("Tell from {}: {}", tell.sender, tell.message), + &format!( + "Tell from {} {} ago: {}", + tell.sender, human_dur, tell.message + ), ) { return ExecutionStatus::Err(Box::new(e)); } -- cgit v1.2.3-70-g09d2 From 8ea98aab1ea34e0213380082577e2a3ff2d3aa2e Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 27 Feb 2018 16:13:52 +0100 Subject: Fix UTF8 errors in the download function --- src/utils.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 0b965c8..99b04c4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -13,11 +13,18 @@ pub fn download(max_kib: usize, url: &str) -> Option { Ok(mut response) => { let mut body = String::new(); - // 500 kilobyte buffer - let mut buf = [0; 500 * 1000]; + // 100 kibibyte buffer + let mut buf = [0; 100 * 1024]; let mut written = 0; + let mut vec = Vec::new(); + let mut end_of_valid = None; + // Read until we reach EOF or max_kib KiB loop { + if let Some(eov) = end_of_valid { + vec = vec[..eov].to_vec(); + } + let len = match response.read(&mut buf) { Ok(0) => break, Ok(len) => len, @@ -27,16 +34,24 @@ pub fn download(max_kib: usize, url: &str) -> Option { return None; } }; + vec.extend_from_slice(&buf); - let slice = match str::from_utf8(&buf[..len]) { + end_of_valid = None; + let body_slice = match str::from_utf8(&vec[..len]) { Ok(slice) => slice, Err(e) => { - debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); - return None; + let valid = e.valid_up_to(); + if valid == 0 { + error!("Failed to read bytes from {:?} as UTF8: {}", url, e); + return None; + } + end_of_valid = Some(valid); + + str::from_utf8(&buf[..valid]).unwrap() } }; - body.push_str(slice); + body.push_str(body_slice); written += len; // Check if the file is too large to download -- cgit v1.2.3-70-g09d2 From b40a984ed9b6a948265e1287ecc08f4e16c64ecd Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 01:21:25 +0100 Subject: Create errors with failure The plugins are mostly not using the new errors yet and the error handling in the Factoids plugin is just temporary. --- Cargo.lock | 1 + Cargo.toml | 1 + src/error.rs | 98 ++++++++++++++++++++++++ src/lib.rs | 26 +++---- src/main.rs | 28 +++++-- src/plugins/factoids/mod.rs | 174 +++++++++++++++++------------------------- src/plugins/factoids/utils.rs | 4 +- src/plugins/url.rs | 37 ++++----- src/utils.rs | 101 +++++++++++------------- 9 files changed, 262 insertions(+), 208 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.lock b/Cargo.lock index d823d90..dcbaad5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -391,6 +391,7 @@ dependencies = [ "diesel_infer_schema 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 961ffb9..2d4087a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ serde = "1.0.27" serde_json = "1.0.9" chrono = "0.4.0" glob = "0.2.11" +failure = "0.1.1" frippy_derive = { path = "frippy_derive" } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..9ada5b6 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,98 @@ +//! Errors for `frippy` crate using `failure`. + +use std::io::Error as IoError; +use std::str::Utf8Error; +use irc::error::IrcError; +use reqwest::Error as ReqwestError; + +/// The main crate-wide error type. +#[derive(Debug, Fail)] +pub enum FrippyError { + /// A plugin error + #[fail(display = "A plugin error occured")] + Plugin(#[cause] PluginError), + + /// An IRC error + #[fail(display = "An IRC error occured")] + Irc(#[cause] IrcError), + + /// Missing config error + #[fail(display = "No config file was found")] + MissingConfig, + + /// A reqwest error + #[fail(display = "A reqwest error occured")] + Reqwest(#[cause] ReqwestError), + + /// An I/O error + #[fail(display = "An I/O error occured")] + Io(#[cause] IoError), + + /// A UTF8 error + #[fail(display = "A UTF8 error occured")] + Utf8(#[cause] Utf8Error), + + /// Reached download limit error + #[fail(display = "Reached download limit of {} KiB", limit)] + DownloadLimit { limit: usize }, +} + +/// Errors related to plugins +#[derive(Debug, Fail)] +pub enum PluginError { + /// A Url error + #[fail(display = "A Url error occured")] + Url(#[cause] UrlError), + + /// A Factoids error + #[fail(display = "{}", error)] + Factoids { error: String }, +} + +/// A URL plugin error +#[derive(Debug, Fail)] +pub enum UrlError { + /// Missing URL error + #[fail(display = "No URL was found")] + MissingUrl, + + /// Missing title error + #[fail(display = "No title was found")] + MissingTitle, +} + +impl From for FrippyError { + fn from(e: UrlError) -> FrippyError { + FrippyError::Plugin(PluginError::Url(e)) + } +} + +impl From for FrippyError { + fn from(e: PluginError) -> FrippyError { + FrippyError::Plugin(e) + } +} + +impl From for FrippyError { + fn from(e: IrcError) -> FrippyError { + FrippyError::Irc(e) + } +} + +impl From for FrippyError { + fn from(e: ReqwestError) -> FrippyError { + FrippyError::Reqwest(e) + } +} + +impl From for FrippyError { + fn from(e: IoError) -> FrippyError { + FrippyError::Io(e) + } +} + +impl From for FrippyError { + fn from(e: Utf8Error) -> FrippyError { + FrippyError::Utf8(e) + } +} diff --git a/src/lib.rs b/src/lib.rs index 657b0eb..42b0089 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,8 @@ extern crate r2d2; #[cfg(feature = "mysql")] extern crate r2d2_diesel; +#[macro_use] +extern crate failure; #[macro_use] extern crate frippy_derive; #[macro_use] @@ -47,11 +49,13 @@ extern crate log; extern crate chrono; extern crate humantime; extern crate irc; +extern crate reqwest; extern crate time; pub mod plugin; pub mod plugins; pub mod utils; +pub mod error; use std::collections::HashMap; use std::fmt; @@ -60,6 +64,7 @@ use std::sync::Arc; pub use irc::client::prelude::*; pub use irc::error::IrcError; +use error::FrippyError; use plugin::*; @@ -142,20 +147,15 @@ impl Bot { /// reactor.run().unwrap(); /// # } /// ``` - pub fn connect(&self, reactor: &mut IrcReactor, config: &Config) -> Result<(), String> { + pub fn connect(&self, reactor: &mut IrcReactor, config: &Config) -> Result<(), FrippyError> { info!("Plugins loaded: {}", self.plugins); - let client = match reactor.prepare_client_and_connect(config) { - Ok(v) => v, - Err(e) => return Err(format!("Failed to connect: {}", e)), - }; + let client = reactor.prepare_client_and_connect(config)?; info!("Connected to IRC server"); - match client.identify() { - Ok(_) => info!("Identified"), - Err(e) => return Err(format!("Failed to identify: {}", e)), - }; + client.identify()?; + info!("Identified"); // TODO Verify if we actually need to clone plugins twice let plugins = self.plugins.clone(); @@ -253,10 +253,10 @@ impl ThreadedPlugins { &mut self, server: &IrcClient, mut command: PluginCommand, - ) -> Result<(), IrcError> { + ) -> Result<(), FrippyError> { if !command.tokens.iter().any(|s| !s.is_empty()) { let help = format!("Use \"{} help\" to get help", server.current_nickname()); - return server.send_notice(&command.source, &help); + server.send_notice(&command.source, &help)?; } // Check if the command is for this plugin @@ -284,7 +284,7 @@ impl ThreadedPlugins { command.tokens[0] ); - server.send_notice(&command.source, &help) + Ok(server.send_notice(&command.source, &help)?) } } } @@ -293,7 +293,7 @@ impl fmt::Display for ThreadedPlugins { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let plugin_names = self.plugins .iter() - .map(|(_, p)| p.name().to_string()) + .map(|(_, p)| p.name().to_owned()) .collect::>(); write!(f, "{}", plugin_names.join(", ")) } diff --git a/src/main.rs b/src/main.rs index ec04d33..461387d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate frippy; extern crate glob; extern crate irc; extern crate time; +extern crate failure; #[cfg(feature = "mysql")] extern crate diesel; @@ -26,9 +27,11 @@ use log::{Level, LevelFilter, Metadata, Record}; use irc::client::reactor::IrcReactor; use glob::glob; +use failure::Fail; use frippy::plugins; use frippy::Config; +use frippy::error::FrippyError; #[cfg(feature = "mysql")] embed_migrations!(); @@ -67,6 +70,18 @@ impl log::Log for Logger { static LOGGER: Logger = Logger; fn main() { + // Print any errors that caused frippy to shut down + if let Err(e) = run() { + let mut causes = e.causes(); + + error!("{}", causes.next().unwrap()); + for cause in causes { + error!("caused by: {}", cause); + } + }; +} + +fn run() -> Result<(), FrippyError> { log::set_max_level(if cfg!(debug_assertions) { LevelFilter::Debug } else { @@ -92,12 +107,11 @@ fn main() { // Without configs the bot would just idle if configs.is_empty() { - error!("No config file found"); - return; + return Err(FrippyError::MissingConfig); } // Create an event loop to run the connections on. - let mut reactor = IrcReactor::new().unwrap(); + let mut reactor = IrcReactor::new()?; // Open a connection and add work for each config for config in configs { @@ -127,8 +141,7 @@ fn main() { let manager = ConnectionManager::::new(url.clone()); match r2d2::Pool::builder().build(manager) { - Ok(pool) => match embedded_migrations::run(&*pool.get() - .expect("Failed to get connection")) + Ok(pool) => match embedded_migrations::run(&*pool.get()?) { Ok(_) => { let pool = Arc::new(pool); @@ -166,10 +179,9 @@ fn main() { } } - bot.connect(&mut reactor, &config) - .expect("Failed to connect"); + bot.connect(&mut reactor, &config)?; } // Run the bots until they throw an error - an error could be loss of connection - reactor.run().unwrap(); + Ok(reactor.run()?) } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index d6abb1d..3f89943 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -6,6 +6,9 @@ use std::sync::Mutex; use self::rlua::prelude::*; use irc::client::prelude::*; use irc::error::IrcError; +use error::FrippyError; +use error::PluginError; +use failure::Fail; use time; use chrono::NaiveDateTime; @@ -40,8 +43,8 @@ impl Factoids { } } - fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, &str> { - let count = try_lock!(self.factoids).count_factoids(name)?; + fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, FrippyError> { + let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() })?; let tm = time::now().to_timespec(); let factoid = database::NewFactoid { @@ -54,74 +57,60 @@ impl Factoids { match try_lock!(self.factoids).insert_factoid(&factoid) { DbResponse::Success => Ok("Successfully added"), - DbResponse::Failed(e) => Err(e), + DbResponse::Failed(e) => Err(PluginError::Factoids { error: e.to_owned() })?, } } - fn add(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<(), IrcError> { + fn add(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<&str, FrippyError> { if command.tokens.len() < 2 { - return self.invalid_command(client, command); + return Ok(self.invalid_command(client, command).map(|()| "")?); } let name = command.tokens.remove(0); let content = command.tokens.join(" "); - match self.create_factoid(&name, &content, &command.source) { - Ok(v) => client.send_notice(&command.source, v), - Err(e) => client.send_notice(&command.source, e), - } + Ok(self.create_factoid(&name, &content, &command.source)?) } - fn save_from_url( + fn add_from_url( &self, client: &IrcClient, command: &mut PluginCommand, - ) -> Result<(), IrcError> { + ) -> Result<&str, FrippyError> { if command.tokens.len() < 2 { - return self.invalid_command(client, command); + return Ok(self.invalid_command(client, command).map(|()| "")?); } let name = command.tokens.remove(0); let url = &command.tokens[0]; - if let Some(content) = ::utils::download(1024, url) { - match self.create_factoid(&name, &content, &command.source) { - Ok(v) => client.send_notice(&command.source, v), - Err(e) => client.send_notice(&command.source, e), - } - } else { - client.send_notice(&command.source, "Failed to download.") - } + let content = ::utils::download(1024, url)?; + + Ok(self.create_factoid(&name, &content, &command.source)?) } - fn remove(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<(), IrcError> { + fn remove(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<&str, FrippyError> { if command.tokens.len() < 1 { - return self.invalid_command(client, command); + return Ok(self.invalid_command(client, command).map(|()| "")?); } let name = command.tokens.remove(0); - let count = match try_lock!(self.factoids).count_factoids(&name) { - Ok(c) => c, - Err(e) => return client.send_notice(&command.source, e), - }; + let count = try_lock!(self.factoids).count_factoids(&name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; match try_lock!(self.factoids).delete_factoid(&name, count - 1) { - DbResponse::Success => client.send_notice(&command.source, "Successfully removed"), - DbResponse::Failed(e) => client.send_notice(&command.source, e), + DbResponse::Success => Ok("Successfully removed"), + DbResponse::Failed(e) => Err(PluginError::Factoids { error: e.to_owned() })?, } } - fn get(&self, client: &IrcClient, command: &PluginCommand) -> Result<(), IrcError> { + fn get(&self, client: &IrcClient, command: &PluginCommand) -> Result { let (name, idx) = match command.tokens.len() { - 0 => return self.invalid_command(client, command), + 0 => return Ok(self.invalid_command(client, command).map(|()| String::new())?), 1 => { let name = &command.tokens[0]; - let count = match try_lock!(self.factoids).count_factoids(name) { - Ok(c) => c, - Err(e) => return client.send_notice(&command.source, e), - }; + let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; if count < 1 { - return client.send_notice(&command.source, &format!("{} does not exist", name)); + Err(PluginError::Factoids { error: format!("{} does not exist", name) })?; } (name, count - 1) @@ -130,7 +119,7 @@ impl Factoids { let name = &command.tokens[0]; let idx = match i32::from_str(&command.tokens[1]) { Ok(i) => i, - Err(_) => return client.send_notice(&command.source, "Invalid index"), + Err(_) => Err(PluginError::Factoids { error: String::from("Invalid index") })?, }; (name, idx) @@ -139,61 +128,37 @@ impl Factoids { let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, - None => { - return client - .send_notice(&command.source, &format!("{}~{} does not exist", name, idx)) - } + None => Err(PluginError::Factoids { error: format!("{}~{} does not exist", name, idx) })?, }; let message = factoid.content.replace("\n", "|").replace("\r", ""); - client.send_privmsg(&command.target, &format!("{}: {}", factoid.name, message)) + Ok(format!("{}: {}", factoid.name, message)) } - fn info(&self, client: &IrcClient, command: &PluginCommand) -> Result<(), IrcError> { + fn info(&self, client: &IrcClient, command: &PluginCommand) -> Result { match command.tokens.len() { - 0 => self.invalid_command(client, command), + 0 => Ok(self.invalid_command(client, command).map(|()| String::new())?), 1 => { let name = &command.tokens[0]; - let count = match try_lock!(self.factoids).count_factoids(name) { - Ok(c) => c, - Err(e) => return client.send_notice(&command.source, e), - }; + let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; - match count { - 0 => client.send_notice(&command.source, &format!("{} does not exist", name)), - 1 => client - .send_privmsg(&command.target, &format!("There is 1 version of {}", name)), - _ => client.send_privmsg( - &command.target, - &format!("There are {} versions of {}", count, name), - ), - } + Ok(match count { + 0 => Err(PluginError::Factoids { error: format!("{} does not exist", name) })?, + 1 => format!("There is 1 version of {}", name), + _ => format!("There are {} versions of {}", count, name), + }) } _ => { let name = &command.tokens[0]; - let idx = match i32::from_str(&command.tokens[1]) { - Ok(i) => i, - Err(_) => return client.send_notice(&command.source, "Invalid index"), - }; + let idx = i32::from_str(&command.tokens[1]).map_err(|_| PluginError::Factoids { error: String::from("Invalid index") })?; let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { Some(v) => v, - None => { - return client.send_notice( - &command.source, - &format!("{}~{} does not exist", name, idx), - ) - } + None => return Ok(format!("{}~{} does not exist", name, idx)), }; - client.send_privmsg( - &command.target, - &format!( - "{}: Added by {} at {} UTC", - name, factoid.author, factoid.created - ), - ) + Ok(format!("{}: Added by {} at {} UTC", name, factoid.author, factoid.created)) } } } @@ -202,39 +167,31 @@ impl Factoids { &self, client: &IrcClient, mut command: PluginCommand, - error: bool, - ) -> Result<(), IrcError> { + ) -> Result { if command.tokens.len() < 1 { - self.invalid_command(client, &command) + Ok(self.invalid_command(client, &command).map(|()| String::new())?) } else { let name = command.tokens.remove(0); - let count = match try_lock!(self.factoids).count_factoids(&name) { - Ok(c) => c, - Err(e) => return client.send_notice(&command.source, e), - }; - - let factoid = match try_lock!(self.factoids).get_factoid(&name, count - 1) { - Some(v) => v.content, - None if error => return self.invalid_command(client, &command), - None => return Ok(()), - }; + let count = try_lock!(self.factoids).count_factoids(&name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; + let factoid = try_lock!(self.factoids).get_factoid(&name, count - 1).ok_or(PluginError::Factoids { error: format!("The factoid \"{}\" does not exist", name) })?; - let value = &if factoid.starts_with('>') { - let factoid = String::from(&factoid[1..]); + let content = factoid.content; + let value = if content.starts_with('>') { + let content = String::from(&content[1..]); - if factoid.starts_with('>') { - factoid + if content.starts_with('>') { + content } else { - match self.run_lua(&name, &factoid, &command) { + match self.run_lua(&name, &content, &command) { Ok(v) => v, Err(e) => format!("\"{}\"", e), } } } else { - factoid + content }; - client.send_privmsg(&command.target, &value.replace("\n", "|").replace("\r", "")) + Ok(value.replace("\n", "|").replace("\r", "")) } } @@ -293,12 +250,15 @@ impl Plugin for Factoids { let t: Vec = content.split(' ').map(ToOwned::to_owned).collect(); let c = PluginCommand { - source: message.source_nickname().unwrap().to_string(), - target: message.response_target().unwrap().to_string(), + source: message.source_nickname().unwrap().to_owned(), + target: message.response_target().unwrap().to_owned(), tokens: t, }; - self.exec(client, c, false) + match self.exec(client, c) { + Ok(f) => client.send_privmsg(&message.response_target().unwrap(), &f), + Err(_) => Ok(()), + } } else { Ok(()) } @@ -309,16 +269,24 @@ impl Plugin for Factoids { return self.invalid_command(client, &command); } + let target = command.target.clone(); + let source = command.source.clone(); + let sub_command = command.tokens.remove(0); - match sub_command.as_ref() { - "add" => self.add(client, &mut command), - "fromurl" => self.save_from_url(client, &mut command), - "remove" => self.remove(client, &mut command), + let result = match sub_command.as_ref() { + "add" => self.add(client, &mut command).map(|s| s.to_owned()), + "fromurl" => self.add_from_url(client, &mut command).map(|s| s.to_owned()), + "remove" => self.remove(client, &mut command).map(|s| s.to_owned()), "get" => self.get(client, &command), "info" => self.info(client, &command), - "exec" => self.exec(client, command, true), - _ => self.invalid_command(client, &command), - } + "exec" => self.exec(client, command), + _ => self.invalid_command(client, &command).map(|()| String::new()).map_err(|e| e.into()), + }; + + Ok(match result { + Ok(v) => client.send_privmsg(&target, &v), + Err(e) => client.send_notice(&source, &e.cause().unwrap().to_string()), + }?) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs index fc86fb3..036dcc6 100644 --- a/src/plugins/factoids/utils.rs +++ b/src/plugins/factoids/utils.rs @@ -10,8 +10,8 @@ use self::LuaError::RuntimeError; pub fn download(_: &Lua, url: String) -> Result { match utils::download(1024, &url) { - Some(v) => Ok(v), - None => Err(RuntimeError(format!("Failed to download {}", url))), + Ok(v) => Ok(v), + Err(e) => Err(RuntimeError(format!("Failed to download {} - {}", url, e.to_string()))), } } diff --git a/src/plugins/url.rs b/src/plugins/url.rs index b19d4e5..af6f36f 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -11,6 +11,9 @@ use self::select::predicate::Name; use plugin::*; use utils; +use error::FrippyError; +use error::UrlError; +use failure::Fail; lazy_static! { static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap(); @@ -28,14 +31,10 @@ impl Url { } fn grep_url(&self, msg: &str) -> Option { - match RE.captures(msg) { - Some(captures) => { - debug!("Url captures: {:?}", captures); + let captures = RE.captures(msg)?; + debug!("Url captures: {:?}", captures); - Some(captures.get(2)?.as_str().to_string()) - } - None => None, - } + Some(captures.get(2)?.as_str().to_owned()) } fn get_title(&self, body: &str) -> Option { @@ -49,21 +48,11 @@ impl Url { Some(title_text) } - fn url(&self, text: &str) -> Result { - let url = match self.grep_url(text) { - Some(url) => url, - None => return Err("No Url was found."), - }; - - match utils::download(self.max_kib, &url) { - Some(body) => { - match self.get_title(&body) { - Some(title) => Ok(title), - None => Err("No title was found.") - } - } - None => Err("Failed to download document."), - } + fn url(&self, text: &str) -> Result { + let url = self.grep_url(text).ok_or(UrlError::MissingUrl)?; + let body = utils::download(self.max_kib, &url)?; + + Ok(self.get_title(&body).ok_or(UrlError::MissingTitle)?) } } @@ -86,7 +75,7 @@ impl Plugin for Url { Err(e) => { error!("Url plugin error: {}", e); Ok(()) - }, + } }, _ => Ok(()), } @@ -100,7 +89,7 @@ impl Plugin for Url { } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { - self.url(&command.tokens[0]).map_err(String::from) + self.url(&command.tokens[0]).map_err(|e| e.cause().unwrap().to_string()) } } diff --git a/src/utils.rs b/src/utils.rs index 99b04c4..68ad4d8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,73 +1,58 @@ -extern crate reqwest; - use std::str; use std::io::{self, Read}; -use self::reqwest::Client; -use self::reqwest::header::Connection; +use reqwest::Client; +use reqwest::header::Connection; -pub fn download(max_kib: usize, url: &str) -> Option { - let response = Client::new().get(url).header(Connection::close()).send(); +use error::FrippyError; - match response { - Ok(mut response) => { - let mut body = String::new(); +pub fn download(max_kib: usize, url: &str) -> Result { + let mut response = Client::new().get(url).header(Connection::close()).send()?; - // 100 kibibyte buffer - let mut buf = [0; 100 * 1024]; - let mut written = 0; - let mut vec = Vec::new(); - let mut end_of_valid = None; + let mut body = String::new(); - // Read until we reach EOF or max_kib KiB - loop { - if let Some(eov) = end_of_valid { - vec = vec[..eov].to_vec(); - } + // 100 kibibyte buffer + let mut buf = [0; 100 * 1024]; + let mut written = 0; + let mut vec = Vec::new(); + let mut end_of_valid = None; - let len = match response.read(&mut buf) { - Ok(0) => break, - Ok(len) => len, - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, - Err(e) => { - debug!("Download from {:?} failed: {}", url, e); - return None; - } - }; - vec.extend_from_slice(&buf); + // Read until we reach EOF or max_kib KiB + loop { + if let Some(eov) = end_of_valid { + vec = vec[..eov].to_vec(); + } - end_of_valid = None; - let body_slice = match str::from_utf8(&vec[..len]) { - Ok(slice) => slice, - Err(e) => { - let valid = e.valid_up_to(); - if valid == 0 { - error!("Failed to read bytes from {:?} as UTF8: {}", url, e); - return None; - } - end_of_valid = Some(valid); + let len = match response.read(&mut buf) { + Ok(0) => break, + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => Err(e)?, + }; + vec.extend_from_slice(&buf); + + end_of_valid = None; + let body_slice = match str::from_utf8(&vec[..len]) { + Ok(slice) => slice, + Err(e) => { + let valid = e.valid_up_to(); + if valid == 0 { + Err(e)?; + } + end_of_valid = Some(valid); - str::from_utf8(&buf[..valid]).unwrap() - } - }; + str::from_utf8(&buf[..valid])? + } + }; - body.push_str(body_slice); - written += len; + body.push_str(body_slice); + written += len; - // Check if the file is too large to download - if written > max_kib * 1024 { - debug!( - "Stopping download - File from {:?} is larger than {} KiB", - url, max_kib - ); - return None; - } - } - Some(body) - } - Err(e) => { - debug!("Bad response from {:?}: ({})", url, e); - None + // Check if the file is too large to download + if written > max_kib * 1024 { + Err(FrippyError::DownloadLimit { limit: max_kib })?; } } + + Ok(body) } -- cgit v1.2.3-70-g09d2 From 1b6fc1039e0d3de8f61179dc046751f8448026a7 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 03:57:21 +0100 Subject: Add missing error for r2d2 --- src/error.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/error.rs b/src/error.rs index 9ada5b6..54d6ba4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ use std::io::Error as IoError; use std::str::Utf8Error; use irc::error::IrcError; use reqwest::Error as ReqwestError; +use r2d2::Error as R2d2Error; /// The main crate-wide error type. #[derive(Debug, Fail)] @@ -32,6 +33,10 @@ pub enum FrippyError { #[fail(display = "A UTF8 error occured")] Utf8(#[cause] Utf8Error), + /// An r2d2 error + #[fail(display = "An r2d2 error occured")] + R2d2, + /// Reached download limit error #[fail(display = "Reached download limit of {} KiB", limit)] DownloadLimit { limit: usize }, @@ -96,3 +101,9 @@ impl From for FrippyError { FrippyError::Utf8(e) } } + +impl From for FrippyError { + fn from(e: R2d2Error) -> FrippyError { + FrippyError::R2d2(e) + } +} -- cgit v1.2.3-70-g09d2 From c8913b532f5c125791821a806d875d2bed529675 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 03:59:28 +0100 Subject: Add missing cause to r2d2 error --- src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 54d6ba4..c6cecb4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -35,7 +35,7 @@ pub enum FrippyError { /// An r2d2 error #[fail(display = "An r2d2 error occured")] - R2d2, + R2d2(#[cause] R2d2Error), /// Reached download limit error #[fail(display = "Reached download limit of {} KiB", limit)] -- cgit v1.2.3-70-g09d2 From 244b999e9bb4f43b3ec9d2ac85ed7c8cb53ce7b3 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 14:33:39 +0100 Subject: Test mysql build on travis and cache dependencies --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index cae9543..992a201 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,14 @@ matrix: allow_failures: - rust: nightly +script: + - cargo build --verbose + - cargo test --verbose + - cargo build --verbose --features mysql + - cargo test --verbose --features mysql + +cache: cargo + notifications: email: false irc: -- cgit v1.2.3-70-g09d2 From 090dea2091eb12559004b27a38a9c5f1afc32626 Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 14:44:01 +0100 Subject: Add the mysql error to the mysql feature --- src/error.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/error.rs b/src/error.rs index c6cecb4..2ceb4cc 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ use std::io::Error as IoError; use std::str::Utf8Error; use irc::error::IrcError; use reqwest::Error as ReqwestError; +#[cfg(feature = "mysql")] use r2d2::Error as R2d2Error; /// The main crate-wide error type. @@ -34,6 +35,7 @@ pub enum FrippyError { Utf8(#[cause] Utf8Error), /// An r2d2 error + #[cfg(feature = "mysql")] #[fail(display = "An r2d2 error occured")] R2d2(#[cause] R2d2Error), @@ -102,6 +104,7 @@ impl From for FrippyError { } } +#[cfg(feature = "mysql")] impl From for FrippyError { fn from(e: R2d2Error) -> FrippyError { FrippyError::R2d2(e) -- cgit v1.2.3-70-g09d2 From d7c8b0cc39dc938ed099bcec6c28877044684f1e Mon Sep 17 00:00:00 2001 From: Jokler Date: Wed, 28 Feb 2018 17:01:14 +0100 Subject: Remove unnecessary builds from travis --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 992a201..afb7296 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,7 @@ matrix: - rust: nightly script: - - cargo build --verbose - cargo test --verbose - - cargo build --verbose --features mysql - cargo test --verbose --features mysql cache: cargo -- cgit v1.2.3-70-g09d2 From 7cdca0b7d75172d8f900e8e755ff07ed8a72966a Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 1 Mar 2018 17:27:49 +0100 Subject: Simplify the download function --- src/error.rs | 8 ++++---- src/utils.rs | 29 ++++------------------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/error.rs b/src/error.rs index 2ceb4cc..674faaa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -30,9 +30,9 @@ pub enum FrippyError { #[fail(display = "An I/O error occured")] Io(#[cause] IoError), - /// A UTF8 error - #[fail(display = "A UTF8 error occured")] - Utf8(#[cause] Utf8Error), + /// A decoding error + #[fail(display = "Failed to decode bytes")] + Decoding(#[cause] Utf8Error), /// An r2d2 error #[cfg(feature = "mysql")] @@ -100,7 +100,7 @@ impl From for FrippyError { impl From for FrippyError { fn from(e: Utf8Error) -> FrippyError { - FrippyError::Utf8(e) + FrippyError::Decoding(e) } } diff --git a/src/utils.rs b/src/utils.rs index 68ad4d8..1f3a117 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -9,43 +9,21 @@ use error::FrippyError; pub fn download(max_kib: usize, url: &str) -> Result { let mut response = Client::new().get(url).header(Connection::close()).send()?; - let mut body = String::new(); - // 100 kibibyte buffer let mut buf = [0; 100 * 1024]; let mut written = 0; - let mut vec = Vec::new(); - let mut end_of_valid = None; + let mut bytes = Vec::new(); // Read until we reach EOF or max_kib KiB loop { - if let Some(eov) = end_of_valid { - vec = vec[..eov].to_vec(); - } - let len = match response.read(&mut buf) { Ok(0) => break, Ok(len) => len, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, Err(e) => Err(e)?, }; - vec.extend_from_slice(&buf); - - end_of_valid = None; - let body_slice = match str::from_utf8(&vec[..len]) { - Ok(slice) => slice, - Err(e) => { - let valid = e.valid_up_to(); - if valid == 0 { - Err(e)?; - } - end_of_valid = Some(valid); - - str::from_utf8(&buf[..valid])? - } - }; - body.push_str(body_slice); + bytes.extend_from_slice(&buf); written += len; // Check if the file is too large to download @@ -53,6 +31,7 @@ pub fn download(max_kib: usize, url: &str) -> Result { Err(FrippyError::DownloadLimit { limit: max_kib })?; } } + let body = str::from_utf8(&bytes)?; - Ok(body) + Ok(body.to_string()) } -- cgit v1.2.3-70-g09d2 From d8406b107c651321c9e166abc36fc66730d965a1 Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 1 Mar 2018 18:34:03 +0100 Subject: Use lossy UTF8 conversion and add a log_error function --- src/error.rs | 11 ----------- src/main.rs | 9 +-------- src/plugins/factoids/mod.rs | 2 +- src/plugins/factoids/utils.rs | 2 +- src/plugins/url.rs | 7 ++----- src/utils.rs | 26 +++++++++++++++++++++----- 6 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/error.rs b/src/error.rs index 674faaa..fa232be 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,6 @@ //! Errors for `frippy` crate using `failure`. use std::io::Error as IoError; -use std::str::Utf8Error; use irc::error::IrcError; use reqwest::Error as ReqwestError; #[cfg(feature = "mysql")] @@ -30,10 +29,6 @@ pub enum FrippyError { #[fail(display = "An I/O error occured")] Io(#[cause] IoError), - /// A decoding error - #[fail(display = "Failed to decode bytes")] - Decoding(#[cause] Utf8Error), - /// An r2d2 error #[cfg(feature = "mysql")] #[fail(display = "An r2d2 error occured")] @@ -98,12 +93,6 @@ impl From for FrippyError { } } -impl From for FrippyError { - fn from(e: Utf8Error) -> FrippyError { - FrippyError::Decoding(e) - } -} - #[cfg(feature = "mysql")] impl From for FrippyError { fn from(e: R2d2Error) -> FrippyError { diff --git a/src/main.rs b/src/main.rs index 461387d..3432e3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ extern crate frippy; extern crate glob; extern crate irc; extern crate time; -extern crate failure; #[cfg(feature = "mysql")] extern crate diesel; @@ -27,7 +26,6 @@ use log::{Level, LevelFilter, Metadata, Record}; use irc::client::reactor::IrcReactor; use glob::glob; -use failure::Fail; use frippy::plugins; use frippy::Config; @@ -72,12 +70,7 @@ static LOGGER: Logger = Logger; fn main() { // Print any errors that caused frippy to shut down if let Err(e) = run() { - let mut causes = e.causes(); - - error!("{}", causes.next().unwrap()); - for cause in causes { - error!("caused by: {}", cause); - } + frippy::utils::log_error(e); }; } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 3f89943..806bb7e 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -83,7 +83,7 @@ impl Factoids { let name = command.tokens.remove(0); let url = &command.tokens[0]; - let content = ::utils::download(1024, url)?; + let content = ::utils::download(url, Some(1024))?; Ok(self.create_factoid(&name, &content, &command.source)?) } diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs index 036dcc6..009b46b 100644 --- a/src/plugins/factoids/utils.rs +++ b/src/plugins/factoids/utils.rs @@ -9,7 +9,7 @@ use super::rlua::prelude::*; use self::LuaError::RuntimeError; pub fn download(_: &Lua, url: String) -> Result { - match utils::download(1024, &url) { + match utils::download(&url, Some(1024)) { Ok(v) => Ok(v), Err(e) => Err(RuntimeError(format!("Failed to download {} - {}", url, e.to_string()))), } diff --git a/src/plugins/url.rs b/src/plugins/url.rs index af6f36f..6f00466 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -50,7 +50,7 @@ impl Url { fn url(&self, text: &str) -> Result { let url = self.grep_url(text).ok_or(UrlError::MissingUrl)?; - let body = utils::download(self.max_kib, &url)?; + let body = utils::download(&url, Some(self.max_kib))?; Ok(self.get_title(&body).ok_or(UrlError::MissingTitle)?) } @@ -72,10 +72,7 @@ impl Plugin for Url { match message.command { Command::PRIVMSG(_, ref content) => match self.url(content) { Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), - Err(e) => { - error!("Url plugin error: {}", e); - Ok(()) - } + Err(e) => Ok(utils::log_error(e)), }, _ => Ok(()), } diff --git a/src/utils.rs b/src/utils.rs index 1f3a117..cf91b37 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,9 +4,14 @@ use std::io::{self, Read}; use reqwest::Client; use reqwest::header::Connection; +use failure::Fail; use error::FrippyError; -pub fn download(max_kib: usize, url: &str) -> Result { +/// Downloads the file and converts it to a String. +/// Any invalid bytes are converted to a replacement character. +/// +/// The error indicated either a failed download or that the DownloadLimit was reached +pub fn download(url: &str, max_kib: Option) -> Result { let mut response = Client::new().get(url).header(Connection::close()).send()?; // 100 kibibyte buffer @@ -27,11 +32,22 @@ pub fn download(max_kib: usize, url: &str) -> Result { written += len; // Check if the file is too large to download - if written > max_kib * 1024 { - Err(FrippyError::DownloadLimit { limit: max_kib })?; + if let Some(max_kib) = max_kib { + if written > max_kib * 1024 { + Err(FrippyError::DownloadLimit { limit: max_kib })?; + } } } - let body = str::from_utf8(&bytes)?; - Ok(body.to_string()) + Ok(String::from_utf8_lossy(&bytes).into_owned()) +} + + +pub fn log_error(e: FrippyError) { + let mut causes = e.causes(); + + error!("{}", causes.next().unwrap()); + for cause in causes { + error!("caused by: {}", cause); + } } -- cgit v1.2.3-70-g09d2 From 0bcc7c0923852b48ebbb94ceeecc98f551fa920d Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 2 Mar 2018 17:31:29 +0100 Subject: Add accidentally removed errors --- src/plugins/tell/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index a2c49f2..3a8feeb 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -43,13 +43,13 @@ impl Tell { let sender = command.source.to_owned(); if receiver == sender { - //return Err(String::from("That's your name!")); + 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)); + return Err(format!("{} is in this channel.", receiver)); } } } -- cgit v1.2.3-70-g09d2 From 0b4131e8cf91ed10f24d3faed341034d518aea53 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 2 Mar 2018 22:11:21 +0100 Subject: Use Error & ErrorKind pair instead of simple enums Each plugin should define its own errors with a respective variant in the main ErrorKind of frippy. A new procedural macro was added to reduce the boilerplate required for new error system. It can be used by deriving "Error" and adding a name for the Error via the "error" attribute. So far non of the plugins except for Url and Factoids use their own errors yet. --- Cargo.lock | 40 ++++++++- frippy_derive/Cargo.toml | 5 +- frippy_derive/src/lib.rs | 86 +++++++++++++++++- src/error.rs | 114 +++++------------------- src/lib.rs | 56 ++++++------ src/main.rs | 51 ++++++----- src/plugin.rs | 21 +++-- src/plugins/currency.rs | 28 +++--- src/plugins/emoji.rs | 25 +++--- src/plugins/factoids/database.rs | 88 ++++++++---------- src/plugins/factoids/mod.rs | 187 +++++++++++++++++++++++---------------- src/plugins/factoids/utils.rs | 6 +- src/plugins/help.rs | 16 ++-- src/plugins/keepnick.rs | 29 +++--- src/plugins/mod.rs | 23 ++--- src/plugins/tell/mod.rs | 32 ++++--- src/plugins/url.rs | 63 ++++++++----- src/utils.rs | 34 ++++--- 18 files changed, 528 insertions(+), 376 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dcbaad5..acb6f80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -414,8 +414,9 @@ dependencies = [ name = "frippy_derive" version = "0.1.0" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -925,6 +926,14 @@ name = "precomputed-hash" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pulldown-cmark" version = "0.0.15" @@ -949,6 +958,14 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "r2d2" version = "0.8.2" @@ -1246,6 +1263,16 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synom" version = "0.11.3" @@ -1427,6 +1454,11 @@ name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode_names" version = "0.1.7" @@ -1636,10 +1668,12 @@ dependencies = [ "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" "checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" "checksum r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9c29bad92da76d02bc2c020452ebc3a3fe6fa74cfab91e711c43116e4fb1a3" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" @@ -1675,6 +1709,7 @@ dependencies = [ "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" @@ -1695,6 +1730,7 @@ dependencies = [ "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)" = "" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" diff --git a/frippy_derive/Cargo.toml b/frippy_derive/Cargo.toml index 937afba..b258f57 100644 --- a/frippy_derive/Cargo.toml +++ b/frippy_derive/Cargo.toml @@ -7,5 +7,6 @@ authors = ["Jokler "] proc-macro = true [dependencies] -syn = "0.11.11" -quote = "0.3.15" +syn = "0.12.13" +quote = "0.4.2" +failure = "0.1.1" diff --git a/frippy_derive/src/lib.rs b/frippy_derive/src/lib.rs index 2622f0b..efa349a 100644 --- a/frippy_derive/src/lib.rs +++ b/frippy_derive/src/lib.rs @@ -1,18 +1,20 @@ - //! Provides the plugin derive macro +#![recursion_limit="128"] extern crate proc_macro; extern crate syn; #[macro_use] extern crate quote; +extern crate failure; + use proc_macro::TokenStream; #[proc_macro_derive(PluginName)] pub fn derive_plugin(data: TokenStream) -> TokenStream { - let ast = syn::parse_derive_input(&data.to_string()).unwrap(); + let ast = syn::parse(data).unwrap(); let gen = expand_plugin(&ast); - gen.parse().unwrap() + gen.into() } fn expand_plugin(ast: &syn::DeriveInput) -> quote::Tokens { @@ -27,3 +29,81 @@ fn expand_plugin(ast: &syn::DeriveInput) -> quote::Tokens { } } } + +#[proc_macro_derive(Error, attributes(error))] +pub fn derive_error(data: TokenStream) -> TokenStream { + let ast = syn::parse(data).unwrap(); + let tokens = expand_error(&ast); + // panic!("{}", tokens.to_string()); + tokens.into() +} + +fn expand_error(ast: &syn::DeriveInput) -> quote::Tokens { + if let syn::Data::Enum(_) = ast.data { + } else { + panic!("Error should only be derived on ErrorKind enums"); + }; + + let mut name = None; + for attr in &ast.attrs { + if let Some(syn::Meta::NameValue(name_value)) = attr.interpret_meta() { + if "error" == name_value.ident.to_string() { + if let syn::Lit::Str(lit) = name_value.lit { + name = Some(lit.value()); + } + } + } + }; + + let struct_name = if let Some(name) = name { + syn::Ident::from(name) + } else { + panic!("Define the error attribute for all Error derives"); + }; + + let enum_name = &ast.ident; + + quote! { + #[derive(Debug)] + pub struct #struct_name { + inner: ::failure::Context<#enum_name>, + } + + impl #struct_name { + pub fn kind(&self) -> #enum_name { + *self.inner.get_context() + } + } + + impl From<#enum_name> for #struct_name { + fn from(kind: #enum_name) -> #struct_name { + #struct_name { + inner: ::failure::Context::new(kind), + } + } + } + + impl From<::failure::Context<#enum_name>> for #struct_name { + fn from(inner: ::failure::Context<#enum_name>) -> #struct_name { + #struct_name { inner: inner } + } + } + + impl ::failure::Fail for #struct_name { + fn cause(&self) -> Option<&::failure::Fail> { + self.inner.cause() + } + + fn backtrace(&self) -> Option<&::failure::Backtrace> { + self.inner.backtrace() + } + } + + impl ::std::fmt::Display for #struct_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + use std::fmt; + fmt::Display::fmt(&self.inner, f) + } + } + } +} diff --git a/src/error.rs b/src/error.rs index fa232be..36d5724 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,101 +1,31 @@ //! Errors for `frippy` crate using `failure`. -use std::io::Error as IoError; -use irc::error::IrcError; -use reqwest::Error as ReqwestError; -#[cfg(feature = "mysql")] -use r2d2::Error as R2d2Error; +use failure::Fail; -/// The main crate-wide error type. -#[derive(Debug, Fail)] -pub enum FrippyError { - /// A plugin error - #[fail(display = "A plugin error occured")] - Plugin(#[cause] PluginError), - - /// An IRC error - #[fail(display = "An IRC error occured")] - Irc(#[cause] IrcError), - - /// Missing config error - #[fail(display = "No config file was found")] - MissingConfig, - - /// A reqwest error - #[fail(display = "A reqwest error occured")] - Reqwest(#[cause] ReqwestError), - - /// An I/O error - #[fail(display = "An I/O error occured")] - Io(#[cause] IoError), - - /// An r2d2 error - #[cfg(feature = "mysql")] - #[fail(display = "An r2d2 error occured")] - R2d2(#[cause] R2d2Error), - - /// Reached download limit error - #[fail(display = "Reached download limit of {} KiB", limit)] - DownloadLimit { limit: usize }, +pub fn log_error(e: FrippyError) { + let text = e.causes() + .skip(1) + .fold(format!("{}", e), |acc, err| format!("{}: {}", acc, err)); + error!("{}", text); } -/// Errors related to plugins -#[derive(Debug, Fail)] -pub enum PluginError { - /// A Url error - #[fail(display = "A Url error occured")] - Url(#[cause] UrlError), - - /// A Factoids error - #[fail(display = "{}", error)] - Factoids { error: String }, -} - -/// A URL plugin error -#[derive(Debug, Fail)] -pub enum UrlError { - /// Missing URL error - #[fail(display = "No URL was found")] - MissingUrl, - - /// Missing title error - #[fail(display = "No title was found")] - MissingTitle, -} - -impl From for FrippyError { - fn from(e: UrlError) -> FrippyError { - FrippyError::Plugin(PluginError::Url(e)) - } -} - -impl From for FrippyError { - fn from(e: PluginError) -> FrippyError { - FrippyError::Plugin(e) - } -} - -impl From for FrippyError { - fn from(e: IrcError) -> FrippyError { - FrippyError::Irc(e) - } -} +/// The main crate-wide error type. +#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] +#[error = "FrippyError"] +pub enum ErrorKind { + /// Connection error + #[fail(display = "A connection error occured")] + Connection, -impl From for FrippyError { - fn from(e: ReqwestError) -> FrippyError { - FrippyError::Reqwest(e) - } -} + /// A Url error + #[fail(display = "A Url error has occured")] + Url, -impl From for FrippyError { - fn from(e: IoError) -> FrippyError { - FrippyError::Io(e) - } -} + /// A Tell error + #[fail(display = "A Tell error has occured")] + Tell, -#[cfg(feature = "mysql")] -impl From for FrippyError { - fn from(e: R2d2Error) -> FrippyError { - FrippyError::R2d2(e) - } + /// A Factoids error + #[fail(display = "A Factoids error has occured")] + Factoids, } diff --git a/src/lib.rs b/src/lib.rs index 42b0089..8cf1e2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,8 @@ use std::sync::Arc; pub use irc::client::prelude::*; pub use irc::error::IrcError; -use error::FrippyError; +use error::*; +use failure::ResultExt; use plugin::*; @@ -150,11 +151,13 @@ impl Bot { pub fn connect(&self, reactor: &mut IrcReactor, config: &Config) -> Result<(), FrippyError> { info!("Plugins loaded: {}", self.plugins); - let client = reactor.prepare_client_and_connect(config)?; + let client = reactor + .prepare_client_and_connect(config) + .context(ErrorKind::Connection)?; info!("Connected to IRC server"); - client.identify()?; + client.identify().context(ErrorKind::Connection)?; info!("Identified"); // TODO Verify if we actually need to clone plugins twice @@ -169,25 +172,25 @@ impl Bot { } fn process_msg( - server: &IrcClient, + client: &IrcClient, mut plugins: ThreadedPlugins, message: Message, ) -> Result<(), IrcError> { // Log any channels we join if let Command::JOIN(ref channel, _, _) = message.command { - if message.source_nickname().unwrap() == server.current_nickname() { + if message.source_nickname().unwrap() == client.current_nickname() { info!("Joined {}", channel); } } // Check for possible command and save the result for later - let command = PluginCommand::from(&server.current_nickname().to_lowercase(), &message); + let command = PluginCommand::from(&client.current_nickname().to_lowercase(), &message); - plugins.execute_plugins(server, message); + plugins.execute_plugins(client, message); // If the message contained a command, handle it if let Some(command) = command { - if let Err(e) = plugins.handle_command(server, command) { + if let Err(e) = plugins.handle_command(client, command) { error!("Failed to handle command: {}", e); } } @@ -218,12 +221,12 @@ impl ThreadedPlugins { self.plugins.remove(&name.to_lowercase()).map(|_| ()) } - pub fn execute_plugins(&mut self, server: &IrcClient, message: Message) { + pub fn execute_plugins(&mut self, client: &IrcClient, message: Message) { let message = Arc::new(message); for (name, plugin) in self.plugins.clone() { // Send the message to the plugin if the plugin needs it - match plugin.execute(server, &message) { + match plugin.execute(client, &message) { ExecutionStatus::Done => (), ExecutionStatus::Err(e) => error!("Error in {} - {}", name, e), ExecutionStatus::RequiresThread => { @@ -233,15 +236,15 @@ impl ThreadedPlugins { message.to_string().replace("\r\n", "") ); - // Clone everything before the move - the server uses an Arc internally too + // Clone everything before the move - the client uses an Arc internally too let plugin = Arc::clone(&plugin); let message = Arc::clone(&message); - let server = server.clone(); + let client = client.clone(); // Execute the plugin in another thread spawn(move || { - if let Err(e) = plugin.execute_threaded(&server, &message) { - error!("Error in {} - {}", name, e); + if let Err(e) = plugin.execute_threaded(&client, &message) { + log_error(e); }; }); } @@ -251,12 +254,14 @@ impl ThreadedPlugins { pub fn handle_command( &mut self, - server: &IrcClient, + client: &IrcClient, mut command: PluginCommand, ) -> Result<(), FrippyError> { if !command.tokens.iter().any(|s| !s.is_empty()) { - let help = format!("Use \"{} help\" to get help", server.current_nickname()); - server.send_notice(&command.source, &help)?; + let help = format!("Use \"{} help\" to get help", client.current_nickname()); + client + .send_notice(&command.source, &help) + .context(ErrorKind::Connection)?; } // Check if the command is for this plugin @@ -266,12 +271,12 @@ impl ThreadedPlugins { debug!("Sending command \"{:?}\" to {}", command, name); - // Clone for the move - the server uses an Arc internally - let server = server.clone(); + // Clone for the move - the client uses an Arc internally + let client = client.clone(); let plugin = Arc::clone(plugin); spawn(move || { - if let Err(e) = plugin.command(&server, command) { - error!("Error in {} command - {}", name, e); + if let Err(e) = plugin.command(&client, command) { + log_error(e); }; }); @@ -280,11 +285,13 @@ impl ThreadedPlugins { let help = format!( "\"{} {}\" is not a command, \ try \"{0} help\" instead.", - server.current_nickname(), + client.current_nickname(), command.tokens[0] ); - Ok(server.send_notice(&command.source, &help)?) + Ok(client + .send_notice(&command.source, &help) + .context(ErrorKind::Connection)?) } } } @@ -298,6 +305,3 @@ impl fmt::Display for ThreadedPlugins { write!(f, "{}", plugin_names.join(", ")) } } - -#[cfg(test)] -mod tests {} diff --git a/src/main.rs b/src/main.rs index 3432e3e..b9a4b8f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,8 @@ extern crate r2d2; #[cfg(feature = "mysql")] extern crate r2d2_diesel; +#[macro_use] +extern crate failure; #[macro_use] extern crate log; @@ -27,9 +29,16 @@ use log::{Level, LevelFilter, Metadata, Record}; use irc::client::reactor::IrcReactor; use glob::glob; -use frippy::plugins; +pub use frippy::plugins::help::Help; +pub use frippy::plugins::url::Url; +pub use frippy::plugins::emoji::Emoji; +pub use frippy::plugins::tell::Tell; +pub use frippy::plugins::currency::Currency; +pub use frippy::plugins::keepnick::KeepNick; +pub use frippy::plugins::factoids::Factoids; + use frippy::Config; -use frippy::error::FrippyError; +use failure::Error; #[cfg(feature = "mysql")] embed_migrations!(); @@ -70,11 +79,14 @@ static LOGGER: Logger = Logger; fn main() { // Print any errors that caused frippy to shut down if let Err(e) = run() { - frippy::utils::log_error(e); + let text = e.causes() + .skip(1) + .fold(format!("{}", e), |acc, err| format!("{}: {}", acc, err)); + error!("{}", text); }; } -fn run() -> Result<(), FrippyError> { +fn run() -> Result<(), Error> { log::set_max_level(if cfg!(debug_assertions) { LevelFilter::Debug } else { @@ -100,7 +112,7 @@ fn run() -> Result<(), FrippyError> { // Without configs the bot would just idle if configs.is_empty() { - return Err(FrippyError::MissingConfig); + bail!("No config file was found"); } // Create an event loop to run the connections on. @@ -119,11 +131,11 @@ fn run() -> Result<(), FrippyError> { } let mut bot = frippy::Bot::new(); - bot.add_plugin(plugins::Help::new()); - bot.add_plugin(plugins::Url::new(1024)); - bot.add_plugin(plugins::Emoji::new()); - bot.add_plugin(plugins::Currency::new()); - bot.add_plugin(plugins::KeepNick::new()); + bot.add_plugin(Help::new()); + bot.add_plugin(Url::new(1024)); + bot.add_plugin(Emoji::new()); + bot.add_plugin(Currency::new()); + bot.add_plugin(KeepNick::new()); #[cfg(feature = "mysql")] { @@ -134,25 +146,24 @@ fn run() -> Result<(), FrippyError> { let manager = ConnectionManager::::new(url.clone()); match r2d2::Pool::builder().build(manager) { - Ok(pool) => match embedded_migrations::run(&*pool.get()?) - { + Ok(pool) => match embedded_migrations::run(&*pool.get()?) { Ok(_) => { let pool = Arc::new(pool); - bot.add_plugin(plugins::Factoids::new(pool.clone())); - bot.add_plugin(plugins::Tell::new(pool.clone())); + bot.add_plugin(Factoids::new(pool.clone())); + bot.add_plugin(Tell::new(pool.clone())); info!("Connected to MySQL server") } Err(e) => { - bot.add_plugin(plugins::Factoids::new(HashMap::new())); - bot.add_plugin(plugins::Tell::new(HashMap::new())); + bot.add_plugin(Factoids::new(HashMap::new())); + bot.add_plugin(Tell::new(HashMap::new())); error!("Failed to run migrations: {}", e); } }, Err(e) => error!("Failed to connect to database: {}", e), } } else { - bot.add_plugin(plugins::Factoids::new(HashMap::new())); - bot.add_plugin(plugins::Tell::new(HashMap::new())); + bot.add_plugin(Factoids::new(HashMap::new())); + bot.add_plugin(Tell::new(HashMap::new())); } } #[cfg(not(feature = "mysql"))] @@ -160,8 +171,8 @@ fn run() -> Result<(), FrippyError> { if mysql_url.is_some() { error!("frippy was not built with the mysql feature") } - bot.add_plugin(plugins::Factoids::new(HashMap::new())); - bot.add_plugin(plugins::Tell::new(HashMap::new())); + bot.add_plugin(Factoids::new(HashMap::new())); + bot.add_plugin(Tell::new(HashMap::new())); } if let Some(disabled_plugins) = disabled_plugins { diff --git a/src/plugin.rs b/src/plugin.rs index f33fa80..e57f072 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -2,16 +2,17 @@ use std::fmt; use irc::client::prelude::*; -use irc::error::IrcError; +use error::FrippyError; /// Describes if a [`Plugin`](trait.Plugin.html) is done working on a /// [`Message`](../../irc/proto/message/struct.Message.html) or if another thread is required. #[derive(Debug)] pub enum ExecutionStatus { - /// The [`Plugin`](trait.Plugin.html) does not need to do any more work on this [`Message`](../../irc/proto/message/struct.Message.html). + /// The [`Plugin`](trait.Plugin.html) does not need to do any more work on this + /// [`Message`](../../irc/proto/message/struct.Message.html). Done, /// An error occured during the execution. - Err(Box), + Err(FrippyError), /// The execution needs to be done by [`execute_threaded()`](trait.Plugin.html#tymethod.execute_threaded). RequiresThread, } @@ -19,15 +20,17 @@ pub enum ExecutionStatus { /// `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 { - /// Handles messages which are not commands or returns [`RequiresThread`](enum.ExecutionStatus.html#variant.RequiresThread) + /// Handles messages which are not commands or returns + /// [`RequiresThread`](enum.ExecutionStatus.html#variant.RequiresThread) /// if [`execute_threaded()`](trait.Plugin.html#tymethod.execute_threaded) should be used instead. - fn execute(&self, server: &IrcClient, message: &Message) -> ExecutionStatus; + fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus; /// Handles messages which are not commands in a new thread. - fn execute_threaded(&self, server: &IrcClient, message: &Message) -> Result<(), IrcError>; + fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError>; /// Handles any command directed at this plugin. - fn command(&self, server: &IrcClient, command: PluginCommand) -> Result<(), IrcError>; - /// Similar to [`command()`](trait.Plugin.html#tymethod.command) but return a String instead of sending messages directly to IRC. - fn evaluate(&self, server: &IrcClient, command: PluginCommand) -> Result; + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError>; + /// Similar to [`command()`](trait.Plugin.html#tymethod.command) but return a String instead of + /// sending messages directly to IRC. + fn evaluate(&self, client: &IrcClient, command: PluginCommand) -> Result; } /// `PluginName` is required by [`Plugin`](trait.Plugin.html). diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs index 958c8e2..53a245c 100644 --- a/src/plugins/currency.rs +++ b/src/plugins/currency.rs @@ -6,7 +6,6 @@ use std::io::Read; use std::num::ParseFloatError; use irc::client::prelude::*; -use irc::error::IrcError; use self::reqwest::Client; use self::reqwest::header::Connection; @@ -14,6 +13,10 @@ use self::serde_json::Value; use plugin::*; +use error::FrippyError; +use error::ErrorKind as FrippyErrorKind; +use failure::ResultExt; + #[derive(PluginName, Default, Debug)] pub struct Currency; @@ -124,20 +127,28 @@ impl Plugin for Currency { ExecutionStatus::Done } - fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), FrippyError> { panic!("Currency does not implement the execute function!") } - fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), FrippyError> { if command.tokens.is_empty() { - return client.send_notice(&command.source, &self.invalid_command(client)); + return Ok(client + .send_notice(&command.source, &self.invalid_command(client)) + .context(FrippyErrorKind::Connection)?); } match command.tokens[0].as_ref() { - "help" => client.send_notice(&command.source, &self.help(client)), + "help" => Ok(client + .send_notice(&command.source, &self.help(client)) + .context(FrippyErrorKind::Connection)?), _ => match self.convert(client, &mut command) { - Ok(msg) => client.send_privmsg(&command.target, &msg), - Err(msg) => client.send_notice(&command.source, &msg), + Ok(msg) => Ok(client + .send_privmsg(&command.target, &msg) + .context(FrippyErrorKind::Connection)?), + Err(msg) => Ok(client + .send_notice(&command.source, &msg) + .context(FrippyErrorKind::Connection)?), }, } } @@ -153,6 +164,3 @@ impl Plugin for Currency { } } } - -#[cfg(test)] -mod tests {} diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index a4276f4..f1d9376 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -3,10 +3,14 @@ extern crate unicode_names; use std::fmt; use irc::client::prelude::*; -use irc::error::IrcError; use plugin::*; +use error::FrippyError; +use error::ErrorKind as FrippyErrorKind; +use failure::Fail; +use failure::ResultExt; + struct EmojiHandle { symbol: char, count: i32, @@ -100,21 +104,23 @@ impl Plugin for Emoji { .send_privmsg(message.response_target().unwrap(), &self.emoji(content)) { Ok(_) => ExecutionStatus::Done, - Err(e) => ExecutionStatus::Err(Box::new(e)), + Err(e) => ExecutionStatus::Err(e.context(FrippyErrorKind::Connection).into()), }, _ => ExecutionStatus::Done, } } - fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), FrippyError> { 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.", - ) + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> { + Ok(client + .send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) + .context(FrippyErrorKind::Connection)?) } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { @@ -126,6 +132,3 @@ impl Plugin for Emoji { } } } - -#[cfg(test)] -mod tests {} diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index 88aa0fd..b1fe8dd 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -13,13 +13,12 @@ use diesel::mysql::MysqlConnection; use r2d2::Pool; #[cfg(feature = "mysql")] use r2d2_diesel::ConnectionManager; +#[cfg(feature = "mysql")] +use failure::ResultExt; use chrono::NaiveDateTime; -pub enum DbResponse { - Success, - Failed(&'static str), -} +use super::error::*; #[cfg_attr(feature = "mysql", derive(Queryable))] #[derive(Clone, Debug)] @@ -42,15 +41,15 @@ pub struct NewFactoid<'a> { } pub trait Database: Send { - fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse; - fn get_factoid(&self, name: &str, idx: i32) -> Option; - fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse; - fn count_factoids(&self, name: &str) -> Result; + fn insert_factoid(&mut self, factoid: &NewFactoid) -> Result<(), FactoidsError>; + fn get_factoid(&self, name: &str, idx: i32) -> Result; + fn delete_factoid(&mut self, name: &str, idx: i32) -> Result<(), FactoidsError>; + fn count_factoids(&self, name: &str) -> Result; } // HashMap impl Database for HashMap<(String, i32), Factoid> { - fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse { + fn insert_factoid(&mut self, factoid: &NewFactoid) -> Result<(), FactoidsError> { let factoid = Factoid { name: String::from(factoid.name), idx: factoid.idx, @@ -61,23 +60,25 @@ impl Database for HashMap<(String, i32), Factoid> { let name = factoid.name.clone(); match self.insert((name, factoid.idx), factoid) { - None => DbResponse::Success, - Some(_) => DbResponse::Failed("Factoid was overwritten"), + None => Ok(()), + Some(_) => Err(ErrorKind::Duplicate)?, } } - fn get_factoid(&self, name: &str, idx: i32) -> Option { - self.get(&(String::from(name), idx)).cloned() + fn get_factoid(&self, name: &str, idx: i32) -> Result { + Ok(self.get(&(String::from(name), idx)) + .cloned() + .ok_or(ErrorKind::NotFound)?) } - fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse { + fn delete_factoid(&mut self, name: &str, idx: i32) -> Result<(), FactoidsError> { match self.remove(&(String::from(name), idx)) { - Some(_) => DbResponse::Success, - None => DbResponse::Failed("Factoid not found"), + Some(_) => Ok(()), + None => Err(ErrorKind::NotFound)?, } } - fn count_factoids(&self, name: &str) -> Result { + fn count_factoids(&self, name: &str) -> Result { Ok(self.iter().filter(|&(&(ref n, _), _)| n == name).count() as i32) } } @@ -102,38 +103,31 @@ use self::schema::factoids; #[cfg(feature = "mysql")] impl Database for Arc>> { - fn insert_factoid(&mut self, factoid: &NewFactoid) -> DbResponse { + fn insert_factoid(&mut self, factoid: &NewFactoid) -> Result<(), FactoidsError> { use diesel; - let conn = &*self.get().expect("Failed to get connection"); - match diesel::insert_into(factoids::table) + let conn = &*self.get().context(ErrorKind::NoConnection)?; + diesel::insert_into(factoids::table) .values(factoid) .execute(conn) - { - Ok(_) => DbResponse::Success, - Err(e) => { - error!("DB Insertion Error: {}", e); - DbResponse::Failed("Failed to add factoid") - } - } + .context(ErrorKind::MysqlError)?; + + Ok(()) } - fn get_factoid(&self, name: &str, idx: i32) -> Option { - let conn = &*self.get().expect("Failed to get connection"); - match factoids::table.find((name, idx)).first(conn) { - Ok(f) => Some(f), - Err(e) => { - error!("DB Count Error: {}", e); - None - } - } + fn get_factoid(&self, name: &str, idx: i32) -> Result { + let conn = &*self.get().context(ErrorKind::NoConnection)?; + Ok(factoids::table + .find((name, idx)) + .first(conn) + .context(ErrorKind::MysqlError)?) } - fn delete_factoid(&mut self, name: &str, idx: i32) -> DbResponse { + fn delete_factoid(&mut self, name: &str, idx: i32) -> Result<(), FactoidsError> { use diesel; use self::factoids::columns; - let conn = &*self.get().expect("Failed to get connection"); + let conn = &*self.get().context(ErrorKind::NoConnection)?; match diesel::delete( factoids::table .filter(columns::name.eq(name)) @@ -142,22 +136,19 @@ impl Database for Arc>> { { Ok(v) => { if v > 0 { - DbResponse::Success + Ok(()) } else { - DbResponse::Failed("Could not find any factoid with that name") + Err(ErrorKind::NotFound)? } } - Err(e) => { - error!("DB Deletion Error: {}", e); - DbResponse::Failed("Failed to delete factoid") - } + Err(e) => Err(e).context(ErrorKind::MysqlError)?, } } - fn count_factoids(&self, name: &str) -> Result { + fn count_factoids(&self, name: &str) -> Result { use diesel; - let conn = &*self.get().expect("Failed to get connection"); + let conn = &*self.get().context(ErrorKind::NoConnection)?; let count: Result = factoids::table .filter(factoids::columns::name.eq(name)) .count() @@ -166,10 +157,7 @@ impl Database for Arc>> { match count { Ok(c) => Ok(c as i32), Err(diesel::NotFound) => Ok(0), - Err(e) => { - error!("DB Count Error: {}", e); - Err("Database Error") - } + Err(e) => Err(e).context(ErrorKind::MysqlError)?, } } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 806bb7e..2f3690f 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -5,21 +5,22 @@ use std::str::FromStr; use std::sync::Mutex; use self::rlua::prelude::*; use irc::client::prelude::*; -use irc::error::IrcError; -use error::FrippyError; -use error::PluginError; -use failure::Fail; use time; use chrono::NaiveDateTime; use plugin::*; pub mod database; -use self::database::{Database, DbResponse}; +use self::database::Database; mod utils; use self::utils::*; +use failure::ResultExt; +use error::ErrorKind as FrippyErrorKind; +use error::FrippyError; +use self::error::*; + static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); #[derive(PluginName)] @@ -43,8 +44,13 @@ impl Factoids { } } - fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, FrippyError> { - let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() })?; + fn create_factoid( + &self, + name: &str, + content: &str, + author: &str, + ) -> Result<&str, FactoidsError> { + let count = try_lock!(self.factoids).count_factoids(name)?; let tm = time::now().to_timespec(); let factoid = database::NewFactoid { @@ -55,15 +61,14 @@ impl Factoids { created: NaiveDateTime::from_timestamp(tm.sec, 0u32), }; - match try_lock!(self.factoids).insert_factoid(&factoid) { - DbResponse::Success => Ok("Successfully added"), - DbResponse::Failed(e) => Err(PluginError::Factoids { error: e.to_owned() })?, - } + Ok(try_lock!(self.factoids) + .insert_factoid(&factoid) + .map(|()| "Successfully added!")?) } - fn add(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<&str, FrippyError> { + fn add(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { if command.tokens.len() < 2 { - return Ok(self.invalid_command(client, command).map(|()| "")?); + Err(ErrorKind::InvalidCommand)?; } let name = command.tokens.remove(0); @@ -72,45 +77,41 @@ impl Factoids { Ok(self.create_factoid(&name, &content, &command.source)?) } - fn add_from_url( - &self, - client: &IrcClient, - command: &mut PluginCommand, - ) -> Result<&str, FrippyError> { + fn add_from_url(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { if command.tokens.len() < 2 { - return Ok(self.invalid_command(client, command).map(|()| "")?); + Err(ErrorKind::InvalidCommand)?; } let name = command.tokens.remove(0); let url = &command.tokens[0]; - let content = ::utils::download(url, Some(1024))?; + let content = ::utils::download(url, Some(1024)).context(ErrorKind::Download)?; Ok(self.create_factoid(&name, &content, &command.source)?) } - fn remove(&self, client: &IrcClient, command: &mut PluginCommand) -> Result<&str, FrippyError> { + fn remove(&self, command: &mut PluginCommand) -> Result<&str, FactoidsError> { if command.tokens.len() < 1 { - return Ok(self.invalid_command(client, command).map(|()| "")?); + Err(ErrorKind::InvalidCommand)?; } let name = command.tokens.remove(0); - let count = try_lock!(self.factoids).count_factoids(&name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; + let count = try_lock!(self.factoids).count_factoids(&name)?; match try_lock!(self.factoids).delete_factoid(&name, count - 1) { - DbResponse::Success => Ok("Successfully removed"), - DbResponse::Failed(e) => Err(PluginError::Factoids { error: e.to_owned() })?, + Ok(()) => Ok("Successfully removed"), + Err(e) => Err(e)?, } } - fn get(&self, client: &IrcClient, command: &PluginCommand) -> Result { + fn get(&self, command: &PluginCommand) -> Result { let (name, idx) = match command.tokens.len() { - 0 => return Ok(self.invalid_command(client, command).map(|()| String::new())?), + 0 => Err(ErrorKind::InvalidCommand)?, 1 => { let name = &command.tokens[0]; - let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; + let count = try_lock!(self.factoids).count_factoids(name)?; if count < 1 { - Err(PluginError::Factoids { error: format!("{} does not exist", name) })?; + Err(ErrorKind::NotFound)?; } (name, count - 1) @@ -119,61 +120,55 @@ impl Factoids { let name = &command.tokens[0]; let idx = match i32::from_str(&command.tokens[1]) { Ok(i) => i, - Err(_) => Err(PluginError::Factoids { error: String::from("Invalid index") })?, + Err(_) => Err(ErrorKind::InvalidCommand)?, }; (name, idx) } }; - let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { - Some(v) => v, - None => Err(PluginError::Factoids { error: format!("{}~{} does not exist", name, idx) })?, - }; + let factoid = try_lock!(self.factoids) + .get_factoid(name, idx) + .context(ErrorKind::NotFound)?; let message = factoid.content.replace("\n", "|").replace("\r", ""); Ok(format!("{}: {}", factoid.name, message)) } - fn info(&self, client: &IrcClient, command: &PluginCommand) -> Result { + fn info(&self, command: &PluginCommand) -> Result { match command.tokens.len() { - 0 => Ok(self.invalid_command(client, command).map(|()| String::new())?), + 0 => Err(ErrorKind::InvalidCommand)?, 1 => { let name = &command.tokens[0]; - let count = try_lock!(self.factoids).count_factoids(name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; + let count = try_lock!(self.factoids).count_factoids(name)?; Ok(match count { - 0 => Err(PluginError::Factoids { error: format!("{} does not exist", name) })?, + 0 => Err(ErrorKind::NotFound)?, 1 => format!("There is 1 version of {}", name), _ => format!("There are {} versions of {}", count, name), }) } _ => { let name = &command.tokens[0]; - let idx = i32::from_str(&command.tokens[1]).map_err(|_| PluginError::Factoids { error: String::from("Invalid index") })?; - - let factoid = match try_lock!(self.factoids).get_factoid(name, idx) { - Some(v) => v, - None => return Ok(format!("{}~{} does not exist", name, idx)), - }; + let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?; + let factoid = try_lock!(self.factoids).get_factoid(name, idx)?; - Ok(format!("{}: Added by {} at {} UTC", name, factoid.author, factoid.created)) + Ok(format!( + "{}: Added by {} at {} UTC", + name, factoid.author, factoid.created + )) } } } - fn exec( - &self, - client: &IrcClient, - mut command: PluginCommand, - ) -> Result { + fn exec(&self, mut command: PluginCommand) -> Result { if command.tokens.len() < 1 { - Ok(self.invalid_command(client, &command).map(|()| String::new())?) + Err(ErrorKind::InvalidIndex)? } else { let name = command.tokens.remove(0); - let count = try_lock!(self.factoids).count_factoids(&name).map_err(|e| PluginError::Factoids { error: e.to_owned() } )?; - let factoid = try_lock!(self.factoids).get_factoid(&name, count - 1).ok_or(PluginError::Factoids { error: format!("The factoid \"{}\" does not exist", name) })?; + let count = try_lock!(self.factoids).count_factoids(&name)?; + let factoid = try_lock!(self.factoids).get_factoid(&name, count - 1)?; let content = factoid.content; let value = if content.starts_with('>') { @@ -225,10 +220,6 @@ impl Factoids { Ok(output.join("|")) } - - fn invalid_command(&self, client: &IrcClient, command: &PluginCommand) -> Result<(), IrcError> { - client.send_notice(&command.source, "Invalid Command") - } } impl Plugin for Factoids { @@ -243,7 +234,7 @@ impl Plugin for Factoids { } } - fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> { if let Command::PRIVMSG(_, mut content) = message.command.clone() { content.remove(0); @@ -255,18 +246,22 @@ impl Plugin for Factoids { tokens: t, }; - match self.exec(client, c) { - Ok(f) => client.send_privmsg(&message.response_target().unwrap(), &f), - Err(_) => Ok(()), - } + Ok(match self.exec(c) { + Ok(f) => client + .send_privmsg(&message.response_target().unwrap(), &f) + .context(FrippyErrorKind::Connection)?, + Err(_) => (), + }) } else { Ok(()) } } - fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, client: &IrcClient, mut command: PluginCommand) -> Result<(), FrippyError> { if command.tokens.is_empty() { - return self.invalid_command(client, &command); + return Ok(client + .send_notice(&command.target, "Invalid command") + .context(FrippyErrorKind::Connection)?); } let target = command.target.clone(); @@ -274,19 +269,27 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); let result = match sub_command.as_ref() { - "add" => self.add(client, &mut command).map(|s| s.to_owned()), - "fromurl" => self.add_from_url(client, &mut command).map(|s| s.to_owned()), - "remove" => self.remove(client, &mut command).map(|s| s.to_owned()), - "get" => self.get(client, &command), - "info" => self.info(client, &command), - "exec" => self.exec(client, command), - _ => self.invalid_command(client, &command).map(|()| String::new()).map_err(|e| e.into()), + "add" => self.add(&mut command).map(|s| s.to_owned()), + "fromurl" => self.add_from_url(&mut command).map(|s| s.to_owned()), + "remove" => self.remove(&mut command).map(|s| s.to_owned()), + "get" => self.get(&command), + "info" => self.info(&command), + "exec" => self.exec(command), + _ => Err(ErrorKind::InvalidCommand.into()), }; Ok(match result { - Ok(v) => client.send_privmsg(&target, &v), - Err(e) => client.send_notice(&source, &e.cause().unwrap().to_string()), - }?) + Ok(v) => client + .send_privmsg(&target, &v) + .context(FrippyErrorKind::Connection)?, + Err(e) => { + let message = e.to_string(); + client + .send_notice(&source, &message) + .context(FrippyErrorKind::Connection)?; + Err(e).context(FrippyErrorKind::Factoids)? + } + }) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { @@ -301,3 +304,39 @@ impl fmt::Debug for Factoids { write!(f, "Factoids {{ ... }}") } } + +pub mod error { + #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] + #[error = "FactoidsError"] + pub enum ErrorKind { + /// Invalid command error + #[fail(display = "Invalid Command")] + InvalidCommand, + + /// Invalid index error + #[fail(display = "Invalid index")] + InvalidIndex, + + /// Download error + #[fail(display = "Download failed")] + Download, + + /// Duplicate error + #[fail(display = "Entry already exists")] + Duplicate, + + /// Not found error + #[fail(display = "Factoid was not found")] + NotFound, + + /// MySQL error + #[cfg(feature = "mysql")] + #[fail(display = "Failed to execute MySQL Query")] + MysqlError, + + /// No connection error + #[cfg(feature = "mysql")] + #[fail(display = "No connection to the database")] + NoConnection, + } +} diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs index 009b46b..70ac8a7 100644 --- a/src/plugins/factoids/utils.rs +++ b/src/plugins/factoids/utils.rs @@ -11,7 +11,11 @@ use self::LuaError::RuntimeError; pub fn download(_: &Lua, url: String) -> Result { match utils::download(&url, Some(1024)) { Ok(v) => Ok(v), - Err(e) => Err(RuntimeError(format!("Failed to download {} - {}", url, e.to_string()))), + Err(e) => Err(RuntimeError(format!( + "Failed to download {} - {}", + url, + e.to_string() + ))), } } diff --git a/src/plugins/help.rs b/src/plugins/help.rs index 4dd93d7..7e3658d 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -1,8 +1,11 @@ use irc::client::prelude::*; -use irc::error::IrcError; use plugin::*; +use error::FrippyError; +use error::ErrorKind as FrippyErrorKind; +use failure::ResultExt; + #[derive(PluginName, Default, Debug)] pub struct Help; @@ -17,18 +20,17 @@ impl Plugin for Help { ExecutionStatus::Done } - fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), FrippyError> { panic!("Help should not use threading") } - fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - client.send_notice(&command.source, "Help has not been added yet.") + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> { + Ok(client + .send_notice(&command.source, "Help has not been added yet.") + .context(FrippyErrorKind::Connection)?) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { Err(String::from("Help has not been added yet.")) } } - -#[cfg(test)] -mod tests {} diff --git a/src/plugins/keepnick.rs b/src/plugins/keepnick.rs index bdabd90..58ac167 100644 --- a/src/plugins/keepnick.rs +++ b/src/plugins/keepnick.rs @@ -1,8 +1,11 @@ use irc::client::prelude::*; -use irc::error::IrcError; use plugin::*; +use error::FrippyError; +use error::ErrorKind as FrippyErrorKind; +use failure::ResultExt; + #[derive(PluginName, Default, Debug)] pub struct KeepNick; @@ -25,9 +28,12 @@ impl KeepNick { if client_nick != cfg_nick { info!("Trying to switch nick from {} to {}", client_nick, cfg_nick); - match client.send(Command::NICK(cfg_nick)) { + match client + .send(Command::NICK(cfg_nick)) + .context(FrippyErrorKind::Connection) + { Ok(_) => ExecutionStatus::Done, - Err(e) => ExecutionStatus::Err(Box::new(e)), + Err(e) => ExecutionStatus::Err(e.into()), } } else { ExecutionStatus::Done @@ -45,21 +51,20 @@ impl Plugin for KeepNick { } } - fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), FrippyError> { 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.", - ) + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> { + Ok(client + .send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) + .context(FrippyErrorKind::Connection)?) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { Err(String::from("This Plugin does not implement any commands.")) } } - -#[cfg(test)] -mod tests {} diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 5b32efd..9a3ba2f 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,17 +1,8 @@ //! Collection of plugins included -mod help; -mod url; -mod emoji; -mod tell; -mod currency; -mod factoids; -mod keepnick; - -pub use self::help::Help; -pub use self::url::Url; -pub use self::emoji::Emoji; -pub use self::tell::Tell; -pub use self::currency::Currency; -pub use self::factoids::Factoids; -pub use self::factoids::database; -pub use self::keepnick::KeepNick; +pub mod help; +pub mod url; +pub mod emoji; +pub mod tell; +pub mod currency; +pub mod factoids; +pub mod keepnick; diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index 3a8feeb..7052b3e 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -1,5 +1,4 @@ use irc::client::prelude::*; -use irc::error::IrcError; use std::time::Duration; use std::sync::Mutex; @@ -10,6 +9,11 @@ use humantime::format_duration; use plugin::*; +use error::FrippyError; +use error::ErrorKind as FrippyErrorKind; +use failure::Fail; +use failure::ResultExt; + pub mod database; use self::database::{Database, DbResponse}; @@ -84,7 +88,7 @@ impl Tell { tell.sender, human_dur, tell.message ), ) { - return ExecutionStatus::Err(Box::new(e)); + return ExecutionStatus::Err(e.context(FrippyErrorKind::Connection).into()); } debug!( "Sent {:?} from {:?} to {:?}", @@ -123,22 +127,30 @@ impl Plugin for Tell { } } - fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), IrcError> { + fn execute_threaded(&self, _: &IrcClient, _: &Message) -> Result<(), FrippyError> { panic!("Tell should not use threading") } - fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> { if command.tokens.is_empty() { - return client.send_notice(&command.source, &self.invalid_command(client)); + return Ok(client + .send_notice(&command.source, &self.invalid_command(client)) + .context(FrippyErrorKind::Connection)?); } - match command.tokens[0].as_ref() { - "help" => client.send_notice(&command.source, &self.help(client)), + Ok(match command.tokens[0].as_ref() { + "help" => client + .send_notice(&command.source, &self.help(client)) + .context(FrippyErrorKind::Connection), _ => match self.tell_command(client, &command) { - Ok(msg) => client.send_notice(&command.source, msg), - Err(msg) => client.send_notice(&command.source, &msg), + Ok(msg) => client + .send_notice(&command.source, msg) + .context(FrippyErrorKind::Connection), + Err(msg) => client + .send_notice(&command.source, &msg) + .context(FrippyErrorKind::Connection), }, - } + }?) } fn evaluate(&self, _: &IrcClient, _: PluginCommand) -> Result { diff --git a/src/plugins/url.rs b/src/plugins/url.rs index 6f00466..fa4c6f4 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -2,7 +2,6 @@ extern crate regex; extern crate select; use irc::client::prelude::*; -use irc::error::IrcError; use self::regex::Regex; @@ -11,9 +10,12 @@ use self::select::predicate::Name; use plugin::*; use utils; + +use self::error::*; use error::FrippyError; -use error::UrlError; +use error::ErrorKind as FrippyErrorKind; use failure::Fail; +use failure::ResultExt; lazy_static! { static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap(); @@ -48,11 +50,11 @@ impl Url { Some(title_text) } - fn url(&self, text: &str) -> Result { - let url = self.grep_url(text).ok_or(UrlError::MissingUrl)?; - let body = utils::download(&url, Some(self.max_kib))?; + fn url(&self, text: &str) -> Result { + let url = self.grep_url(text).ok_or(ErrorKind::MissingUrl)?; + let body = utils::download(&url, Some(self.max_kib)).context(ErrorKind::Download)?; - Ok(self.get_title(&body).ok_or(UrlError::MissingTitle)?) + Ok(self.get_title(&body).ok_or(ErrorKind::MissingTitle)?) } } @@ -68,27 +70,48 @@ impl Plugin for Url { } } - fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), IrcError> { - match message.command { + fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> { + Ok(match message.command { Command::PRIVMSG(_, ref content) => match self.url(content) { - Ok(title) => client.send_privmsg(message.response_target().unwrap(), &title), - Err(e) => Ok(utils::log_error(e)), + Ok(title) => client + .send_privmsg(message.response_target().unwrap(), &title) + .context(FrippyErrorKind::Connection)?, + Err(e) => Err(e).context(FrippyErrorKind::Url)?, }, - _ => Ok(()), - } + _ => (), + }) } - fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), IrcError> { - client.send_notice( - &command.source, - "This Plugin does not implement any commands.", - ) + fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> { + Ok(client + .send_notice( + &command.source, + "This Plugin does not implement any commands.", + ) + .context(FrippyErrorKind::Connection)?) } fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result { - self.url(&command.tokens[0]).map_err(|e| e.cause().unwrap().to_string()) + self.url(&command.tokens[0]) + .map_err(|e| e.cause().unwrap().to_string()) } } -#[cfg(test)] -mod tests {} +pub mod error { + /// A URL plugin error + #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] + #[error = "UrlError"] + pub enum ErrorKind { + /// A download error + #[fail(display = "A download error occured")] + Download, + + /// Missing URL error + #[fail(display = "No URL was found")] + MissingUrl, + + /// Missing title error + #[fail(display = "No title was found")] + MissingTitle, + } +} diff --git a/src/utils.rs b/src/utils.rs index cf91b37..06156be 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,15 +4,19 @@ use std::io::{self, Read}; use reqwest::Client; use reqwest::header::Connection; -use failure::Fail; -use error::FrippyError; +use failure::ResultExt; +use self::error::{DownloadError, ErrorKind}; /// Downloads the file and converts it to a String. /// Any invalid bytes are converted to a replacement character. /// /// The error indicated either a failed download or that the DownloadLimit was reached -pub fn download(url: &str, max_kib: Option) -> Result { - let mut response = Client::new().get(url).header(Connection::close()).send()?; +pub fn download(url: &str, max_kib: Option) -> Result { + let mut response = Client::new() + .get(url) + .header(Connection::close()) + .send() + .context(ErrorKind::Connection)?; // 100 kibibyte buffer let mut buf = [0; 100 * 1024]; @@ -25,7 +29,7 @@ pub fn download(url: &str, max_kib: Option) -> Result break, Ok(len) => len, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, - Err(e) => Err(e)?, + Err(e) => Err(e).context(ErrorKind::Read)?, }; bytes.extend_from_slice(&buf); @@ -34,7 +38,7 @@ pub fn download(url: &str, max_kib: Option) -> Result max_kib * 1024 { - Err(FrippyError::DownloadLimit { limit: max_kib })?; + Err(ErrorKind::DownloadLimit)?; } } } @@ -42,12 +46,20 @@ pub fn download(url: &str, max_kib: Option) -> Result Date: Sat, 3 Mar 2018 18:02:36 +0100 Subject: Make tells caase insensitive and only check JOINs --- src/plugin.rs | 2 +- src/plugins/tell/mod.rs | 42 ++++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/plugin.rs b/src/plugin.rs index e57f072..bc428d5 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -45,7 +45,7 @@ pub trait Plugin: PluginName + Send + Sync + fmt::Debug { /// #[derive(PluginName)] /// struct Foo; /// ``` -pub trait PluginName: Send + Sync + fmt::Debug { +pub trait PluginName { /// Returns the name of the `Plugin`. fn name(&self) -> &str; } diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index 7052b3e..4f6bfa0 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -38,22 +38,27 @@ impl Tell { } } - fn tell_command(&self, client: &IrcClient, command: &PluginCommand) -> Result<&str, String> { + 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(); + let receiver = &command.tokens[0]; + let sender = command.source; - if receiver == sender { + if receiver.eq_ignore_ascii_case(&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)); + if let Some(channels) = client.list_channels() { + for channel in channels { + if let Some(users) = client.list_users(&channel) { + if users + .iter() + .any(|u| u.get_nickname().eq_ignore_ascii_case(&receiver)) + { + return Err(format!("{} is online in another channel.", receiver)); + } } } } @@ -62,7 +67,7 @@ impl Tell { let message = command.tokens[1..].join(" "); let tell = database::NewTellMessage { sender: &sender, - receiver: &receiver, + receiver: &receiver.to_lowercase(), time: NaiveDateTime::from_timestamp(tm.sec, 0u32), message: &message, }; @@ -73,9 +78,9 @@ impl Tell { } } - fn send_tell(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { + fn send_tells(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { let mut tells = try_lock!(self.tells); - if let Some(tell_messages) = tells.get_tells(receiver) { + if let Some(tell_messages) = tells.get_tells(&receiver.to_lowercase()) { for tell in tell_messages { let now = Duration::new(time::now().to_timespec().sec as u64, 0); let dur = now - Duration::new(tell.time.timestamp() as u64, 0); @@ -96,7 +101,8 @@ impl Tell { ); } } - tells.delete_tells(receiver); + tells.delete_tells(&receiver.to_lowercase()); + ExecutionStatus::Done } @@ -120,9 +126,7 @@ impl Tell { impl Plugin for Tell { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { - Command::JOIN(_, _, _) | Command::PRIVMSG(_, _) => { - self.send_tell(client, message.source_nickname().unwrap()) - } + Command::JOIN(_, _, _) => self.send_tells(client, message.source_nickname().unwrap()), _ => ExecutionStatus::Done, } } @@ -138,16 +142,18 @@ impl Plugin for Tell { .context(FrippyErrorKind::Connection)?); } + let sender = command.source.to_owned(); + Ok(match command.tokens[0].as_ref() { "help" => client .send_notice(&command.source, &self.help(client)) .context(FrippyErrorKind::Connection), - _ => match self.tell_command(client, &command) { + _ => match self.tell_command(client, command) { Ok(msg) => client - .send_notice(&command.source, msg) + .send_notice(&sender, msg) .context(FrippyErrorKind::Connection), Err(msg) => client - .send_notice(&command.source, &msg) + .send_notice(&sender, &msg) .context(FrippyErrorKind::Connection), }, }?) -- cgit v1.2.3-70-g09d2 From 71caa43d6fe4e54722c3d504c29d030255d0f0ee Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 3 Mar 2018 18:04:44 +0100 Subject: Correct error message on tell --- src/plugins/tell/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index 4f6bfa0..f781ed8 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -57,7 +57,7 @@ impl Tell { .iter() .any(|u| u.get_nickname().eq_ignore_ascii_case(&receiver)) { - return Err(format!("{} is online in another channel.", receiver)); + return Err(format!("{} is currently online.", receiver)); } } } -- cgit v1.2.3-70-g09d2 From 2754dac394cf48b840d3085715a2ffd1c97afdee Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 4 Mar 2018 01:46:11 +0100 Subject: Fix doctests --- src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8cf1e2f..a740ec7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,9 +16,9 @@ //! let mut reactor = IrcReactor::new().unwrap(); //! let mut bot = Bot::new(); //! -//! bot.add_plugin(plugins::Help::new()); -//! bot.add_plugin(plugins::Emoji::new()); -//! bot.add_plugin(plugins::Currency::new()); +//! bot.add_plugin(plugins::help::Help::new()); +//! bot.add_plugin(plugins::emoji::Emoji::new()); +//! bot.add_plugin(plugins::currency::Currency::new()); //! //! bot.connect(&mut reactor, &config).unwrap(); //! reactor.run().unwrap(); @@ -101,7 +101,7 @@ impl Bot { /// use frippy::{plugins, Bot}; /// /// let mut bot = frippy::Bot::new(); - /// bot.add_plugin(plugins::Help::new()); + /// bot.add_plugin(plugins::help::Help::new()); /// ``` pub fn add_plugin(&mut self, plugin: T) { self.plugins.add(plugin); @@ -116,7 +116,7 @@ impl Bot { /// use frippy::{plugins, Bot}; /// /// let mut bot = frippy::Bot::new(); - /// bot.add_plugin(plugins::Help::new()); + /// bot.add_plugin(plugins::help::Help::new()); /// bot.remove_plugin("Help"); /// ``` pub fn remove_plugin(&mut self, name: &str) -> Option<()> { -- cgit v1.2.3-70-g09d2 From 095af339c035bc750993318311c9a35ea455e9a7 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 5 Mar 2018 16:13:45 +0100 Subject: Add Tell specific errors and improve error logging for commands --- src/lib.rs | 2 +- src/plugins/tell/database.rs | 72 ++++++++++++--------------- src/plugins/tell/mod.rs | 114 +++++++++++++++++++++++++++++-------------- 3 files changed, 110 insertions(+), 78 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a740ec7..ebadb86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,7 +228,7 @@ impl ThreadedPlugins { // Send the message to the plugin if the plugin needs it match plugin.execute(client, &message) { ExecutionStatus::Done => (), - ExecutionStatus::Err(e) => error!("Error in {} - {}", name, e), + ExecutionStatus::Err(e) => log_error(e), ExecutionStatus::RequiresThread => { debug!( "Spawning thread to execute {} with {}", diff --git a/src/plugins/tell/database.rs b/src/plugins/tell/database.rs index 277847e..40ec6fc 100644 --- a/src/plugins/tell/database.rs +++ b/src/plugins/tell/database.rs @@ -16,10 +16,10 @@ use r2d2_diesel::ConnectionManager; use chrono::NaiveDateTime; -pub enum DbResponse { - Success, - Failed(&'static str), -} +#[cfg(feature = "mysql")] +use failure::ResultExt; + +use super::error::*; #[cfg_attr(feature = "mysql", derive(Queryable))] #[derive(PartialEq, Clone, Debug)] @@ -41,14 +41,14 @@ pub struct NewTellMessage<'a> { } pub trait Database: Send { - fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse; - fn get_tells(&self, receiver: &str) -> Option>; - fn delete_tells(&mut self, receiver: &str) -> DbResponse; + fn insert_tell(&mut self, tell: &NewTellMessage) -> Result<(), TellError>; + fn get_tells(&self, receiver: &str) -> Result, TellError>; + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError>; } // HashMap impl Database for HashMap> { - fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse { + fn insert_tell(&mut self, tell: &NewTellMessage) -> Result<(), TellError> { let tell = TellMessage { id: 0, sender: tell.sender.to_string(), @@ -62,17 +62,17 @@ impl Database for HashMap> { .or_insert_with(|| Vec::with_capacity(3)); (*tell_messages).push(tell); - DbResponse::Success + Ok(()) } - fn get_tells(&self, receiver: &str) -> Option> { - self.get(receiver).cloned() + fn get_tells(&self, receiver: &str) -> Result, TellError> { + Ok(self.get(receiver).cloned().ok_or(ErrorKind::NotFound)?) } - fn delete_tells(&mut self, receiver: &str) -> DbResponse { + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError> { match self.remove(receiver) { - Some(_) => DbResponse::Success, - None => DbResponse::Failed("Tells not found"), + Some(_) => Ok(()), + None => Err(ErrorKind::NotFound)?, } } } @@ -97,47 +97,37 @@ use self::schema::tells; #[cfg(feature = "mysql")] impl Database for Arc>> { - fn insert_tell(&mut self, tell: &NewTellMessage) -> DbResponse { + fn insert_tell(&mut self, tell: &NewTellMessage) -> Result<(), TellError> { use diesel; let conn = &*self.get().expect("Failed to get connection"); - match diesel::insert_into(tells::table).values(tell).execute(conn) { - Ok(_) => DbResponse::Success, - Err(e) => { - error!("DB failed to insert tell: {}", e); - DbResponse::Failed("Failed to save Tell") - } - } + diesel::insert_into(tells::table) + .values(tell) + .execute(conn) + .context(ErrorKind::MysqlError)?; + + Ok(()) } - fn get_tells(&self, receiver: &str) -> Option> { + fn get_tells(&self, receiver: &str) -> Result, TellError> { use self::tells::columns; - let conn = &*self.get().expect("Failed to get connection"); - match tells::table + let conn = &*self.get().context(ErrorKind::NoConnection)?; + Ok(tells::table .filter(columns::receiver.eq(receiver)) .order(columns::time.asc()) .load::(conn) - { - Ok(f) => Some(f), - Err(e) => { - error!("DB failed to get tells: {}", e); - None - } - } + .context(ErrorKind::MysqlError)?) } - fn delete_tells(&mut self, receiver: &str) -> DbResponse { + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError> { use diesel; use self::tells::columns; - let conn = &*self.get().expect("Failed to get connection"); - match diesel::delete(tells::table.filter(columns::receiver.eq(receiver))).execute(conn) { - Ok(_) => DbResponse::Success, - Err(e) => { - error!("DB failed to delete tells: {}", e); - DbResponse::Failed("Failed to delete tells") - } - } + let conn = &*self.get().context(ErrorKind::NoConnection)?; + diesel::delete(tells::table.filter(columns::receiver.eq(receiver))) + .execute(conn) + .context(ErrorKind::MysqlError)?; + Ok(()) } } diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index f781ed8..ccca300 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -9,13 +9,14 @@ use humantime::format_duration; use plugin::*; -use error::FrippyError; -use error::ErrorKind as FrippyErrorKind; use failure::Fail; use failure::ResultExt; +use error::ErrorKind as FrippyErrorKind; +use error::FrippyError; +use self::error::*; pub mod database; -use self::database::{Database, DbResponse}; +use self::database::Database; macro_rules! try_lock { ( $m:expr ) => { @@ -38,16 +39,20 @@ impl Tell { } } - fn tell_command(&self, client: &IrcClient, command: PluginCommand) -> Result<&str, String> { + fn tell_command( + &self, + client: &IrcClient, + command: PluginCommand, + ) -> Result { if command.tokens.len() < 2 { - return Err(self.invalid_command(client)); + return Ok(self.invalid_command(client)); } let receiver = &command.tokens[0]; let sender = command.source; if receiver.eq_ignore_ascii_case(&sender) { - return Err(String::from("That's your name!")); + return Ok(String::from("That's your name!")); } if let Some(channels) = client.list_channels() { @@ -57,7 +62,7 @@ impl Tell { .iter() .any(|u| u.get_nickname().eq_ignore_ascii_case(&receiver)) { - return Err(format!("{} is currently online.", receiver)); + return Ok(format!("{} is currently online.", receiver)); } } } @@ -72,36 +77,49 @@ impl Tell { message: &message, }; - match try_lock!(self.tells).insert_tell(&tell) { - DbResponse::Success => Ok("Got it!"), - DbResponse::Failed(e) => Err(e.to_string()), - } + try_lock!(self.tells).insert_tell(&tell)?; + + Ok(String::from("Got it!")) } fn send_tells(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { let mut tells = try_lock!(self.tells); - if let Some(tell_messages) = tells.get_tells(&receiver.to_lowercase()) { - for tell in tell_messages { - let now = Duration::new(time::now().to_timespec().sec as u64, 0); - let dur = now - Duration::new(tell.time.timestamp() as u64, 0); - let human_dur = format_duration(dur); - - if let Err(e) = client.send_notice( - receiver, - &format!( - "Tell from {} {} ago: {}", - tell.sender, human_dur, tell.message - ), - ) { - return ExecutionStatus::Err(e.context(FrippyErrorKind::Connection).into()); - } - debug!( - "Sent {:?} from {:?} to {:?}", - tell.message, tell.sender, receiver - ); + + let tell_messages = match tells.get_tells(&receiver.to_lowercase()) { + Ok(t) => t, + Err(e) => { + // This warning only occurs if frippy is built without a database + #[allow(unreachable_patterns)] + return match e.kind() { + ErrorKind::NotFound => ExecutionStatus::Done, + _ => ExecutionStatus::Err(e.context(FrippyErrorKind::Tell).into()), + }; + } + }; + + for tell in tell_messages { + let now = Duration::new(time::now().to_timespec().sec as u64, 0); + let dur = now - Duration::new(tell.time.timestamp() as u64, 0); + let human_dur = format_duration(dur); + + if let Err(e) = client.send_notice( + receiver, + &format!( + "Tell from {} {} ago: {}", + tell.sender, human_dur, tell.message + ), + ) { + return ExecutionStatus::Err(e.context(FrippyErrorKind::Connection).into()); } + debug!( + "Sent {:?} from {:?} to {:?}", + tell.message, tell.sender, receiver + ); } - tells.delete_tells(&receiver.to_lowercase()); + + if let Err(e) = tells.delete_tells(&receiver.to_lowercase()) { + return ExecutionStatus::Err(e.context(FrippyErrorKind::Tell).into()); + }; ExecutionStatus::Done } @@ -126,7 +144,9 @@ impl Tell { impl Plugin for Tell { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { - Command::JOIN(_, _, _) => self.send_tells(client, message.source_nickname().unwrap()), + Command::JOIN(_, _, _) => { + self.send_tells(client, message.source_nickname().unwrap()) + } _ => ExecutionStatus::Done, } } @@ -147,14 +167,16 @@ impl Plugin for Tell { Ok(match command.tokens[0].as_ref() { "help" => client .send_notice(&command.source, &self.help(client)) - .context(FrippyErrorKind::Connection), + .context(FrippyErrorKind::Connection) + .into(), _ => match self.tell_command(client, command) { Ok(msg) => client - .send_notice(&sender, msg) - .context(FrippyErrorKind::Connection), - Err(msg) => client .send_notice(&sender, &msg) .context(FrippyErrorKind::Connection), + Err(e) => client + .send_notice(&sender, &e.to_string()) + .context(FrippyErrorKind::Connection) + .into() }, }?) } @@ -170,3 +192,23 @@ impl fmt::Debug for Tell { write!(f, "Tell {{ ... }}") } } + +pub mod error { + #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)] + #[error = "TellError"] + pub enum ErrorKind { + /// Not found command error + #[fail(display = "Tell was not found")] + NotFound, + + /// MySQL error + #[cfg(feature = "mysql")] + #[fail(display = "Failed to execute MySQL Query")] + MysqlError, + + /// No connection error + #[cfg(feature = "mysql")] + #[fail(display = "No connection to the database")] + NoConnection, + } +} -- cgit v1.2.3-70-g09d2 From 3e439f17248a5168c22955d7cb4d0a9ba7531e5f Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 5 Mar 2018 16:15:44 +0100 Subject: Fix formatting --- src/plugins/tell/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index ccca300..dad5235 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -144,9 +144,7 @@ impl Tell { impl Plugin for Tell { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { match message.command { - Command::JOIN(_, _, _) => { - self.send_tells(client, message.source_nickname().unwrap()) - } + Command::JOIN(_, _, _) => self.send_tells(client, message.source_nickname().unwrap()), _ => ExecutionStatus::Done, } } @@ -174,9 +172,9 @@ impl Plugin for Tell { .send_notice(&sender, &msg) .context(FrippyErrorKind::Connection), Err(e) => client - .send_notice(&sender, &e.to_string()) - .context(FrippyErrorKind::Connection) - .into() + .send_notice(&sender, &e.to_string()) + .context(FrippyErrorKind::Connection) + .into(), }, }?) } -- cgit v1.2.3-70-g09d2 From 1bb6e307f1011456b28bb6eb27abc80e71ef187d Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 5 Mar 2018 18:11:51 +0100 Subject: Check for outstanding tells when a userlist is received --- src/plugins/tell/database.rs | 17 +++++++++ src/plugins/tell/mod.rs | 87 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/src/plugins/tell/database.rs b/src/plugins/tell/database.rs index 40ec6fc..98e9fb3 100644 --- a/src/plugins/tell/database.rs +++ b/src/plugins/tell/database.rs @@ -43,6 +43,7 @@ pub struct NewTellMessage<'a> { pub trait Database: Send { fn insert_tell(&mut self, tell: &NewTellMessage) -> Result<(), TellError>; fn get_tells(&self, receiver: &str) -> Result, TellError>; + fn get_receivers(&self) -> Result, TellError>; fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError>; } @@ -69,6 +70,12 @@ impl Database for HashMap> { Ok(self.get(receiver).cloned().ok_or(ErrorKind::NotFound)?) } + fn get_receivers(&self) -> Result, TellError> { + Ok(self.iter() + .map(|(receiver, _)| receiver.to_owned()) + .collect::>()) + } + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError> { match self.remove(receiver) { Some(_) => Ok(()), @@ -120,6 +127,16 @@ impl Database for Arc>> { .context(ErrorKind::MysqlError)?) } + fn get_receivers(&self) -> Result, TellError> { + use self::tells::columns; + + let conn = &*self.get().context(ErrorKind::NoConnection)?; + Ok(tells::table + .select(columns::receiver) + .load::(conn) + .context(ErrorKind::MysqlError)?) + } + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError> { use diesel; use self::tells::columns; diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index dad5235..a5a7116 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -51,6 +51,10 @@ impl Tell { let receiver = &command.tokens[0]; let sender = command.source; + if receiver.eq_ignore_ascii_case(client.current_nickname()) { + return Ok(String::from("I am right here!")); + } + if receiver.eq_ignore_ascii_case(&sender) { return Ok(String::from("That's your name!")); } @@ -82,7 +86,36 @@ impl Tell { Ok(String::from("Got it!")) } - fn send_tells(&self, client: &IrcClient, receiver: &str) -> ExecutionStatus { + fn on_namelist( + &self, + client: &IrcClient, + channel: &str, + ) -> Result<(), FrippyError> { + let receivers = try_lock!(self.tells) + .get_receivers() + .context(FrippyErrorKind::Tell)?; + + if let Some(users) = client.list_users(channel) { + debug!("Outstanding tells for {:?}", receivers); + + for receiver in users + .iter() + .map(|u| u.get_nickname()) + .filter(|u| receivers.iter().any(|r| r == &u.to_lowercase())) + { + self.send_tells(client, receiver)?; + } + + Ok(()) + } else { + Ok(()) + } + } + fn send_tells(&self, client: &IrcClient, receiver: &str) -> Result<(), FrippyError> { + if client.current_nickname() == receiver { + return Ok(()); + } + let mut tells = try_lock!(self.tells); let tell_messages = match tells.get_tells(&receiver.to_lowercase()) { @@ -91,8 +124,8 @@ impl Tell { // This warning only occurs if frippy is built without a database #[allow(unreachable_patterns)] return match e.kind() { - ErrorKind::NotFound => ExecutionStatus::Done, - _ => ExecutionStatus::Err(e.context(FrippyErrorKind::Tell).into()), + ErrorKind::NotFound => Ok(()), + _ => Err(e.context(FrippyErrorKind::Tell))?, }; } }; @@ -102,26 +135,27 @@ impl Tell { let dur = now - Duration::new(tell.time.timestamp() as u64, 0); let human_dur = format_duration(dur); - if let Err(e) = client.send_notice( - receiver, - &format!( - "Tell from {} {} ago: {}", - tell.sender, human_dur, tell.message - ), - ) { - return ExecutionStatus::Err(e.context(FrippyErrorKind::Connection).into()); - } + client + .send_notice( + receiver, + &format!( + "Tell from {} {} ago: {}", + tell.sender, human_dur, tell.message + ), + ) + .context(FrippyErrorKind::Connection)?; + debug!( "Sent {:?} from {:?} to {:?}", tell.message, tell.sender, receiver ); } - if let Err(e) = tells.delete_tells(&receiver.to_lowercase()) { - return ExecutionStatus::Err(e.context(FrippyErrorKind::Tell).into()); - }; + tells + .delete_tells(&receiver.to_lowercase()) + .context(FrippyErrorKind::Tell)?; - ExecutionStatus::Done + Ok(()) } fn invalid_command(&self, client: &IrcClient) -> String { @@ -143,9 +177,26 @@ impl Tell { impl Plugin for Tell { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { - match message.command { + let res = match message.command { Command::JOIN(_, _, _) => self.send_tells(client, message.source_nickname().unwrap()), - _ => ExecutionStatus::Done, + Command::Response(resp, ref chan_info, _) => { + if resp == Response::RPL_NAMREPLY { + debug!("NAMREPLY info: {:?}", chan_info); + + self.on_namelist( + client, + &chan_info[chan_info.len() - 1], + ) + } else { + Ok(()) + } + } + _ => Ok(()), + }; + + match res { + Ok(_) => ExecutionStatus::Done, + Err(e) => ExecutionStatus::Err(e), } } -- cgit v1.2.3-70-g09d2 From 2208ada6677b8aa4a5651fb21021049c1e59a1d4 Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 8 Mar 2018 16:53:11 +0100 Subject: Use a naive search for html titles to speed it up --- Cargo.lock | 149 ----------------------------------------------------- Cargo.toml | 1 - src/plugins/url.rs | 21 ++++---- 3 files changed, 9 insertions(+), 162 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acb6f80..ef78edb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,19 +46,6 @@ dependencies = [ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bit-set" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit-vec" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "0.9.1" @@ -177,14 +164,6 @@ dependencies = [ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "debug_unreachable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "derive-error-chain" version = "0.10.1" @@ -403,7 +382,6 @@ dependencies = [ "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -433,15 +411,6 @@ name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "futf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "futures" version = "0.1.18" @@ -471,18 +440,6 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "html5ever" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "httparse" version = "1.2.4" @@ -673,24 +630,6 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "markup5ever" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "matches" version = "0.1.6" @@ -921,11 +860,6 @@ name = "pkg-config" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "proc-macro2" version = "0.2.3" @@ -1083,11 +1017,6 @@ name = "rustc-demangle" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "safemem" version = "0.2.0" @@ -1135,15 +1064,6 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "select" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "semver" version = "0.6.0" @@ -1223,36 +1143,6 @@ name = "smallvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "string_cache" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string_cache_codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string_cache_shared" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "syn" version = "0.11.11" @@ -1304,16 +1194,6 @@ dependencies = [ "remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tendril" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" version = "0.3.5" @@ -1464,14 +1344,6 @@ name = "unicode_names" version = "0.1.7" source = "git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode#d97b80c3c35b9f1d04085409087ef113c94cde17" -[[package]] -name = "unreachable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unreachable" version = "1.0.0" @@ -1490,11 +1362,6 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "utf-8" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1568,8 +1435,6 @@ dependencies = [ "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" -"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" -"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" @@ -1585,7 +1450,6 @@ dependencies = [ "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" -"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" "checksum derive-error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92183014af72c63aea490e66526c712bf1066ac50f66c9f34824f02483ec1d98" "checksum diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925325c57038f2f14c0413bdf6a92ca72acff644959d0a1a9ebf8d19be7e9c01" @@ -1612,13 +1476,11 @@ dependencies = [ "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0bab5b5e94f5c31fc764ba5dd9ad16568aae5d4825538c01d6bca680c9bf94a7" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5369e01a05e3404c421b5d6dcfea6ecf7d5e65eba8a275948151358cd8282042" "checksum hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)" = "47659bb1cb7ef3cd7b4f9bd2a11349b8d92097d34f9597a3c09e9bcefaf92b61" @@ -1640,8 +1502,6 @@ dependencies = [ "checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -"checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum migrations_internals 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd916de6df9ac7e811e7e1ac28e0abfebe5205f3b29a7bda9ec8a41ee980a4eb" @@ -1667,7 +1527,6 @@ dependencies = [ "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" @@ -1686,14 +1545,12 @@ dependencies = [ "checksum reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "241faa9a8ca28a03cbbb9815a5d085f271d4c0168a19181f106aa93240c22ddb" "checksum rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6a9d2d1da31dd5cb4878789b924e46a600bdca4895b30f2efd6370d0dfc80e" "checksum rustc-demangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f312457f8a4fa31d3581a6f423a70d6c33a10b95291985df55f1ff670ec10ce8" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" "checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" @@ -1705,16 +1562,12 @@ dependencies = [ "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" -"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" -"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" -"checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" @@ -1732,10 +1585,8 @@ dependencies = [ "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)" = "" -"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" -"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" diff --git a/Cargo.toml b/Cargo.toml index 2d4087a..3f280b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ time = "0.1.39" humantime = "1.1.0" rlua = "0.12.2" reqwest = "0.8.5" -select = "0.4.2" regex = "0.2.6" lazy_static = "1.0.0" serde = "1.0.27" diff --git a/src/plugins/url.rs b/src/plugins/url.rs index fa4c6f4..4c33cba 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -1,13 +1,9 @@ extern crate regex; -extern crate select; use irc::client::prelude::*; use self::regex::Regex; -use self::select::document::Document; -use self::select::predicate::Name; - use plugin::*; use utils; @@ -39,22 +35,23 @@ impl Url { Some(captures.get(2)?.as_str().to_owned()) } - fn get_title(&self, body: &str) -> Option { - let doc = Document::from(body.as_ref()); - let title = doc.find(Name("title")).next()?; - let title = title.children().next()?; - let title_text = title.as_text()?.trim().replace("\n", "|"); + fn get_title<'a>(&self, body: &'a str) -> Option<&'a str> { + let title = body.find("") + .map(|start| body.find("").map(|end| &body[start + 7..end])) + .and_then(|s| s); + debug!("Title: {:?}", title); - debug!("Text: {:?}", title_text); - Some(title_text) + title } fn url(&self, text: &str) -> Result { let url = self.grep_url(text).ok_or(ErrorKind::MissingUrl)?; let body = utils::download(&url, Some(self.max_kib)).context(ErrorKind::Download)?; - Ok(self.get_title(&body).ok_or(ErrorKind::MissingTitle)?) + let title = self.get_title(&body).ok_or(ErrorKind::MissingTitle)?; + + Ok(title.to_owned()) } } -- cgit v1.2.3-70-g09d2 From e5e7a8d49729601b62e81d28e547d3828e839b28 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 9 Mar 2018 14:53:33 +0100 Subject: Check NICK commands in the tell plugin --- src/plugins/tell/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/tell/mod.rs b/src/plugins/tell/mod.rs index a5a7116..bdfb55c 100644 --- a/src/plugins/tell/mod.rs +++ b/src/plugins/tell/mod.rs @@ -179,6 +179,7 @@ impl Plugin for Tell { fn execute(&self, client: &IrcClient, message: &Message) -> ExecutionStatus { let res = match message.command { Command::JOIN(_, _, _) => self.send_tells(client, message.source_nickname().unwrap()), + Command::NICK(ref nick) => self.send_tells(client, nick), Command::Response(resp, ref chan_info, _) => { if resp == Response::RPL_NAMREPLY { debug!("NAMREPLY info: {:?}", chan_info); -- cgit v1.2.3-70-g09d2 From 9be7f31ee2d37800c7d23a9fff7d7ab8a2e076ed Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 10 Mar 2018 01:30:13 +0100 Subject: Decode html encoded characters in titles --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/plugins/url.rs | 16 +++++++++++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef78edb..2b6a8fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -373,6 +373,7 @@ dependencies = [ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "frippy_derive 0.1.0", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "irc 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -440,6 +441,11 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "httparse" version = "1.2.4" @@ -1481,6 +1487,7 @@ dependencies = [ "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5369e01a05e3404c421b5d6dcfea6ecf7d5e65eba8a275948151358cd8282042" "checksum hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)" = "47659bb1cb7ef3cd7b4f9bd2a11349b8d92097d34f9597a3c09e9bcefaf92b61" diff --git a/Cargo.toml b/Cargo.toml index 3f280b6..192939a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ glob = "0.2.11" failure = "0.1.1" frippy_derive = { path = "frippy_derive" } +htmlescape = "0.3.1" [dependencies.unicode_names] git = 'https://github.com/Jokler/unicode_names' diff --git a/src/plugins/url.rs b/src/plugins/url.rs index 4c33cba..e75d893 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -1,3 +1,4 @@ +extern crate htmlescape; extern crate regex; use irc::client::prelude::*; @@ -35,23 +36,24 @@ impl Url { Some(captures.get(2)?.as_str().to_owned()) } - fn get_title<'a>(&self, body: &'a str) -> Option<&'a str> { + fn get_title<'a>(&self, body: &str) -> Result { let title = body.find("") .map(|start| body.find("").map(|end| &body[start + 7..end])) - .and_then(|s| s); + .and_then(|s| s).ok_or(ErrorKind::MissingTitle)?; + debug!("Title: {:?}", title); - title + htmlescape::decode_html(title).map_err(|_| ErrorKind::HtmlDecoding.into()) } fn url(&self, text: &str) -> Result { let url = self.grep_url(text).ok_or(ErrorKind::MissingUrl)?; let body = utils::download(&url, Some(self.max_kib)).context(ErrorKind::Download)?; - let title = self.get_title(&body).ok_or(ErrorKind::MissingTitle)?; + let title = self.get_title(&body)?; - Ok(title.to_owned()) + Ok(title.replace('\n', "|").replace('\r', "|")) } } @@ -110,5 +112,9 @@ pub mod error { /// Missing title error #[fail(display = "No title was found")] MissingTitle, + + /// Html decoding error + #[fail(display = "Failed to decode Html characters")] + HtmlDecoding, } } -- cgit v1.2.3-70-g09d2 From 8e40e919aca8b8592be43e2c5bbcc0717bf14a6b Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 11 Mar 2018 20:55:40 +0100 Subject: Consider title tags with attributes --- src/plugins/url.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/url.rs b/src/plugins/url.rs index e75d893..bff840f 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -37,10 +37,20 @@ impl Url { } fn get_title<'a>(&self, body: &str) -> Result { - let title = body.find("") - .map(|start| body.find("").map(|end| &body[start + 7..end])) - .and_then(|s| s).ok_or(ErrorKind::MissingTitle)?; - + let title = body.find("') + .map(|offset| tag + offset + 1) + .map(|start| { + body[start..] + .find("") + .map(|offset| start + offset) + .map(|end| &body[start..end]) + }) + }) + .and_then(|s| s.and_then(|s| s)) + .ok_or(ErrorKind::MissingTitle)?; debug!("Title: {:?}", title); -- cgit v1.2.3-70-g09d2