Skip to content

Commit

Permalink
Return failed songs from Library is now possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Polochon-street committed Sep 22, 2024
1 parent c867708 commit 45c0ab2
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## bliss 0.9.2
* Add a way to retrieve failed analysis for a Library.

## bliss 0.9.1
* Expose the Mahalanobis distance in the library feature, reading the
learned matrix in metric learning.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bliss-audio"
version = "0.9.1"
version = "0.9.2"
build = "build.rs"
authors = ["Polochon-street <[email protected]>"]
edition = "2021"
Expand Down
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ ask questions if you want to tackle an item.
- Improve bliss-python somehow / use it in a small demo project maybe?
A blissify in python?
- Investigate what type SAMPLE_RATE is in Aubio - maybe u16 is enough
- Should library really use `indicatif`? And not leave it up to the CLI program itself?
- Library: the database should maybe have errored_songs in a separate column (and remove
the "analyzed" flag?)

## Done
- Split out ffmpeg (see https://github.com/Polochon-street/bliss-rs/issues/63 and https://users.rust-lang.org/t/proper-way-to-abstract-a-third-party-provider/107076/8)
Expand Down
91 changes: 78 additions & 13 deletions src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,17 @@ pub struct Library<Config, D: ?Sized> {
decoder: PhantomData<D>,
}

/// Hold an error that happened while processing songs during analysis.
#[derive(Debug, Eq, PartialEq)]
pub struct ProcessingError {
/// The path of the song whose analysis was attempted.
pub song_path: PathBuf,
/// The actual error string.
pub error: String,
/// Features version the analysis was attempted with.
pub features_version: u16,
}

/// Struct holding both a Bliss song, as well as any extra info
/// that a user would want to store in the database related to that
/// song.
Expand Down Expand Up @@ -1372,6 +1383,28 @@ impl<Config: AppConfigTrait, D: ?Sized + DecoderTrait> Library<Config, D> {
Ok(())
}

/// Return all the songs that failed the analysis.
pub fn get_failed_songs(&self) -> Result<Vec<ProcessingError>> {
let conn = self.sqlite_conn.lock().unwrap();
let mut stmt = conn.prepare(
"
select path, error, version
from song where error is not null order by id
",
)?;
let rows = stmt.query_map([], |row| {
Ok(ProcessingError {
song_path: row.get::<_, String>(0)?.into(),
error: row.get(1)?,
features_version: row.get(2)?,
})
})?;
Ok(rows
.into_iter()
.map(|r| r.unwrap())
.collect::<Vec<ProcessingError>>())
}

/// Delete a song with path `song_path` from the database.
///
/// Errors out if the song is not in the database.
Expand Down Expand Up @@ -1777,80 +1810,90 @@ mod test {
insert into song (
id, path, artist, title, album, album_artist, track_number,
disc_number, genre, duration, analyzed, version, extra_info,
cue_path, audio_file_path
cue_path, audio_file_path, error
) values (
1001, '/path/to/song1001', 'Artist1001', 'Title1001', 'An Album1001',
'An Album Artist1001', 3, 1, 'Electronica1001', 310, true,
1, '{\"ignore\": true, \"metadata_bliss_does_not_have\":
\"/path/to/charlie1001\"}', null, null
\"/path/to/charlie1001\"}', null, null, null
),
(
2001, '/path/to/song2001', 'Artist2001', 'Title2001', 'An Album2001',
'An Album Artist2001', 2, 1, 'Electronica2001', 410, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie2001\"}', null, null
\"/path/to/charlie2001\"}', null, null, null
),
(
2201, '/path/to/song2201', 'Artist2001', 'Title2001', 'An Album2001',
'An Album Artist2001', 1, 2, 'Electronica2001', 410, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie2201\"}', null, null
\"/path/to/charlie2201\"}', null, null, null
),
(
3001, '/path/to/song3001', null, null, null,
null, null, null, null, null, false, 1, '{}', null, null
null, null, null, null, null, false, 1, '{}', null, null, null
),
(
4001, '/path/to/song4001', 'Artist4001', 'Title4001', 'An Album4001',
'An Album Artist4001', 1, 1, 'Electronica4001', 510, true,
0, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie4001\"}', null, null
\"/path/to/charlie4001\"}', null, null, null
),
(
5001, '/path/to/song5001', 'Artist5001', 'Title5001', 'An Album1001',
'An Album Artist5001', 1, 1, 'Electronica5001', 610, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie5001\"}', null, null
\"/path/to/charlie5001\"}', null, null, null
),
(
6001, '/path/to/song6001', 'Artist6001', 'Title6001', 'An Album2001',
'An Album Artist6001', 1, 1, 'Electronica6001', 710, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie6001\"}', null, null
\"/path/to/charlie6001\"}', null, null, null
),
(
7001, '/path/to/song7001', 'Artist7001', 'Title7001', 'An Album7001',
'An Album Artist7001', 1, 1, 'Electronica7001', 810, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie7001\"}', null, null
\"/path/to/charlie7001\"}', null, null, null
),
(
7002, '/path/to/cuetrack.cue/CUE_TRACK001', 'CUE Artist',
'CUE Title 01', 'CUE Album',
'CUE Album Artist', 1, 1, null, 810, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie7001\"}', '/path/to/cuetrack.cue',
'/path/to/cuetrack.flac'
'/path/to/cuetrack.flac', null
),
(
7003, '/path/to/cuetrack.cue/CUE_TRACK002', 'CUE Artist',
'CUE Title 02', 'CUE Album',
'CUE Album Artist', 2, 1, null, 910, true,
1, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie7001\"}', '/path/to/cuetrack.cue',
'/path/to/cuetrack.flac'
'/path/to/cuetrack.flac', null
),
(
8001, '/path/to/song8001', 'Artist8001', 'Title8001', 'An Album1001',
'An Album Artist8001', 3, 1, 'Electronica8001', 910, true,
0, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie8001\"}', null, null
\"/path/to/charlie8001\"}', null, null, null
),
(
9001, './data/s16_stereo_22_5kHz.flac', 'Artist9001', 'Title9001',
'An Album9001', 'An Album Artist8001', 3, 1, 'Electronica8001',
1010, true, 0, '{\"ignore\": false, \"metadata_bliss_does_not_have\":
\"/path/to/charlie7001\"}', null, null
\"/path/to/charlie7001\"}', null, null, null
),
(
404, './data/not-existing.m4a', null, null,
null, null, null, null, null,
null, false, 0, null, null, null, 'error finding the file'
),
(
502, './data/invalid-file.m4a', null, null,
null, null, null, null, null,
null, false, 0, null, null, null, 'error decoding the file'
);
",
[],
Expand Down Expand Up @@ -3644,4 +3687,26 @@ mod test {
.unwrap();
assert!(config_dir.is_dir());
}

#[test]
#[cfg(feature = "ffmpeg")]
fn test_library_get_failed_songs() {
let (mut library, _temp_dir, _) = setup_test_library();
let failed_songs = library.get_failed_songs().unwrap();
assert_eq!(
failed_songs,
vec![
ProcessingError {
song_path: PathBuf::from("./data/not-existing.m4a"),
error: String::from("error finding the file"),
features_version: 0,
},
ProcessingError {
song_path: PathBuf::from("./data/invalid-file.m4a"),
error: String::from("error decoding the file"),
features_version: 0,
}
]
);
}
}

0 comments on commit 45c0ab2

Please sign in to comment.