diff options
| author | Nathan Perry <avaglir@gmail.com> | 2018-04-30 15:54:20 -0400 |
|---|---|---|
| committer | Nathan Perry <avaglir@gmail.com> | 2018-04-30 15:54:20 -0400 |
| commit | 652a36f172df43c080d6dc1d3680166ee3045f82 (patch) | |
| tree | 50557b4e26f6c0f0e594498dfb35081cba4c988c | |
| parent | 9f3a555c2801c00a78e8380d8acc3d5931972335 (diff) | |
add reactions, change add/recall meme structure
| -rw-r--r-- | Cargo.lock | 16 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/commands/meme.rs | 362 | ||||
| -rw-r--r-- | src/commands/mod.rs | 16 |
4 files changed, 68 insertions, 328 deletions
@@ -105,7 +105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -155,7 +155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -167,7 +167,7 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -267,7 +267,7 @@ name = "diesel" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -356,7 +356,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -423,7 +423,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1210,7 +1210,7 @@ version = "0.5.2" source = "git+https://github.com/mammothbane/serenity#3ad76eb543e281bbe2b37288eb10a2cab5ac6231" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "evzht9h3nznqzwl 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1774,7 +1774,7 @@ dependencies = [ "checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b2bf7093258c32e0825b635948de528a5949799dcd61bef39534c8aab95870c" +"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" "checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" @@ -1,6 +1,6 @@ [package] name = "thulani" -version = "0.1.2" +version = "0.1.3" authors = ["Nathan Perry <avaglir@gmail.com>"] [features] diff --git a/src/commands/meme.rs b/src/commands/meme.rs index fcff7f5..6c78fc5 100644 --- a/src/commands/meme.rs +++ b/src/commands/meme.rs @@ -1,26 +1,8 @@ -use std::time::Duration; - use rand::{thread_rng, Rng}; use serenity::http::AttachmentType; use serenity::builder::CreateMessage; use serenity::framework::standard::Args; use diesel::PgConnection; -use reqwest::{ - Client, - header::{ - Headers, - ContentLength, - UserAgent, - Accept, - AcceptEncoding, - Encoding, - qitem, - ContentType, - }, - mime -}; -use regex::{Regex, Match}; -use clap::{Arg, App, SubCommand, AppSettings}; use super::*; use super::playback::CtxExt; @@ -29,168 +11,65 @@ use db::*; use failure::Error; use Result; -lazy_static! { - static ref COMMAND_REGEX: Regex = Regex::new( - r"^!(?:thulani|thulando|thulando madando|thulan)\s+meme\s*(.*)" - ).expect("unable to compile command regex"); - - static ref QUOTES_REGEX: Regex = Regex::new( - r##"\s*(?:"([^"]*)"|([^"\s]*))\s*"## - ).expect("unable to compile quotes regex"); -} - -pub fn meme(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> { - let arg_str = COMMAND_REGEX - .captures(&msg.content) - .ok_or::<Error>(::failure::err_msg("message content not recognized"))? - .get(1) - .ok_or::<Error>(::failure::err_msg("first capture group not found"))? - .as_str(); - - let normalized = format!("meme {}", arg_str); +pub fn meme(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> { + if args.len() == 0 { + return rand_meme(ctx, msg); + } - let args = QUOTES_REGEX - .captures_iter(&normalized) - .map(|capture| { - capture.iter() - .skip(1) - .fold(None, |acc, opt| acc.or(opt)) - .map(|m: Match| m.as_str()) - .ok_or::<Error>(::failure::err_msg("couldn't extract matching group from capture")) - }) - .collect::<Result<Vec<_>>>()?; + let search = args.full(); - let matches = match app().get_matches_from_safe_borrow(args.iter()) { + let conn = connection()?; + let mem = match find_meme(&conn, search) { Ok(x) => x, Err(e) => { - warn!("syntax error: {:?}", e); - - return send(msg.channel_id, "hwaet the fuck fix your syntax", msg.tts); - } + send(msg.channel_id, "what in ryan's name", msg.tts)?; + return Err(e) + }, }; - trace!("{:?}", matches); - - lazy_static! { - static ref GEN_HELP: String = { - let mut str = Vec::new(); - app().write_long_help(&mut str).expect("unable to write out help"); - String::from_utf8(str).expect("unable to read long help as utf8") - }; - } - - if matches.is_present("help") { // because clap is stupid - return send(msg.channel_id, &format!("```{}```", &*GEN_HELP), msg.tts); - } - - if let Some(add_matches) = matches.subcommand_matches("add") { - lazy_static! { - static ref ADD_HELP: String = { - let mut str = Vec::new(); - app_add().write_long_help(&mut str).expect("unable to write out help"); - String::from_utf8(str).expect("unable to read long help as utf8") - }; - } - - if add_matches.is_present("help") { - return send(msg.channel_id, &format!("```{}```", &*ADD_HELP), msg.tts); - } - - let image = add_matches.value_of("image"); - let audio = add_matches.value_of("audio"); - let text = add_matches.value_of("text"); - - let title = match add_matches.value_of("TITLE") { - Some(title) => title, - None => { - send(msg.channel_id, "bottom text", msg.tts)?; - return Err(::failure::err_msg("title missing")); - } - }; - - if image.is_none() && audio.is_none() && text.is_none() { - return send(msg.channel_id, "hahAA it's empty xdddd", msg.tts); - } - - let conn = connection()?; - - lazy_static! { - static ref CLIENT: Client = { - let mut headers = Headers::new(); - headers.set(AcceptEncoding(vec!(qitem(Encoding::Gzip)))); - headers.set(UserAgent::new("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0)")); - headers.set(Accept(vec![ - qitem(mime::IMAGE_STAR), - qitem("video/webm".parse().unwrap()) - ])); - - Client::builder() - .default_headers(headers) - .timeout(Duration::from_secs(5)) - .build() - .expect("couldn't construct http client") - }; - } - - let image_id = image.map(|url| load_image(&*CLIENT, &conn, url, title, msg)).transpose()?; + send_meme(ctx, &mem, &conn, msg) +} - if let Some(_) = audio { - return send(msg.channel_id, "hueh?", msg.tts); - } +pub fn addmeme(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> { + let title = args.single_quoted::<String>()?; + let text = match args.multiple_quoted::<String>() { + Ok(text) => text.join(" "), + Err(_) => "".to_owned(), + }; - return NewMeme { - title: title.to_owned(), - content: text.map(|s| s.to_owned()), - image_id, - audio_id: None, - metadata_id: 0, - }.save(&conn, msg.author.id.0).map(|_| {}); - } + let text = if text.is_empty() { None } else { Some(text) }; - if let Some(matches) = matches.subcommand_matches("delete") { - lazy_static! { - static ref DELETE_HELP: String = { - let mut str = Vec::new(); - app_delete().write_long_help(&mut str).expect("unable to write out help"); - String::from_utf8(str).expect("unable to read long help as utf8") - }; - } + let conn = connection()?; - if matches.is_present("help") { - return send(msg.channel_id, &format!("```{}```", &*DELETE_HELP), msg.tts); - } + let image = msg.attachments.first() + .ok_or(::failure::err_msg("no attachment")) + .and_then(|att| { + let data = att.download()?; + Image::create(&conn, &att.filename, data, msg.author.id.0) + }) + .ok(); - return send(msg.channel_id, "hwaet", msg.tts); + if image.is_none() && text.is_none() { + return send(msg.channel_id, "hahAA it's empty xdddd", msg.tts); } - if let Some(matches) = matches.subcommand_matches("post") { - lazy_static! { - static ref POST_HELP: String = { - let mut str = Vec::new(); - app_post().write_long_help(&mut str).expect("unable to write out help"); - String::from_utf8(str).expect("unable to read long help as utf8") - }; - } - - if matches.is_present("help") { - return send(msg.channel_id, &format!("```{}```", &*POST_HELP), msg.tts); - } + NewMeme { + title, + content: text, + image_id: image, + audio_id: None, + metadata_id: 0, + }.save(&conn, msg.author.id.0).map(|_| {})?; - if let Some(search) = matches.value_of("SEARCH") { - let conn = connection()?; - let mem = match find_meme(&conn, search) { - Ok(x) => x, - Err(e) => { - send(msg.channel_id, "what in ryan's name", msg.tts)?; - return Err(e) - }, - }; + return msg.react("👌"); +} - return send_meme(ctx, &mem, &conn, msg); - } - } +pub fn delmeme(_: &mut Context, msg: &Message, _: Args) -> Result<()> { + send(msg.channel_id, "hwaet", msg.tts) +} - rand_meme(ctx, msg) +pub fn renamememe(_: &mut Context, msg: &Message, _: Args) -> Result<()> { + send(msg.channel_id, "hwaet", msg.tts) } fn rand_meme(ctx: &Context, message: &Message) -> Result<()> { @@ -274,158 +153,3 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res Ok(()) } - -fn load_image(client: &Client, conn: &PgConnection, url: &str, title: &str, msg: &Message) -> Result<i32> { - let url = url.to_owned(); - if url.to_lowercase().trim() == "attached" { - let res = msg.attachments.first() - .ok_or::<Error>(::failure::err_msg("no attachments found")) - .and_then(|att| { - let data = att.download()?; - let image_id = Image::create(&conn, &att.filename, data, msg.author.id.0)?; - - Ok(image_id) - }); - - if res.is_err() { - send(msg.channel_id, "fix yer gotdang attachments", msg.tts)?; - } - - return res; - } - - let resp = client.head(&url).send()?; - - if !resp.status().is_success() { - send(msg.channel_id, "pick a better url next time thanks", msg.tts)?; - bail!("request failed"); - } - - let len = resp.headers().get::<ContentLength>() - .map(|ct_len| **ct_len) - .unwrap_or(0); - - let content_type_valid = resp.headers().get::<ContentType>() - .map(|ct_type| ct_type.type_() == "image" || (ct_type.type_() == "video" && ct_type.subtype() == "webm")) - .unwrap_or(false); - - if len > 20_000_000 || !content_type_valid { - send(msg.channel_id, "yer pushin me over the fuckin line", msg.tts)?; - bail!("content invalid"); - } - - let mut resp = client.get(&url).send()?; - - if !resp.status().is_success() { - send(msg.channel_id, "bad link reeeeee", msg.tts)?; - bail!("request failed"); - } - - let len = resp.headers().get::<ContentLength>() - .map(|ct_len| **ct_len) - .unwrap_or(0); - - let content_type_valid = resp.headers().get::<ContentType>() - .map(|ct_type| ct_type.type_() == "image" || (ct_type.type_() == "video" && ct_type.subtype() == "webm")) - .unwrap_or(false); - - if len > 20_000_000 || !content_type_valid { - send(msg.channel_id, "are ye fuckin serious", msg.tts)?; - bail!("content invalid"); - } - - let mut data = Vec::with_capacity(len as usize); - ::std::io::copy(&mut resp, &mut data)?; - - let ext = resp.headers().get::<ContentType>() - .and_then(|typ| ::mime_guess::get_extensions(typ.type_().as_str(), typ.subtype().as_str())) - .and_then(|x| x.first()) - .map(|x| match *x { - "jpe" => "jpg", - x => x, - }) - .unwrap_or(&"bin"); - - let filename = format!("{}.{}", title, ext); - Image::create(conn, &filename, data, msg.author.id.0) -} - -fn app<'a, 'b>() -> App<'a, 'b> { - App::new("meme") - .about("manipulate memes. pass no arguments to produce a randomly-selected meme.") - .global_settings(&vec![AppSettings::DisableHelpSubcommand, AppSettings::DisableVersion]) - .arg(Arg::with_name("help") - .short("h") - .long("help") - .help("show this help message") - ) - .subcommand(app_add()) - .subcommand(app_delete()) - .subcommand(app_post()) -} - -fn app_post<'a, 'b>() -> App<'a, 'b> { - SubCommand::with_name("post") - .about("post a specific meme (partial, exact, case-insensitive matches only)") - .global_settings(&vec![AppSettings::DisableHelpSubcommand, AppSettings::DisableVersion]) - .arg(Arg::with_name("SEARCH") - .takes_value(true) - .index(1) - ) - .arg(Arg::with_name("help") - .short("h") - .long("help") - .help("show this help message") - ) -} - -fn app_add<'a, 'b>() -> App<'a, 'b> { - SubCommand::with_name("add") - .about("add a meme to the database") - .global_settings(&vec![AppSettings::DisableHelpSubcommand, AppSettings::DisableVersion]) - .arg(Arg::with_name("help") - .short("h") - .long("help") - .help("show this help message") - ) - .arg(Arg::with_name("TITLE") - .index(1) - .help("title for new meme") - .takes_value(true) - ) - .arg(Arg::with_name("image") - .short("i") - .long("image") - .multiple(false) - .help("url of image to attach (use 'attached' to use image attached to message)") - .takes_value(true) - ) - .arg(Arg::with_name("audio") - .short("a") - .long("audio") - .multiple(false) - .help("address of a video downloadable with youtube-dl. timestamps not yet supported.") - .takes_value(true) - ) - .arg(Arg::with_name("text") - .short("t") - .long("text") - .multiple(false) - .help("text to play back") - .takes_value(true) - ) -} - -fn app_delete<'a, 'b>() -> App<'a, 'b> { - SubCommand::with_name("delete") - .about("delete a meme from the database") - .global_settings(&vec![AppSettings::DisableHelpSubcommand, AppSettings::DisableVersion]) - .arg(Arg::with_name("help") - .short("h") - .long("help") - .help("show this help message") - ) - .arg(Arg::with_name("title") - .index(1) - ) -}
\ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 542d649..056aec6 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -80,6 +80,22 @@ fn register_db(f: StandardFramework) -> StandardFramework { .guild_only(true) .help_available(false) .cmd(meme)) + .command("addmeme", |c| c + .guild_only(true) + .desc("first argument is title, everything after is text. one attached image is included if present.") + .cmd(addmeme) + ) + .command("delmeme", |c| c + .guild_only(true) + .desc("not currently working") + .cmd(delmeme) + ) + .command("renamememe", |c| c + .guild_only(true) + .desc("not currently working") + .help_available(false) + .cmd(renamememe) + ) } #[cfg(not(feature = "diesel"))] |
