From b5d9bca981292f4a5b656b74457514d4eb5fd0a7 Mon Sep 17 00:00:00 2001 From: Antoine Gersant Date: Wed, 16 Nov 2016 16:34:36 -0800 Subject: [PATCH] Added support for Ogg Vorbis --- Cargo.lock | 28 ++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/api.rs | 1 + src/error.rs | 10 ++++++++++ src/index.rs | 34 ++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ 6 files changed, 77 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index fd8004a..c6f9548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,9 @@ dependencies = [ "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "iron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (git+https://github.com/retep998/winapi-rs)", + "lewton 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "mount 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ogg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "oven 1.0.0 (git+https://github.com/agersant/oven?branch=remove_cookie_dep)", "params 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)", @@ -315,6 +317,11 @@ dependencies = [ "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ieee754" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "image" version = "0.10.3" @@ -401,6 +408,16 @@ name = "lazy_static" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lewton" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ieee754 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ogg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libc" version = "0.2.16" @@ -569,6 +586,14 @@ dependencies = [ "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ogg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "openssl" version = "0.7.14" @@ -1088,6 +1113,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "eb27e8a3e8f17ac43ffa41bbda9cf5ad3f9f13ef66fa4873409d4902310275f7" "checksum id3 0.1.10 (git+https://github.com/jameshurst/rust-id3)" = "" "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" +"checksum ieee754 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4b09e329f1c87586e560c9de4f2c737a39033f8d9579f3b9949fa14532234c93" "checksum image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "559d5ebbe9ec73111799e49c07717944b244f8accf5de33a8a8128bc3ecd2e00" "checksum inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" "checksum iron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fb1b2d809f84bf347e472d5758762b5c804e0c622970235f156d82673e4d334" @@ -1098,6 +1124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" +"checksum lewton 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc51bb49b92a1a7ab1739bb8c3fe5c96d9509a91683039c2c1f20da3a3c3faf5" "checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d" "checksum libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cbc058951ab6a3ef35ca16462d7642c4867e6403520811f28537a4e2f2db3e71" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" @@ -1118,6 +1145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf" "checksum num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "8359ea48994f253fa958b5b90b013728b06f54872e5a58bce39540fcdd0f2527" "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3" +"checksum ogg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "780fc298e7c28a3d5b49638da41b99136d535564ca7060574dab61a845e4947d" "checksum openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "c4117b6244aac42ed0150a6019b4d953d28247c5dd6ae6f46ae469b5f2318733" "checksum openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89c47ee94c352eea9ddaf8e364be7f978a3bb6d66d73176572484238dd5a5c3f" "checksum openssl-sys-extras 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5e1dba7d3d03d80f045bf0d60111dc69213b67651e7c889527a3badabb9fa" diff --git a/Cargo.toml b/Cargo.toml index 61462e9..648e060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,9 @@ hyper = "0.9.10" id3 = { git = "https://github.com/jameshurst/rust-id3" } image = "0.10.3" iron = "0.4.0" +lewton = "0.4.0" mount = "0.2.1" +ogg = "0.4.0" oven = { git = "https://github.com/agersant/oven", branch = "remove_cookie_dep" } params = "0.3.1" regex = "0.1" diff --git a/src/api.rs b/src/api.rs index e42f96a..a1076f0 100644 --- a/src/api.rs +++ b/src/api.rs @@ -41,6 +41,7 @@ impl From for IronError { PError::UnsupportedMetadataFormat => IronError::new(err, status::InternalServerError), PError::APEParseError => IronError::new(err, status::InternalServerError), PError::ID3ParseError => IronError::new(err, status::InternalServerError), + PError::VorbisParseError => IronError::new(err, status::InternalServerError), PError::Unauthorized => IronError::new(err, status::Unauthorized), PError::IncorrectCredentials => IronError::new(err, status::BadRequest), } diff --git a/src/error.rs b/src/error.rs index 9e811a2..50cc3ea 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ use std::fmt; use std::io; use id3; use image; +use lewton; #[derive(Debug)] pub enum PError { @@ -24,6 +25,7 @@ pub enum PError { UnsupportedMetadataFormat, APEParseError, ID3ParseError, + VorbisParseError, Unauthorized, IncorrectCredentials, } @@ -52,6 +54,12 @@ impl From for PError { } } +impl From for PError { + fn from(_: lewton::VorbisError) -> PError { + PError::VorbisParseError + } +} + impl error::Error for PError { fn description(&self) -> &str { match *self { @@ -74,6 +82,7 @@ impl error::Error for PError { PError::UnsupportedMetadataFormat => "Unsupported metadata format", PError::APEParseError => "Error while reading APE tag", PError::ID3ParseError => "Error while reading ID3 tag", + PError::VorbisParseError => "Error while reading Vorbis tag", PError::Unauthorized => "Authentication required", PError::IncorrectCredentials => "Incorrect username/password combination", } @@ -111,6 +120,7 @@ impl fmt::Display for PError { PError::UnsupportedMetadataFormat => write!(f, "Unsupported metadata format"), PError::APEParseError => write!(f, "Error while reading APE tag"), PError::ID3ParseError => write!(f, "Error while reading ID3 tag"), + PError::VorbisParseError => write!(f, "Error while reading Vorbis tag"), PError::Unauthorized => write!(f, "Authentication required"), PError::IncorrectCredentials => write!(f, "Incorrect username/password combination"), } diff --git a/src/index.rs b/src/index.rs index 9f5a752..ea6bf5d 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,6 +1,8 @@ use core::ops::Deref; use ape; use id3::Tag; +use lewton::inside_ogg::OggStreamReader; +use ogg::PacketReader; use regex::Regex; use sqlite; use sqlite::{Connection, State, Statement, Value}; @@ -54,6 +56,7 @@ impl SongTags { match utils::get_audio_format(path) { Some(AudioFormat::MP3) => SongTags::read_id3(path), Some(AudioFormat::MPC) => SongTags::read_ape(path), + Some(AudioFormat::OGG) => SongTags::read_vorbis(path), _ => Err(PError::UnsupportedMetadataFormat), } } @@ -130,6 +133,37 @@ impl SongTags { year: year, }) } + + fn read_vorbis(path: &Path) -> Result { + + let file = try!(fs::File::open(path)); + let source = try!(OggStreamReader::new(PacketReader::new(file))); + + let mut tags = SongTags { + artist: None, + album_artist: None, + album: None, + title: None, + disc_number: None, + track_number: None, + year: None, + }; + + for (key, value) in source.comment_hdr.comment_list { + match key.as_str() { + "TITLE" => tags.title = Some(value), + "ALBUM" => tags.album = Some(value), + "ARTIST" => tags.artist = Some(value), + "ALBUMARTIST" => tags.album_artist = Some(value), + "TRACKNUMBER" => tags.track_number = value.parse::().ok(), + "DISCNUMBER" => tags.disc_number = value.parse::().ok(), + "DATE" => tags.year = value.parse::().ok(), + _ => (), + } + } + + Ok(tags) + } } #[derive(Debug, RustcEncodable)] diff --git a/src/main.rs b/src/main.rs index b4e79de..271f181 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,9 @@ extern crate hyper; extern crate id3; extern crate image; extern crate iron; +extern crate lewton; extern crate mount; +extern crate ogg; extern crate oven; extern crate params; extern crate regex;