From 0685c9676ddf7b650796465e85c4e2d53f596e46 Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 31 Oct 2019 01:07:19 +0100 Subject: Quote: Return random quote on missing user arg --- src/plugins/quote/database.rs | 55 ++++++++++++++++++++++++++++++++++++------- src/plugins/quote/mod.rs | 52 +++++++++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/plugins/quote/database.rs b/src/plugins/quote/database.rs index 49d6058..c8f550e 100644 --- a/src/plugins/quote/database.rs +++ b/src/plugins/quote/database.rs @@ -41,8 +41,10 @@ pub struct NewQuote<'a> { pub trait Database: Send + Sync { fn insert_quote(&mut self, quote: &NewQuote) -> Result<(), QuoteError>; - fn get_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result; - fn count_quotes(&self, quotee: &str, channel: &str) -> Result; + fn get_user_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result; + fn get_channel_quote(&self, channel: &str, idx: i32) -> Result; + fn count_user_quotes(&self, quotee: &str, channel: &str) -> Result; + fn count_channel_quotes(&self, channel: &str) -> Result; } // HashMap @@ -67,19 +69,34 @@ impl Database } } - fn get_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result { + fn get_user_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result { Ok(self .get(&(quotee.to_owned(), channel.to_owned(), idx)) .cloned() .ok_or(ErrorKind::NotFound)?) } - fn count_quotes(&self, quotee: &str, channel: &str) -> Result { + fn get_channel_quote(&self, channel: &str, idx: i32) -> Result { + Ok(self + .iter() + .filter(|&(&(_, ref c, _), _)| c == channel) + .nth(idx as usize - 1) + .ok_or(ErrorKind::NotFound)?.1.clone()) + } + + fn count_user_quotes(&self, quotee: &str, channel: &str) -> Result { Ok(self .iter() .filter(|&(&(ref n, ref c, _), _)| n == quotee && c == channel) .count() as i32) } + + fn count_channel_quotes(&self, channel: &str) -> Result { + Ok(self + .iter() + .filter(|&(&(_, ref c, _), _)| c == channel) + .count() as i32) + } } // Diesel automatically defines the quotes module as public. @@ -104,7 +121,6 @@ use self::schema::quotes; #[cfg(feature = "mysql")] impl Database for Arc>> { fn insert_quote(&mut self, quote: &NewQuote) -> Result<(), QuoteError> { - use diesel; let conn = &*self.get().context(ErrorKind::NoConnection)?; diesel::insert_into(quotes::table) @@ -115,7 +131,7 @@ impl Database for Arc>> { Ok(()) } - fn get_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result { + fn get_user_quote(&self, quotee: &str, channel: &str, idx: i32) -> Result { let conn = &*self.get().context(ErrorKind::NoConnection)?; Ok(quotes::table .find((quotee, channel, idx)) @@ -123,8 +139,16 @@ impl Database for Arc>> { .context(ErrorKind::MysqlError)?) } - fn count_quotes(&self, quotee: &str, channel: &str) -> Result { - use diesel; + fn get_channel_quote(&self, channel: &str, idx: i32) -> Result { + let conn = &*self.get().context(ErrorKind::NoConnection)?; + Ok(quotes::table + .filter(quotes::columns::channel.eq(channel)) + .offset(idx as i64 - 1) + .first(conn) + .context(ErrorKind::MysqlError)?) + } + + fn count_user_quotes(&self, quotee: &str, channel: &str) -> Result { let conn = &*self.get().context(ErrorKind::NoConnection)?; let count: Result = quotes::table @@ -139,4 +163,19 @@ impl Database for Arc>> { Err(e) => Err(e).context(ErrorKind::MysqlError)?, } } + + fn count_channel_quotes(&self, channel: &str) -> Result { + + let conn = &*self.get().context(ErrorKind::NoConnection)?; + let count: Result = quotes::table + .filter(quotes::columns::channel.eq(channel)) + .count() + .get_result(conn); + + match count { + Ok(c) => Ok(c as i32), + Err(diesel::NotFound) => Ok(0), + Err(e) => Err(e).context(ErrorKind::MysqlError)?, + } + } } diff --git a/src/plugins/quote/mod.rs b/src/plugins/quote/mod.rs index edeed40..c6e33fe 100644 --- a/src/plugins/quote/mod.rs +++ b/src/plugins/quote/mod.rs @@ -44,7 +44,7 @@ impl Quote { content: &str, author: &str, ) -> Result<&str, QuoteError> { - let count = self.quotes.read().count_quotes(quotee, channel)?; + let count = self.quotes.read().count_user_quotes(quotee, channel)?; let tm = time::now().to_timespec(); let quote = database::NewQuote { @@ -80,13 +80,13 @@ impl Quote { } fn get(&self, command: &PluginCommand) -> Result { - if command.tokens.is_empty() { - Err(ErrorKind::InvalidCommand)?; - } - - let quotee = &command.tokens[0]; + let quotee = &command.tokens.get(0); let channel = &command.target; - let count = self.quotes.read().count_quotes(quotee, channel)?; + let count = if let Some(quotee) = quotee { + self.quotes.read().count_user_quotes(quotee, channel)? + } else { + self.quotes.read().count_channel_quotes(channel)? + }; if count < 1 { Err(ErrorKind::NotFound)?; @@ -109,11 +109,19 @@ impl Quote { } }; - let quote = self - .quotes - .read() - .get_quote(quotee, channel, idx) - .context(ErrorKind::NotFound)?; + let quote = if let Some(quotee) = quotee { + self + .quotes + .read() + .get_user_quote(quotee, channel, idx) + .context(ErrorKind::NotFound)? + } else { + self + .quotes + .read() + .get_channel_quote(channel, idx) + .context(ErrorKind::NotFound)? + }; Ok(format!( "\"{}\" - {}[{}/{}]", @@ -122,12 +130,22 @@ impl Quote { } fn info(&self, command: &PluginCommand) -> Result { - match command.tokens.len() { - 0 => Err(ErrorKind::InvalidCommand)?, + let tokens = command.tokens.iter().filter(|t| !t.is_empty()).collect::>(); + match tokens.len() { + 0 => { + let channel = &command.target; + let count = self.quotes.read().count_channel_quotes(channel)?; + + Ok(match count { + 0 => Err(ErrorKind::NotFound)?, + 1 => format!("1 quote was saved in {}", channel), + _ => format!("{} quotes were saved in {}", channel, count), + }) + } 1 => { let quotee = &command.tokens[0]; let channel = &command.target; - let count = self.quotes.read().count_quotes(quotee, channel)?; + let count = self.quotes.read().count_user_quotes(quotee, channel)?; Ok(match count { 0 => Err(ErrorKind::NotFound)?, @@ -141,7 +159,7 @@ impl Quote { let idx = i32::from_str(&command.tokens[1]).context(ErrorKind::InvalidIndex)?; let idx = if idx < 0 { - self.quotes.read().count_quotes(quotee, channel)? + idx + 1 + self.quotes.read().count_user_quotes(quotee, channel)? + idx + 1 } else { idx }; @@ -149,7 +167,7 @@ impl Quote { let quote = self .quotes .read() - .get_quote(quotee, channel, idx) + .get_user_quote(quotee, channel, idx) .context(ErrorKind::NotFound)?; Ok(format!( -- cgit v1.2.3-70-g09d2