diff --git a/Cargo.lock b/Cargo.lock index de403b3..106fef9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,45 +1,3 @@ -[root] -name = "polaris" -version = "0.7.1" -dependencies = [ - "ape 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel 0.16.0 (git+https://github.com/diesel-rs/diesel?rev=034049d)", - "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", - "id3 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (git+https://github.com/retep998/winapi-rs?branch=0.2)", - "lewton 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "metaflac 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "mount 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "params 0.6.0 (git+https://github.com/euclio/params?branch=update)", - "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "secure-session 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.1 (git+https://github.com/retep998/winapi-rs?branch=0.2)", - "simplelog 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "staticfile 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "user32-sys 0.2.0 (git+https://github.com/retep998/winapi-rs?branch=0.2)", - "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (git+https://github.com/retep998/winapi-rs?branch=0.2)", -] - [[package]] name = "adler32" version = "1.0.0" @@ -1091,6 +1049,48 @@ dependencies = [ "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "polaris" +version = "0.7.1" +dependencies = [ + "ape 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 0.16.0 (git+https://github.com/diesel-rs/diesel?rev=034049d)", + "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", + "id3 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (git+https://github.com/retep998/winapi-rs?branch=0.2)", + "lewton 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "metaflac 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mount 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "params 0.6.0 (git+https://github.com/euclio/params?branch=update)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "secure-session 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "shell32-sys 0.1.1 (git+https://github.com/retep998/winapi-rs?branch=0.2)", + "simplelog 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "staticfile 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (git+https://github.com/retep998/winapi-rs?branch=0.2)", + "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (git+https://github.com/retep998/winapi-rs?branch=0.2)", +] + [[package]] name = "quote" version = "0.3.15" diff --git a/src/db/migrations/20171015224223_add_song_duration/down.sql b/src/db/migrations/20171015224223_add_song_duration/down.sql new file mode 100644 index 0000000..6f538da --- /dev/null +++ b/src/db/migrations/20171015224223_add_song_duration/down.sql @@ -0,0 +1,19 @@ +CREATE TEMPORARY TABLE songs_backup(id, path, parent, track_number, disc_number, title, artist, album_artist, year, album, artwork); +INSERT INTO songs_backup SELECT id, path, parent, track_number, disc_number, title, artist, album_artist, year, album, artwork FROM songs; +DROP TABLE songs; +CREATE TABLE songs ( + id INTEGER PRIMARY KEY NOT NULL, + path TEXT NOT NULL, + parent TEXT NOT NULL, + track_number INTEGER, + disc_number INTEGER, + title TEXT, + artist TEXT, + album_artist TEXT, + year INTEGER, + album TEXT, + artwork TEXT, + UNIQUE(path) ON CONFLICT REPLACE +); +INSERT INTO songs SELECT * FROM songs_backup; +DROP TABLE songs_backup; diff --git a/src/db/migrations/20171015224223_add_song_duration/up.sql b/src/db/migrations/20171015224223_add_song_duration/up.sql new file mode 100644 index 0000000..cea3ac5 --- /dev/null +++ b/src/db/migrations/20171015224223_add_song_duration/up.sql @@ -0,0 +1 @@ +ALTER TABLE songs ADD COLUMN duration INTEGER; diff --git a/src/db/schema.sqlite b/src/db/schema.sqlite index 02c3662..02b6a9b 100644 Binary files a/src/db/schema.sqlite and b/src/db/schema.sqlite differ diff --git a/src/index.rs b/src/index.rs index f28ff72..8ea7e15 100644 --- a/src/index.rs +++ b/src/index.rs @@ -49,6 +49,7 @@ pub struct Song { pub year: Option, pub album: Option, pub artwork: Option, + pub duration: Option, } #[derive(Debug, Queryable, Serialize)] @@ -84,6 +85,7 @@ struct NewSong { year: Option, album: Option, artwork: Option, + duration: Option } #[derive(Debug, Insertable)] @@ -247,6 +249,7 @@ impl<'conn> IndexBuilder<'conn> { disc_number: tags.disc_number.map(|n| n as i32), track_number: tags.track_number.map(|n| n as i32), title: tags.title, + duration: tags.duration.map(|n| n as i32), artist: tags.artist, album_artist: tags.album_artist, album: tags.album, diff --git a/src/metadata.rs b/src/metadata.rs index b5d8f7c..71ff39b 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -10,11 +10,12 @@ use errors::*; use utils; use utils::AudioFormat; -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub struct SongTags { pub disc_number: Option, pub track_number: Option, pub title: Option, + pub duration: Option, pub artist: Option, pub album_artist: Option, pub album: Option, @@ -50,6 +51,7 @@ fn read_id3(path: &Path) -> Result { album_artist: album_artist, album: album, title: title, + duration: None, disc_number: disc_number, track_number: track_number, year: year, @@ -98,6 +100,7 @@ fn read_ape(path: &Path) -> Result { album_artist: album_artist, album: album, title: title, + duration: None, disc_number: disc_number, track_number: track_number, year: year, @@ -114,6 +117,7 @@ fn read_vorbis(path: &Path) -> Result { album_artist: None, album: None, title: None, + duration:None, disc_number: None, track_number: None, year: None, @@ -142,11 +146,18 @@ fn read_flac(path: &Path) -> Result { .get("DISCNUMBER") .and_then(|d| d[0].parse::().ok()); let year = vorbis.get("DATE").and_then(|d| d[0].parse::().ok()); + let streaminfo = tag.get_blocks(metaflac::BlockType::StreamInfo); + let duration = match streaminfo.first() { + Some(&&metaflac::Block::StreamInfo(ref s)) => Some((s.total_samples as u32 / s.sample_rate) as u32), + _ => None + }; + Ok(SongTags { artist: vorbis.artist().map(|v| v[0].clone()), album_artist: vorbis.album_artist().map(|v| v[0].clone()), album: vorbis.album().map(|v| v[0].clone()), title: vorbis.title().map(|v| v[0].clone()), + duration: duration, disc_number: disc_number, track_number: vorbis.track(), year: year, @@ -162,9 +173,11 @@ fn test_read_metadata() { artist: Some("TEST ARTIST".into()), album_artist: Some("TEST ALBUM ARTIST".into()), album: Some("TEST ALBUM".into()), + duration: None, year: Some(2016), }; + let flac_sample_tag = SongTags {duration: Some(0), ..sample_tags.clone()}; assert_eq!(read(Path::new("test/sample.mp3")).unwrap(), sample_tags); assert_eq!(read(Path::new("test/sample.ogg")).unwrap(), sample_tags); - assert_eq!(read(Path::new("test/sample.flac")).unwrap(), sample_tags); + assert_eq!(read(Path::new("test/sample.flac")).unwrap(), flac_sample_tag); }