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

View file

@ -75,7 +75,8 @@ fn main() {
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(
StandardFramework::new()
@ -97,7 +98,8 @@ fn main() {
"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("skip", Skip::new(media_data.clone()))
.cmd("ip", IP::new())

View file

@ -12,6 +12,9 @@ use rand::{seq::SliceRandom, thread_rng};
use super::super::prelude::*;
use rusqlite::params;
use rusqlite::types::{FromSql, ToSql};
pub struct Play {
media: Arc<MediaData>,
}
@ -113,15 +116,41 @@ impl Play {
msg: &serenity::model::channel::Message,
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) {
Ok(source) => source,
Err(why) => {
println!("Err starting source: {:?}", why);
print_error!(
msg.channel_id
.say(format!("Error using youtube-dl: {}", why))
);
print_error!(msg
.channel_id
.say(format!("Error using youtube-dl: {}", why)));
return;
}
@ -135,6 +164,13 @@ 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");
}
print_error!(msg.channel_id.say(info));
@ -147,21 +183,21 @@ impl Play {
ctx: &mut serenity::client::Context,
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();
for file in files {
let os_name = file.unwrap().file_name();
let name = os_name.to_str().unwrap();
if name != "RMusicBot" && name != "bot.conf" && name != "start.sh" {
songs.push(Song {
name: name.to_string(),
});
}
for name_result in rows {
songs.push(Song {
name: name_result.unwrap(),
});
}
let mut rng = thread_rng();
@ -169,6 +205,44 @@ impl Play {
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 {
@ -203,7 +277,7 @@ impl serenity::framework::standard::Command for Play {
} else if arg.starts_with("http") {
self.handle_http_request(ctx, msg, &arg);
} else {
print_error!(msg.channel_id.say("Unsupported argument list"));
self.handle_song_request(ctx, msg, &arg);
}
} else {
print_error!(msg.channel_id.say("Unsupported argument list"));

View file

@ -5,6 +5,8 @@ use std::sync::Arc;
use super::super::prelude::*;
use rusqlite::params;
pub struct Remove {
media: Arc<MediaData>,
}
@ -23,15 +25,21 @@ impl serenity::framework::standard::Command for Remove {
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();
sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name])
.expect("failed deleting song");
if !name.is_empty() {
match fs::remove_file(&name) {
Ok(_) => print_error!(
msg.channel_id
.say(format!("Remove current song ({}) from local disk", 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,

View file

@ -8,6 +8,9 @@ use std::sync::{Arc, Mutex, MutexGuard};
use super::prelude::*;
use rusqlite::types::ToSql;
use rusqlite::{params, Connection};
pub struct Song {
pub name: String,
}
@ -17,9 +20,41 @@ pub struct MediaData {
current_song: Mutex<RefCell<Option<LockedAudio>>>,
song_name: Mutex<RefCell<String>>,
pub next_callback: RefCell<Option<Arc<Fn() -> ()>>>,
sql_data_base: Mutex<Connection>,
}
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(
&self,
ctx: &mut serenity::client::Context,
@ -70,6 +105,10 @@ impl MediaData {
Ok(())
}
pub fn lock_db(&self) -> MutexGuard<Connection> {
self.sql_data_base.lock().unwrap()
}
pub fn song_mut(&self) -> MutexGuard<RefCell<Option<LockedAudio>>> {
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 Sync for MediaData {}