RMusicBot/src/player/commands/play.rs

267 lines
6.8 KiB
Rust
Raw Normal View History

2018-11-14 14:29:58 +00:00
use super::super::prelude::*;
2019-04-03 09:42:06 +00:00
use rusqlite::params;
2019-09-14 14:34:00 +00:00
use rand::{seq::SliceRandom, thread_rng};
2019-07-12 08:39:03 +00:00
use serenity::prelude::*;
use serenity::voice::LockedAudio;
use serenity::{
framework::standard::{macros::command, Args, CommandResult},
model::channel::Message,
};
2019-09-14 14:34:00 +00:00
use utilities::prelude::*;
2019-07-12 08:39:03 +00:00
#[command]
2019-07-12 12:41:51 +00:00
fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
2019-09-14 14:34:00 +00:00
if let Err(err) = channel_contains_author(ctx, msg) {
msg.channel_id.say(&ctx.http, err)?;
2019-07-12 08:39:03 +00:00
return Ok(());
2018-11-14 14:29:58 +00:00
}
2019-07-12 12:41:51 +00:00
let mut data = ctx.data.write();
let media = match data.get_mut::<Media>() {
Some(media) => media,
None => {
2019-09-14 14:34:00 +00:00
msg.channel_id.say(&ctx.http, "could not find media data")?;
2019-07-12 08:39:03 +00:00
return Ok(());
2018-11-14 14:29:58 +00:00
}
2019-07-12 08:39:03 +00:00
};
2018-11-14 14:29:58 +00:00
2019-07-12 08:39:03 +00:00
if args.len() == 0 {
2019-07-12 12:41:51 +00:00
if !check_for_continue(media.song_mut()) {
2019-09-14 14:34:00 +00:00
msg.channel_id
.say(&ctx.http, "Must provide a URL to a video or audio")?;
2019-07-12 08:39:03 +00:00
}
2019-09-14 14:34:00 +00:00
} else {
let first_arg = args.current().unwrap();
2018-11-14 14:29:58 +00:00
2019-09-14 14:34:00 +00:00
if first_arg == "--local" {
2019-07-12 12:41:51 +00:00
handle_local_request(media, ctx, msg)?;
2019-09-14 14:34:00 +00:00
} else if first_arg.starts_with("http") {
handle_http_request(media, ctx, msg, first_arg)?;
2019-07-12 08:39:03 +00:00
} else {
2019-09-15 11:19:32 +00:00
let mut arg_list = args.single::<String>()?;
2019-09-14 14:34:00 +00:00
for arg in args.iter::<String>() {
arg_list += &format!(" {}", arg?.trim());
}
2019-09-15 11:19:32 +00:00
handle_song_request(media, ctx, msg, &arg_list)?
2018-11-14 15:43:53 +00:00
}
2019-07-12 08:39:03 +00:00
}
2018-11-14 15:43:53 +00:00
2019-07-12 08:39:03 +00:00
Ok(())
}
2019-04-28 12:13:36 +00:00
2019-07-12 12:41:51 +00:00
fn check_for_continue(song_lock: &Option<LockedAudio>) -> bool {
match song_lock {
2019-07-12 08:39:03 +00:00
Some(song) => {
let song_clone = song.clone();
let mut audio_lock = song_clone.lock();
2019-04-28 12:13:36 +00:00
2019-07-12 08:39:03 +00:00
audio_lock.play();
true
}
None => false,
}
}
2019-04-28 12:13:36 +00:00
2019-07-12 08:39:03 +00:00
fn append_songs(
media: &mut MediaData,
2019-07-12 12:41:51 +00:00
ctx: &Context,
msg: &Message,
2019-07-12 08:39:03 +00:00
mut source: Vec<Song>,
2019-09-14 14:34:00 +00:00
) -> VerboseResult<()> {
2019-07-12 12:41:51 +00:00
media.playlist_mut().append(&mut source);
2019-04-03 09:42:06 +00:00
2019-09-15 11:19:32 +00:00
println!("start playing");
2019-09-14 14:34:00 +00:00
MediaData::start_playing(ctx, media, msg)?;
2018-11-14 14:29:58 +00:00
2019-07-12 08:39:03 +00:00
Ok(())
}
2018-11-14 14:29:58 +00:00
2019-07-12 08:39:03 +00:00
fn handle_http_request(
media: &mut MediaData,
2019-07-12 12:41:51 +00:00
ctx: &serenity::client::Context,
2019-07-12 08:39:03 +00:00
msg: &serenity::model::channel::Message,
2019-09-14 14:34:00 +00:00
url: &str,
) -> VerboseResult<()> {
2019-07-12 12:41:51 +00:00
let mut names = Vec::new();
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
{
let sql = media.db();
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
Ok(statement) => statement,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed preparing data base access"),
2019-07-12 12:41:51 +00:00
};
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed querying rows"),
};
2019-07-12 12:41:51 +00:00
for name_result in rows {
let name = match name_result {
Ok(name) => name,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed getting name from row"),
2019-07-12 12:41:51 +00:00
};
names.push(name);
}
2019-07-12 08:39:03 +00:00
}
2019-07-12 08:39:03 +00:00
if names.len() > 0 {
2019-09-14 14:34:00 +00:00
msg.channel_id
.say(&ctx.http, "song already loaded!")
.map_err(|err| format!("{}", err))?;
2019-07-12 12:41:51 +00:00
append_songs(
media,
2019-07-12 08:39:03 +00:00
ctx,
msg,
names.iter().map(|n| Song { name: n.clone() }).collect(),
)?;
2019-07-12 12:41:51 +00:00
} else {
let source = match youtube_dl(&url) {
Ok(source) => source,
Err(why) => {
println!("Err starting source: {:?}", why);
2019-04-28 12:13:36 +00:00
2019-09-14 14:34:00 +00:00
msg.channel_id
.say(&ctx.http, format!("Error using youtube-dl: {}", why))
.map_err(|err| format!("{}", err))?;
2018-11-14 14:29:58 +00:00
2019-07-12 12:41:51 +00:00
return Ok(());
}
};
2018-11-14 15:43:53 +00:00
2019-07-12 12:41:51 +00:00
let mut info = if source.len() == 1 {
"Finished downloading song:".to_string()
} else {
"Finished downloading songs:".to_string()
};
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
{
let sql = media.db();
2018-11-14 15:43:53 +00:00
2019-07-12 12:41:51 +00:00
for song in &source {
info = format!("{}\n\t{}", info, song.name);
2019-04-28 12:13:36 +00:00
2019-07-12 12:41:51 +00:00
if sql
.execute(
"INSERT INTO Vulva3 (name, link)
2019-07-12 08:39:03 +00:00
VALUES (?1, ?2)",
2019-07-12 12:41:51 +00:00
params![song.name, url],
)
.is_err()
{
2019-09-14 14:34:00 +00:00
create_error!("failed inserting songs into db");
2019-07-12 12:41:51 +00:00
}
}
2018-11-14 15:43:53 +00:00
}
2019-09-14 14:34:00 +00:00
msg.channel_id
.say(&ctx.http, info)
.map_err(|err| format!("{}", err))?;
2018-11-14 15:43:53 +00:00
2019-07-12 12:41:51 +00:00
append_songs(media, ctx, msg, source)?;
}
2019-04-28 12:13:36 +00:00
2019-07-12 08:39:03 +00:00
Ok(())
}
2019-04-03 09:42:06 +00:00
2019-07-12 08:39:03 +00:00
fn handle_local_request(
media: &mut MediaData,
2019-07-12 12:41:51 +00:00
ctx: &serenity::client::Context,
2019-07-12 08:39:03 +00:00
msg: &serenity::model::channel::Message,
2019-09-14 14:34:00 +00:00
) -> VerboseResult<()> {
2019-07-12 12:41:51 +00:00
let mut songs = Vec::new();
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
{
let sql = media.db();
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
Ok(statement) => statement,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed preparing data base access"),
2019-07-12 12:41:51 +00:00
};
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed querying rows"),
2019-04-28 12:13:36 +00:00
};
2019-04-03 09:42:06 +00:00
2019-07-12 12:41:51 +00:00
for name_result in rows {
let name = match name_result {
Ok(name) => name,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed getting name from row"),
2019-07-12 12:41:51 +00:00
};
songs.push(Song { name });
}
2019-07-12 08:39:03 +00:00
}
2019-04-03 09:42:06 +00:00
2019-07-12 08:39:03 +00:00
let mut rng = thread_rng();
songs.shuffle(&mut rng);
2019-04-28 12:13:36 +00:00
2019-07-12 12:41:51 +00:00
append_songs(media, ctx, msg, songs)?;
2019-04-03 09:42:06 +00:00
2019-07-12 08:39:03 +00:00
Ok(())
}
2019-04-03 09:42:06 +00:00
2019-07-12 08:39:03 +00:00
fn handle_song_request(
media: &mut MediaData,
2019-07-12 12:41:51 +00:00
ctx: &serenity::client::Context,
2019-07-12 08:39:03 +00:00
msg: &serenity::model::channel::Message,
pattern: &str,
2019-09-14 14:34:00 +00:00
) -> VerboseResult<()> {
2019-09-15 11:19:32 +00:00
println!("song request ({})", pattern);
2019-07-12 12:41:51 +00:00
let mut songs = Vec::new();
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
{
let sql = media.db();
let mut stmt = match sql.prepare(&format!(
"SELECT name FROM Vulva3 WHERE name LIKE '%{}%'",
pattern
)) {
Ok(statement) => statement,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed preparing data base access"),
2019-07-12 12:41:51 +00:00
};
2019-07-12 08:39:03 +00:00
2019-07-12 12:41:51 +00:00
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed querying rows"),
2019-07-12 08:39:03 +00:00
};
2019-04-28 12:13:36 +00:00
2019-07-12 12:41:51 +00:00
for name_result in rows {
let name = match name_result {
Ok(name) => name,
2019-09-14 14:34:00 +00:00
Err(_) => create_error!("failed getting name from row"),
2019-07-12 12:41:51 +00:00
};
songs.push(Song { name });
}
2019-04-03 09:42:06 +00:00
}
2018-11-14 14:29:58 +00:00
2019-09-15 11:19:32 +00:00
println!("{:?}", &songs);
2019-07-12 08:39:03 +00:00
if !songs.is_empty() {
let mut rng = thread_rng();
songs.shuffle(&mut rng);
2018-11-14 14:29:58 +00:00
2019-09-15 11:19:32 +00:00
println!("append songs");
2019-07-12 12:41:51 +00:00
append_songs(media, ctx, msg, songs)?;
2019-07-12 08:39:03 +00:00
} else {
2019-09-14 14:34:00 +00:00
msg.channel_id
.say(&ctx.http, format!("no song found with pattern {}", pattern))
.map_err(|err| format!("{}", err))?;
2018-11-14 14:29:58 +00:00
}
2019-07-12 08:39:03 +00:00
Ok(())
2018-11-14 14:29:58 +00:00
}