mirror of
https://github.com/Dangoware/dmp-core.git
synced 2025-04-19 09:42:53 -05:00
fixed a function and removed Album Art function
This commit is contained in:
parent
b04a166c1b
commit
9457c5c996
2 changed files with 33 additions and 96 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue