aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2019-02-17 01:59:22 -0500
committerNathan Perry <avaglir@gmail.com>2019-02-17 01:59:22 -0500
commite9e3458225cfc0fdc20a7d2960ef15d4de349802 (patch)
tree036dbf021aafb2479faae487c9d71f8d1b0f2e43
parent27ab061563de6c7d1b79dccd8585655ef8aa9700 (diff)
support audio memes
-rw-r--r--src/audio/mod.rs2
-rw-r--r--src/audio/play_queue.rs3
-rw-r--r--src/audio/timeutil.rs3
-rw-r--r--src/audio/ytdl.rs9
-rw-r--r--src/commands/meme.rs70
-rw-r--r--src/commands/mod.rs5
-rw-r--r--src/main.rs2
7 files changed, 81 insertions, 13 deletions
diff --git a/src/audio/mod.rs b/src/audio/mod.rs
index a7f3e83..eaebf55 100644
--- a/src/audio/mod.rs
+++ b/src/audio/mod.rs
@@ -19,7 +19,7 @@ use crate::{
};
pub use self::timeutil::parse_times;
-pub use self::ytdl::ytdl;
+pub use self::ytdl::*;
pub use self::play_queue::PlayQueue;
mod timeutil;
diff --git a/src/audio/play_queue.rs b/src/audio/play_queue.rs
index 6f3a130..deb4e2c 100644
--- a/src/audio/play_queue.rs
+++ b/src/audio/play_queue.rs
@@ -103,11 +103,10 @@ impl PlayQueue {
}
},
Right(ref vec) => {
- ::serenity::voice::opus(true, ::std::io::Cursor::new(vec.clone()))
+ ::serenity::voice::pcm(true, ::std::io::Cursor::new(vec.clone()))
}
};
-
let mut manager = voice_manager.lock();
let handler = manager.join(*TARGET_GUILD_ID, must_env_lookup::<u64>("VOICE_CHANNEL"));
diff --git a/src/audio/timeutil.rs b/src/audio/timeutil.rs
index d0bd9d5..b2232de 100644
--- a/src/audio/timeutil.rs
+++ b/src/audio/timeutil.rs
@@ -59,7 +59,6 @@ mod test {
assert_eq!(captures.name("seconds").unwrap().as_str(), "3");
assert!(START_REGEX.captures("").is_none());
- assert!(START_REGEX.captures("start s").is_none());
let captures = START_REGEX.captures("start 1").unwrap();
assert_eq!(captures.name("seconds").unwrap().as_str(), "1");
@@ -74,7 +73,6 @@ mod test {
assert_eq!(captures.name("seconds").unwrap().as_str(), "3");
assert!(DUR_REGEX.captures("").is_none());
- assert!(DUR_REGEX.captures("dur s").is_none());
let captures = DUR_REGEX.captures("dur 1").unwrap();
assert_eq!(captures.name("seconds").unwrap().as_str(), "1");
@@ -89,7 +87,6 @@ mod test {
assert_eq!(captures.name("seconds").unwrap().as_str(), "3");
assert!(END_REGEX.captures("").is_none());
- assert!(END_REGEX.captures("end s").is_none());
let captures = END_REGEX.captures("end 1").unwrap();
assert_eq!(captures.name("seconds").unwrap().as_str(), "1");
diff --git a/src/audio/ytdl.rs b/src/audio/ytdl.rs
index d16d166..8384db4 100644
--- a/src/audio/ytdl.rs
+++ b/src/audio/ytdl.rs
@@ -42,7 +42,7 @@ impl Drop for ChildContainer {
}
}
-pub fn ytdl(uri: &str, start: Option<Duration>, end: Option<Duration>) -> Result<Box<AudioSource>> {
+pub fn ytdl_reader(uri: &str, start: Option<Duration>, end: Option<Duration>) -> Result<Box<dyn Read + Send>> {
let args = [
"-f",
"webm[abr>0]/bestaudio/best",
@@ -113,5 +113,10 @@ pub fn ytdl(uri: &str, start: Option<Duration>, end: Option<Duration>) -> Result
.stdout(Stdio::piped())
.spawn()?;
- Ok(pcm(true, ChildContainer(command)))
+ Ok(Box::new(ChildContainer(command)))
+}
+
+pub fn ytdl(uri: &str, start: Option<Duration>, end: Option<Duration>) -> Result<Box<AudioSource>> {
+ let command = ytdl_reader(uri, start, end)?;
+ Ok(pcm(true, command))
}
diff --git a/src/commands/meme.rs b/src/commands/meme.rs
index 0305e79..922091c 100644
--- a/src/commands/meme.rs
+++ b/src/commands/meme.rs
@@ -1,9 +1,13 @@
-use std::sync::RwLock;
+use std::{
+ io::{BufReader, Read},
+ sync::RwLock,
+};
use diesel::PgConnection;
use failure::Error;
use lazy_static::lazy_static;
use rand::{Rng, thread_rng};
+use url::Url;
use serenity::{
builder::CreateMessage,
framework::standard::Args,
@@ -17,6 +21,8 @@ use crate::{
CtxExt,
PlayArgs,
PlayQueue,
+ ytdl_reader,
+ parse_times,
},
commands::{
send,
@@ -128,6 +134,59 @@ pub fn addmeme(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
msg.react("👌")
}
+pub fn addaudiomeme(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
+ let title = args.single_quoted::<String>()?;
+ let audio_str = args.single_quoted::<String>()?;
+
+ let elems = audio_str.split_whitespace().collect::<Vec<_>>();
+
+ if elems.len() == 0 {
+ return Err(::failure::err_msg("no audio link was provided"))
+ }
+
+ let audio_link = Url::parse(elems[0])?;
+ let opts = elems[1..].join(" ");
+ let (start, end) = parse_times(opts);
+
+ let audio_reader = BufReader::new(ytdl_reader(audio_link.as_str(), start, end)?);
+
+ let text = match args.multiple_quoted::<String>() {
+ Ok(text) => text.join(" "),
+ Err(_) => "".to_owned(),
+ };
+
+ let text = if text.is_empty() { None } else { Some(text) };
+
+ let conn = connection()?;
+
+ 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();
+
+ let mut audio_data = Vec::new();
+ audio_reader.take(5 * 1024 * 1024).read_to_end(&mut audio_data)?;
+
+ if audio_data.len() == 0 {
+ return send(msg.channel_id, "🔇🔇🔇🔕🔕🔕🔕🔕🔇🔕🔕🔇🔕🔕📣📢📣📢📣", msg.tts);
+ }
+
+ let audio_id = Audio::create(&conn, audio_data, msg.author.id.0)?;
+
+ NewMeme {
+ title,
+ content: text,
+ image_id: image,
+ audio_id: Some(audio_id),
+ metadata_id: 0,
+ }.save(&conn, msg.author.id.0).map(|_| {})?;
+
+ msg.react("👌")
+}
+
pub fn delmeme(_: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
let title = args.single_quoted::<String>()?;
@@ -194,16 +253,19 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res
match t.content {
Some(ref text) => ret.content(text),
- None => ret
+ None => ret,
}
};
match image {
Some(image) => {
let image = image?;
- msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image.data, &image.filename))), create_msg)?
+ msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image.data, &image.filename))), create_msg)?;
+ },
+ None => match t.content {
+ Some(_) => { msg.channel_id.send_message(create_msg)?; },
+ None => {},
},
- None => msg.channel_id.send_message(create_msg)?,
};
// note: slight edge-case race condition here: there could have been something queued since we
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index b991c18..d5d91e2 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -88,6 +88,11 @@ fn register_db(f: StandardFramework) -> StandardFramework {
.desc("first argument is title, everything after is text. one attached image is included if present.")
.cmd(addmeme)
)
+ .command("addaudiomeme", |c| c
+ .guild_only(true)
+ .desc("title, audio link, text, with optional image")
+ .cmd(addaudiomeme)
+ )
.command("delmeme", |c| c
.guild_only(true)
.desc("delete a meme by name (exact match only)")
diff --git a/src/main.rs b/src/main.rs
index 7202556..708d778 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,7 +16,7 @@ extern crate serenity;
extern crate sha1;
extern crate typemap;
extern crate url;
-#[macro_use] extern crate itertools;
+#[cfg_attr(test, macro_use)] extern crate itertools;
extern crate time;
extern crate serde_json;