diff --git a/src/confighandler.rs b/src/confighandler.rs index f44a6b9..ec1f502 100644 --- a/src/confighandler.rs +++ b/src/confighandler.rs @@ -57,12 +57,14 @@ impl Value { T: FromStr, { match self { - Value::Array(value_array) => for value_string in value_array { - match value_string.parse::() { - Ok(val) => array.push(val), - Err(_) => return Err(format!("error parsing value {}", value_string)), + Value::Array(value_array) => { + for value_string in value_array { + match value_string.parse::() { + Ok(val) => array.push(val), + Err(_) => return Err(format!("error parsing value {}", value_string)), + } } - }, + } _ => return Err("key_value has wrong format".to_string()), }; @@ -121,7 +123,7 @@ pub fn read_config(file_name: &str) -> Result, @@ -77,37 +75,37 @@ impl Play { ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, mut source: Vec, - ) { + ) -> Result<(), String> { { - let playlist_mutex = self.media.playlist_mut(); + let playlist_mutex = self.media.playlist_mut()?; playlist_mutex.borrow_mut().append(&mut source); } - let manager_lock = ctx.data.lock().get::().cloned().unwrap(); + if let Some(manager_lock) = ctx.data.lock().get::().cloned() { + Self::check_join_channel(&manager_lock, msg); - Self::check_join_channel(&manager_lock, msg); + let check_finished = { + let media_clone = self.media.clone(); + let channel_id = msg.channel_id; + let manager_lock_clone = manager_lock.clone(); - let check_finished = { - let media_clone = self.media.clone(); - let channel_id = msg.channel_id; - let manager_lock_clone = manager_lock.clone(); + Arc::new(move || { + let callback = match media_clone.next_callback.borrow().deref() { + Some(callback) => callback.clone(), + None => { + println!("next_callback not set!"); + return; + } + }; - Arc::new(move || { - let callback = match media_clone.next_callback.borrow().deref() { - Some(callback) => callback.clone(), - None => { - println!("next_callback not set!"); - return; - } - }; + MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback); + }) + }; - MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback); - }) - }; + MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock); + } - MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock); - - //MediaData::start_thread(&self.media, msg.channel_id, &manager_lock); + Ok(()) } fn handle_http_request( @@ -115,20 +113,27 @@ impl Play { ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, url: &String, - ) { - let sql = self.media.lock_db(); + ) -> Result<(), String> { + let sql = self.media.lock_db()?; - let mut stmt = sql - .prepare("SELECT name FROM Vulva3 WHERE link = ?") - .unwrap(); + let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") { + Ok(statement) => statement, + Err(_) => return Err("failed preparing data base access".to_string()), + }; - let rows = stmt - .query_map(&[url], |row| row.get(0) as rusqlite::Result) - .expect("failed requesting db"); + let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result) { + Ok(rows) => rows, + Err(_) => return Err("failed querying rows".to_string()), + }; let mut names = Vec::new(); for name_result in rows { - names.push(name_result.unwrap()); + let name = match name_result { + Ok(name) => name, + Err(_) => return Err("failed getting name from row".to_string()), + }; + + names.push(name); } if names.len() > 0 { @@ -138,9 +143,9 @@ impl Play { ctx, msg, names.iter().map(|n| Song { name: n.clone() }).collect(), - ); + )?; - return; + return Ok(()); } let source = match youtube_dl(&url) { @@ -152,7 +157,7 @@ impl Play { .channel_id .say(format!("Error using youtube-dl: {}", why))); - return; + return Ok(()); } }; @@ -165,45 +170,58 @@ impl Play { for song in &source { info = format!("{}\n\t{}", info, song.name); - sql.execute( - "INSERT INTO Vulva3 (name, link) - VALUES (?1, ?2)", - params![song.name, url], - ) - .expect("failed inserting song"); + if sql + .execute( + "INSERT INTO Vulva3 (name, link) + VALUES (?1, ?2)", + params![song.name, url], + ) + .is_err() + { + return Err("failed inserting songs into db".to_string()); + } } print_error!(msg.channel_id.say(info)); - self.append_songs(ctx, msg, source); + self.append_songs(ctx, msg, source)?; + + Ok(()) } fn handle_local_request( &self, ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, - ) { - //print_error!(self.media.reset(ctx, msg)); + ) -> Result<(), String> { + let sql = self.media.lock_db()?; - let sql = self.media.lock_db(); + let mut stmt = match sql.prepare("SELECT name FROM Vulva3") { + Ok(statement) => statement, + Err(_) => return Err("failed preparing data base access".to_string()), + }; - let mut stmt = sql.prepare("SELECT name FROM Vulva3").unwrap(); - - let rows = stmt - .query_map(params![], |row| row.get(0) as rusqlite::Result) - .expect("failed requesting db"); + let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result) { + Ok(rows) => rows, + Err(_) => return Err("failed querying rows".to_string()), + }; let mut songs = Vec::new(); for name_result in rows { - songs.push(Song { - name: name_result.unwrap(), - }); + let name = match name_result { + Ok(name) => name, + Err(_) => return Err("failed getting name from row".to_string()), + }; + + songs.push(Song { name }); } let mut rng = thread_rng(); songs.shuffle(&mut rng); - self.append_songs(ctx, msg, songs); + self.append_songs(ctx, msg, songs)?; + + Ok(()) } fn handle_song_request( @@ -211,37 +229,44 @@ impl Play { ctx: &mut serenity::client::Context, msg: &serenity::model::channel::Message, pattern: &str, - ) { - let sql = self.media.lock_db(); + ) -> Result<(), String> { + let sql = self.media.lock_db()?; - let mut stmt = sql - .prepare(&format!( - "SELECT name FROM Vulva3 WHERE name LIKE '%{}%'", - pattern - )) - .unwrap(); + let mut stmt = match sql.prepare(&format!( + "SELECT name FROM Vulva3 WHERE name LIKE '%{}%'", + pattern + )) { + Ok(statement) => statement, + Err(_) => return Err("failed preparing data base access".to_string()), + }; - let rows = stmt - .query_map(params![], |row| row.get(0) as rusqlite::Result) - .expect("failed requesting db"); + let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result) { + Ok(rows) => rows, + Err(_) => return Err("failed querying rows".to_string()), + }; let mut songs = Vec::new(); for name_result in rows { - songs.push(Song { - name: name_result.unwrap(), - }); + let name = match name_result { + Ok(name) => name, + Err(_) => return Err("failed getting name from row".to_string()), + }; + + songs.push(Song { name }); } if !songs.is_empty() { let mut rng = thread_rng(); songs.shuffle(&mut rng); - self.append_songs(ctx, msg, songs); + self.append_songs(ctx, msg, songs)?; } else { print_error!(msg .channel_id .say(format!("no song found with pattern {}", pattern))); } + + Ok(()) } } @@ -262,7 +287,7 @@ impl serenity::framework::standard::Command for Play { } if args.len() == 0 { - if !Self::check_for_continue(self.media.song_mut()) { + 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 { @@ -273,11 +298,11 @@ impl serenity::framework::standard::Command for Play { }; if arg == "--local" { - self.handle_local_request(ctx, msg); + self.handle_local_request(ctx, msg)?; } else if arg.starts_with("http") { - self.handle_http_request(ctx, msg, &arg); + self.handle_http_request(ctx, msg, &arg)?; } else { - self.handle_song_request(ctx, msg, &arg); + self.handle_song_request(ctx, msg, &arg)?; } } else { print_error!(msg.channel_id.say("Unsupported argument list")); diff --git a/src/player/commands/remove.rs b/src/player/commands/remove.rs index 259ed48..5a7b88d 100644 --- a/src/player/commands/remove.rs +++ b/src/player/commands/remove.rs @@ -27,13 +27,16 @@ impl serenity::framework::standard::Command for Remove { ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { // (1) - let song_name = self.media.name_mut(); + let song_name = self.media.name_mut()?; let name: String = song_name.borrow().clone(); - let sql = self.media.lock_db(); + let sql = self.media.lock_db()?; - sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name]) - .expect("failed deleting song"); + if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name]) { + return Err(serenity::framework::standard::CommandError( + "failed executing sql delete".to_string(), + )); + } if !name.is_empty() { match fs::remove_file(&name) { diff --git a/src/player/commands/skip.rs b/src/player/commands/skip.rs index 08cd249..efabe8f 100644 --- a/src/player/commands/skip.rs +++ b/src/player/commands/skip.rs @@ -31,61 +31,60 @@ impl serenity::framework::standard::Command for Skip { return Ok(()); } - let mut manager_lock = ctx.data.lock().get::().cloned().unwrap(); + if let Some(mut manager_lock) = ctx.data.lock().get::().cloned() { + let mut manager = manager_lock.lock(); - let mut manager = manager_lock.lock(); + let guild_id = match guild_id(msg.channel_id) { + Some(id) => id, + None => { + println!("error getting guild id"); + print_error!(msg.channel_id.say("error getting guild id")); - let guild_id = match guild_id(msg.channel_id) { - Some(id) => id, - None => { - println!("error getting guild id"); - print_error!(msg.channel_id.say("error getting guild id")); + return Ok(()); + } + }; - return Ok(()); - } - }; + if let Some(handler) = handler(guild_id, &mut manager) { + let playlist_mutex = self.media.playlist_mut()?; + let mut playlist = playlist_mutex.borrow_mut(); - if let Some(handler) = handler(guild_id, &mut manager) { - let playlist_mutex = self.media.playlist_mut(); - let mut playlist = playlist_mutex.borrow_mut(); + let song_mutex = self.media.song_mut()?; + let mut song = song_mutex.borrow_mut(); - let song_mutex = self.media.song_mut(); - let mut song = song_mutex.borrow_mut(); + if playlist.is_empty() { + print_error!(msg + .channel_id + .say("playlist is empty, no next song available")); - if playlist.is_empty() { - print_error!( - msg.channel_id - .say("playlist is empty, no next song available") - ); + return Ok(()); + } else { + let first = playlist.remove(0); - return Ok(()); - } else { - let first = playlist.remove(0); + handler.stop(); - handler.stop(); + let source = match ffmpeg(first.name.clone()) { + Ok(mpeg) => mpeg, + Err(_) => { + playlist.clear(); + *song = None; - let source = match ffmpeg(first.name.clone()) { - Ok(mpeg) => mpeg, - Err(_) => { - playlist.clear(); - *song = None; + return Ok(()); + } + }; - return Ok(()); + match self.media.next_callback.borrow().as_ref() { + Some(callback) => { + *song = + Some(handler.play_returning_and_callback(source, callback.clone())); + let song_name = self.media.name_mut()?; + *song_name.borrow_mut() = first.name.clone(); + + print_error!(msg + .channel_id + .say(format!("Skipped current song, now playing: {}", first.name))); + } + None => println!("error getting callback from media"), } - }; - - match self.media.next_callback.borrow().as_ref() { - Some(callback) => { - *song = Some(handler.play_returning_and_callback(source, callback.clone())); - let song_name = self.media.name_mut(); - *song_name.borrow_mut() = first.name.clone(); - - print_error!( - msg.channel_id - .say(format!("Skipped current song, now playing: {}", first.name)) - ); - } - None => println!("error getting callback from media"), } } } diff --git a/src/player/mediadata.rs b/src/player/mediadata.rs index 5a92bb2..b4bac0b 100644 --- a/src/player/mediadata.rs +++ b/src/player/mediadata.rs @@ -8,7 +8,6 @@ use std::sync::{Arc, Mutex, MutexGuard}; use super::prelude::*; -use rusqlite::types::ToSql; use rusqlite::{params, Connection}; pub struct Song { @@ -61,17 +60,17 @@ impl MediaData { msg: &serenity::model::channel::Message, ) -> Result<(), String> { { - let playlist = self.playlist_mut(); + let playlist = self.playlist_mut()?; playlist.borrow_mut().clear(); } { - let song = self.song_mut(); + let song = self.song_mut()?; *song.borrow_mut() = None; } { - let name = self.name_mut(); + let name = self.name_mut()?; *name.borrow_mut() = String::new(); } @@ -79,8 +78,7 @@ impl MediaData { *self.next_callback.borrow_mut() = None; } - { - let manager_lock = ctx.data.lock().get::().cloned().unwrap(); + if let Some(manager_lock) = ctx.data.lock().get::().cloned() { let mut manager = manager_lock.lock(); let guild_id = match guild_id(msg.channel_id) { @@ -105,20 +103,32 @@ impl MediaData { Ok(()) } - pub fn lock_db(&self) -> MutexGuard { - self.sql_data_base.lock().unwrap() + pub fn lock_db(&self) -> Result, String> { + match self.sql_data_base.lock() { + Ok(sql) => Ok(sql), + Err(_) => Err("failed locking db".to_string()), + } } - pub fn song_mut(&self) -> MutexGuard>> { - self.current_song.lock().unwrap() + pub fn song_mut(&self) -> Result>>, String> { + match self.current_song.lock() { + Ok(sql) => Ok(sql), + Err(_) => Err("failed locking current song".to_string()), + } } - pub fn playlist_mut(&self) -> MutexGuard>> { - self.playlist.lock().unwrap() + pub fn playlist_mut(&self) -> Result>>, String> { + match self.playlist.lock() { + Ok(sql) => Ok(sql), + Err(_) => Err("failed locking playlist".to_string()), + } } - pub fn name_mut(&self) -> MutexGuard> { - self.song_name.lock().unwrap() + pub fn name_mut(&self) -> Result>, String> { + match self.song_name.lock() { + Ok(sql) => Ok(sql), + Err(_) => Err("failed locking current song name".to_string()), + } } pub fn start_playing( @@ -131,7 +141,14 @@ impl MediaData { ) { // check if there is already playing let already_started = { - let song_lock = mediadata.song_mut(); + let song_lock = match mediadata.song_mut() { + Ok(song) => song, + Err(msg) => { + println!("{}", msg); + return; + } + }; + let song = song_lock.borrow(); song.is_some() }; @@ -175,13 +192,31 @@ impl MediaData { } }; - let playlist_lock = mediadata.playlist_mut(); + let playlist_lock = match mediadata.playlist_mut() { + Ok(playlist) => playlist, + Err(msg) => { + println!("{}", msg); + return; + } + }; let mut playlist = playlist_lock.borrow_mut(); - let song_name_lock = mediadata.name_mut(); + let song_name_lock = match mediadata.name_mut() { + Ok(name) => name, + Err(msg) => { + println!("{}", msg); + return; + } + }; let mut name = song_name_lock.borrow_mut(); - let song_lock = mediadata.song_mut(); + let song_lock = match mediadata.song_mut() { + Ok(song) => song, + Err(msg) => { + println!("{}", msg); + return; + } + }; let mut song = song_lock.borrow_mut(); if playlist.is_empty() { diff --git a/src/player/player.rs b/src/player/player.rs index 27bf2a6..00fc2e7 100644 --- a/src/player/player.rs +++ b/src/player/player.rs @@ -32,35 +32,38 @@ pub fn channel_contains_author( msg: &serenity::model::channel::Message, ) -> bool { let (guild_id, voice_channel_id_bot) = { - let manager_lock = ctx.data.lock().get::().cloned().unwrap(); + match ctx.data.lock().get::().cloned() { + Some(manager_lock) => { + let mut manager = manager_lock.lock(); + let guild_id = match guild_id(msg.channel_id) { + Some(guild_id) => guild_id, + None => { + println!("error getting guild_id"); + return true; + } + }; - let mut manager = manager_lock.lock(); - let guild_id = match guild_id(msg.channel_id) { - Some(guild_id) => guild_id, - None => { - println!("error getting guild_id"); - return true; + let handler = match handler(guild_id, &mut manager) { + Some(handler) => handler, + None => { + println!("error getting handler"); + return true; + } + }; + + ( + guild_id, + match handler.channel_id { + Some(id) => id, + None => { + println!("error getting channel_id for bot"); + return true; + } + }, + ) } - }; - - let handler = match handler(guild_id, &mut manager) { - Some(handler) => handler, - None => { - println!("error getting handler"); - return true; - } - }; - - ( - guild_id, - match handler.channel_id { - Some(id) => id, - None => { - println!("error getting channel_id for bot"); - return true; - } - }, - ) + None => return false, + } }; let author = &msg.author;