From 4f518fc445eb73ae2b9dc3a5761c9a2406e86bf2 Mon Sep 17 00:00:00 2001 From: Paul Lietar Date: Mon, 28 Dec 2015 16:55:01 +0100 Subject: [PATCH] Get track availability and alternatives --- protocol/proto/metadata.proto | 8 ++++---- src/metadata.rs | 21 ++++++++++++++++++++- src/util/mod.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/protocol/proto/metadata.proto b/protocol/proto/metadata.proto index 2f5d216..e2563fd 100644 --- a/protocol/proto/metadata.proto +++ b/protocol/proto/metadata.proto @@ -43,7 +43,7 @@ message Album { optional bytes gid = 0x1; optional string name = 0x2; repeated Artist artist = 0x3; - optional Type type = 0x4; + optional Type typ = 0x4; enum Type { ALBUM = 0x1; SINGLE = 0x2; @@ -112,7 +112,7 @@ message Disc { } message Copyright { - optional Type type = 0x1; + optional Type typ = 0x1; enum Type { P = 0x0; C = 0x1; @@ -123,7 +123,7 @@ message Copyright { message Restriction { optional string countries_allowed = 0x2; optional string countries_forbidden = 0x3; - optional Type type = 0x4; + optional Type typ = 0x4; enum Type { STREAMING = 0x0; } @@ -137,7 +137,7 @@ message SalePeriod { } message ExternalId { - optional string type = 0x1; + optional string typ = 0x1; optional string id = 0x2; } diff --git a/src/metadata.rs b/src/metadata.rs index 16250fb..51b1ff4 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -3,9 +3,22 @@ use protobuf; use librespot_protocol as protocol; use mercury::{MercuryRequest, MercuryMethod}; -use util::{SpotifyId, FileId}; +use util::{SpotifyId, FileId, StrChunksExt}; use session::Session; +fn countrylist_contains(list: &str, country: &str) -> bool { + list.chunks(2).any(|cc| cc == country) +} + +fn parse_restrictions<'s, I>(restrictions: I, country: &str, catalogue: &str) -> bool + where I : Iterator { + restrictions + .filter(|r| r.get_catalogue_str().contains(&catalogue.to_owned())) + .all(|r| !countrylist_contains(r.get_countries_forbidden(), country) + && (!r.has_countries_allowed() + || countrylist_contains(r.get_countries_allowed(), country))) +} + pub trait MetadataTrait : Send + 'static { type Message: protobuf::MessageStatic; @@ -19,6 +32,8 @@ pub struct Track { pub name: String, pub album: SpotifyId, pub files: Vec, + pub alternatives: Vec, + pub available: bool, } #[derive(Debug)] @@ -59,6 +74,10 @@ impl MetadataTrait for Track { FileId(dst) }) .collect(), + alternatives: msg.get_alternative().iter() + .map(|alt| SpotifyId::from_raw(alt.get_gid())) + .collect(), + available: parse_restrictions(msg.get_restriction().iter(), "FR", "premium"), } } } diff --git a/src/util/mod.rs b/src/util/mod.rs index c334851..9c851d4 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -105,3 +105,29 @@ pub fn powm(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint { return result; } +pub struct StrChunks<'s>(&'s str, usize); + +pub trait StrChunksExt { + fn chunks<'s>(&'s self, size: usize) -> StrChunks<'s>; +} + +impl StrChunksExt for str { + fn chunks<'a>(&'a self, size: usize) -> StrChunks<'a> { + StrChunks(self, size) + } +} + +impl <'s> Iterator for StrChunks<'s> { + type Item = &'s str; + fn next(&mut self) -> Option<&'s str> { + let &mut StrChunks(data, size) = self; + if data.is_empty() { + None + } else { + let ret = Some(&data[..size]); + self.0 = &data[size..]; + ret + } + } +} +