diff options
| author | Jokler <jokler.contact@gmail.com> | 2018-03-05 18:11:51 +0100 |
|---|---|---|
| committer | Jokler <jokler.contact@gmail.com> | 2018-03-05 18:11:51 +0100 |
| commit | 1bb6e307f1011456b28bb6eb27abc80e71ef187d (patch) | |
| tree | 5cb3b84e07a3252e247704fac058848148ccd441 /src | |
| parent | 3e439f17248a5168c22955d7cb4d0a9ba7531e5f (diff) | |
| download | frippy-1bb6e307f1011456b28bb6eb27abc80e71ef187d.tar.gz frippy-1bb6e307f1011456b28bb6eb27abc80e71ef187d.zip | |
Check for outstanding tells when a userlist is received
Diffstat (limited to 'src')
| -rw-r--r-- | src/plugins/tell/database.rs | 17 | ||||
| -rw-r--r-- | 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<Vec<TellMessage>, TellError>; + fn get_receivers(&self) -> Result<Vec<String>, TellError>; fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError>; } @@ -69,6 +70,12 @@ impl Database for HashMap<String, Vec<TellMessage>> { Ok(self.get(receiver).cloned().ok_or(ErrorKind::NotFound)?) } + fn get_receivers(&self) -> Result<Vec<String>, TellError> { + Ok(self.iter() + .map(|(receiver, _)| receiver.to_owned()) + .collect::<Vec<_>>()) + } + fn delete_tells(&mut self, receiver: &str) -> Result<(), TellError> { match self.remove(receiver) { Some(_) => Ok(()), @@ -120,6 +127,16 @@ impl Database for Arc<Pool<ConnectionManager<MysqlConnection>>> { .context(ErrorKind::MysqlError)?) } + fn get_receivers(&self) -> Result<Vec<String>, TellError> { + use self::tells::columns; + + let conn = &*self.get().context(ErrorKind::NoConnection)?; + Ok(tells::table + .select(columns::receiver) + .load::<String>(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<T: Database> Tell<T> { 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<T: Database> Tell<T> { 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<T: Database> Tell<T> { // 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<T: Database> Tell<T> { 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<T: Database> Tell<T> { impl<T: Database> Plugin for Tell<T> { 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), } } |
