diff --git a/IF.Lastfm.Core/Objects/Album.cs b/IF.Lastfm.Core/Objects/Album.cs
index f911b9f..96c399b 100644
--- a/IF.Lastfm.Core/Objects/Album.cs
+++ b/IF.Lastfm.Core/Objects/Album.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -31,8 +32,6 @@ public class Album
///
/// TODO datetime parsing
/// TODO images
- /// TODO tags
- /// TODO tracks
///
///
///
@@ -49,6 +48,12 @@ public static Album ParseJToken(JToken token)
a.Url = new Uri(token.Value("url"), UriKind.Absolute);
+ var tracksToken = token.SelectToken("tracks").SelectToken("track");
+ a.Tracks = tracksToken.Children().Select(trackToken => Track.ParseJToken(trackToken, a.Name));
+
+ var tagsToken = token.SelectToken("toptags").SelectToken("tag");
+ a.TopTags = tagsToken.Children().Select(Tag.ParseJToken);
+
return a;
}
}
diff --git a/IF.Lastfm.Core/Objects/Tag.cs b/IF.Lastfm.Core/Objects/Tag.cs
index c794031..dbf802f 100644
--- a/IF.Lastfm.Core/Objects/Tag.cs
+++ b/IF.Lastfm.Core/Objects/Tag.cs
@@ -1,6 +1,25 @@
-namespace IF.Lastfm.Core.Objects
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace IF.Lastfm.Core.Objects
{
public class Tag
{
+ #region Properties
+
+ public string Name { get; set; }
+ public Uri Url { get; set; }
+
+ #endregion
+
+ public static Tag ParseJToken(JToken token)
+ {
+ var t = new Tag();
+
+ t.Name = token.Value("name");
+ t.Url = new Uri(token.Value("url"), UriKind.Absolute);
+
+ return t;
+ }
}
}
\ No newline at end of file
diff --git a/IF.Lastfm.Core/Objects/Track.cs b/IF.Lastfm.Core/Objects/Track.cs
index a9eccf4..5ff563b 100644
--- a/IF.Lastfm.Core/Objects/Track.cs
+++ b/IF.Lastfm.Core/Objects/Track.cs
@@ -1,6 +1,73 @@
-namespace IF.Lastfm.Core.Objects
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json.Linq;
+
+namespace IF.Lastfm.Core.Objects
{
+ ///
+ /// TODO Wiki, Images, Stream availability
+ ///
public class Track
{
+ #region Properties
+
+ public string Name { get; set; }
+ public TimeSpan Duration { get; set; }
+ public string Mbid { get; set; }
+ public string ArtistName { get; set; }
+ public Uri Url { get; set; }
+
+ public string AlbumName { get; set; }
+
+ public int? ListenerCount { get; set; }
+ public int? TotalPlayCount { get; set; }
+ public IEnumerable TopTags { get; set; }
+
+ #endregion
+
+ ///
+ /// Parses the given JToken into a track
+ ///
+ /// A valid JToken
+ /// track equivalent to the JToken
+ /// If this method is used directly then the duration attribute will be parsed as MILLIseconds
+ public static Track ParseJToken(JToken token)
+ {
+ var t = new Track();
+
+ t.Name = token.Value("name");
+ t.Mbid = token.Value("mbid");
+ t.Url = new Uri(token.Value("url"), UriKind.Absolute);
+ t.ArtistName = token.SelectToken("artist").Value("name");
+
+ var tagsToken = token.SelectToken("toptags").SelectToken("tag");
+ t.TopTags = tagsToken.Children().Select(Tag.ParseJToken);
+
+ // api returns milliseconds when track.getInfo is called directly
+ var secs = token.Value("duration");
+ t.Duration = TimeSpan.FromMilliseconds(secs);
+
+ return t;
+ }
+
+ ///
+ /// Parses the given JToken into a track
+ ///
+ /// A valid JToken
+ /// Name of the album this track belongs to
+ /// track equivalent to the JToken
+ /// If this method is used then the duration attribute will be parsed as seconds
+ public static Track ParseJToken(JToken token, string albumName)
+ {
+ var t = ParseJToken(token);
+ t.AlbumName = albumName;
+
+ // the api returns seconds for this value when not track.getInfo
+ var secs = token.Value("duration");
+ t.Duration = TimeSpan.FromSeconds(secs);
+
+ return t;
+ }
}
}
\ No newline at end of file