From cab60e1560be223379e3c65e0d8f7d9b41834bc2 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Mon, 11 Dec 2023 02:27:33 -0600 Subject: [PATCH 1/3] Made foobar reader compliant with new Trait --- src/music_storage/db_reader/foobar/reader.rs | 130 ++++++++++--------- src/music_storage/db_reader/foobar/utils.rs | 15 +++ 2 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 src/music_storage/db_reader/foobar/utils.rs diff --git a/src/music_storage/db_reader/foobar/reader.rs b/src/music_storage/db_reader/foobar/reader.rs index 017d7fc..23872b0 100644 --- a/src/music_storage/db_reader/foobar/reader.rs +++ b/src/music_storage/db_reader/foobar/reader.rs @@ -1,7 +1,10 @@ -use chrono::{DateTime, Utc}; +use std::collections::BTreeMap; use std::{fs::File, io::Read, path::PathBuf, time::Duration}; -use crate::music_storage::db_reader::common::{get_bytes, get_bytes_vec, get_datetime}; +use crate::music_storage::db_reader::common::{get_bytes, get_bytes_vec}; +use crate::music_storage::db_reader::extern_library::ExternalLibrary; +use crate::music_storage::library::{Song, URI}; +use super::utils::meta_offset; const MAGIC: [u8; 16] = [ 0xE1, 0xA0, 0x9C, 0x91, 0xF8, 0x3C, 0x77, 0x42, 0x85, 0x2C, 0x3B, 0xCC, 0x14, 0x01, 0xD3, 0xF2, @@ -9,69 +12,31 @@ const MAGIC: [u8; 16] = [ #[derive(Debug)] pub struct FoobarPlaylist { - path: PathBuf, metadata: Vec, + songs: Vec, } -#[derive(Debug, Default)] -pub struct FoobarPlaylistTrack { - flags: i32, - file_name: String, - subsong_index: i32, - file_size: i64, - file_time: DateTime, - duration: Duration, - rpg_album: u32, - rpg_track: u32, - rpk_album: u32, - rpk_track: u32, - entries: Vec<(String, String)>, -} - -impl FoobarPlaylist { - pub fn new(path: &String) -> Self { - FoobarPlaylist { - path: PathBuf::from(path), - metadata: Vec::new(), - } - } - - fn get_meta_offset(&self, offset: usize) -> String { - let mut result_vec = Vec::new(); - - let mut i = offset; - loop { - if self.metadata[i] == 0x00 { - break; - } - - result_vec.push(self.metadata[i]); - i += 1; - } - - String::from_utf8_lossy(&result_vec).into() - } - +impl ExternalLibrary for FoobarPlaylist { /// Reads the entire MusicBee library and returns relevant values /// as a `Vec` of `Song`s - pub fn read(&mut self) -> Result, Box> { - let mut f = File::open(&self.path).unwrap(); + fn from_file(file: &PathBuf) -> Self { + let mut f = File::open(file).unwrap(); let mut buffer = Vec::new(); let mut retrieved_songs: Vec = Vec::new(); // Read the whole file - f.read_to_end(&mut buffer)?; + f.read_to_end(&mut buffer).unwrap(); let mut buf_iter = buffer.into_iter(); // Parse the header let magic = get_bytes::<16>(&mut buf_iter); if magic != MAGIC { - return Err("Magic bytes mismatch!".into()); + panic!("Magic bytes mismatch!"); } let meta_size = i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize; - self.metadata = get_bytes_vec(&mut buf_iter, meta_size); + let metadata = get_bytes_vec(&mut buf_iter, meta_size); let track_count = i32::from_le_bytes(get_bytes(&mut buf_iter)); // Read all the track fields @@ -82,7 +47,7 @@ impl FoobarPlaylist { let has_padding = (0x04 & flags) != 0; let file_name_offset = i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize; - let file_name = self.get_meta_offset(file_name_offset); + let file_name = meta_offset(metadata, file_name_offset); let subsong_index = i32::from_le_bytes(get_bytes(&mut buf_iter)); @@ -98,17 +63,18 @@ impl FoobarPlaylist { let file_size = i64::from_le_bytes(get_bytes(&mut buf_iter)); - let file_time = get_datetime(&mut buf_iter, false); + // TODO: Figure out how to make this work properly + let file_time = i64::from_le_bytes(get_bytes(&mut buf_iter)); let duration = Duration::from_nanos(u64::from_le_bytes(get_bytes(&mut buf_iter)) / 100); - let rpg_album = u32::from_le_bytes(get_bytes(&mut buf_iter)); + let rpg_album = f32::from_le_bytes(get_bytes(&mut buf_iter)); - let rpg_track = u32::from_le_bytes(get_bytes(&mut buf_iter)); + let rpg_track = f32::from_le_bytes(get_bytes(&mut buf_iter)); - let rpk_album = u32::from_le_bytes(get_bytes(&mut buf_iter)); + let rpk_album = f32::from_le_bytes(get_bytes(&mut buf_iter)); - let rpk_track = u32::from_le_bytes(get_bytes(&mut buf_iter)); + let rpk_track = f32::from_le_bytes(get_bytes(&mut buf_iter)); get_bytes::<4>(&mut buf_iter); @@ -121,8 +87,7 @@ impl FoobarPlaylist { for _ in 0..primary_count { println!("{}", i32::from_le_bytes(get_bytes(&mut buf_iter))); - let key = - self.get_meta_offset(i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); + let key = meta_offset(metadata, i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); entries.push((key, String::new())); } @@ -135,18 +100,15 @@ impl FoobarPlaylist { for i in 0..primary_count { println!("primkey {i}"); - let value = - self.get_meta_offset(i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); + let value = meta_offset(metadata, i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); entries[i as usize].1 = value; } // Get secondary Keys for _ in 0..secondary_count { - let key = - self.get_meta_offset(i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); - let value = - self.get_meta_offset(i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); + let key = meta_offset(metadata, i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); + let value = meta_offset(metadata, i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize); entries.push((key, value)); } @@ -171,6 +133,50 @@ impl FoobarPlaylist { retrieved_songs.push(track); } - Ok(retrieved_songs) + Self { + songs: retrieved_songs, + metadata, + } + } + + fn to_songs(&self) -> Vec { + self.songs.iter().map(|song| song.find_song()).collect() + } +} + +#[derive(Debug, Default)] +pub struct FoobarPlaylistTrack { + flags: i32, + file_name: String, + subsong_index: i32, + file_size: i64, + file_time: i64, + duration: Duration, + rpg_album: f32, + rpg_track: f32, + rpk_album: f32, + rpk_track: f32, + entries: Vec<(String, String)>, +} + +impl FoobarPlaylistTrack { + fn find_song(&self) -> Song { + let location = URI::Local(self.file_name.into()); + + Song { + location, + plays: 0, + skips: 0, + favorited: false, + rating: None, + format: None, + duration: self.duration, + play_time: Duration::from_secs(0), + last_played: None, + date_added: None, + date_modified: None, + album_art: Vec::new(), + tags: BTreeMap::new(), + } } } diff --git a/src/music_storage/db_reader/foobar/utils.rs b/src/music_storage/db_reader/foobar/utils.rs new file mode 100644 index 0000000..62ee270 --- /dev/null +++ b/src/music_storage/db_reader/foobar/utils.rs @@ -0,0 +1,15 @@ +pub fn meta_offset(metadata: Vec, offset: usize) -> String { + let mut result_vec = Vec::new(); + + let mut i = offset; + loop { + if metadata[i] == 0x00 { + break; + } + + result_vec.push(metadata[i]); + i += 1; + } + + String::from_utf8_lossy(&result_vec).into() +} From 5000d24a77b841b764d599e1c5d8fdb1175039f3 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Mon, 11 Dec 2023 02:30:03 -0600 Subject: [PATCH 2/3] Fixed errors in foobar reader --- src/lib.rs | 1 + src/music_storage/db_reader/foobar/reader.rs | 6 +++--- src/music_storage/db_reader/foobar/utils.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9981527..c20df16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod music_storage { pub mod db_reader { pub mod foobar { pub mod reader; + pub mod utils; } pub mod musicbee { pub mod reader; diff --git a/src/music_storage/db_reader/foobar/reader.rs b/src/music_storage/db_reader/foobar/reader.rs index 23872b0..165c08b 100644 --- a/src/music_storage/db_reader/foobar/reader.rs +++ b/src/music_storage/db_reader/foobar/reader.rs @@ -36,7 +36,7 @@ impl ExternalLibrary for FoobarPlaylist { } let meta_size = i32::from_le_bytes(get_bytes(&mut buf_iter)) as usize; - let metadata = get_bytes_vec(&mut buf_iter, meta_size); + let metadata = &get_bytes_vec(&mut buf_iter, meta_size); let track_count = i32::from_le_bytes(get_bytes(&mut buf_iter)); // Read all the track fields @@ -135,7 +135,7 @@ impl ExternalLibrary for FoobarPlaylist { Self { songs: retrieved_songs, - metadata, + metadata: metadata.clone(), } } @@ -161,7 +161,7 @@ pub struct FoobarPlaylistTrack { impl FoobarPlaylistTrack { fn find_song(&self) -> Song { - let location = URI::Local(self.file_name.into()); + let location = URI::Local(self.file_name.clone().into()); Song { location, diff --git a/src/music_storage/db_reader/foobar/utils.rs b/src/music_storage/db_reader/foobar/utils.rs index 62ee270..4b02f02 100644 --- a/src/music_storage/db_reader/foobar/utils.rs +++ b/src/music_storage/db_reader/foobar/utils.rs @@ -1,4 +1,4 @@ -pub fn meta_offset(metadata: Vec, offset: usize) -> String { +pub fn meta_offset(metadata: &Vec, offset: usize) -> String { let mut result_vec = Vec::new(); let mut i = offset; From 045cea90bf83da4bc96896790f5c2fb8aae94cbb Mon Sep 17 00:00:00 2001 From: G2-Games Date: Mon, 11 Dec 2023 02:42:13 -0600 Subject: [PATCH 3/3] Applied clippy suggestions --- src/music_player.rs | 18 ++++++++---------- src/music_storage/db_reader/common.rs | 12 +++++------- src/music_storage/db_reader/extern_library.rs | 4 ++-- src/music_storage/db_reader/foobar/reader.rs | 4 ++-- src/music_storage/db_reader/foobar/utils.rs | 2 +- src/music_storage/db_reader/musicbee/reader.rs | 2 +- src/music_storage/db_reader/xml/reader.rs | 2 +- 7 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/music_player.rs b/src/music_player.rs index 4c0ee19..aed3eaf 100644 --- a/src/music_player.rs +++ b/src/music_player.rs @@ -179,7 +179,7 @@ impl Player { match msg.view() { gst::MessageView::Eos(_) => {} gst::MessageView::StreamStart(_) => println!("Stream start"), - gst::MessageView::Error(e) => { + gst::MessageView::Error(_) => { playbin_bus_ctrl .write() .unwrap() @@ -201,7 +201,7 @@ impl Player { .unwrap() .set_state(gst::State::Paused) .unwrap(); - } else if *paused_bus_ctrl.read().unwrap() == false { + } else if !(*paused_bus_ctrl.read().unwrap()) { *buffer_bus_ctrl.write().unwrap() = None; playbin_bus_ctrl .write() @@ -377,19 +377,17 @@ impl Player { /// Seek absolutely pub fn seek_to(&mut self, target_pos: Duration) -> Result<(), Box> { - let start; - if self.start.read().unwrap().is_none() { + let start = if self.start.read().unwrap().is_none() { return Err("Failed to seek: No START time".into()); } else { - start = self.start.read().unwrap().unwrap(); - } + self.start.read().unwrap().unwrap() + }; - let end; - if self.end.read().unwrap().is_none() { + let end = if self.end.read().unwrap().is_none() { return Err("Failed to seek: No END time".into()); } else { - end = self.end.read().unwrap().unwrap(); - } + self.end.read().unwrap().unwrap() + }; let adjusted_target = target_pos + start; let clamped_target = adjusted_target.clamp(start, end); diff --git a/src/music_storage/db_reader/common.rs b/src/music_storage/db_reader/common.rs index 0849081..368d86e 100644 --- a/src/music_storage/db_reader/common.rs +++ b/src/music_storage/db_reader/common.rs @@ -1,15 +1,13 @@ -use std::path::PathBuf; - use chrono::{DateTime, TimeZone, Utc}; pub fn get_bytes(iterator: &mut std::vec::IntoIter) -> [u8; S] { let mut bytes = [0; S]; - for i in 0..S { - bytes[i] = iterator.next().unwrap(); + for byte in bytes.iter_mut().take(S) { + *byte = iterator.next().unwrap(); } - return bytes; + bytes } pub fn get_bytes_vec(iterator: &mut std::vec::IntoIter, number: usize) -> Vec { @@ -19,7 +17,7 @@ pub fn get_bytes_vec(iterator: &mut std::vec::IntoIter, number: usize) -> Ve bytes.push(iterator.next().unwrap()); } - return bytes; + bytes } /// Converts the windows DateTime into Chrono DateTime @@ -28,7 +26,7 @@ pub fn get_datetime(iterator: &mut std::vec::IntoIter, topbyte: bool) -> Dat if topbyte { // Zero the topmost byte - datetime_i64 = datetime_i64 & 0x00FFFFFFFFFFFFFFF; + datetime_i64 &= 0x00FFFFFFFFFFFFFFF; } if datetime_i64 <= 0 { diff --git a/src/music_storage/db_reader/extern_library.rs b/src/music_storage/db_reader/extern_library.rs index dc5c306..4312c4a 100644 --- a/src/music_storage/db_reader/extern_library.rs +++ b/src/music_storage/db_reader/extern_library.rs @@ -1,9 +1,9 @@ -use std::path::PathBuf; +use std::path::Path; use crate::music_storage::library::Song; pub trait ExternalLibrary { - fn from_file(file: &PathBuf) -> Self; + fn from_file(file: &Path) -> Self; fn write(&self) { unimplemented!(); } diff --git a/src/music_storage/db_reader/foobar/reader.rs b/src/music_storage/db_reader/foobar/reader.rs index 165c08b..218d6c0 100644 --- a/src/music_storage/db_reader/foobar/reader.rs +++ b/src/music_storage/db_reader/foobar/reader.rs @@ -1,5 +1,5 @@ use std::collections::BTreeMap; -use std::{fs::File, io::Read, path::PathBuf, time::Duration}; +use std::{fs::File, io::Read, path::Path, time::Duration}; use crate::music_storage::db_reader::common::{get_bytes, get_bytes_vec}; use crate::music_storage::db_reader::extern_library::ExternalLibrary; @@ -19,7 +19,7 @@ pub struct FoobarPlaylist { impl ExternalLibrary for FoobarPlaylist { /// Reads the entire MusicBee library and returns relevant values /// as a `Vec` of `Song`s - fn from_file(file: &PathBuf) -> Self { + fn from_file(file: &Path) -> Self { let mut f = File::open(file).unwrap(); let mut buffer = Vec::new(); let mut retrieved_songs: Vec = Vec::new(); diff --git a/src/music_storage/db_reader/foobar/utils.rs b/src/music_storage/db_reader/foobar/utils.rs index 4b02f02..278aa1a 100644 --- a/src/music_storage/db_reader/foobar/utils.rs +++ b/src/music_storage/db_reader/foobar/utils.rs @@ -1,4 +1,4 @@ -pub fn meta_offset(metadata: &Vec, offset: usize) -> String { +pub fn meta_offset(metadata: &[u8], offset: usize) -> String { let mut result_vec = Vec::new(); let mut i = offset; diff --git a/src/music_storage/db_reader/musicbee/reader.rs b/src/music_storage/db_reader/musicbee/reader.rs index 0a5cac6..9811862 100644 --- a/src/music_storage/db_reader/musicbee/reader.rs +++ b/src/music_storage/db_reader/musicbee/reader.rs @@ -29,7 +29,7 @@ impl MusicBeeDatabase { // Get the song count from the first 4 bytes // and then right shift it by 8 for some reason let mut database_song_count = i32::from_le_bytes(get_bytes(&mut buf_iter)); - database_song_count = database_song_count >> 8; + database_song_count >>= 8; let mut song_count = 0; loop { diff --git a/src/music_storage/db_reader/xml/reader.rs b/src/music_storage/db_reader/xml/reader.rs index bc651c5..fe6bc64 100644 --- a/src/music_storage/db_reader/xml/reader.rs +++ b/src/music_storage/db_reader/xml/reader.rs @@ -28,7 +28,7 @@ impl XmlLibrary { } } impl ExternalLibrary for XmlLibrary { - fn from_file(file: &PathBuf) -> Self { + fn from_file(file: &Path) -> Self { let mut reader = Reader::from_file(file).unwrap(); reader.trim_text(true); //count every event, for fun ig?