Browse Source

Get track availability and alternatives

Paul Lietar 9 years ago
parent
commit
4f518fc445
3 changed files with 50 additions and 5 deletions
  1. 4 4
      protocol/proto/metadata.proto
  2. 20 1
      src/metadata.rs
  3. 26 0
      src/util/mod.rs

+ 4 - 4
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;
 }
 

+ 20 - 1
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<Item=&'s protocol::metadata::Restriction> {
+    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<FileId>,
+    pub alternatives: Vec<SpotifyId>,
+    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"),
         }
     }
 }

+ 26 - 0
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
+        }
+    }
+}
+