diff options
| -rw-r--r-- | src/commands/meme.rs | 28 | ||||
| -rw-r--r-- | src/db/mod.rs | 42 |
2 files changed, 30 insertions, 40 deletions
diff --git a/src/commands/meme.rs b/src/commands/meme.rs index 9cba630..0f9cda8 100644 --- a/src/commands/meme.rs +++ b/src/commands/meme.rs @@ -30,7 +30,10 @@ use crate::{ PlayQueue, }, commands::send, - db::*, + db::{ + *, + rand_meme as db_rand_meme, + }, Result, }; @@ -238,29 +241,8 @@ fn rand_meme(ctx: &Context, message: &Message) -> Result<()> { let conn = connection()?; let should_audio = ctx.currently_playing() && ctx.users_listening()?; - let modulus = if should_audio { 3 } else { 2 }; - - let mem = match thread_rng().gen::<u32>() % modulus { - 0 => rand_text(&conn), - 1 => rand_image(&conn), - 2 => rand_audio(&conn), - _ => unreachable!(), - } - .or_else(|_| rand_text(&conn)) - .and_then(|mut mem| { - let mut ctr = 0; - while !should_audio && mem.audio_id.is_some() { - mem = rand_text(&conn)?; - ctr += 1; - if ctr > 10 { - send(message.channel_id, "yer listenin to somethin else", message.tts)?; - bail!("looped too many times trying to find a non-audio meme"); - } - } - - Ok(mem) - }); + let mem = db_rand_meme(&conn, should_audio); match mem { Ok(mem) => { diff --git a/src/db/mod.rs b/src/db/mod.rs index 1ff05ce..1c2a032 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -102,26 +102,34 @@ pub fn delete_meme<T: AsRef<str>>(conn: &PgConnection, search: T, deleted_by: u6 }) } -pub fn rand_text(conn: &PgConnection) -> Result<Meme> { - memes::table - .filter(memes::content.is_not_null()) - .order(random.desc()) - .first::<Meme>(conn) - .map_err(Error::from) -} +pub fn rand_meme(conn: &PgConnection, audio: bool) -> Result<Meme> { + use rand::{thread_rng, seq::SliceRandom}; + use failure::err_msg; + use std::ops::Try; -pub fn rand_image(conn: &PgConnection) -> Result<Meme> { - memes::table - .filter(memes::image_id.is_not_null()) - .order(random.desc()) - .first::<Meme>(conn) - .map_err(Error::from) -} + let ids: Vec<i32> = if audio { + memes::table + .select(memes::id) + .filter(memes::content.is_not_null() + .or(memes::image_id.is_not_null()) + .or(memes::audio_id.is_not_null())) + .load(conn) + .map_err(Error::from)? + } else { + memes::table + .select(memes::id) + .filter(memes::content.is_not_null() + .or(memes::image_id.is_not_null())) + .load(conn) + .map_err(Error::from)? + }; + + let id = ids.choose(&mut thread_rng()) + .into_result() + .map_err( |_| err_msg("couldn't load meme"))?; -pub fn rand_audio(conn: &PgConnection) -> Result<Meme> { memes::table - .filter(memes::audio_id.is_not_null()) - .order(random.desc()) + .find(id) .first::<Meme>(conn) .map_err(Error::from) } |
