mirror of
https://github.com/Dangoware/dmp-core.git
synced 2025-04-19 13:22:54 -05:00
Can query by URI now
This commit is contained in:
parent
bde2d194dc
commit
140bae703a
2 changed files with 51 additions and 25 deletions
|
@ -79,8 +79,9 @@ impl MusicController {
|
||||||
&self,
|
&self,
|
||||||
query_string: &String,
|
query_string: &String,
|
||||||
target_tags: Vec<Tag>,
|
target_tags: Vec<Tag>,
|
||||||
|
search_location: bool,
|
||||||
sort_by: Vec<Tag>
|
sort_by: Vec<Tag>
|
||||||
) -> Option<Vec<&Song>> {
|
) -> Option<Vec<&Song>> {
|
||||||
self.library.query(query_string, &target_tags, &sort_by)
|
self.library.query(query_string, &target_tags, search_location, &sort_by)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use file_format::{FileFormat, Kind};
|
use file_format::{FileFormat, Kind};
|
||||||
use lofty::{AudioFile, ItemKey, ItemValue, Probe, TagType, TaggedFileExt};
|
use lofty::{AudioFile, ItemKey, ItemValue, Probe, TagType, TaggedFileExt};
|
||||||
|
use std::any::Any;
|
||||||
use std::{error::Error, io::BufReader};
|
use std::{error::Error, io::BufReader};
|
||||||
|
|
||||||
use chrono::{serde::ts_seconds_option, DateTime, Utc};
|
use chrono::{serde::ts_seconds_option, DateTime, Utc};
|
||||||
|
@ -15,7 +16,6 @@ use unidecode::unidecode;
|
||||||
|
|
||||||
// Fun parallel stuff
|
// Fun parallel stuff
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use rayon::iter;
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::music_controller::config::Config;
|
use crate::music_controller::config::Config;
|
||||||
|
@ -35,20 +35,22 @@ pub enum Tag {
|
||||||
Comment,
|
Comment,
|
||||||
Track,
|
Track,
|
||||||
Disk,
|
Disk,
|
||||||
Key(String)
|
Key(String),
|
||||||
|
Field(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for Tag {
|
impl ToString for Tag {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Title => "TrackTitle".into(),
|
Self::Title => "TrackTitle".into(),
|
||||||
Self::Album => "AlbumTitle".into(),
|
Self::Album => "AlbumTitle".into(),
|
||||||
Self::Artist => "TrackArtist".into(),
|
Self::Artist => "TrackArtist".into(),
|
||||||
Self::Genre => "Genre".into(),
|
Self::Genre => "Genre".into(),
|
||||||
Self::Comment => "Comment".into(),
|
Self::Comment => "Comment".into(),
|
||||||
Self::Track => "TrackNumber".into(),
|
Self::Track => "TrackNumber".into(),
|
||||||
Self::Disk => "DiscNumber".into(),
|
Self::Disk => "DiscNumber".into(),
|
||||||
Self::Key(key) => key.into()
|
Self::Key(key) => key.into(),
|
||||||
|
Self::Field(f) => f.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,17 +97,12 @@ impl Song {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tags(&self, target_keys: &Vec<String>) -> Vec<Option<String>> {
|
pub fn get_field(&self, target_field: &str) -> Box<dyn Any> {
|
||||||
let mut results = Vec::new();
|
match target_field {
|
||||||
for tag in &self.tags {
|
"location" => Box::new(self.location.clone()),
|
||||||
for key in target_keys {
|
"plays" => Box::new(self.plays.clone()),
|
||||||
if &tag.0.to_string() == key {
|
_ => todo!()
|
||||||
results.push(Some(tag.1.to_owned()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results.push(None);
|
|
||||||
}
|
}
|
||||||
results
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +113,15 @@ pub enum URI {
|
||||||
Remote(Service, String),
|
Remote(Service, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToString for URI {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
URI::Local(location) => location.to_string(),
|
||||||
|
URI::Remote(_, location) => location.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub enum Service {
|
pub enum Service {
|
||||||
InternetRadio,
|
InternetRadio,
|
||||||
|
@ -142,7 +148,7 @@ pub struct MusicLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize(input_string: &String) -> String {
|
pub fn normalize(input_string: &String) -> String {
|
||||||
unidecode(input_string).to_ascii_lowercase().replace(|c: char| !c.is_alphanumeric() && !c.is_ascii_punctuation(), "")
|
unidecode(input_string).to_ascii_lowercase().replace(|c: char| !c.is_alphanumeric(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MusicLibrary {
|
impl MusicLibrary {
|
||||||
|
@ -207,7 +213,9 @@ impl MusicLibrary {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_by_uri(&self, path: &URI) -> Option<Song> {
|
/// Queries for a [Song] by its [URI], returning a single Song
|
||||||
|
/// with the URI that matches
|
||||||
|
fn query_by_uri(&self, path: &URI) -> Option<Song> {
|
||||||
for track in &self.library {
|
for track in &self.library {
|
||||||
if path == &track.location {
|
if path == &track.location {
|
||||||
return Some(track.clone());
|
return Some(track.clone());
|
||||||
|
@ -348,14 +356,14 @@ impl MusicLibrary {
|
||||||
|
|
||||||
match self.add_song_to_db(new_song) {
|
match self.add_song_to_db(new_song) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(error) => ()
|
Err(_error) => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_song_to_db(&mut self, new_song: Song) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn add_song_to_db(&mut self, new_song: Song) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match self.find_by_uri(&new_song.location) {
|
match self.query_by_uri(&new_song.location) {
|
||||||
Some(_) => return Err(format!("URI already in database: {:?}", new_song.location).into()),
|
Some(_) => return Err(format!("URI already in database: {:?}", new_song.location).into()),
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
@ -366,7 +374,7 @@ impl MusicLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_song_tags(&mut self, new_tags: Song) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn update_song_tags(&mut self, new_tags: Song) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match self.find_by_uri(&new_tags.location) {
|
match self.query_by_uri(&new_tags.location) {
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
None => return Err(format!("URI not in database!").into())
|
None => return Err(format!("URI not in database!").into())
|
||||||
}
|
}
|
||||||
|
@ -379,6 +387,7 @@ impl MusicLibrary {
|
||||||
&self,
|
&self,
|
||||||
query_string: &String, // The query itself
|
query_string: &String, // The query itself
|
||||||
target_tags: &Vec<Tag>, // The tags to search
|
target_tags: &Vec<Tag>, // The tags to search
|
||||||
|
search_location: bool, // Whether to search the location field or not
|
||||||
sort_by: &Vec<Tag>, // Tags to sort the resulting data by
|
sort_by: &Vec<Tag>, // Tags to sort the resulting data by
|
||||||
) -> Option<Vec<&Song>> {
|
) -> Option<Vec<&Song>> {
|
||||||
let songs = Arc::new(Mutex::new(Vec::new()));
|
let songs = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
@ -391,9 +400,25 @@ impl MusicLibrary {
|
||||||
|
|
||||||
if normalize(&tag.1).contains(&normalize(&query_string)) {
|
if normalize(&tag.1).contains(&normalize(&query_string)) {
|
||||||
songs.lock().unwrap().push(track);
|
songs.lock().unwrap().push(track);
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !search_location {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a URL in the song
|
||||||
|
match &track.location {
|
||||||
|
URI::Local(path) if normalize(&path).contains(&normalize(&query_string)) => {
|
||||||
|
songs.lock().unwrap().push(track);
|
||||||
|
return
|
||||||
|
},
|
||||||
|
URI::Remote(_, path) if normalize(&path).contains(&normalize(&query_string)) => {
|
||||||
|
songs.lock().unwrap().push(track);
|
||||||
|
return
|
||||||
|
}, _ => ()
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
let lock = Arc::try_unwrap(songs).expect("Lock still has multiple owners!");
|
let lock = Arc::try_unwrap(songs).expect("Lock still has multiple owners!");
|
||||||
|
|
Loading…
Reference in a new issue