mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-04-19 10:02:53 -05:00
made prepatory changes to the library
This commit is contained in:
parent
3c93110037
commit
c6b561c7af
5 changed files with 75 additions and 27 deletions
|
@ -4,7 +4,7 @@ use std::{
|
||||||
io::{Error, Write, Read}, sync::{Arc, RwLock},
|
io::{Error, Write, Read}, sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::to_string_pretty;
|
use serde_json::to_string_pretty;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -126,6 +126,23 @@ impl Config {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_backup(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
match &self.backup_folder {
|
||||||
|
Some(path) => {
|
||||||
|
let mut writer = path.clone();
|
||||||
|
writer.set_extension("tmp");
|
||||||
|
let mut file = OpenOptions::new().create(true).truncate(true).read(true).write(true).open(&writer)?;
|
||||||
|
let config = to_string_pretty(self)?;
|
||||||
|
// dbg!(&config);
|
||||||
|
|
||||||
|
file.write_all(config.as_bytes())?;
|
||||||
|
fs::rename(writer, self.path.as_path())?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
None => Err(ConfigError::NoBackupLibrary.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_file(path: PathBuf) -> Result<Self, Error> {
|
pub fn read_file(path: PathBuf) -> Result<Self, Error> {
|
||||||
let mut file: File = File::open(path)?;
|
let mut file: File = File::open(path)?;
|
||||||
let mut bun: String = String::new();
|
let mut bun: String = String::new();
|
||||||
|
@ -144,6 +161,8 @@ pub enum ConfigError {
|
||||||
//TODO: do something about playlists
|
//TODO: do something about playlists
|
||||||
#[error("Please provide a better m3u8 Playlist")]
|
#[error("Please provide a better m3u8 Playlist")]
|
||||||
BadPlaylist,
|
BadPlaylist,
|
||||||
|
#[error("No backup Config folder present")]
|
||||||
|
NoBackupLibrary,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,16 +185,16 @@ fn config_test() {
|
||||||
};
|
};
|
||||||
config.write_file();
|
config.write_file();
|
||||||
let arc = Arc::new(RwLock::from(config));
|
let arc = Arc::new(RwLock::from(config));
|
||||||
MusicLibrary::init(arc.clone(), lib_a.uuid.clone()).unwrap();
|
MusicLibrary::init(arc.clone(), lib_a.uuid).unwrap();
|
||||||
MusicLibrary::init(arc.clone(), lib_b.uuid.clone()).unwrap();
|
MusicLibrary::init(arc.clone(), lib_b.uuid).unwrap();
|
||||||
MusicLibrary::init(arc.clone(), lib_c.uuid.clone()).unwrap();
|
MusicLibrary::init(arc.clone(), lib_c.uuid).unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test2() {
|
fn test2() {
|
||||||
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
||||||
let uuid = config.libraries.get_default().unwrap().uuid.clone();
|
let uuid = config.libraries.get_default().unwrap().uuid;
|
||||||
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), uuid).unwrap();
|
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), uuid).unwrap();
|
||||||
lib.scan_folder("test-config/music/").unwrap();
|
lib.scan_folder("test-config/music/").unwrap();
|
||||||
lib.save(config.clone()).unwrap();
|
lib.save(config.clone()).unwrap();
|
||||||
|
@ -187,7 +206,7 @@ fn test2() {
|
||||||
fn test3() {
|
fn test3() {
|
||||||
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
let config = Config::read_file(PathBuf::from("test-config/config_test.json")).unwrap();
|
||||||
let uuid = config.libraries.get_default().unwrap().uuid;
|
let uuid = config.libraries.get_default().unwrap().uuid;
|
||||||
let mut lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), uuid).unwrap();
|
let lib = MusicLibrary::init(Arc::new(RwLock::from(config.clone())), uuid).unwrap();
|
||||||
|
|
||||||
dbg!(lib);
|
dbg!(lib);
|
||||||
}
|
}
|
|
@ -52,12 +52,12 @@ pub struct Controller {
|
||||||
// queues: Vec<Queue>,
|
// queues: Vec<Queue>,
|
||||||
config: Arc<RwLock<Config>>,
|
config: Arc<RwLock<Config>>,
|
||||||
// library: MusicLibrary,
|
// library: MusicLibrary,
|
||||||
controller_mail: MailMan<ControllerCommand, ControllerResponse>,
|
controller_mail: MailMan<ControllerCmd, ControllerResponse>,
|
||||||
db_mail: MailMan<DatabaseCommand, DatabaseResponse>,
|
db_mail: MailMan<DatabaseCmd, DatabaseResponse>,
|
||||||
queue_mail: Vec<MailMan<QueueCommand, QueueResponse>>,
|
queue_mail: Vec<MailMan<QueueCmd, QueueResponse>>,
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ControllerCommand {
|
pub enum ControllerCmd {
|
||||||
Default,
|
Default,
|
||||||
Test
|
Test
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,12 @@ pub enum ControllerCommand {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ControllerResponse {
|
enum ControllerResponse {
|
||||||
Empty,
|
Empty,
|
||||||
QueueMailMan(MailMan<QueueCommand, QueueResponse>),
|
QueueMailMan(MailMan<QueueCmd, QueueResponse>),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DatabaseCommand {
|
pub enum DatabaseCmd {
|
||||||
Default,
|
Default,
|
||||||
Test,
|
Test,
|
||||||
GetSongs,
|
GetSongs,
|
||||||
|
@ -88,7 +88,7 @@ enum DatabaseResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum QueueCommand {
|
enum QueueCmd {
|
||||||
Default,
|
Default,
|
||||||
Test,
|
Test,
|
||||||
Play,
|
Play,
|
||||||
|
@ -128,7 +128,7 @@ impl<T, U> MailMan<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, mail: T) -> Result<(), Box<dyn Error>> {
|
pub fn send(&self, mail: T) -> Result<(), Box<dyn Error>> {
|
||||||
&self.tx.send(mail).unwrap();
|
self.tx.send(mail).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ impl Controller {
|
||||||
|
|
||||||
let (out_thread_controller, in_thread) = MailMan::double();
|
let (out_thread_controller, in_thread) = MailMan::double();
|
||||||
let monitor_thread = spawn(move || {
|
let monitor_thread = spawn(move || {
|
||||||
use ControllerCommand::*;
|
use ControllerCmd::*;
|
||||||
loop {
|
loop {
|
||||||
let command = in_thread.recv().unwrap();
|
let command = in_thread.recv().unwrap();
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ impl Controller {
|
||||||
|
|
||||||
let (out_thread_db, in_thread) = MailMan::double();
|
let (out_thread_db, in_thread) = MailMan::double();
|
||||||
let db_monitor = spawn(move || {
|
let db_monitor = spawn(move || {
|
||||||
use DatabaseCommand::*;
|
use DatabaseCmd::*;
|
||||||
loop {
|
loop {
|
||||||
let command = in_thread.recv().unwrap();
|
let command = in_thread.recv().unwrap();
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_db_songs(&self) -> Vec<Song> {
|
fn get_db_songs(&self) -> Vec<Song> {
|
||||||
self.db_mail.send(DatabaseCommand::GetSongs);
|
self.db_mail.send(DatabaseCmd::GetSongs);
|
||||||
match self.db_mail.recv().unwrap() {
|
match self.db_mail.recv().unwrap() {
|
||||||
DatabaseResponse::Songs(songs) => songs,
|
DatabaseResponse::Songs(songs) => songs,
|
||||||
_ => Vec::new()
|
_ => Vec::new()
|
||||||
|
@ -227,9 +227,9 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_queue(&mut self) {
|
pub fn new_queue(&mut self) {
|
||||||
let (out_thread_queue, in_thread) = MailMan::<QueueCommand, QueueResponse>::double();
|
let (out_thread_queue, in_thread) = MailMan::<QueueCmd, QueueResponse>::double();
|
||||||
let queues_monitor = spawn(move || {
|
let queues_monitor = spawn(move || {
|
||||||
use QueueCommand::*;
|
use QueueCmd::*;
|
||||||
let mut queue = Queue::new().unwrap();
|
let mut queue = Queue::new().unwrap();
|
||||||
loop {
|
loop {
|
||||||
let command = in_thread.recv().unwrap();
|
let command = in_thread.recv().unwrap();
|
||||||
|
@ -263,27 +263,27 @@ impl Controller {
|
||||||
|
|
||||||
fn play(&self, index: usize) -> Result<(), Box<dyn Error>> {
|
fn play(&self, index: usize) -> Result<(), Box<dyn Error>> {
|
||||||
let mail = &self.queue_mail[index];
|
let mail = &self.queue_mail[index];
|
||||||
mail.send(QueueCommand::Play)?;
|
mail.send(QueueCmd::Play)?;
|
||||||
dbg!(mail.recv()?);
|
dbg!(mail.recv()?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_songs(&self, index: usize, songs: Vec<Song>) -> Result<(), Box<dyn Error>> {
|
fn set_songs(&self, index: usize, songs: Vec<Song>) -> Result<(), Box<dyn Error>> {
|
||||||
let mail = &self.queue_mail[index];
|
let mail = &self.queue_mail[index];
|
||||||
mail.send(QueueCommand::SetSongs(songs))?;
|
mail.send(QueueCmd::SetSongs(songs))?;
|
||||||
dbg!(mail.recv()?);
|
dbg!(mail.recv()?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enqueue(&self, index: usize, uri: URI) -> Result<(), Box<dyn Error>> {
|
fn enqueue(&self, index: usize, uri: URI) -> Result<(), Box<dyn Error>> {
|
||||||
let mail = &self.queue_mail[index];
|
let mail = &self.queue_mail[index];
|
||||||
mail.send(QueueCommand::Enqueue(uri))?;
|
mail.send(QueueCmd::Enqueue(uri))?;
|
||||||
// dbg!(mail.recv()?);
|
// dbg!(mail.recv()?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn scan_folder(&self, folder: String) -> Result<(), Box<dyn Error>> {
|
fn scan_folder(&self, folder: String) -> Result<(), Box<dyn Error>> {
|
||||||
let mail = &self.db_mail;
|
let mail = &self.db_mail;
|
||||||
mail.send(DatabaseCommand::ReadFolder(folder))?;
|
mail.send(DatabaseCmd::ReadFolder(folder))?;
|
||||||
dbg!(mail.recv()?);
|
dbg!(mail.recv()?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ impl FoobarPlaylistTrack {
|
||||||
plays: 0,
|
plays: 0,
|
||||||
skips: 0,
|
skips: 0,
|
||||||
favorited: false,
|
favorited: false,
|
||||||
|
// banned: None,
|
||||||
rating: None,
|
rating: None,
|
||||||
format: None,
|
format: None,
|
||||||
duration: self.duration,
|
duration: self.duration,
|
||||||
|
|
|
@ -15,7 +15,7 @@ use chrono::prelude::*;
|
||||||
|
|
||||||
use crate::config::config::{Config, ConfigLibrary};
|
use crate::config::config::{Config, ConfigLibrary};
|
||||||
use crate::music_storage::db_reader::extern_library::ExternalLibrary;
|
use crate::music_storage::db_reader::extern_library::ExternalLibrary;
|
||||||
use crate::music_storage::library::{AlbumArt, MusicLibrary, Service, Song, Tag, URI};
|
use crate::music_storage::library::{AlbumArt, MusicLibrary, Service, Song, Tag, URI, BannedType};
|
||||||
use crate::music_storage::utils;
|
use crate::music_storage::utils;
|
||||||
|
|
||||||
use urlencoding::decode;
|
use urlencoding::decode;
|
||||||
|
@ -149,7 +149,7 @@ impl ExternalLibrary for ITunesLibrary {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sug: URI = if track.location.contains("file://localhost/") {
|
let location: URI = if track.location.contains("file://localhost/") {
|
||||||
URI::Local(PathBuf::from(
|
URI::Local(PathBuf::from(
|
||||||
decode(track.location.strip_prefix("file://localhost/").unwrap())
|
decode(track.location.strip_prefix("file://localhost/").unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -169,11 +169,16 @@ impl ExternalLibrary for ITunesLibrary {
|
||||||
let play_time_ = StdDur::from_secs(track.plays as u64 * dur.as_secs());
|
let play_time_ = StdDur::from_secs(track.plays as u64 * dur.as_secs());
|
||||||
|
|
||||||
let ny: Song = Song {
|
let ny: Song = Song {
|
||||||
location: sug,
|
location,
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
plays: track.plays,
|
plays: track.plays,
|
||||||
skips: 0,
|
skips: 0,
|
||||||
favorited: track.favorited,
|
favorited: track.favorited,
|
||||||
|
// banned: if track.banned {
|
||||||
|
// Some(BannedType::All)
|
||||||
|
// }else {
|
||||||
|
// None
|
||||||
|
// },
|
||||||
rating: track.rating,
|
rating: track.rating,
|
||||||
format: match FileFormat::from_file(PathBuf::from(&loc)) {
|
format: match FileFormat::from_file(PathBuf::from(&loc)) {
|
||||||
Ok(e) => Some(e),
|
Ok(e) => Some(e),
|
||||||
|
|
|
@ -115,6 +115,26 @@ impl ToString for Field {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub enum BannedType {
|
||||||
|
Shuffle,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub enum DoNotTrack {
|
||||||
|
// TODO: add services to not track
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
|
enum SongType {
|
||||||
|
// TODO: add song types
|
||||||
|
Main,
|
||||||
|
Instrumental,
|
||||||
|
Remix,
|
||||||
|
Custom(String)
|
||||||
|
}
|
||||||
|
|
||||||
/// Stores information about a single song
|
/// Stores information about a single song
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
|
@ -123,6 +143,7 @@ pub struct Song {
|
||||||
pub plays: i32,
|
pub plays: i32,
|
||||||
pub skips: i32,
|
pub skips: i32,
|
||||||
pub favorited: bool,
|
pub favorited: bool,
|
||||||
|
// pub banned: Option<BannedType>,
|
||||||
pub rating: Option<u8>,
|
pub rating: Option<u8>,
|
||||||
pub format: Option<FileFormat>,
|
pub format: Option<FileFormat>,
|
||||||
pub duration: Duration,
|
pub duration: Duration,
|
||||||
|
@ -261,6 +282,7 @@ impl Song {
|
||||||
plays: 0,
|
plays: 0,
|
||||||
skips: 0,
|
skips: 0,
|
||||||
favorited: false,
|
favorited: false,
|
||||||
|
// banned: None,
|
||||||
rating: None,
|
rating: None,
|
||||||
format,
|
format,
|
||||||
duration,
|
duration,
|
||||||
|
@ -384,6 +406,7 @@ impl Song {
|
||||||
plays: 0,
|
plays: 0,
|
||||||
skips: 0,
|
skips: 0,
|
||||||
favorited: false,
|
favorited: false,
|
||||||
|
// banned: None,
|
||||||
rating: None,
|
rating: None,
|
||||||
format,
|
format,
|
||||||
duration,
|
duration,
|
||||||
|
@ -397,7 +420,7 @@ impl Song {
|
||||||
tracks.push((new_song, audio_location.clone()));
|
tracks.push((new_song, audio_location.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((tracks))
|
Ok(tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue