From 3565a10387a0e4b93bf5d7e016ae5aebdec9866f Mon Sep 17 00:00:00 2001 From: Rikki Tooley Date: Tue, 23 Jul 2013 15:42:10 +0100 Subject: [PATCH] track.getInfo. Also fixes #2 (track.getShouts failing for single shout, added properties to PageResponse to help) --- .../Commands/TrackApi/GetTrackInfoCommand.cs | 69 +++++++++++++++++++ ...utsCommand.cs => GetTrackShoutsCommand.cs} | 27 +++++--- IF.Lastfm.Core/Api/Helpers/PageResponse.cs | 39 +++++++---- IF.Lastfm.Core/Api/ITrackApi.cs | 3 + IF.Lastfm.Core/Api/TrackApi.cs | 17 ++++- IF.Lastfm.Core/IF.Lastfm.Core.csproj | 3 +- IF.Lastfm.Core/Objects/Track.cs | 7 ++ 7 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackInfoCommand.cs rename IF.Lastfm.Core/Api/Commands/TrackApi/{GetShoutsCommand.cs => GetTrackShoutsCommand.cs} (70%) diff --git a/IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackInfoCommand.cs b/IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackInfoCommand.cs new file mode 100644 index 0000000..8c1de08 --- /dev/null +++ b/IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackInfoCommand.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using IF.Lastfm.Core.Api.Enums; +using IF.Lastfm.Core.Api.Helpers; +using IF.Lastfm.Core.Objects; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace IF.Lastfm.Core.Api.Commands.TrackApi +{ + internal class GetTrackInfoCommand : GetAsyncCommandBase> + { + public string TrackName { get; set; } + public string ArtistName { get; set; } + public string Username { get; set; } + public bool Autocorrect { get; set; } + + public GetTrackInfoCommand(IAuth auth, string trackname, string artistname) + : base(auth) + { + Method = "track.getInfo"; + TrackName = trackname; + ArtistName = artistname; + } + + public async override Task> ExecuteAsync() + { + var parameters = new Dictionary + { + {"track", TrackName}, + {"artist", ArtistName}, + {"autocorrect", Convert.ToInt32(Autocorrect).ToString()} + }; + + if (!string.IsNullOrWhiteSpace(Username)) + { + parameters.Add("username", Username); + } + + var apiUrl = LastFm.FormatApiUrl(Method, Auth.ApiKey, parameters); + Url = new Uri(apiUrl, UriKind.Absolute); + + return await ExecuteInternal(); + } + + public async override Task> HandleResponse(HttpResponseMessage response) + { + string json = await response.Content.ReadAsStringAsync(); + + LastFmApiError error; + if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode) + { + var jtoken = JsonConvert.DeserializeObject(json); + + var track = Track.ParseJToken(jtoken.SelectToken("track")); + + return LastResponse.CreateSuccessResponse(track); + } + else + { + return LastResponse.CreateErrorResponse(error); + } + } + } +} diff --git a/IF.Lastfm.Core/Api/Commands/TrackApi/GetShoutsCommand.cs b/IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackShoutsCommand.cs similarity index 70% rename from IF.Lastfm.Core/Api/Commands/TrackApi/GetShoutsCommand.cs rename to IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackShoutsCommand.cs index 672cb8e..becb49b 100644 --- a/IF.Lastfm.Core/Api/Commands/TrackApi/GetShoutsCommand.cs +++ b/IF.Lastfm.Core/Api/Commands/TrackApi/GetTrackShoutsCommand.cs @@ -12,13 +12,13 @@ namespace IF.Lastfm.Core.Api.Commands.TrackApi { - internal class GetShoutsCommand : GetAsyncCommandBase> + internal class GetTrackShoutsCommand : GetAsyncCommandBase> { public string TrackName { get; set; } public string ArtistName { get; set; } public bool Autocorrect { get; set; } - public GetShoutsCommand(IAuth auth, string trackname, string artistname) : base(auth) + public GetTrackShoutsCommand(IAuth auth, string trackname, string artistname) : base(auth) { Method = "track.getShouts"; TrackName = trackname; @@ -50,19 +50,26 @@ public async override Task> HandleResponse(HttpResponseMessa if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode) { JToken jtoken = JsonConvert.DeserializeObject(json).SelectToken("shouts"); - var shoutsToken = jtoken.SelectToken("shout"); - + + var pageresponse = PageResponse.CreateSuccessResponse(); + pageresponse.AddPageInfoFromJToken(jtoken.SelectToken("@attr")); + var shouts = new List(); - if (shoutsToken != null) + if (shoutsToken != null && pageresponse.TotalItems > 0) { - shouts.AddRange(shoutsToken.Children().Select(Shout.ParseJToken)); + if (pageresponse.TotalItems == 1) + { + // array notation isn't used on the api if there is only one shout. + shouts.Add(Shout.ParseJToken(shoutsToken)); + } + else + { + shouts.AddRange(shoutsToken.Children().Select(Shout.ParseJToken)); + } } - var pageresponse = PageResponse.CreateSuccessResponse(shouts); - - var attrToken = jtoken.SelectToken("@attr"); - pageresponse.AddPageInfoFromJToken(attrToken); + pageresponse.Content = shouts; return pageresponse; } diff --git a/IF.Lastfm.Core/Api/Helpers/PageResponse.cs b/IF.Lastfm.Core/Api/Helpers/PageResponse.cs index 0ee709d..33c7031 100644 --- a/IF.Lastfm.Core/Api/Helpers/PageResponse.cs +++ b/IF.Lastfm.Core/Api/Helpers/PageResponse.cs @@ -8,8 +8,11 @@ namespace IF.Lastfm.Core.Api.Helpers { public class PageResponse : IEnumerable { - private int _page = 1; - private int _totalPages = 1; + public PageResponse() + { + Page = 1; + TotalPages = 1; + } #region Properties @@ -17,17 +20,9 @@ public class PageResponse : IEnumerable public bool Success { get; set; } public LastFmApiError Error { get; set; } - public int Page - { - get { return _page; } - set { _page = value; } - } - - public int TotalPages - { - get { return _totalPages; } - set { _totalPages = value; } - } + public int Page { get; set; } + public int TotalPages { get; set; } + public int TotalItems { get; set; } #endregion @@ -61,6 +56,21 @@ IEnumerator IEnumerable.GetEnumerator() #region Factory methods + /// + /// Sometimes we need this object before we can set the content. Make sure to set the content! + /// + /// + public static PageResponse CreateSuccessResponse() + { + var r = new PageResponse + { + Success = true, + Error = LastFmApiError.None + }; + + return r; + } + public static PageResponse CreateSuccessResponse(IEnumerable content) { var r = new PageResponse @@ -99,6 +109,9 @@ public void AddPageInfoFromJToken(JToken attrToken) var totalPages = attrToken.Value("totalPages"); TotalPages = !string.IsNullOrWhiteSpace(totalPages) ? Convert.ToInt32(totalPages) : 1; + + var totalItems = attrToken.Value("total"); + TotalItems = !string.IsNullOrWhiteSpace(totalItems) ? Convert.ToInt32(totalItems) : 1; } // {"@attr": { diff --git a/IF.Lastfm.Core/Api/ITrackApi.cs b/IF.Lastfm.Core/Api/ITrackApi.cs index 444cbaa..03e9a31 100644 --- a/IF.Lastfm.Core/Api/ITrackApi.cs +++ b/IF.Lastfm.Core/Api/ITrackApi.cs @@ -19,5 +19,8 @@ Task> GetShoutsForTrackAsync(string trackname, string artist Task> GetShoutsForTrackWithMbidAsync(string mbid, int page = 0, int count = LastFm.DefaultPageLength); + + Task> GetInfoAsync(string trackname, string artistname, string username = ""); + Task> GetInfoWithMbidAsynnc(string mbid, string username = ""); } } \ No newline at end of file diff --git a/IF.Lastfm.Core/Api/TrackApi.cs b/IF.Lastfm.Core/Api/TrackApi.cs index b53f35a..8e5345b 100644 --- a/IF.Lastfm.Core/Api/TrackApi.cs +++ b/IF.Lastfm.Core/Api/TrackApi.cs @@ -62,7 +62,7 @@ public Task ScrobbleAsync(IEnumerable scrobble) public async Task> GetShoutsForTrackAsync(string trackname, string artistname, int page = 0, int count = LastFm.DefaultPageLength) { - var command = new GetShoutsCommand(Auth, trackname, artistname) + var command = new GetTrackShoutsCommand(Auth, trackname, artistname) { Page = page, Count = count, @@ -74,5 +74,20 @@ public Task> GetShoutsForTrackWithMbidAsync(string mbid, int { throw new NotImplementedException(); } + + public async Task> GetInfoAsync(string trackname, string artistname, string username = "") + { + var command = new GetTrackInfoCommand(Auth, trackname, artistname) + { + Username = username + }; + + return await command.ExecuteAsync(); + } + + public Task> GetInfoWithMbidAsynnc(string mbid, string username = "") + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/IF.Lastfm.Core/IF.Lastfm.Core.csproj b/IF.Lastfm.Core/IF.Lastfm.Core.csproj index 206dfb1..d301b39 100644 --- a/IF.Lastfm.Core/IF.Lastfm.Core.csproj +++ b/IF.Lastfm.Core/IF.Lastfm.Core.csproj @@ -44,7 +44,8 @@ - + + diff --git a/IF.Lastfm.Core/Objects/Track.cs b/IF.Lastfm.Core/Objects/Track.cs index 3ff1628..679aef3 100644 --- a/IF.Lastfm.Core/Objects/Track.cs +++ b/IF.Lastfm.Core/Objects/Track.cs @@ -28,6 +28,7 @@ public class Track : ILastFmObject public IEnumerable TopTags { get; set; } public DateTime? TimePlayed { get; set; } + public bool? IsLoved { get; set; } #endregion @@ -78,6 +79,12 @@ internal static Track ParseJToken(JToken token) t.Images = imageCollection; } + var lovedToken = token.SelectToken("userloved"); + if (lovedToken != null) + { + t.IsLoved = Convert.ToBoolean(lovedToken.Value()); + } + // api returns milliseconds when track.getInfo is called directly var secs = token.Value("duration"); if (Math.Abs(secs - default(double)) > double.Epsilon)