Library

Struct Library 

Source
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: Config

The 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>

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Source

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.

Source

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.

Source

pub fn get_failed_songs(&self) -> Result<Vec<ProcessingError>>

Return all the songs that failed the analysis.

Source

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.

Source

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>
where Config: Freeze, D: ?Sized,

§

impl<Config, D> RefUnwindSafe for Library<Config, D>
where Config: RefUnwindSafe, D: RefUnwindSafe + ?Sized,

§

impl<Config, D> Send for Library<Config, D>
where Config: Send, D: Send + ?Sized,

§

impl<Config, D> Sync for Library<Config, D>
where Config: Sync, D: Sync + ?Sized,

§

impl<Config, D> Unpin for Library<Config, D>
where Config: Unpin, D: Unpin + ?Sized,

§

impl<Config, D> UnwindSafe for Library<Config, D>
where Config: UnwindSafe, D: UnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V