diff options
| author | Nathan Perry <avaglir@gmail.com> | 2019-03-03 02:39:24 -0500 |
|---|---|---|
| committer | Nathan Perry <avaglir@gmail.com> | 2019-03-03 02:39:24 -0500 |
| commit | 83a06bfbd18e4f539b8e42e8e65d719040863100 (patch) | |
| tree | 93e93db99ee97b75672f714e48fdfd3ce53bde92 /src | |
| parent | 410596f875111fab3d666a472c61be8869d7f7ec (diff) | |
record meme invocations
Diffstat (limited to 'src')
| -rw-r--r-- | src/commands/meme.rs | 79 | ||||
| -rw-r--r-- | src/commands/mod.rs | 6 | ||||
| -rw-r--r-- | src/db/models.rs | 49 | ||||
| -rw-r--r-- | src/db/schema.rs | 12 |
4 files changed, 121 insertions, 25 deletions
diff --git a/src/commands/meme.rs b/src/commands/meme.rs index f83b793..84035ff 100644 --- a/src/commands/meme.rs +++ b/src/commands/meme.rs @@ -4,12 +4,10 @@ use std::{ Command, Stdio, }, - sync::RwLock, }; use diesel::PgConnection; use failure::Error; -use lazy_static::lazy_static; use rand::{Rng, thread_rng}; use serenity::{ builder::CreateMessage, @@ -38,17 +36,6 @@ use crate::{ Result, }; -lazy_static! { - static ref LAST_MEME: RwLock<Option<i32>> = RwLock::new(None); -} - -fn update_meme(meme: &Meme) -> Result<()> { - let mut opt = LAST_MEME.write().map_err(|_| crate::failure::err_msg("unable to acquire lock"))?; - *opt = Some(meme.id); - - Ok(()) -} - #[inline] pub fn meme(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> { _meme(ctx, msg, args, false) @@ -69,7 +56,7 @@ fn _meme(ctx: &mut Context, msg: &Message, args: Args, audio_only: bool) -> Resu let conn = connection()?; let mem = match find_meme(&conn, search) { Ok(x) => { - update_meme(&x)?; + InvocationRecord::create(&conn, msg.author.id.0, msg.id.0, x.id, false)?; x }, @@ -90,17 +77,13 @@ fn _meme(ctx: &mut Context, msg: &Message, args: Args, audio_only: bool) -> Resu } pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { - use failure::err_msg; - let conn = connection()?; - let meme = LAST_MEME.read() - .map_err(|_| err_msg("unable to acquire read lock")) - .and_then(|id| { - id.ok_or(err_msg("no previous meme")) - .and_then(|id| { - Meme::find(&conn, id) - }) - }); + + let record = match InvocationRecord::last(&conn) { + Ok(x) => x, + Err(_) => return send(msg.channel_id, "no one has ever memed before", msg.tts), + }; + let meme = Meme::find(&conn, record.meme_id); match meme { Ok(ref meme) => { @@ -117,6 +100,52 @@ pub fn wat(_: &mut Context, msg: &Message, _: Args) -> Result<()> { meme.map(|_| {}) } +pub fn history(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { + use itertools::Itertools; + + const MAX_HIST: usize = 8; + const DEFAULT_HIST: usize = 3; + + let conn = connection()?; + + let n = args.single_quoted::<usize>().unwrap_or(DEFAULT_HIST); + + if n > MAX_HIST { + send(msg.channel_id, "YER PUSHIN ME OVER THE FUCKIN LINE", true)?; + } + + let n = n.min(MAX_HIST); + + let records = InvocationRecord::last_n(&conn, n)?; + + if records.len() == 0 { + return send(msg.channel_id, "i don't remember anything :(", msg.tts); + } + + let resp = records + .into_iter() + .enumerate() + .rev() + .map(|(i, rec)| { + Meme::find(&conn, rec.meme_id) + .and_then(|meme| { + Metadata::find(&conn, meme.metadata_id).map(|metadata| (metadata, meme)) + }) + .map(|(metadata, meme)| { + let author_name = crate::TARGET_GUILD_ID.member(metadata.created_by as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + let invoker_name = crate::TARGET_GUILD_ID.member(rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + format!("{}. \"{}\" by {} ({}). invoked by {} at {}", i + 1, meme.title, author_name, metadata.created.date(), invoker_name, rec.time) + }) + .unwrap_or_else(|_| { + let invoker_name = crate::TARGET_GUILD_ID.member(rec.user_id as u64).map(|m| m.display_name().into_owned()).unwrap_or("???".to_owned()); + format!("{}. not found. invoked by {} at {}", i + 1, invoker_name, rec.time) + }) + }) + .join("\n"); + + send(msg.channel_id, &resp, false) +} + pub fn addmeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> { let mut args = Args::new(args.rest(), &[" ".to_owned(), "\n".to_owned(), "\t".to_owned()]); @@ -273,7 +302,7 @@ fn rand_meme(ctx: &Context, message: &Message, audio_only: bool) -> Result<()> { match mem { Ok(mem) => { - update_meme(&mem)?; + InvocationRecord::create(&conn, message.author.id.0, message.id.0, mem.id, true)?; send_meme(ctx, &mem, &conn, message).map_err(Error::from) }, err @ Err(_) => { diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 8009093..2f18e9f 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -116,6 +116,12 @@ fn register_db(f: StandardFramework) -> StandardFramework { .desc("get meme stats") .cmd(stats) ) + .command("history", |c| c + .known_as("hist") + .guild_only(true) + .desc("history of recent messages") + .cmd(history) + ) } #[cfg(not(feature = "diesel"))] diff --git a/src/db/models.rs b/src/db/models.rs index 67aa1ca..66e161a 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -235,3 +235,52 @@ pub struct NewTombstone { pub metadata_id: i32, pub meme_id: i32, } + +#[derive(Queryable, Identifiable, PartialEq, Debug)] +#[table_name="invocation_records"] +pub struct InvocationRecord { + pub id: i32, + pub user_id: i64, + pub message_id: i64, + pub meme_id: i32, + pub time: NaiveDateTime, + pub random: bool, +} + +#[derive(Insertable, PartialEq, Debug)] +#[table_name="invocation_records"] +pub struct NewInvocationRecord { + pub user_id: i64, + pub message_id: i64, + pub meme_id: i32, + pub random: bool, +} + +impl InvocationRecord { + pub fn create(conn: &PgConnection, user_id: u64, message_id: u64, meme_id: i32, random: bool) -> Result<Self> { + ::diesel::insert_into(invocation_records::table) + .values(&NewInvocationRecord { + user_id: user_id as i64, + message_id: message_id as i64, + meme_id, + random, + }) + .get_result::<InvocationRecord>(conn) + .map_err(Error::from) + } + + pub fn last(conn: &PgConnection) -> Result<Self> { + invocation_records::table + .order(invocation_records::time.desc()) + .first(conn) + .map_err(Error::from) + } + + pub fn last_n(conn: &PgConnection, n: usize) -> Result<Vec<Self>> { + invocation_records::table + .order(invocation_records::time.desc()) + .limit(n as i64) + .load(conn) + .map_err(Error::from) + } +} diff --git a/src/db/schema.rs b/src/db/schema.rs index 8749731..1ab5fa1 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -27,6 +27,17 @@ table! { } table! { + invocation_records (id) { + id -> Int4, + user_id -> Int8, + message_id -> Int8, + meme_id -> Int4, + time -> Timestamp, + random -> Bool, + } +} + +table! { memes (id) { id -> Int4, title -> Varchar, @@ -67,6 +78,7 @@ allow_tables_to_appear_in_same_query!( audio, audit_records, images, + invocation_records, memes, metadata, tombstones, |
