aboutsummaryrefslogtreecommitdiff
path: root/src/commands/meme/create.rs
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2019-03-30 03:31:30 -0400
committerNathan Perry <avaglir@gmail.com>2019-03-30 03:31:30 -0400
commita6f5334f984531cf2304b6333b138944517d3703 (patch)
tree6ca29344197c4c0bc6d567c96bc41d4b01991fad /src/commands/meme/create.rs
parentbe142ead930d5fc770320e530aec9ad3c2dbc842 (diff)
restructure meme module
Diffstat (limited to 'src/commands/meme/create.rs')
-rw-r--r--src/commands/meme/create.rs174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/commands/meme/create.rs b/src/commands/meme/create.rs
new file mode 100644
index 0000000..245f067
--- /dev/null
+++ b/src/commands/meme/create.rs
@@ -0,0 +1,174 @@
+use std::{
+ io::Read,
+ process::{
+ Command,
+ Stdio,
+ },
+};
+
+use diesel::result::Error as DieselError;
+use serenity::{
+ framework::standard::Args,
+ model::channel::Message,
+ prelude::*,
+};
+use url::Url;
+
+use crate::{
+ audio::{
+ parse_times,
+ ytdl_url,
+ },
+ commands::send,
+ db::{
+ Audio,
+ connection,
+ Image,
+ NewMeme,
+ },
+ Result,
+};
+
+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()]);
+
+ let title = args.single_quoted::<String>()?;
+ let text = args.rest().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();
+
+ if image.is_none() && text.is_none() {
+ warn!("tried to create non-audio meme with no image or text");
+ return send(msg.channel_id, "hahAA it's empty xdddd", msg.tts);
+ }
+
+ let save_result = NewMeme {
+ title,
+ content: text,
+ image_id: image,
+ audio_id: None,
+ metadata_id: 0,
+ }.save(&conn, msg.author.id.0).map(|_| {});
+
+ use diesel::result::DatabaseErrorKind;
+ match save_result {
+ Ok(_) => msg.react("👌"),
+ Err(e) => {
+ if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) = e.downcast_ref::<DieselError>() {
+ error!("tried to create meme that already exists");
+ msg.react("❌")?;
+ return send(msg.channel_id, "that meme already exists", msg.tts);
+ }
+
+ return Err(e);
+ }
+ }
+}
+
+pub fn addaudiomeme(_: &mut Context, msg: &Message, args: Args) -> Result<()> {
+ let mut args = Args::new(args.rest(), &[" ".to_owned(), "\n".to_owned(), "\t".to_owned()]);
+
+ 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 {
+ send(msg.channel_id, "are you stupid", msg.tts)?;
+ 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 youtube_url = ytdl_url(audio_link.as_str())?;
+
+ let duration_opts = if let Some(e) = end {
+ vec! [
+ "-ss".to_owned(), start.map_or_else(
+ || "00:00:00".to_owned(),
+ |s| format!("{:02}:{:02}:{:02}", s.num_hours(), s.num_minutes() % 60, s.num_seconds() % 60)
+ ),
+
+ "-to".to_owned(), format!("{:02}:{:02}:{:02}", e.num_hours(), e.num_minutes() % 60, e.num_seconds() % 60),
+ ]
+ } else {
+ vec! []
+ };
+
+ let ffmpeg_command = Command::new("ffmpeg")
+ .arg("-i")
+ .arg(youtube_url)
+ .args(duration_opts)
+ .args(&[
+ "-ac", "2",
+ "-ar", "48000",
+ "-f", "opus",
+ "-acodec", "libopus",
+ "-b:a", "96k",
+ "-fs", "5M",
+ "-",
+ ])
+ .stdout(Stdio::piped())
+ .stderr(Stdio::null())
+ .stdin(Stdio::null())
+ .spawn()?;
+
+ let mut audio_reader = ffmpeg_command.stdout.unwrap();
+
+ let text = args.rest().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();
+ let bytes = audio_reader.read_to_end(&mut audio_data)?;
+
+ if bytes == 0 {
+ debug!("read 0 bytes from audio reader");
+ return send(msg.channel_id, "🔇🔇🔇🔕🔕🔕🔕🔕🔇🔕🔕🔇🔕🔕📣📢📣📢📣", msg.tts);
+ }
+
+ let audio_id = Audio::create(&conn, audio_data, msg.author.id.0)?;
+
+ let save_result = NewMeme {
+ title,
+ content: text,
+ image_id: image,
+ audio_id: Some(audio_id),
+ metadata_id: 0,
+ }.save(&conn, msg.author.id.0).map(|_| {});
+
+ use diesel::result::DatabaseErrorKind;
+ match save_result {
+ Ok(_) => msg.react("👌"),
+ Err(e) => {
+ if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) = e.downcast_ref::<DieselError>() {
+ error!("tried to create meme that already exists");
+ msg.react("❌")?;
+ return send(msg.channel_id, "that meme already exists", msg.tts);
+ }
+
+ return Err(e);
+ }
+ }
+}