From ee1d099c6acdb38a173a7455804724f3a1b78836 Mon Sep 17 00:00:00 2001 From: Nathan Perry Date: Thu, 5 Apr 2018 22:52:02 -0400 Subject: consolidate memes to one table --- src/commands/meme.rs | 126 +++++++++++++++++++++++++-------------------------- src/db/mod.rs | 52 ++++++++++----------- src/db/models.rs | 94 ++++++++++++++++++++------------------ src/db/schema.rs | 46 +++++-------------- 4 files changed, 146 insertions(+), 172 deletions(-) (limited to 'src') diff --git a/src/commands/meme.rs b/src/commands/meme.rs index bb7315c..43362e1 100644 --- a/src/commands/meme.rs +++ b/src/commands/meme.rs @@ -30,89 +30,85 @@ command!(meme(ctx, msg, args) { let ch = msg.channel_id; if args.len() == 0 { - let conn = connection()?; - - let should_audio = ctx.currently_playing() && ctx.users_listening()?; - let dist: WeightedChoice<'static, MemeType> = if should_audio { - WeightedChoice::new(unsafe { &mut MEME_WEIGHTS }) - } else { - WeightedChoice::new(unsafe { &mut MEME_WEIGHTS[..2] }) - }; - - match dist.sample(&mut thread_rng()) { - MemeType::Text => { - let mut text_meme = rand_text(&conn)?; - - let mut ctr = 0; - while !should_audio && text_meme.audio_id.is_some() { - text_meme = rand_text(&conn)?; - - ctr += 1; - if ctr > 10 { - warn!("looped 10 times trying to find a non-audio text meme"); - return Ok(()); - } - } - - send_text(ctx, &text_meme, &conn, msg)?; - }, - MemeType::Image => { - let image_meme = rand_image(&conn)?; - let image = image_meme.associated_data(&conn)?; - - send_image(&image_meme, &image, ch)?; - }, - MemeType::Audio => { - let audio = rand_audio(&conn)?.associated_data(&conn)?; - send_audio(ctx, msg, &audio)?; - } - } + rand_meme(ctx, msg)?; + return Ok(()); } }); -fn send_text(ctx: &Context, t: &TextMeme, conn: &PgConnection, msg: &Message) -> Result<()> { - let (image, audio) = t.associated_data(conn)?; +fn rand_meme(ctx: &Context, message: &Message) -> Result<()> { + let conn = connection()?; - let dist = WeightedChoice::new(unsafe { &mut TTS_WEIGHTS }); + let should_audio = ctx.currently_playing() && ctx.users_listening()?; + let dist: WeightedChoice<'static, MemeType> = if should_audio { + WeightedChoice::new(unsafe { &mut MEME_WEIGHTS }) + } else { + WeightedChoice::new(unsafe { &mut MEME_WEIGHTS[..2] }) + }; - let create_msg = |m: CreateMessage| m - .tts(dist.sample(&mut thread_rng())) - .content(&t.content); + match dist.sample(&mut thread_rng()) { + MemeType::Text => { + let mut text_meme = rand_text(&conn)?; - match image { - Some(image) => msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image.data, &t.title))), create_msg)?, - None => msg.channel_id.send_message(create_msg)?, - }; + let mut ctr = 0; + while !should_audio && text_meme.audio_id.is_some() { + text_meme = rand_text(&conn)?; - if let Some(audio) = audio { - send_audio(ctx, msg, &audio)?; + ctr += 1; + if ctr > 10 { + warn!("looped 10 times trying to find a non-audio text meme"); + return Ok(()); + } + } + + send_meme(ctx, &text_meme, &conn, message)?; + }, + MemeType::Image => send_meme(ctx, &rand_image(&conn)?, &conn, message)?, + MemeType::Audio => send_meme(ctx, &rand_audio(&conn)?, &conn, message)?, } Ok(()) } -fn send_image(image_meme: &ImageMeme, image: &Image, ch: ChannelId) -> Result<()> { - ch.send_files(vec!(AttachmentType::Bytes((&image.data, &image_meme.title))), |m| m.content(""))?; - Ok(()) -} -// note: slight edge-case race condition here: there could have been something queued since we -// checked whether anything was playing. not a significant negative impact and unlikely, so i'm -// not worrying about it -fn send_audio(ctx: &Context, msg: &Message, audio: &Audio) -> Result<()> { - let queue_lock = ctx.data.lock().get::().cloned().unwrap(); - let mut play_queue = queue_lock.write().unwrap(); +fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Result<()> { + let image = t.image(conn); + let audio = t.audio(conn); + + let dist = WeightedChoice::new(unsafe { &mut TTS_WEIGHTS }); + + let create_msg = |m: CreateMessage| { + let ret = m + .tts(dist.sample(&mut thread_rng())); + + match t.content { + Some(ref text) => ret.content(text), + None => ret + } + }; + + match image { + Some(image) => msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image?.data, &t.title))), create_msg)?, + None => msg.channel_id.send_message(create_msg)?, + }; - play_queue.queue.push_front(PlayArgs{ - initiator: msg.author.name.clone(), - data: ::either::Right(audio.data.clone()), - sender_channel: msg.channel_id, - }); + // note: slight edge-case race condition here: there could have been something queued since we + // checked whether anything was playing. not a significant negative impact and unlikely, so i'm + // not worrying about it + if let Some(audio) = audio { + let audio = audio?; + let queue_lock = ctx.data.lock().get::().cloned().unwrap(); + let mut play_queue = queue_lock.write().unwrap(); + + play_queue.queue.push_front(PlayArgs{ + initiator: msg.author.name.clone(), + data: ::either::Right(audio.data.clone()), + sender_channel: msg.channel_id, + }); + } Ok(()) } - pub fn db_fallback(ctx: &mut Context, msg: &Message, s: &str) -> Result<()> { diff --git a/src/db/mod.rs b/src/db/mod.rs index e1c3a55..258d5a5 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -19,60 +19,58 @@ pub fn connection() -> Result { CONN_MGR.connect().map_err(Error::from) } -pub trait AssociatedData { - type Associated; - - fn associated_data(&self, conn: &PgConnection) -> Result; -} - -pub fn find_text(conn: &PgConnection, search: String) -> Result { +pub fn find_text(conn: &PgConnection, search: String) -> Result { + use diesel::dsl::sql; let format_search = format!("%{}%", search); - text_memes::table - .filter(text_memes::title.ilike(&format_search).or(text_memes::content.ilike(&format_search))) + memes::table + .filter(memes::title.ilike(&format_search).or(sql(&format!("content ILIKE %{}%", search)))) .limit(1) - .first::(conn) + .first::(conn) .map_err(Error::from) } -pub fn find_audio(conn: &PgConnection, search: String) -> Result { +pub fn find_audio(conn: &PgConnection, search: String) -> Result { let format_search = format!("%{}%", search); - audio_memes::table - .filter(audio_memes::title.ilike(format_search)) + memes::table + .filter(memes::title.ilike(format_search).and(memes::audio_id.is_not_null())) .limit(1) - .first::(conn) + .first::(conn) .map_err(Error::from) } -pub fn find_image(conn: &PgConnection, search: String) -> Result { +pub fn find_image(conn: &PgConnection, search: String) -> Result { let format_search = format!("%{}%", search); - image_memes::table - .filter(image_memes::title.ilike(format_search)) + memes::table + .filter(memes::title.ilike(format_search).and(memes::image_id.is_not_null())) .limit(1) - .first::(conn) + .first::(conn) .map_err(Error::from) } -pub fn rand_text(conn: &PgConnection) -> Result { - text_memes::table +pub fn rand_text(conn: &PgConnection) -> Result { + memes::table + .filter(memes::content.is_not_null()) .order(random.desc()) - .first::(conn) + .first::(conn) .map_err(Error::from) } -pub fn rand_image(conn: &PgConnection) -> Result { - image_memes::table +pub fn rand_image(conn: &PgConnection) -> Result { + memes::table + .filter(memes::image_id.is_not_null()) .order(random.desc()) - .first::(conn) + .first::(conn) .map_err(Error::from) } -pub fn rand_audio(conn: &PgConnection) -> Result { - audio_memes::table +pub fn rand_audio(conn: &PgConnection) -> Result { + memes::table + .filter(memes::audio_id.is_not_null()) .order(random.desc()) - .first::(conn) + .first::(conn) .map_err(Error::from) } diff --git a/src/db/models.rs b/src/db/models.rs index c07a12a..7479fff 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -2,85 +2,73 @@ use chrono::naive::NaiveDateTime; use diesel::prelude::*; use super::schema::*; -use super::AssociatedData; use ::{Result, Error}; -#[derive(Insertable, Queryable, Identifiable, PartialEq, AsChangeset, Debug)] -#[table_name="text_memes"] -pub struct TextMeme { +#[derive(Queryable, Identifiable, PartialEq, Debug)] +#[table_name="memes"] +pub struct Meme { pub id: i32, pub title: String, - pub content: String, + pub content: Option, pub image_id: Option, pub audio_id: Option, pub metadata_id: i32, } -impl AssociatedData for TextMeme { - type Associated = (Option, Option