diff options
| author | Jokler <jokler.contact@gmail.com> | 2018-02-25 18:54:16 +0100 |
|---|---|---|
| committer | Jokler <jokler.contact@gmail.com> | 2018-02-25 18:54:16 +0100 |
| commit | 92668ad4c53edcc1a317a16aa5ea30ca502f54ee (patch) | |
| tree | 4a93dad53b06f2b4dccfaf0282e8e9ee94b3a070 /src/plugins/tell/mod.rs | |
| parent | 76461addd2fb7ec383123b1efc4368b7662eea04 (diff) | |
| download | frippy-92668ad4c53edcc1a317a16aa5ea30ca502f54ee.tar.gz frippy-92668ad4c53edcc1a317a16aa5ea30ca502f54ee.zip | |
Add Mysql as a possible database to the Tell plugin
Diffstat (limited to 'src/plugins/tell/mod.rs')
| -rw-r--r-- | src/plugins/tell/mod.rs | 144 |
1 files changed, 144 insertions, 0 deletions
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<T: Database> { + tells: Mutex<T>, +} + +impl<T: Database> Tell<T> { + pub fn new(db: T) -> Tell<T> { + 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<T: Database> Plugin for Tell<T> { + 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<String, String> { + Err(String::from("This Plugin does not implement any commands.")) + } +} + +use std::fmt; +impl<T: Database> fmt::Debug for Tell<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Tell {{ ... }}") + } +} |
