Add database to handle local files
This commit is contained in:
parent
8bc59f1c40
commit
4aa7edf16a
5 changed files with 148 additions and 34 deletions
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
Loading…
Reference in a new issue