use parking_lot; use serenity; use serenity::voice::LockedAudio; use std::cell::RefCell; use std::ops::DerefMut; use std::sync::{Arc, MutexGuard}; use super::super::prelude::*; pub struct Play { media: Arc, } impl Play { pub fn new(media_data: Arc) -> Play { Play { media: media_data } } fn check_for_continue(song_lock: MutexGuard>>) -> bool { match song_lock.borrow_mut().deref_mut() { Some(song) => { let song_clone = song.clone(); let mut audio_lock = song_clone.lock(); audio_lock.play(); true } None => false, } } fn check_join_channel( manager_lock: &Arc>, msg: &serenity::model::channel::Message, ) { let guild = match msg.guild() { Some(guild) => guild, None => { display_error!(msg.channel_id.say("Groups and DMs not supported")); return; } }; let guild_id = guild.read().id; let channel_id = guild .read() .voice_states .get(&msg.author.id) .and_then(|voice_state| voice_state.channel_id); let connect_to = match channel_id { Some(channel) => channel, None => { display_error!(msg.reply("Not in a voice channel")); return; } }; let mut manager = manager_lock.lock(); manager.join(guild_id, connect_to); } fn handle_http_request( &self, ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, url: &String, ) { let mut source = match youtube_dl(&url) { Ok(source) => source, Err(why) => { println!("Err starting source: {:?}", why); print_error!( msg.channel_id .say(format!("Error using youtube-dl: {}", why)) ); return; } }; { let playlist_mutex = self.media.playlist_mut(); playlist_mutex.borrow_mut().append(&mut source); } let manager_lock = ctx.data.lock().get::().cloned().unwrap(); Self::check_join_channel(&manager_lock, msg); MediaData::start_thread(&self.media, msg.channel_id, &manager_lock); } fn handle_local_request( &self, ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, ) { print_error!(self.media.reset(ctx, msg)); // TODO: read local file directory and play songs in arbitrary order } } impl serenity::framework::standard::Command for Play { #[allow(unreachable_code, unused_mut)] fn execute( &self, mut ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, mut args: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { if args.len() == 0 { if !Self::check_for_continue(self.media.song_mut()) { print_error!(msg.channel_id.say("Must provide a URL to a video or audio")); } } else if args.len() == 1 { let arg = match args.single::() { Ok(arg) => arg, // can't happen, since we tested for length == 1 Err(_) => return Ok(()), }; if arg == "--local" { self.handle_local_request(ctx, msg); } else if arg.starts_with("http") { self.handle_http_request(ctx, msg, &arg); } else { print_error!(msg.channel_id.say("Unsupported argument list")); } } else { print_error!(msg.channel_id.say("Unsupported argument list")); } Ok(()) } }