aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2018-02-12 20:44:59 +0100
committerJokler <jokler.contact@gmail.com>2018-02-12 20:44:59 +0100
commitfb2a38846743f4b075b5f3bf9e9130fcf2f7bfec (patch)
treea1a58454e1ce629a0902486dac4bfdaf64e83108
parent72f1411f1c72a9271c7d3993a3e307050e8d1b31 (diff)
downloadfrippy-fb2a38846743f4b075b5f3bf9e9130fcf2f7bfec.tar.gz
frippy-fb2a38846743f4b075b5f3bf9e9130fcf2f7bfec.zip
Add Tell Plugin
-rw-r--r--src/plugins/mod.rs2
-rw-r--r--src/plugins/tell.rs133
2 files changed, 135 insertions, 0 deletions
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<HashMap<String, TellMessage>>,
+}
+
+#[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<String, String> {
+ Err(String::from("This Plugin does not implement any commands."))
+ }
+}
+
+#[cfg(test)]
+mod tests {}