pub struct Library<Config, D: ?Sized> {
pub config: Config,
pub sqlite_conn: Arc<Mutex<Connection>>,
/* private fields */
}Expand description
A struct used to hold a collection of Songs, with convenience methods to add, remove and update songs.
Provide it either the BaseConfig, or a Config extending
BaseConfig.
TODO code example
Fields§
§config: ConfigThe configuration struct, containing both information
from BaseConfig as well as user-defined values.
sqlite_conn: Arc<Mutex<Connection>>SQL connection to the database.
Implementations§
Source§impl<Config: AppConfigTrait, D: ?Sized + DecoderTrait> Library<Config, D>
impl<Config: AppConfigTrait, D: ?Sized + DecoderTrait> Library<Config, D>
Sourcepub fn new(config: Config) -> Result<Self>
pub fn new(config: Config) -> Result<Self>
Create a new Library object from the given Config struct that
implements the AppConfigTrait.
writing the configuration to the file given in
config.config_path.
This function should only be called once, when a user wishes to create a completely new “library”. Otherwise, load an existing library file using Library::from_config_path.
Sourcepub fn from_config_path(config_path: Option<PathBuf>) -> Result<Self>
pub fn from_config_path(config_path: Option<PathBuf>) -> Result<Self>
Load a library from a configuration path.
If no configuration path is provided, the path is set using default data folder path.
Sourcepub fn version_sanity_check(&mut self) -> Result<Vec<SanityError>>
pub fn version_sanity_check(&mut self) -> Result<Vec<SanityError>>
Check whether the library contains songs analyzed with different, incompatible versions of bliss.
Returns a vector filled with potential errors. A sane database would return Ok() with an empty vector.
Sourcepub fn new_from_base(
config_path: Option<PathBuf>,
database_path: Option<PathBuf>,
analysis_options: Option<AnalysisOptions>,
) -> Result<Self>where
BaseConfig: Into<Config>,
pub fn new_from_base(
config_path: Option<PathBuf>,
database_path: Option<PathBuf>,
analysis_options: Option<AnalysisOptions>,
) -> Result<Self>where
BaseConfig: Into<Config>,
Create a new Library object from a minimal configuration setup,
writing it to config_path.
Sourcepub fn playlist_from<'a, T: Serialize + DeserializeOwned + Clone + 'a>(
&self,
song_paths: &[&str],
) -> Result<impl Iterator<Item = LibrarySong<T>> + 'a>
pub fn playlist_from<'a, T: Serialize + DeserializeOwned + Clone + 'a>( &self, song_paths: &[&str], ) -> Result<impl Iterator<Item = LibrarySong<T>> + 'a>
Build a playlist of playlist_length items from a set of already analyzed
songs in the library at song_path.
It uses the ExentedIsolationForest score as a distance between songs, and deduplicates songs that are too close.
Generating a playlist from a single song is also possible, and is just the special case where song_paths is a slice of length 1.
Sourcepub fn playlist_from_custom<'a, T, F, I>(
&self,
initial_song_paths: &[&str],
distance: &'a dyn DistanceMetricBuilder,
sort_by: F,
deduplicate: bool,
) -> Result<impl Iterator<Item = LibrarySong<T>> + 'a>where
T: Serialize + DeserializeOwned + Clone + 'a,
F: Fn(&[LibrarySong<T>], &[LibrarySong<T>], &'a dyn DistanceMetricBuilder) -> I,
I: Iterator<Item = LibrarySong<T>> + 'a,
pub fn playlist_from_custom<'a, T, F, I>(
&self,
initial_song_paths: &[&str],
distance: &'a dyn DistanceMetricBuilder,
sort_by: F,
deduplicate: bool,
) -> Result<impl Iterator<Item = LibrarySong<T>> + 'a>where
T: Serialize + DeserializeOwned + Clone + 'a,
F: Fn(&[LibrarySong<T>], &[LibrarySong<T>], &'a dyn DistanceMetricBuilder) -> I,
I: Iterator<Item = LibrarySong<T>> + 'a,
Build a playlist of playlist_length items from a set of already analyzed
song(s) in the library initial_song_paths, using distance metric distance,
and sorting function sort_by.
Note: The resulting playlist includes the songs specified in initial_song_paths
at the beginning. Use Iterator::skip on the resulting iterator to avoid it.
You can use ready-to-use distance metrics such as ExtendedIsolationForest or euclidean_distance, and ready-to-use sorting functions like closest_to_songs or crate::playlist::song_to_song.
If you want to use the sorting functions in a uniform manner, you can do something like this:
use bliss_audio::library::LibrarySong;
use bliss_audio::playlist::{closest_to_songs, song_to_song};
// The user would be choosing this
let use_closest_to_songs = true;
let sort = |x: &[LibrarySong<()>],
y: &[LibrarySong<()>],
z|
-> Box<dyn Iterator<Item = LibrarySong<()>>> {
match use_closest_to_songs {
false => Box::new(closest_to_songs(x, y, z)),
true => Box::new(song_to_song(x, y, z)),
}
};and use playlist_from_custom with that sort as sort_by.
Generating a playlist from a single song is also possible, and is just the special case where song_paths is a slice with a single song.
Sourcepub fn album_playlist_from<T: Serialize + DeserializeOwned + Clone + PartialEq>(
&self,
album_title: String,
number_albums: usize,
) -> Result<Vec<LibrarySong<T>>>
pub fn album_playlist_from<T: Serialize + DeserializeOwned + Clone + PartialEq>( &self, album_title: String, number_albums: usize, ) -> Result<Vec<LibrarySong<T>>>
Make a playlist of number_albums albums closest to the album
with title album_title.
The playlist starts with the album with album_title, and contains
number_albums on top of that one.
Returns the songs of each album ordered by bliss’ track_number.
Sourcepub fn update_library<P: Into<PathBuf>>(
&mut self,
paths: Vec<P>,
delete_everything_else: bool,
show_progress_bar: bool,
) -> Result<()>
pub fn update_library<P: Into<PathBuf>>( &mut self, paths: Vec<P>, delete_everything_else: bool, show_progress_bar: bool, ) -> Result<()>
Analyze and store all songs in paths that haven’t been already analyzed,
re-analyzing songs with newer feature versions if there was an update
of bliss features.
Use this function if you don’t have any extra data to bundle with each song.
Setting delete_everything_else to true will delete the paths that are
not mentionned in paths_extra_info from the database. If you do not
use it, because you only pass the new paths that need to be analyzed to
this function, make sure to delete yourself from the database the songs
that have been deleted from storage.
If your library
contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Sourcepub fn update_library_with_options<P: Into<PathBuf>>(
&mut self,
paths: Vec<P>,
delete_everything_else: bool,
show_progress_bar: bool,
analysis_options: AnalysisOptions,
) -> Result<()>
pub fn update_library_with_options<P: Into<PathBuf>>( &mut self, paths: Vec<P>, delete_everything_else: bool, show_progress_bar: bool, analysis_options: AnalysisOptions, ) -> Result<()>
Analyze and store all songs in paths that haven’t been already analyzed,
with analysis options (including features version). If the features
version in the analysis options are newer than the ones in the song
database, all those songs are updated.
Use this function if you don’t have any extra data to bundle with each song.
Setting delete_everything_else to true will delete the paths that are
not mentionned in paths_extra_info from the database. If you do not
use it, because you only pass the new paths that need to be analyzed to
this function, make sure to delete yourself from the database the songs
that have been deleted from storage.
If your library
contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Sourcepub fn update_library_extra_info<T: Serialize + DeserializeOwned + Clone, P: Into<PathBuf>>(
&mut self,
paths_extra_info: Vec<(P, T)>,
delete_everything_else: bool,
show_progress_bar: bool,
) -> Result<()>
pub fn update_library_extra_info<T: Serialize + DeserializeOwned + Clone, P: Into<PathBuf>>( &mut self, paths_extra_info: Vec<(P, T)>, delete_everything_else: bool, show_progress_bar: bool, ) -> Result<()>
Analyze and store all songs in paths_extra_info that haven’t already
been analyzed, along with some extra metadata serializable, and known
before song analysis.
Setting delete_everything_else to true will delete the paths that are
not mentionned in paths_extra_info from the database. If you do not
use it, because you only pass the new paths that need to be analyzed to
this function, make sure to delete yourself from the database the songs
that have been deleted from storage.
Sourcepub fn update_library_convert_extra_info<T: Serialize + DeserializeOwned + Clone, U, P: Into<PathBuf>>(
&mut self,
paths_extra_info: Vec<(P, U)>,
delete_everything_else: bool,
show_progress_bar: bool,
convert_extra_info: fn(U, &Song, &Self) -> T,
analysis_options: AnalysisOptions,
) -> Result<()>
pub fn update_library_convert_extra_info<T: Serialize + DeserializeOwned + Clone, U, P: Into<PathBuf>>( &mut self, paths_extra_info: Vec<(P, U)>, delete_everything_else: bool, show_progress_bar: bool, convert_extra_info: fn(U, &Song, &Self) -> T, analysis_options: AnalysisOptions, ) -> Result<()>
Analyze and store all songs in paths_extra_info that haven’t
been already analyzed, as well as handling extra, user-specified metadata,
that can’t directly be serializable,
or that need input from the analyzed Song to be processed. If you
just want to analyze and store songs along with some directly
serializable values, consider using Library::update_library_extra_info,
or Library::update_library if you just want the analyzed songs
stored as is.
paths_extra_info is a tuple made out of song paths, along
with any extra info you want to store for each song.
If your library
contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Setting delete_everything_else to true will delete the paths that are
not mentionned in paths_extra_info from the database. If you do not
use it, because you only pass the new paths that need to be analyzed to
this function, make sure to delete yourself from the database the songs
that have been deleted from storage.
convert_extra_info is a function that you should specify how
to convert that extra info to something serializable.
analysis_options contains the desired analysis options, i.e. number
of cores and the version of the features you want your library to be
analyzed with. It will reanalyze songs that have features version older
than latest’s, and set the config file’s features_version to the specified version.
Sourcepub fn analyze_paths<P: Into<PathBuf>>(
&mut self,
paths: Vec<P>,
show_progress_bar: bool,
) -> Result<()>
pub fn analyze_paths<P: Into<PathBuf>>( &mut self, paths: Vec<P>, show_progress_bar: bool, ) -> Result<()>
Analyze and store all songs in paths.
Use this function if you don’t have any extra data to bundle with each song.
If your library contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Sourcepub fn analyze_paths_with_options<P: Into<PathBuf>>(
&mut self,
paths: Vec<P>,
show_progress_bar: bool,
analysis_options: AnalysisOptions,
) -> Result<()>
pub fn analyze_paths_with_options<P: Into<PathBuf>>( &mut self, paths: Vec<P>, show_progress_bar: bool, analysis_options: AnalysisOptions, ) -> Result<()>
Analyze and store all songs in paths, setting analysis options such
as features version and the number and cores.
Be careful not to analyze
some songs with a different features version than the rest of the database!
Use this function if you don’t have any extra data to bundle with each song.
If your library contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Sourcepub fn analyze_paths_extra_info<T: Serialize + DeserializeOwned + Debug + Clone, P: Into<PathBuf>>(
&mut self,
paths_extra_info: Vec<(P, T)>,
show_progress_bar: bool,
analysis_options: AnalysisOptions,
) -> Result<()>
pub fn analyze_paths_extra_info<T: Serialize + DeserializeOwned + Debug + Clone, P: Into<PathBuf>>( &mut self, paths_extra_info: Vec<(P, T)>, show_progress_bar: bool, analysis_options: AnalysisOptions, ) -> Result<()>
Analyze and store all songs in paths_extra_info, along with some
extra metadata serializable, and known before song analysis.
Updates the value of features_version in the config, using bliss’
latest version.
If your library
contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
Sourcepub fn analyze_paths_convert_extra_info<T: Serialize + DeserializeOwned + Clone, U, P: Into<PathBuf>>(
&mut self,
paths_extra_info: Vec<(P, U)>,
show_progress_bar: bool,
convert_extra_info: fn(U, &Song, &Self) -> T,
analysis_options: AnalysisOptions,
) -> Result<()>
pub fn analyze_paths_convert_extra_info<T: Serialize + DeserializeOwned + Clone, U, P: Into<PathBuf>>( &mut self, paths_extra_info: Vec<(P, U)>, show_progress_bar: bool, convert_extra_info: fn(U, &Song, &Self) -> T, analysis_options: AnalysisOptions, ) -> Result<()>
Analyze and store all songs in paths_extra_info, along with some
extra, user-specified metadata, that can’t directly be serializable,
or that need input from the analyzed Song to be processed.
If you just want to analyze and store songs, along with some
directly serializable metadata values, consider using
Library::analyze_paths_extra_info, or Library::analyze_paths for
the simpler use cases.
Updates the value of features_version in the config, using bliss’
latest version.
paths_extra_info is a tuple made out of song paths, along
with any extra info you want to store for each song. If your library
contains CUE files, pass the CUE file path only, and not individual
CUE track names: passing vec![file.cue] will add
individual tracks with the cue_info field set in the database.
convert_extra_info is a function that you should specify
to convert that extra info to something serializable.
Sourcepub fn songs_from_library<T: Serialize + DeserializeOwned + Clone>(
&self,
) -> Result<Vec<LibrarySong<T>>>
pub fn songs_from_library<T: Serialize + DeserializeOwned + Clone>( &self, ) -> Result<Vec<LibrarySong<T>>>
Retrieve all songs which have been analyzed with the bliss version specified in the configuration.
Returns an error if one or several songs have a different number of features than they should, indicating the offending song id.
Sourcepub fn songs_from_album<T: Serialize + DeserializeOwned + Clone>(
&self,
album_title: &str,
) -> Result<Vec<LibrarySong<T>>>
pub fn songs_from_album<T: Serialize + DeserializeOwned + Clone>( &self, album_title: &str, ) -> Result<Vec<LibrarySong<T>>>
Get a LibrarySong from a given album title.
This will return all songs with corresponding bliss “album” tag, and will order them by track number.
Sourcepub fn song_from_path<T: Serialize + DeserializeOwned + Clone>(
&self,
song_path: &str,
) -> Result<LibrarySong<T>>
pub fn song_from_path<T: Serialize + DeserializeOwned + Clone>( &self, song_path: &str, ) -> Result<LibrarySong<T>>
Get a LibrarySong from a given file path. TODO pathbuf here too
Sourcepub fn store_song<T: Serialize + DeserializeOwned + Clone>(
&mut self,
library_song: &LibrarySong<T>,
) -> Result<(), BlissError>
pub fn store_song<T: Serialize + DeserializeOwned + Clone>( &mut self, library_song: &LibrarySong<T>, ) -> Result<(), BlissError>
Store a Song in the database, overidding any existing song with the same path by that one.
Sourcepub fn store_failed_song<P: Into<PathBuf>>(
&mut self,
song_path: P,
e: BlissError,
features_version: FeaturesVersion,
) -> Result<()>
pub fn store_failed_song<P: Into<PathBuf>>( &mut self, song_path: P, e: BlissError, features_version: FeaturesVersion, ) -> Result<()>
Store an errored Song in the SQLite database.
If there already is an existing song with that path, replace it by the latest failed result.
Sourcepub fn get_failed_songs(&self) -> Result<Vec<ProcessingError>>
pub fn get_failed_songs(&self) -> Result<Vec<ProcessingError>>
Return all the songs that failed the analysis.
Sourcepub fn delete_path<P: Into<PathBuf>>(&mut self, song_path: P) -> Result<()>
pub fn delete_path<P: Into<PathBuf>>(&mut self, song_path: P) -> Result<()>
Delete a song with path song_path from the database.
Errors out if the song is not in the database.
Sourcepub fn delete_paths<P: Into<PathBuf>, I: IntoIterator<Item = P>>(
&mut self,
paths: I,
) -> Result<usize>
pub fn delete_paths<P: Into<PathBuf>, I: IntoIterator<Item = P>>( &mut self, paths: I, ) -> Result<usize>
Delete a set of songs with paths song_paths from the database.
Will return Ok(count) even if less songs than expected were deleted from the database.
Auto Trait Implementations§
impl<Config, D> Freeze for Library<Config, D>
impl<Config, D> RefUnwindSafe for Library<Config, D>
impl<Config, D> Send for Library<Config, D>
impl<Config, D> Sync for Library<Config, D>
impl<Config, D> Unpin for Library<Config, D>
impl<Config, D> UnwindSafe for Library<Config, D>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more