From 8a945187475b8b54e44e680788d1688c6227ddf1 Mon Sep 17 00:00:00 2001 From: trivernis Date: Thu, 8 Apr 2021 10:57:36 +0200 Subject: [PATCH] Add querying to play command Signed-off-by: trivernis --- src/commands/music/mod.rs | 17 +++++++++++++---- src/commands/music/play.rs | 13 ++++--------- src/commands/music/play_next.rs | 13 ++++--------- src/providers/music/mod.rs | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/commands/music/mod.rs b/src/commands/music/mod.rs index 93c35e1..f780adc 100644 --- a/src/commands/music/mod.rs +++ b/src/commands/music/mod.rs @@ -22,8 +22,10 @@ use queue::QUEUE_COMMAND; use shuffle::SHUFFLE_COMMAND; use skip::SKIP_COMMAND; -use crate::providers::music::{get_video_information, get_videos_for_playlist}; use crate::providers::music::queue::{MusicQueue, Song}; +use crate::providers::music::{ + get_video_information, get_videos_for_playlist, search_video_information, +}; use crate::utils::error::{BotError, BotResult}; use crate::utils::store::Store; @@ -149,13 +151,20 @@ async fn play_next_in_queue( } /// Returns the list of songs for a given url -async fn get_songs_for_url(ctx: &&Context, msg: &Message, url: &str) -> BotResult> { - let mut songs: Vec = get_videos_for_playlist(url)? +async fn get_songs_for_query(ctx: &&Context, msg: &Message, query: &str) -> BotResult> { + let mut songs: Vec = get_videos_for_playlist(query)? .into_iter() .map(Song::from) .collect(); if songs.len() == 0 { - let song: Song = get_video_information(url)?.into(); + let song: Song = if !query.starts_with("http") { + search_video_information(query)? + .ok_or(BotError::Msg(format!("Noting found for {}", query)))? + .into() + } else { + get_video_information(query)?.into() + }; + msg.channel_id .send_message(&ctx.http, |m| { m.embed(|mut e| { diff --git a/src/commands/music/play.rs b/src/commands/music/play.rs index 80c1904..90668e9 100644 --- a/src/commands/music/play.rs +++ b/src/commands/music/play.rs @@ -1,10 +1,10 @@ use serenity::client::Context; -use serenity::framework::standard::{Args, CommandError, CommandResult}; use serenity::framework::standard::macros::command; +use serenity::framework::standard::{Args, CommandError, CommandResult}; use serenity::model::channel::Message; use crate::commands::music::{ - get_channel_for_author, get_queue_for_guild, get_songs_for_url, get_voice_manager, + get_channel_for_author, get_queue_for_guild, get_songs_for_query, get_voice_manager, join_channel, play_next_in_queue, }; use crate::database::get_database_from_context; @@ -15,14 +15,9 @@ use crate::database::guild::SETTING_AUTOSHUFFLE; #[description("Plays a song in a voice channel")] #[usage("play ")] #[min_args(1)] -#[max_args(1)] #[aliases("p")] async fn play(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let url = args.message(); - - if !url.starts_with("http") { - return Err(CommandError::from("The provided url is not valid")); - } + let query = args.message(); let guild = msg.guild(&ctx.cache).await.unwrap(); @@ -37,7 +32,7 @@ async fn play(ctx: &Context, msg: &Message, args: Args) -> CommandResult { let handler_lock = handler.ok_or(CommandError::from("Not in a voice channel"))?; - let songs = get_songs_for_url(&ctx, msg, url).await?; + let songs = get_songs_for_query(&ctx, msg, query).await?; let queue = get_queue_for_guild(ctx, &guild.id).await?; diff --git a/src/commands/music/play_next.rs b/src/commands/music/play_next.rs index 6c7d939..74a5f36 100644 --- a/src/commands/music/play_next.rs +++ b/src/commands/music/play_next.rs @@ -1,10 +1,10 @@ use serenity::client::Context; -use serenity::framework::standard::{Args, CommandError, CommandResult}; use serenity::framework::standard::macros::command; +use serenity::framework::standard::{Args, CommandError, CommandResult}; use serenity::model::channel::Message; use crate::commands::music::{ - get_channel_for_author, get_queue_for_guild, get_songs_for_url, get_voice_manager, + get_channel_for_author, get_queue_for_guild, get_songs_for_query, get_voice_manager, join_channel, play_next_in_queue, }; @@ -13,15 +13,10 @@ use crate::commands::music::{ #[description("Puts a song as the next to play in the queue")] #[usage("play_next ")] #[min_args(1)] -#[max_args(2)] #[aliases("pn")] #[allowed_roles("DJ")] async fn play_next(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let url = args.message(); - - if !url.starts_with("http") { - return Err(CommandError::from("The provided url is not valid")); - } + let query = args.message(); let guild = msg.guild(&ctx.cache).await.unwrap(); @@ -36,7 +31,7 @@ async fn play_next(ctx: &Context, msg: &Message, args: Args) -> CommandResult { let handler = handler.ok_or(CommandError::from("Not in a voice channel"))?; - let mut songs = get_songs_for_url(&ctx, msg, url).await?; + let mut songs = get_songs_for_query(&ctx, msg, query).await?; let queue = get_queue_for_guild(ctx, &guild.id).await?; let play_first = { diff --git a/src/providers/music/mod.rs b/src/providers/music/mod.rs index b389cf3..d0ef667 100644 --- a/src/providers/music/mod.rs +++ b/src/providers/music/mod.rs @@ -36,3 +36,20 @@ pub(crate) fn get_video_information(url: &str) -> BotResult { Ok(information) } + +/// Searches for a video +pub(crate) fn search_video_information(query: &str) -> BotResult> { + let ytdl = Command::new("youtube-dl") + .args(&[ + "--no-warnings", + "--dump-json", + "-i", + format!("ytsearch:\"{}\"", query).as_str(), + ]) + .stdout(Stdio::piped()) + .spawn()?; + + let information = serde_json::from_reader(ytdl.stdout.unwrap())?; + + Ok(information) +}