Start implementing serenity 0.6
This commit is contained in:
parent
da1c9a5d2e
commit
4276428a8b
14 changed files with 557 additions and 628 deletions
32
src/main.rs
32
src/main.rs
|
@ -11,8 +11,24 @@ mod confighandler;
|
|||
mod macros;
|
||||
mod player;
|
||||
|
||||
use serenity::client::Client;
|
||||
use serenity::framework::StandardFramework;
|
||||
use serenity::{
|
||||
framework::standard::{
|
||||
help_commands,
|
||||
macros::{check, command, group, help},
|
||||
Args, CheckResult, CommandGroup, CommandOptions, CommandResult, DispatchError, HelpOptions,
|
||||
StandardFramework,
|
||||
},
|
||||
model::{
|
||||
channel::{Channel, Message},
|
||||
gateway::Ready,
|
||||
id::UserId,
|
||||
},
|
||||
utils::{content_safe, ContentSafeOptions},
|
||||
};
|
||||
|
||||
// This imports `typemap`'s `Key` as `TypeMapKey`.
|
||||
use serenity::prelude::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use confighandler::*;
|
||||
|
@ -32,6 +48,12 @@ impl Default for Config {
|
|||
}
|
||||
}
|
||||
|
||||
group!({
|
||||
name: "general",
|
||||
options: {},
|
||||
commands: [ip]
|
||||
});
|
||||
|
||||
fn main() {
|
||||
// read config file
|
||||
let config_file = check_result_return!(read_config("bot.conf"));
|
||||
|
@ -71,13 +93,15 @@ fn main() {
|
|||
// voice manager into it. This allows the voice manager to be accessible by
|
||||
// event handlers and framework commands.
|
||||
{
|
||||
let mut data = client.data.lock();
|
||||
let mut data = client.data.write();
|
||||
data.insert::<VoiceManager>(Arc::clone(&client.voice_manager));
|
||||
}
|
||||
|
||||
let media_data =
|
||||
Arc::new(MediaData::new("Penis1").expect("failed to create media data handle"));
|
||||
|
||||
/*
|
||||
|
||||
client.with_framework(
|
||||
StandardFramework::new()
|
||||
.configure(|c| c.prefix(&config.prefix).on_mention(true))
|
||||
|
@ -109,4 +133,6 @@ fn main() {
|
|||
let _ = client
|
||||
.start()
|
||||
.map_err(|why| println!("Client ended: {:?}", why));
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
use serenity;
|
||||
|
||||
pub struct Help {
|
||||
prefix: String,
|
||||
commands: Vec<String>,
|
||||
}
|
||||
|
||||
impl Help {
|
||||
pub fn new(prefix: &String, commands: Vec<String>) -> Help {
|
||||
Help {
|
||||
prefix: prefix.clone(),
|
||||
commands: commands,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for Help {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
_: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
let mut output = String::new();
|
||||
|
||||
output += "Available commands:\n";
|
||||
|
||||
for command in &self.commands {
|
||||
output += &format!("\t{}{}\n", self.prefix, command);
|
||||
}
|
||||
|
||||
print_error!(msg.channel_id.say(output));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,44 +1,35 @@
|
|||
use serenity;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
// This imports `typemap`'s `Key` as `TypeMapKey`.
|
||||
use serenity::prelude::*;
|
||||
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::from_utf8;
|
||||
|
||||
pub struct IP {}
|
||||
#[command]
|
||||
fn ip(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let args = ["ifconfig.me"];
|
||||
|
||||
impl IP {
|
||||
pub fn new() -> IP {
|
||||
IP {}
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for IP {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
_: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
let args = ["ifconfig.me"];
|
||||
|
||||
let out = match Command::new("curl")
|
||||
.args(&args)
|
||||
.stdin(Stdio::null())
|
||||
.output()
|
||||
{
|
||||
Ok(out) => out,
|
||||
Err(_) => return Ok(()),
|
||||
};
|
||||
|
||||
if !out.status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match from_utf8(out.stdout.as_slice()) {
|
||||
Ok(string) => print_error!(msg.author.direct_message(|m| m.content(string))),
|
||||
Err(_) => print_error!(msg.channel_id.say("error getting IP string")),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
let out = match Command::new("curl")
|
||||
.args(&args)
|
||||
.stdin(Stdio::null())
|
||||
.output()
|
||||
{
|
||||
Ok(out) => out,
|
||||
Err(_) => return Ok(()),
|
||||
};
|
||||
|
||||
if !out.status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match from_utf8(out.stdout.as_slice()) {
|
||||
Ok(string) => print_error!(msg.author.direct_message(|m| m.content(string))),
|
||||
Err(_) => print_error!(msg.channel_id.say("error getting IP string")),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,61 +1,52 @@
|
|||
use serenity;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::prelude::*;
|
||||
|
||||
pub struct List {
|
||||
media: Arc<MediaData>,
|
||||
}
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
impl List {
|
||||
pub fn new(media_data: Arc<MediaData>) -> List {
|
||||
List { media: media_data }
|
||||
#[command]
|
||||
fn list(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for List {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
let mut output = String::new();
|
||||
|
||||
let data = ctx.data.read();
|
||||
let media = match data.get::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let mut output = String::new();
|
||||
let playlist = media.playlist();
|
||||
|
||||
{
|
||||
let playlist_mutex = self.media.playlist_mut()?;
|
||||
let playlist = playlist_mutex.borrow();
|
||||
output += &format!(
|
||||
"{} {} queued\n",
|
||||
playlist.len(),
|
||||
if playlist.len() == 1 { "song" } else { "songs" }
|
||||
);
|
||||
|
||||
output += &format!(
|
||||
"{} {} queued\n",
|
||||
playlist.len(),
|
||||
if playlist.len() == 1 { "song" } else { "songs" }
|
||||
);
|
||||
let max_output = 5;
|
||||
|
||||
let max_output = 5;
|
||||
|
||||
for (i, song) in playlist.iter().enumerate() {
|
||||
if i < max_output {
|
||||
output += &format!("\t{}.\t{}\n", i + 1, song.name.clone());
|
||||
} else {
|
||||
output += &format!("\t... and {} more", playlist.len() - max_output);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i, song) in playlist.iter().enumerate() {
|
||||
if i < max_output {
|
||||
output += &format!("\t{}.\t{}\n", i + 1, song.name.clone());
|
||||
} else {
|
||||
output += &format!("\t... and {} more", playlist.len() - max_output);
|
||||
break;
|
||||
}
|
||||
|
||||
print_error!(msg.channel_id.say(output));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
print_error!(msg.channel_id.say(output));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
pub mod help;
|
||||
pub mod ip;
|
||||
pub mod list;
|
||||
pub mod pause;
|
||||
|
|
|
@ -1,45 +1,33 @@
|
|||
use serenity;
|
||||
|
||||
use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::prelude::*;
|
||||
|
||||
pub struct Pause {
|
||||
media: Arc<MediaData>,
|
||||
}
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
impl Pause {
|
||||
pub fn new(media_data: Arc<MediaData>) -> Pause {
|
||||
Pause { media: media_data }
|
||||
#[command]
|
||||
fn pause(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for Pause {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
let data = ctx.data.read();
|
||||
let media = match data.get::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let song_lock = self.media.song_mut()?;
|
||||
media.song().pause();
|
||||
|
||||
if let Some(song) = song_lock.borrow_mut().deref_mut() {
|
||||
let song_clone = song.clone();
|
||||
let mut audio_lock = song_clone.lock();
|
||||
|
||||
audio_lock.pause();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use parking_lot;
|
||||
|
||||
use serenity;
|
||||
use serenity::voice::LockedAudio;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, MutexGuard};
|
||||
|
@ -13,301 +10,300 @@ use super::super::prelude::*;
|
|||
|
||||
use rusqlite::params;
|
||||
|
||||
pub struct Play {
|
||||
media: Arc<MediaData>,
|
||||
use serenity::prelude::*;
|
||||
use serenity::voice::LockedAudio;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
#[command]
|
||||
fn play(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let data = ctx.data.read();
|
||||
let mut media = match data.get_mut::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
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::<String>() {
|
||||
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 {
|
||||
self.handle_song_request(ctx, msg, &arg)?;
|
||||
}
|
||||
} else {
|
||||
print_error!(msg.channel_id.say("Unsupported argument list"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Play {
|
||||
pub fn new(media_data: Arc<MediaData>) -> Play {
|
||||
Play { media: media_data }
|
||||
fn check_for_continue(song_lock: MutexGuard<RefCell<Option<LockedAudio>>>) -> 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<parking_lot::Mutex<serenity::client::bridge::voice::ClientVoiceManager>>,
|
||||
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 append_songs(
|
||||
media: &mut MediaData,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
mut source: Vec<Song>,
|
||||
) -> Result<(), String> {
|
||||
{
|
||||
let playlist_mutex = self.media.playlist_mut()?;
|
||||
playlist_mutex.borrow_mut().append(&mut source);
|
||||
}
|
||||
|
||||
fn check_for_continue(song_lock: MutexGuard<RefCell<Option<LockedAudio>>>) -> bool {
|
||||
match song_lock.borrow_mut().deref_mut() {
|
||||
Some(song) => {
|
||||
let song_clone = song.clone();
|
||||
let mut audio_lock = song_clone.lock();
|
||||
if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
Self::check_join_channel(&manager_lock, msg);
|
||||
|
||||
audio_lock.play();
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
|
||||
})
|
||||
};
|
||||
|
||||
MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock);
|
||||
}
|
||||
|
||||
fn check_join_channel(
|
||||
manager_lock: &Arc<parking_lot::Mutex<serenity::client::bridge::voice::ClientVoiceManager>>,
|
||||
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"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
fn handle_http_request(
|
||||
media: &mut MediaData,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
url: &String,
|
||||
) -> Result<(), String> {
|
||||
let sql = self.media.lock_db()?;
|
||||
|
||||
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 = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
};
|
||||
|
||||
let mut names = Vec::new();
|
||||
for name_result in rows {
|
||||
let name = match name_result {
|
||||
Ok(name) => name,
|
||||
Err(_) => return Err("failed getting name from row".to_string()),
|
||||
};
|
||||
|
||||
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);
|
||||
names.push(name);
|
||||
}
|
||||
|
||||
fn append_songs(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
mut source: Vec<Song>,
|
||||
) -> Result<(), String> {
|
||||
{
|
||||
let playlist_mutex = self.media.playlist_mut()?;
|
||||
playlist_mutex.borrow_mut().append(&mut source);
|
||||
}
|
||||
if names.len() > 0 {
|
||||
print_error!(msg.channel_id.say("song already loaded!"));
|
||||
|
||||
if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
Self::check_join_channel(&manager_lock, msg);
|
||||
self.append_songs(
|
||||
ctx,
|
||||
msg,
|
||||
names.iter().map(|n| Song { name: n.clone() }).collect(),
|
||||
)?;
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
|
||||
})
|
||||
};
|
||||
|
||||
MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn handle_http_request(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
url: &String,
|
||||
) -> Result<(), String> {
|
||||
let sql = self.media.lock_db()?;
|
||||
let source = match youtube_dl(&url) {
|
||||
Ok(source) => source,
|
||||
Err(why) => {
|
||||
println!("Err starting source: {:?}", why);
|
||||
|
||||
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 = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
};
|
||||
|
||||
let mut names = Vec::new();
|
||||
for name_result in rows {
|
||||
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 {
|
||||
print_error!(msg.channel_id.say("song already loaded!"));
|
||||
|
||||
self.append_songs(
|
||||
ctx,
|
||||
msg,
|
||||
names.iter().map(|n| Song { name: n.clone() }).collect(),
|
||||
)?;
|
||||
print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("Error using youtube-dl: {}", why)));
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let source = match youtube_dl(&url) {
|
||||
Ok(source) => source,
|
||||
Err(why) => {
|
||||
println!("Err starting source: {:?}", why);
|
||||
let mut info = if source.len() == 1 {
|
||||
"Finished downloading song:".to_string()
|
||||
} else {
|
||||
"Finished downloading songs:".to_string()
|
||||
};
|
||||
|
||||
print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("Error using youtube-dl: {}", why)));
|
||||
for song in &source {
|
||||
info = format!("{}\n\t{}", info, song.name);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let mut info = if source.len() == 1 {
|
||||
"Finished downloading song:".to_string()
|
||||
} else {
|
||||
"Finished downloading songs:".to_string()
|
||||
};
|
||||
|
||||
for song in &source {
|
||||
info = format!("{}\n\t{}", info, song.name);
|
||||
|
||||
if sql
|
||||
.execute(
|
||||
"INSERT INTO Vulva3 (name, link)
|
||||
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());
|
||||
}
|
||||
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)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_local_request(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
) -> Result<(), String> {
|
||||
let sql = self.media.lock_db()?;
|
||||
print_error!(msg.channel_id.say(info));
|
||||
|
||||
let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
|
||||
Ok(statement) => statement,
|
||||
Err(_) => return Err("failed preparing data base access".to_string()),
|
||||
self.append_songs(ctx, msg, source)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_local_request(
|
||||
media: &mut MediaData,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
) -> Result<(), String> {
|
||||
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 rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
};
|
||||
|
||||
let mut songs = Vec::new();
|
||||
for name_result in rows {
|
||||
let name = match name_result {
|
||||
Ok(name) => name,
|
||||
Err(_) => return Err("failed getting name from row".to_string()),
|
||||
};
|
||||
|
||||
let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
songs.push(Song { name });
|
||||
}
|
||||
|
||||
let mut rng = thread_rng();
|
||||
songs.shuffle(&mut rng);
|
||||
|
||||
self.append_songs(ctx, msg, songs)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_song_request(
|
||||
media: &mut MediaData,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
pattern: &str,
|
||||
) -> Result<(), String> {
|
||||
let sql = self.media.lock_db()?;
|
||||
|
||||
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 = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
};
|
||||
|
||||
let mut songs = Vec::new();
|
||||
for name_result in rows {
|
||||
let name = match name_result {
|
||||
Ok(name) => name,
|
||||
Err(_) => return Err("failed getting name from row".to_string()),
|
||||
};
|
||||
|
||||
let mut songs = Vec::new();
|
||||
for name_result in rows {
|
||||
let name = match name_result {
|
||||
Ok(name) => name,
|
||||
Err(_) => return Err("failed getting name from row".to_string()),
|
||||
};
|
||||
|
||||
songs.push(Song { name });
|
||||
}
|
||||
songs.push(Song { name });
|
||||
}
|
||||
|
||||
if !songs.is_empty() {
|
||||
let mut rng = thread_rng();
|
||||
songs.shuffle(&mut rng);
|
||||
|
||||
self.append_songs(ctx, msg, songs)?;
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("no song found with pattern {}", pattern)));
|
||||
}
|
||||
|
||||
fn handle_song_request(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
pattern: &str,
|
||||
) -> Result<(), String> {
|
||||
let sql = self.media.lock_db()?;
|
||||
|
||||
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 = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
|
||||
Ok(rows) => rows,
|
||||
Err(_) => return Err("failed querying rows".to_string()),
|
||||
};
|
||||
|
||||
let mut songs = Vec::new();
|
||||
for name_result in rows {
|
||||
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)?;
|
||||
} else {
|
||||
print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("no song found with pattern {}", pattern)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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 !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
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::<String>() {
|
||||
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 {
|
||||
self.handle_song_request(ctx, msg, &arg)?;
|
||||
}
|
||||
} else {
|
||||
print_error!(msg.channel_id.say("Unsupported argument list"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,56 +1,50 @@
|
|||
use serenity;
|
||||
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::prelude::*;
|
||||
|
||||
use rusqlite::params;
|
||||
|
||||
pub struct Remove {
|
||||
media: Arc<MediaData>,
|
||||
}
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
impl Remove {
|
||||
pub fn new(media_data: Arc<MediaData>) -> Remove {
|
||||
Remove { media: media_data }
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for Remove {
|
||||
#[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> {
|
||||
// (1)
|
||||
|
||||
let song_name = self.media.name_mut()?;
|
||||
let name: String = song_name.borrow().clone();
|
||||
|
||||
let sql = self.media.lock_db()?;
|
||||
|
||||
if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name]) {
|
||||
return Err(serenity::framework::standard::CommandError(
|
||||
"failed executing sql delete".to_string(),
|
||||
));
|
||||
#[command]
|
||||
fn remove(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||
let data = ctx.data.read();
|
||||
let media = match data.get::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
if !name.is_empty() {
|
||||
match fs::remove_file(&name) {
|
||||
Ok(_) => print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("Remove current song ({}) from local disk", name))),
|
||||
Err(err) => print_error!(msg.channel_id.say(format!(
|
||||
"Error removing file ({}): {:?}",
|
||||
name,
|
||||
err.kind()
|
||||
))),
|
||||
};
|
||||
}
|
||||
let song_name = media.song_name();
|
||||
let sql = media.db();
|
||||
|
||||
Ok(())
|
||||
if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![song_name]) {
|
||||
return Err(serenity::framework::standard::CommandError(
|
||||
"failed executing sql delete".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !song_name.is_empty() {
|
||||
match fs::remove_file(&song_name) {
|
||||
Ok(_) => print_error!(msg.channel_id.say(format!(
|
||||
"Remove current song ({}) from local disk",
|
||||
song_name
|
||||
))),
|
||||
Err(err) => print_error!(msg.channel_id.say(format!(
|
||||
"Error removing file ({}): {:?}",
|
||||
song_name,
|
||||
err.kind()
|
||||
))),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,94 +1,99 @@
|
|||
use serenity;
|
||||
use serenity::voice::ffmpeg;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::prelude::*;
|
||||
|
||||
pub struct Skip {
|
||||
media: Arc<MediaData>,
|
||||
}
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
impl Skip {
|
||||
pub fn new(media_data: Arc<MediaData>) -> Skip {
|
||||
Skip { media: media_data }
|
||||
#[command]
|
||||
fn skip(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for Skip {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(mut manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
let mut manager = manager_lock.lock();
|
||||
|
||||
if let Some(mut manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
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(());
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(handler) = handler(guild_id, &mut manager) {
|
||||
let data = ctx.data.read();
|
||||
let mut media = match data.get_mut::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
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();
|
||||
let mut playlist = media.playlist_mut();
|
||||
let mut song = media.song_mut();
|
||||
|
||||
let song_mutex = self.media.song_mut()?;
|
||||
let mut song = song_mutex.borrow_mut();
|
||||
// if current song is the last song in this playlist, just return
|
||||
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 {
|
||||
// remove the current song from the playlist
|
||||
let first = playlist.remove(0);
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
let first = playlist.remove(0);
|
||||
// stop the current song from playing
|
||||
handler.stop();
|
||||
|
||||
handler.stop();
|
||||
// load next song into memory
|
||||
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(());
|
||||
}
|
||||
};
|
||||
|
||||
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"),
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
// start the next song if possible
|
||||
/*
|
||||
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"),
|
||||
}
|
||||
*/
|
||||
*song = Some(handler.play_returning(source));
|
||||
*media.song_name_mut() = first.name.clone();
|
||||
|
||||
print_error!(msg
|
||||
.channel_id
|
||||
.say(format!("Skipped current song, now playing: {}", first.name)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,37 +1,31 @@
|
|||
use serenity;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::prelude::*;
|
||||
|
||||
pub struct Stop {
|
||||
media: Arc<MediaData>,
|
||||
}
|
||||
use serenity::prelude::*;
|
||||
use serenity::{
|
||||
framework::standard::{macros::command, Args, CommandResult},
|
||||
model::channel::Message,
|
||||
};
|
||||
|
||||
impl Stop {
|
||||
pub fn new(media_data: Arc<MediaData>) -> Stop {
|
||||
Stop { media: media_data }
|
||||
#[command]
|
||||
fn stop(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl serenity::framework::standard::Command for Stop {
|
||||
#[allow(unreachable_code, unused_mut)]
|
||||
fn execute(
|
||||
&self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
_: serenity::framework::standard::Args,
|
||||
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
|
||||
if !channel_contains_author(ctx, msg) {
|
||||
println!(
|
||||
"user {} is not in the same voice channel as the bot",
|
||||
msg.author.name
|
||||
);
|
||||
let data = ctx.data.read();
|
||||
let mut media = match data.get_mut::<MediaData>() {
|
||||
Ok(media) => media,
|
||||
Err(_) => {
|
||||
msg.channel_id.say("could not find media data");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
print_error!(self.media.reset(ctx, msg));
|
||||
print_error!(data.reset(ctx, msg));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@ use serenity::model::id::ChannelId;
|
|||
use serenity::voice::ffmpeg;
|
||||
use serenity::voice::LockedAudio;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
|
@ -15,12 +14,12 @@ pub struct Song {
|
|||
}
|
||||
|
||||
pub struct MediaData {
|
||||
playlist: Mutex<RefCell<Vec<Song>>>,
|
||||
current_song: Mutex<RefCell<Option<LockedAudio>>>,
|
||||
song_name: Mutex<RefCell<String>>,
|
||||
pub next_callback: RefCell<Option<Arc<Fn() -> ()>>>,
|
||||
playlist: Vec<Song>,
|
||||
current_song: Option<LockedAudio>,
|
||||
song_name: String,
|
||||
pub next_callback: Option<Arc<Fn() -> ()>>,
|
||||
|
||||
sql_data_base: Mutex<Connection>,
|
||||
sql_data_base: Connection,
|
||||
}
|
||||
|
||||
impl MediaData {
|
||||
|
@ -32,9 +31,9 @@ impl MediaData {
|
|||
|
||||
match connection.execute(
|
||||
"CREATE TABLE IF NOT EXISTS Vulva3 (
|
||||
name TEXT PRIMARY KEY,
|
||||
link TEXT NOT NULL
|
||||
)",
|
||||
name TEXT PRIMARY KEY,
|
||||
link TEXT NOT NULL
|
||||
)",
|
||||
params![],
|
||||
) {
|
||||
Ok(_) => (),
|
||||
|
@ -45,38 +44,24 @@ impl MediaData {
|
|||
};
|
||||
|
||||
Ok(MediaData {
|
||||
playlist: Mutex::new(RefCell::new(Vec::new())),
|
||||
current_song: Mutex::new(RefCell::new(None)),
|
||||
song_name: Mutex::new(RefCell::new(String::new())),
|
||||
next_callback: RefCell::new(None),
|
||||
playlist: Vec::new(),
|
||||
current_song: None,
|
||||
song_name: String::new(),
|
||||
next_callback: None,
|
||||
|
||||
sql_data_base: Mutex::new(connection),
|
||||
sql_data_base: connection,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reset(
|
||||
&self,
|
||||
&mut self,
|
||||
ctx: &mut serenity::client::Context,
|
||||
msg: &serenity::model::channel::Message,
|
||||
) -> Result<(), String> {
|
||||
{
|
||||
let playlist = self.playlist_mut()?;
|
||||
playlist.borrow_mut().clear();
|
||||
}
|
||||
|
||||
{
|
||||
let song = self.song_mut()?;
|
||||
*song.borrow_mut() = None;
|
||||
}
|
||||
|
||||
{
|
||||
let name = self.name_mut()?;
|
||||
*name.borrow_mut() = String::new();
|
||||
}
|
||||
|
||||
{
|
||||
*self.next_callback.borrow_mut() = None;
|
||||
}
|
||||
self.playlist().clear();
|
||||
self.song = None;
|
||||
self.name = String::new();
|
||||
self.next_callback = None();
|
||||
|
||||
if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
let mut manager = manager_lock.lock();
|
||||
|
@ -103,32 +88,32 @@ impl MediaData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn lock_db(&self) -> Result<MutexGuard<Connection>, String> {
|
||||
match self.sql_data_base.lock() {
|
||||
Ok(sql) => Ok(sql),
|
||||
Err(_) => Err("failed locking db".to_string()),
|
||||
}
|
||||
pub fn db(&self) -> &Connection {
|
||||
&self.sql_data_base
|
||||
}
|
||||
|
||||
pub fn song_mut(&self) -> Result<MutexGuard<RefCell<Option<LockedAudio>>>, String> {
|
||||
match self.current_song.lock() {
|
||||
Ok(sql) => Ok(sql),
|
||||
Err(_) => Err("failed locking current song".to_string()),
|
||||
}
|
||||
pub fn song(&self) -> &Option<LockedAudio> {
|
||||
&self.current_song
|
||||
}
|
||||
|
||||
pub fn playlist_mut(&self) -> Result<MutexGuard<RefCell<Vec<Song>>>, String> {
|
||||
match self.playlist.lock() {
|
||||
Ok(sql) => Ok(sql),
|
||||
Err(_) => Err("failed locking playlist".to_string()),
|
||||
}
|
||||
pub fn song_mut(&mut self) -> &mut Option<LockedAudio> {
|
||||
&mut self.current_song
|
||||
}
|
||||
|
||||
pub fn name_mut(&self) -> Result<MutexGuard<RefCell<String>>, String> {
|
||||
match self.song_name.lock() {
|
||||
Ok(sql) => Ok(sql),
|
||||
Err(_) => Err("failed locking current song name".to_string()),
|
||||
}
|
||||
pub fn playlist(&self) -> &Vec<Song> {
|
||||
&self.playlist
|
||||
}
|
||||
|
||||
pub fn playlist_mut(&mut self) -> &mut Vec<Song> {
|
||||
&mut self.playlist
|
||||
}
|
||||
|
||||
pub fn song_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn song_name_mut(&mut self) -> &mut String {
|
||||
&mut self.name
|
||||
}
|
||||
|
||||
pub fn start_playing(
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use parking_lot;
|
||||
|
||||
use parking_lot::MutexGuard;
|
||||
use serenity;
|
||||
use serenity::client::CACHE;
|
||||
use serenity::model::id::{ChannelId, GuildId};
|
||||
use serenity::voice::Handler;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
pub fn guild_id(channel_id: ChannelId) -> Option<GuildId> {
|
||||
/*
|
||||
match CACHE.read().guild_channel(channel_id) {
|
||||
Some(channel) => Some(channel.read().guild_id),
|
||||
None => {
|
||||
|
@ -15,14 +14,13 @@ pub fn guild_id(channel_id: ChannelId) -> Option<GuildId> {
|
|||
None
|
||||
}
|
||||
}
|
||||
*/
|
||||
None
|
||||
}
|
||||
|
||||
pub fn handler<'a>(
|
||||
guild_id: GuildId,
|
||||
manager: &'a mut parking_lot::MutexGuard<
|
||||
'_,
|
||||
serenity::client::bridge::voice::ClientVoiceManager,
|
||||
>,
|
||||
manager: &'a mut MutexGuard<'_, serenity::client::bridge::voice::ClientVoiceManager>,
|
||||
) -> Option<&'a mut Handler> {
|
||||
manager.get_mut(guild_id)
|
||||
}
|
||||
|
@ -32,7 +30,7 @@ pub fn channel_contains_author(
|
|||
msg: &serenity::model::channel::Message,
|
||||
) -> bool {
|
||||
let (guild_id, voice_channel_id_bot) = {
|
||||
match ctx.data.lock().get::<VoiceManager>().cloned() {
|
||||
match ctx.data.read().get::<VoiceManager>().cloned() {
|
||||
Some(manager_lock) => {
|
||||
let mut manager = manager_lock.lock();
|
||||
let guild_id = match guild_id(msg.channel_id) {
|
||||
|
@ -68,7 +66,7 @@ pub fn channel_contains_author(
|
|||
|
||||
let author = &msg.author;
|
||||
|
||||
let guild = match guild_id.to_guild_cached() {
|
||||
let guild = match guild_id.to_guild_cached(&ctx) {
|
||||
Some(guild) => guild,
|
||||
None => {
|
||||
println!("error getting guild from cache");
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
pub use super::mediadata::{MediaData, Song};
|
||||
|
||||
pub use super::commands::help::Help;
|
||||
pub use super::commands::ip::IP;
|
||||
pub use super::commands::list::List;
|
||||
pub use super::commands::pause::Pause;
|
||||
pub use super::commands::play::Play;
|
||||
pub use super::commands::remove::Remove;
|
||||
pub use super::commands::skip::Skip;
|
||||
pub use super::commands::stop::Stop;
|
||||
pub use super::commands::ip::*;
|
||||
pub use super::commands::list::*;
|
||||
pub use super::commands::pause::*;
|
||||
pub use super::commands::play::*;
|
||||
pub use super::commands::remove::*;
|
||||
pub use super::commands::skip::*;
|
||||
pub use super::commands::stop::*;
|
||||
|
||||
pub use super::eventhandler::Handler;
|
||||
pub use super::voicemanager::VoiceManager;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use parking_lot::Mutex;
|
||||
use serenity::client::bridge::voice::ClientVoiceManager;
|
||||
use serenity::prelude::Mutex;
|
||||
use std::sync::Arc;
|
||||
use typemap::Key;
|
||||
|
||||
|
|
Loading…
Reference in a new issue