fixed a function and removed Album Art function

This commit is contained in:
MrDulfin 2024-05-19 22:29:30 -04:00
parent b04a166c1b
commit 9457c5c996
2 changed files with 33 additions and 96 deletions

View file

@ -107,7 +107,8 @@ impl Controller {
}) })
} }
pub fn q_add(&self, item: Uuid, source: super::queue::PlayerLocation, by_human: bool) { pub fn q_add(&mut self, item: &Uuid, source: super::queue::PlayerLocation, by_human: bool) {
let item = self.library.query_uuid(item).unwrap().0.to_owned();
self.queue.add_item(item, source, by_human) self.queue.add_item(item, source, by_human)
} }
} }

View file

@ -9,16 +9,15 @@ use std::error::Error;
use std::io::Write; use std::io::Write;
use std::ops::ControlFlow::{Break, Continue}; use std::ops::ControlFlow::{Break, Continue};
// Files // Files
use file_format::{FileFormat, Kind}; use file_format::{FileFormat, Kind};
use glib::filename_to_uri; use glib::filename_to_uri;
use lofty::{AudioFile, ItemKey, ItemValue, ParseOptions, Probe, TagType, TaggedFileExt}; use lofty::{AudioFile, ItemKey, ItemValue, ParseOptions, Probe, TagType, TaggedFileExt};
use rcue::parser::parse_from_file; use rcue::parser::parse_from_file;
use uuid::Uuid;
use std::fs::{self, File}; use std::fs::{self, File};
use tempfile::TempDir;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tempfile::TempDir;
use uuid::Uuid;
use walkdir::WalkDir; use walkdir::WalkDir;
// Time // Time
@ -152,7 +151,7 @@ pub enum SongType {
Main, Main,
Instrumental, Instrumental,
Remix, Remix,
Custom(String) Custom(String),
} }
impl Default for SongType { impl Default for SongType {
@ -182,10 +181,9 @@ pub struct Song {
pub date_modified: Option<DateTime<Utc>>, pub date_modified: Option<DateTime<Utc>>,
pub album_art: Vec<AlbumArt>, pub album_art: Vec<AlbumArt>,
pub tags: BTreeMap<Tag, String>, pub tags: BTreeMap<Tag, String>,
pub internal_tags: Vec<InternalTag> pub internal_tags: Vec<InternalTag>,
} }
impl Song { impl Song {
/// Get a tag's value /// Get a tag's value
/// ///
@ -342,7 +340,6 @@ impl Song {
for file in cue_data.files.iter() { for file in cue_data.files.iter() {
let audio_location = &parent_dir.join(file.file.clone()); let audio_location = &parent_dir.join(file.file.clone());
if !audio_location.exists() { if !audio_location.exists() {
continue; continue;
} }
@ -447,80 +444,12 @@ impl Song {
date_modified: Some(chrono::offset::Utc::now()), date_modified: Some(chrono::offset::Utc::now()),
tags, tags,
album_art, album_art,
internal_tags: Vec::new() internal_tags: Vec::new(),
}; };
tracks.push((new_song, audio_location.clone())); tracks.push((new_song, audio_location.clone()));
} }
} }
Ok(tracks) Ok(tracks)
}
/// Takes the AlbumArt[index] and opens it in the native file viewer
pub fn open_album_art(&self, index: usize, temp_dir: &TempDir) -> Result<(), Box<dyn Error>> {
use opener::open;
use urlencoding::decode;
if index >= self.album_art.len() {
return Err("Index out of bounds".into());
}
let uri = match &self.album_art[index] {
AlbumArt::External(uri) => {
PathBuf::from(decode(match uri.as_uri().strip_prefix("file:///") {
Some(e) => e,
None => return Err("Invalid path?".into())
})?.to_owned().to_string())
},
AlbumArt::Embedded(_) => {
let normal_options = ParseOptions::new().parsing_mode(lofty::ParsingMode::Relaxed);
let blank_tag = &lofty::Tag::new(TagType::Id3v2);
let tagged_file: lofty::TaggedFile;
// TODO: add support for other URI types... or don't
#[cfg(target_family = "windows")]
let uri = urlencoding::decode(
match self.primary_uri()?.0.as_uri().strip_prefix("file:///") {
Some(str) => str,
None => return Err("invalid path.. again?".into())
})?.into_owned();
#[cfg(target_family = "unix")]
let uri = urlencoding::decode(
match self.primary_uri()?.as_uri().strip_prefix("file://") {
Some(str) => str,
None => return Err("invalid path.. again?".into())
})?.into_owned();
let tag = match Probe::open(uri)?.options(normal_options).read() {
Ok(file) => {
tagged_file = file;
match tagged_file.primary_tag() {
Some(primary_tag) => primary_tag,
None => match tagged_file.first_tag() {
Some(first_tag) => first_tag,
None => blank_tag,
},
}
}
Err(_) => blank_tag,
};
let data = tag.pictures()[index].data();
let fmt = FileFormat::from_bytes(data);
let file_path = temp_dir.path().join(format!("{}_{index}.{}", self.uuid, fmt.extension()));
File::create(&file_path)?.write_all(data)?;
file_path
},
};
dbg!(open(dbg!(uri))?);
Ok(())
} }
/// Returns a reference to the first valid URI in the song, and any invalid URIs that come before it, or errors if there are no valid URIs /// Returns a reference to the first valid URI in the song, and any invalid URIs that come before it, or errors if there are no valid URIs
@ -533,13 +462,20 @@ impl Song {
if uri.exists()? { if uri.exists()? {
valid_uri = Some(uri); valid_uri = Some(uri);
break; break;
}else { } else {
invalid_uris.push(uri); invalid_uris.push(uri);
} }
} }
match valid_uri { match valid_uri {
Some(uri) => Ok((uri, if !invalid_uris.is_empty() { Some(invalid_uris) } else { None } )), Some(uri) => Ok((
None => Err("No valid URIs for this song".into()) uri,
if !invalid_uris.is_empty() {
Some(invalid_uris)
} else {
None
},
)),
None => Err("No valid URIs for this song".into()),
} }
} }
} }
@ -610,7 +546,7 @@ impl URI {
pub fn as_path(&self) -> Result<&PathBuf, Box<dyn Error>> { pub fn as_path(&self) -> Result<&PathBuf, Box<dyn Error>> {
if let Self::Local(path) = self { if let Self::Local(path) = self {
Ok(path) Ok(path)
}else { } else {
Err("This URI is not local!".into()) Err("This URI is not local!".into())
} }
} }
@ -618,7 +554,7 @@ impl URI {
pub fn exists(&self) -> Result<bool, std::io::Error> { pub fn exists(&self) -> Result<bool, std::io::Error> {
match self { match self {
URI::Local(loc) => loc.try_exists(), URI::Local(loc) => loc.try_exists(),
URI::Cue {location, ..} => location.try_exists(), URI::Cue { location, .. } => location.try_exists(),
URI::Remote(_, _loc) => todo!(), URI::Remote(_, _loc) => todo!(),
} }
} }
@ -703,7 +639,7 @@ pub struct MusicLibrary {
pub uuid: Uuid, pub uuid: Uuid,
pub library: Vec<Song>, pub library: Vec<Song>,
pub playlists: PlaylistFolder, pub playlists: PlaylistFolder,
pub backup_songs: Vec<Song> // maybe move this to the config instead? pub backup_songs: Vec<Song>, // maybe move this to the config instead?
} }
impl MusicLibrary { impl MusicLibrary {
@ -823,7 +759,8 @@ impl MusicLibrary {
fn query_path(&self, path: PathBuf) -> Option<Vec<&Song>> { fn query_path(&self, path: PathBuf) -> Option<Vec<&Song>> {
let result: Arc<Mutex<Vec<&Song>>> = Arc::new(Mutex::new(Vec::new())); let result: Arc<Mutex<Vec<&Song>>> = Arc::new(Mutex::new(Vec::new()));
self.library.par_iter().for_each(|track| { self.library.par_iter().for_each(|track| {
if path == track.primary_uri().unwrap().0.path() { //TODO: make this also not unwrap if path == track.primary_uri().unwrap().0.path() {
//TODO: make this also not unwrap
result.clone().lock().unwrap().push(track); result.clone().lock().unwrap().push(track);
} }
}); });
@ -835,10 +772,7 @@ impl MusicLibrary {
} }
/// Finds all the audio files within a specified folder /// Finds all the audio files within a specified folder
pub fn scan_folder( pub fn scan_folder(&mut self, target_path: &str) -> Result<i32, Box<dyn std::error::Error>> {
&mut self,
target_path: &str,
) -> Result<i32, Box<dyn std::error::Error>> {
let mut total = 0; let mut total = 0;
let mut errors = 0; let mut errors = 0;
for target_file in WalkDir::new(target_path) for target_file in WalkDir::new(target_path)
@ -901,7 +835,6 @@ impl MusicLibrary {
} }
pub fn add_file(&mut self, target_file: &Path) -> Result<(), Box<dyn Error>> { pub fn add_file(&mut self, target_file: &Path) -> Result<(), Box<dyn Error>> {
let new_song = Song::from_file(target_file)?; let new_song = Song::from_file(target_file)?;
match self.add_song(new_song) { match self.add_song(new_song) {
Ok(_) => (), Ok(_) => (),
@ -917,14 +850,13 @@ impl MusicLibrary {
let tracks = Song::from_cue(cuesheet)?; let tracks = Song::from_cue(cuesheet)?;
let mut tracks_added = tracks.len() as i32; let mut tracks_added = tracks.len() as i32;
for (new_song, location) in tracks { for (new_song, location) in tracks {
// Try to remove the original audio file from the db if it exists // Try to remove the original audio file from the db if it exists
if self.remove_uri(&URI::Local(location.clone())).is_ok() { if self.remove_uri(&URI::Local(location.clone())).is_ok() {
tracks_added -= 1 tracks_added -= 1
} }
match self.add_song(new_song) { match self.add_song(new_song) {
Ok(_) => {}, Ok(_) => {}
Err(_error) => { Err(_error) => {
//println!("{}", _error); //println!("{}", _error);
continue; continue;
@ -1194,7 +1126,12 @@ impl MusicLibrary {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::{path::{Path, PathBuf}, sync::{Arc, RwLock}, thread::sleep, time::{Duration, Instant}}; use std::{
path::{Path, PathBuf},
sync::{Arc, RwLock},
thread::sleep,
time::{Duration, Instant},
};
use tempfile::TempDir; use tempfile::TempDir;
@ -1202,7 +1139,6 @@ mod test {
use super::Song; use super::Song;
#[test] #[test]
fn get_art_test() { fn get_art_test() {
let s = Song::from_file(Path::new("")).unwrap(); let s = Song::from_file(Path::new("")).unwrap();
@ -1211,7 +1147,7 @@ mod test {
let now = Instant::now(); let now = Instant::now();
_ = s.open_album_art(0, dir).inspect_err(|e| println!("{e:?}")); _ = s.open_album_art(0, dir).inspect_err(|e| println!("{e:?}"));
_ = s.open_album_art(1, dir).inspect_err(|e| println!("{e:?}")); _ = s.open_album_art(1, dir).inspect_err(|e| println!("{e:?}"));
println!("{}ms", now.elapsed().as_millis() ); println!("{}ms", now.elapsed().as_millis());
sleep(Duration::from_secs(20)); sleep(Duration::from_secs(20));
} }
@ -1223,4 +1159,4 @@ mod test {
let a = MusicLibrary::init(Arc::new(RwLock::from(config)), target_uuid).unwrap(); let a = MusicLibrary::init(Arc::new(RwLock::from(config)), target_uuid).unwrap();
dbg!(a); dbg!(a);
} }
} }