Add database to handle local files

This commit is contained in:
MrRaute 2019-04-03 11:42:06 +02:00
parent 8bc59f1c40
commit 4aa7edf16a
5 changed files with 148 additions and 34 deletions

View file

@ -1,5 +1,6 @@
[package] [package]
name = "RMusicBot" name = "RMusicBot"
edition = "2018"
version = "0.1.0" version = "0.1.0"
authors = ["hodasemi <michaelh.95@t-online.de>"] authors = ["hodasemi <michaelh.95@t-online.de>"]
@ -7,6 +8,7 @@ authors = ["hodasemi <michaelh.95@t-online.de>"]
typemap = "~0.3" typemap = "~0.3"
serde_json = "*" serde_json = "*"
rand = "0.6" rand = "0.6"
rusqlite = { version = "*", features = ["bundled"] }
[dependencies.serenity] [dependencies.serenity]
default-features = false default-features = false

View file

@ -75,7 +75,8 @@ fn main() {
data.insert::<VoiceManager>(Arc::clone(&client.voice_manager)); data.insert::<VoiceManager>(Arc::clone(&client.voice_manager));
} }
let media_data = Arc::new(MediaData::default()); let media_data =
Arc::new(MediaData::new("Penis1").expect("failed to create media data handle"));
client.with_framework( client.with_framework(
StandardFramework::new() StandardFramework::new()
@ -97,7 +98,8 @@ fn main() {
"ip".to_string(), "ip".to_string(),
], ],
), ),
).cmd("stop", Stop::new(media_data.clone())) )
.cmd("stop", Stop::new(media_data.clone()))
.cmd("list", List::new(media_data.clone())) .cmd("list", List::new(media_data.clone()))
.cmd("skip", Skip::new(media_data.clone())) .cmd("skip", Skip::new(media_data.clone()))
.cmd("ip", IP::new()) .cmd("ip", IP::new())

View file

@ -12,6 +12,9 @@ use rand::{seq::SliceRandom, thread_rng};
use super::super::prelude::*; use super::super::prelude::*;
use rusqlite::params;
use rusqlite::types::{FromSql, ToSql};
pub struct Play { pub struct Play {
media: Arc<MediaData>, media: Arc<MediaData>,
} }
@ -113,15 +116,41 @@ impl Play {
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
url: &String, url: &String,
) { ) {
let sql = self.media.lock_db();
let mut stmt = sql
.prepare("SELECT name FROM Vulva3 WHERE link = ?")
.unwrap();
let rows = stmt
.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>)
.expect("failed requesting db");
let mut names = Vec::new();
for name_result in rows {
names.push(name_result.unwrap());
}
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(),
);
return;
}
let source = match youtube_dl(&url) { let source = match youtube_dl(&url) {
Ok(source) => source, Ok(source) => source,
Err(why) => { Err(why) => {
println!("Err starting source: {:?}", why); println!("Err starting source: {:?}", why);
print_error!( print_error!(msg
msg.channel_id .channel_id
.say(format!("Error using youtube-dl: {}", why)) .say(format!("Error using youtube-dl: {}", why)));
);
return; return;
} }
@ -135,6 +164,13 @@ impl Play {
for song in &source { for song in &source {
info = format!("{}\n\t{}", info, song.name); 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");
} }
print_error!(msg.channel_id.say(info)); print_error!(msg.channel_id.say(info));
@ -147,21 +183,21 @@ impl Play {
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
) { ) {
print_error!(self.media.reset(ctx, msg)); //print_error!(self.media.reset(ctx, msg));
let files = fs::read_dir("./").unwrap(); let sql = self.media.lock_db();
let mut stmt = sql.prepare("SELECT name FROM Vulva3").unwrap();
let rows = stmt
.query_map(params![], |row| row.get(0) as rusqlite::Result<String>)
.expect("failed requesting db");
let mut songs = Vec::new(); let mut songs = Vec::new();
for name_result in rows {
for file in files { songs.push(Song {
let os_name = file.unwrap().file_name(); name: name_result.unwrap(),
let name = os_name.to_str().unwrap(); });
if name != "RMusicBot" && name != "bot.conf" && name != "start.sh" {
songs.push(Song {
name: name.to_string(),
});
}
} }
let mut rng = thread_rng(); let mut rng = thread_rng();
@ -169,6 +205,44 @@ impl Play {
self.append_songs(ctx, msg, songs); self.append_songs(ctx, msg, songs);
} }
fn handle_song_request(
&self,
ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message,
pattern: &str,
) {
let sql = self.media.lock_db();
let mut stmt = sql
.prepare(&format!(
"SELECT name FROM Vulva3 WHERE name LIKE '%{}%'",
pattern
))
.unwrap();
let rows = stmt
.query_map(params![], |row| row.get(0) as rusqlite::Result<String>)
.expect("failed requesting db");
let mut songs = Vec::new();
for name_result in rows {
songs.push(Song {
name: name_result.unwrap(),
});
}
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)));
}
}
} }
impl serenity::framework::standard::Command for Play { impl serenity::framework::standard::Command for Play {
@ -203,7 +277,7 @@ impl serenity::framework::standard::Command for Play {
} else if arg.starts_with("http") { } else if arg.starts_with("http") {
self.handle_http_request(ctx, msg, &arg); self.handle_http_request(ctx, msg, &arg);
} else { } else {
print_error!(msg.channel_id.say("Unsupported argument list")); self.handle_song_request(ctx, msg, &arg);
} }
} else { } else {
print_error!(msg.channel_id.say("Unsupported argument list")); print_error!(msg.channel_id.say("Unsupported argument list"));

View file

@ -5,6 +5,8 @@ use std::sync::Arc;
use super::super::prelude::*; use super::super::prelude::*;
use rusqlite::params;
pub struct Remove { pub struct Remove {
media: Arc<MediaData>, media: Arc<MediaData>,
} }
@ -23,15 +25,21 @@ impl serenity::framework::standard::Command for Remove {
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
mut _args: serenity::framework::standard::Args, mut _args: serenity::framework::standard::Args,
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { ) -> ::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 name: String = song_name.borrow().clone();
let sql = self.media.lock_db();
sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name])
.expect("failed deleting song");
if !name.is_empty() { if !name.is_empty() {
match fs::remove_file(&name) { match fs::remove_file(&name) {
Ok(_) => print_error!( Ok(_) => print_error!(msg
msg.channel_id .channel_id
.say(format!("Remove current song ({}) from local disk", name)) .say(format!("Remove current song ({}) from local disk", name))),
),
Err(err) => print_error!(msg.channel_id.say(format!( Err(err) => print_error!(msg.channel_id.say(format!(
"Error removing file ({}): {:?}", "Error removing file ({}): {:?}",
name, name,

View file

@ -8,6 +8,9 @@ use std::sync::{Arc, Mutex, MutexGuard};
use super::prelude::*; use super::prelude::*;
use rusqlite::types::ToSql;
use rusqlite::{params, Connection};
pub struct Song { pub struct Song {
pub name: String, pub name: String,
} }
@ -17,9 +20,41 @@ pub struct MediaData {
current_song: Mutex<RefCell<Option<LockedAudio>>>, current_song: Mutex<RefCell<Option<LockedAudio>>>,
song_name: Mutex<RefCell<String>>, song_name: Mutex<RefCell<String>>,
pub next_callback: RefCell<Option<Arc<Fn() -> ()>>>, pub next_callback: RefCell<Option<Arc<Fn() -> ()>>>,
sql_data_base: Mutex<Connection>,
} }
impl MediaData { impl MediaData {
pub fn new(file: &str) -> Result<MediaData, String> {
let connection = match Connection::open(file) {
Ok(file) => file,
Err(_) => return Err(format!("can't open {}", file)),
};
match connection.execute(
"CREATE TABLE IF NOT EXISTS Vulva3 (
name TEXT PRIMARY KEY,
link TEXT NOT NULL
)",
params![],
) {
Ok(_) => (),
Err(err) => {
println!("{}", err);
return Err(format!("can't create table"));
}
};
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),
sql_data_base: Mutex::new(connection),
})
}
pub fn reset( pub fn reset(
&self, &self,
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
@ -70,6 +105,10 @@ impl MediaData {
Ok(()) Ok(())
} }
pub fn lock_db(&self) -> MutexGuard<Connection> {
self.sql_data_base.lock().unwrap()
}
pub fn song_mut(&self) -> MutexGuard<RefCell<Option<LockedAudio>>> { pub fn song_mut(&self) -> MutexGuard<RefCell<Option<LockedAudio>>> {
self.current_song.lock().unwrap() self.current_song.lock().unwrap()
} }
@ -177,16 +216,5 @@ impl MediaData {
} }
} }
impl Default for MediaData {
fn default() -> MediaData {
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),
}
}
}
unsafe impl Send for MediaData {} unsafe impl Send for MediaData {}
unsafe impl Sync for MediaData {} unsafe impl Sync for MediaData {}