album.getinfo, album.getshouts, artist.getshouts, user.getinfo, user.getshouts

This commit is contained in:
Rikki Tooley 2013-07-28 00:07:15 +01:00
parent 718710d200
commit 2235ba0753
17 changed files with 387 additions and 116 deletions

View File

@ -1,15 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using IF.Lastfm.Core.Api.Commands.AlbumApi; using IF.Lastfm.Core.Api.Commands.AlbumApi;
using IF.Lastfm.Core.Api.Enums;
using IF.Lastfm.Core.Api.Helpers; using IF.Lastfm.Core.Api.Helpers;
using IF.Lastfm.Core.Objects; using IF.Lastfm.Core.Objects;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace IF.Lastfm.Core.Api namespace IF.Lastfm.Core.Api
{ {
@ -37,12 +30,6 @@ public Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist, strin
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task<PageResponse<Shout>> GetShoutsForAlbumAsync(string artist, string album, bool autocorrect = false, int page = 1,
int itemsPerPage = LastFm.DefaultPageLength)
{
throw new NotImplementedException();
}
public Task<PageResponse<Tag>> GetUserTagsForAlbumAsync(string artist, string album, string username, bool autocorrect = false) public Task<PageResponse<Tag>> GetUserTagsForAlbumAsync(string artist, string album, string username, bool autocorrect = false)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -57,5 +44,17 @@ public Task<PageResponse<Album>> SearchForAlbumAsync(string album, int page = 1,
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public async Task<PageResponse<Shout>> GetShoutsAsync(string albumname, string artistname, bool autocorrect = false, int page = 1, int count = LastFm.DefaultPageLength)
{
var command = new GetAlbumShoutsCommand(Auth, albumname, artistname)
{
Page = page,
Autocorrect = autocorrect,
Count = count
};
return await command.ExecuteAsync();
}
} }
} }

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
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.AlbumApi
{
internal class GetAlbumShoutsCommand : GetAsyncCommandBase<PageResponse<Shout>>
{
public string AlbumName { get; set; }
public string ArtistName { get; set; }
public bool Autocorrect { get; set; }
public GetAlbumShoutsCommand(IAuth auth, string albumname, string artistname)
: base(auth)
{
Method = "album.getShouts";
AlbumName = albumname;
ArtistName = artistname;
}
public override Uri BuildRequestUrl()
{
var parameters = new Dictionary<string, string>
{
{"album", Uri.EscapeDataString(AlbumName)},
{"artist", Uri.EscapeDataString(ArtistName)},
{"autocorrect", Convert.ToInt32(Autocorrect).ToString()}
};
base.AddPagingParameters(parameters);
base.DisableCaching(parameters);
var apiUrl = LastFm.FormatApiUrl(Method, Auth.ApiKey, parameters);
return new Uri(apiUrl, UriKind.Absolute);
}
public async override Task<PageResponse<Shout>> HandleResponse(HttpResponseMessage response)
{
string json = await response.Content.ReadAsStringAsync();
LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
{
JToken jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts");
return Shout.ParsePageJToken(jtoken);
}
else
{
return PageResponse<Shout>.CreateErrorResponse(error);
}
}
}
}

View File

@ -45,30 +45,9 @@ public async override Task<PageResponse<Shout>> HandleResponse(HttpResponseMessa
LastFmApiError error; LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode) if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
{ {
JToken jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts"); var jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts");
var shoutsToken = jtoken.SelectToken("shout");
var pageresponse = PageResponse<Shout>.CreateSuccessResponse(); return Shout.ParsePageJToken(jtoken);
pageresponse.AddPageInfoFromJToken(jtoken.SelectToken("@attr"));
var shouts = new List<Shout>();
if (shoutsToken != null && pageresponse.TotalItems > 0)
{
if (pageresponse.Page == pageresponse.TotalPages
&& pageresponse.TotalItems % pageresponse.PageSize == 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));
}
}
pageresponse.Content = shouts;
return pageresponse;
} }
else else
{ {

View File

@ -48,30 +48,9 @@ public async override Task<PageResponse<Shout>> HandleResponse(HttpResponseMessa
LastFmApiError error; LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode) if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
{ {
JToken jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts"); var jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts");
var shoutsToken = jtoken.SelectToken("shout");
var pageresponse = PageResponse<Shout>.CreateSuccessResponse(); return Shout.ParsePageJToken(jtoken);
pageresponse.AddPageInfoFromJToken(jtoken.SelectToken("@attr"));
var shouts = new List<Shout>();
if (shoutsToken != null && pageresponse.TotalItems > 0)
{
if (pageresponse.Page == pageresponse.TotalPages
&& pageresponse.TotalItems % pageresponse.PageSize == 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));
}
}
pageresponse.Content = shouts;
return pageresponse;
} }
else else
{ {

View File

@ -0,0 +1,52 @@
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.Helpers;
using IF.Lastfm.Core.Objects;
using Newtonsoft.Json.Linq;
namespace IF.Lastfm.Core.Api.Commands.TrackApi
{
internal class ScrobbleTracksCommand : PostAsyncCommandBase<LastResponse>
{
public ScrobbleTracksCommand(IAuth auth, Scrobble scrobble) : base(auth)
{
ConstructInternal(auth, new[] { scrobble });
}
public ScrobbleTracksCommand(IAuth auth, IEnumerable<Scrobble> scrobbles) : base(auth)
{
ConstructInternal(auth, scrobbles);
}
private void ConstructInternal(IAuth auth, IEnumerable<Scrobble> scrobbles)
{
Method = "track.scrobble";
}
public override Task<LastResponse> ExecuteAsync()
{
var parameters = new Dictionary<string, string>
{
{"artist", scrobble.Artist},
{"album", scrobble.Album},
{"track", scrobble.Track},
{"albumArtist", scrobble.AlbumArtist},
{"chosenByUser", scrobble.ChosenByUser.ToInt().ToString()},
{"timestamp", scrobble.TimePlayed.ToUnixTimestamp().ToString()},
{"sk", Auth.User.Token}
};
HttpContent post = new StringContent();
}
public override Task<LastResponse> HandleResponse(HttpResponseMessage response)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
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.UserApi
{
internal class GetUserInfoCommand : GetAsyncCommandBase<LastResponse<User>>
{
public string Username { get; set; }
public GetUserInfoCommand(IAuth auth, string username) : base(auth)
{
Method = "user.getInfo";
Username = username;
}
public override Uri BuildRequestUrl()
{
var parameters = new Dictionary<string, string>
{
{"user", Uri.EscapeDataString(Username)}
};
base.DisableCaching(parameters);
var uristring = LastFm.FormatApiUrl(Method, Auth.ApiKey, parameters);
return new Uri(uristring, UriKind.Absolute);
}
public async override Task<LastResponse<User>> HandleResponse(HttpResponseMessage response)
{
string json = await response.Content.ReadAsStringAsync();
LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
{
var jtoken = JsonConvert.DeserializeObject<JToken>(json);
return LastResponse<User>.CreateSuccessResponse(User.ParseJToken(jtoken.SelectToken("user")));
}
else
{
return LastResponse<User>.CreateErrorResponse(error);
}
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
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.UserApi
{
internal class GetUserShoutsCommand : GetAsyncCommandBase<PageResponse<Shout>>
{
public string Username { get; set; }
public GetUserShoutsCommand(IAuth auth, string username) : base(auth)
{
Method = "user.getShouts";
Username = username;
}
public override Uri BuildRequestUrl()
{
var parameters = new Dictionary<string, string>
{
{"user", Uri.EscapeDataString(Username)},
};
base.AddPagingParameters(parameters);
base.DisableCaching(parameters);
var uristring = LastFm.FormatApiUrl(Method, Auth.ApiKey, parameters);
return new Uri(uristring, UriKind.Absolute);
}
public async override Task<PageResponse<Shout>> HandleResponse(HttpResponseMessage response)
{
string json = await response.Content.ReadAsStringAsync();
LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
{
JToken jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("shouts");
return Shout.ParsePageJToken(jtoken);
}
else
{
return PageResponse<Shout>.CreateErrorResponse(error);
}
}
}
}

View File

@ -22,4 +22,11 @@ public enum LastStatsTimeSpan
[ApiName("12month")] [ApiName("12month")]
Year Year
} }
public enum Gender
{
Other = 0,
Male,
Female
}
} }

View File

@ -1,6 +1,4 @@
using System.Collections; using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using IF.Lastfm.Core.Api.Helpers; using IF.Lastfm.Core.Api.Helpers;
using IF.Lastfm.Core.Objects; using IF.Lastfm.Core.Objects;
@ -17,16 +15,23 @@ Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist,
CountryCode country, CountryCode country,
bool autocorrect = false); bool autocorrect = false);
Task<PageResponse<Shout>> GetShoutsForAlbumAsync(string artist, Task<PageResponse<Tag>> GetUserTagsForAlbumAsync(string artist,
string album, string album,
bool autocorrect = false, string username,
bool autocorrect = false);
Task<PageResponse<Tag>> GetTopTagsForAlbumAsync(string artist,
string album,
bool autocorrect = false);
Task<PageResponse<Album>> SearchForAlbumAsync(string album,
int page = 1, int page = 1,
int itemsPerPage = LastFm.DefaultPageLength); int itemsPerPage = LastFm.DefaultPageLength);
Task<PageResponse<Tag>> GetUserTagsForAlbumAsync(string artist, string album, string username, bool autocorrect = false); Task<PageResponse<Shout>> GetShoutsAsync(string albumname,
string artistname,
Task<PageResponse<Tag>> GetTopTagsForAlbumAsync(string artist, string album, bool autocorrect = false); bool autocorrect = false,
int page = 1,
Task<PageResponse<Album>> SearchForAlbumAsync(string album, int page = 1, int itemsPerPage = LastFm.DefaultPageLength); int count = LastFm.DefaultPageLength);
} }
} }

View File

@ -14,6 +14,7 @@ public interface ITrackApi
Task<PageResponse<Shout>> GetShoutsForTrackAsync(string trackname, Task<PageResponse<Shout>> GetShoutsForTrackAsync(string trackname,
string artistname, string artistname,
bool autocorrect = false,
int page = 0, int page = 0,
int count = LastFm.DefaultPageLength); int count = LastFm.DefaultPageLength);

View File

@ -23,5 +23,11 @@ Task<PageResponse<Track>> GetRecentScrobbles(string username,
Task<PageResponse<Station>> GetRecentStations(string username, Task<PageResponse<Station>> GetRecentStations(string username,
int pagenumber, int pagenumber,
int count = LastFm.DefaultPageLength); int count = LastFm.DefaultPageLength);
Task<PageResponse<Shout>> GetShoutsAsync(string username,
int pagenumber,
int count = LastFm.DefaultPageLength);
Task<LastResponse<User>> GetInfoAsync(string username);
} }
} }

View File

@ -60,12 +60,13 @@ public Task<LastResponse> ScrobbleAsync(IEnumerable<Scrobble> scrobble)
throw new NotImplementedException(); throw new NotImplementedException();
} }
public async Task<PageResponse<Shout>> GetShoutsForTrackAsync(string trackname, string artistname, int page = 0, int count = LastFm.DefaultPageLength) public async Task<PageResponse<Shout>> GetShoutsForTrackAsync(string trackname, string artistname, bool autocorrect = false, int page = 0, int count = LastFm.DefaultPageLength)
{ {
var command = new GetTrackShoutsCommand(Auth, trackname, artistname) var command = new GetTrackShoutsCommand(Auth, trackname, artistname)
{ {
Page = page, Page = page,
Count = count, Count = count,
Autocorrect = autocorrect
}; };
return await command.ExecuteAsync(); return await command.ExecuteAsync();
} }

View File

@ -1,14 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using IF.Lastfm.Core.Api.Commands.UserApi; using IF.Lastfm.Core.Api.Commands.UserApi;
using IF.Lastfm.Core.Api.Enums; using IF.Lastfm.Core.Api.Enums;
using IF.Lastfm.Core.Api.Helpers; using IF.Lastfm.Core.Api.Helpers;
using IF.Lastfm.Core.Objects; using IF.Lastfm.Core.Objects;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace IF.Lastfm.Core.Api namespace IF.Lastfm.Core.Api
{ {
@ -68,48 +63,24 @@ public async Task<PageResponse<Station>> GetRecentStations(string username, int
}; };
return await command.ExecuteAsync(); return await command.ExecuteAsync();
}
const string apiMethod = "user.getRecentStations"; public async Task<PageResponse<Shout>> GetShoutsAsync(string username, int pagenumber, int count = LastFm.DefaultPageLength)
{
var command = new GetUserShoutsCommand(Auth, username)
{
Page = pagenumber,
Count = count
};
var methodParameters = new Dictionary<string, string> return await command.ExecuteAsync();
{ }
{"user", Auth.User.Username},
{"page", pagenumber.ToString()},
{"limit", count.ToString()},
{"sk", Auth.User.Token}
};
var apisig = Auth.GenerateMethodSignature(apiMethod, methodParameters); public async Task<LastResponse<User>> GetInfoAsync(string username)
{
var command = new GetUserInfoCommand(Auth, username);
var postContent = LastFm.CreatePostBody(apiMethod, return await command.ExecuteAsync();
Auth.ApiKey,
apisig,
methodParameters);
var httpClient = new HttpClient();
var lastResponse = await httpClient.PostAsync(LastFm.ApiRoot, postContent);
var json = await lastResponse.Content.ReadAsStringAsync();
LastFmApiError error;
if (LastFm.IsResponseValid(json, out error) && lastResponse.IsSuccessStatusCode)
{
var jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("recentstations");
var stationsToken = jtoken.SelectToken("station");
var stations = stationsToken.Children().Select(Station.ParseJToken).ToList();
var pageresponse = PageResponse<Station>.CreateSuccessResponse(stations);
var attrToken = jtoken.SelectToken("@attr");
pageresponse.AddPageInfoFromJToken(attrToken);
return pageresponse;
}
else
{
return PageResponse<Station>.CreateErrorResponse(error);
}
} }
} }
} }

View File

@ -42,6 +42,7 @@
<Compile Include="Api\AlbumApi.cs" /> <Compile Include="Api\AlbumApi.cs" />
<Compile Include="Api\ArtistApi.cs" /> <Compile Include="Api\ArtistApi.cs" />
<Compile Include="Api\Commands\AlbumApi\GetAlbumInfoCommand.cs" /> <Compile Include="Api\Commands\AlbumApi\GetAlbumInfoCommand.cs" />
<Compile Include="Api\Commands\AlbumApi\GetAlbumShoutsCommand.cs" />
<Compile Include="Api\Commands\ArtistApi\GetArtistInfoCommand.cs" /> <Compile Include="Api\Commands\ArtistApi\GetArtistInfoCommand.cs" />
<Compile Include="Api\Commands\ArtistApi\GetArtistShoutsCommand.cs" /> <Compile Include="Api\Commands\ArtistApi\GetArtistShoutsCommand.cs" />
<Compile Include="Api\Commands\GetAsyncCommandBase.cs" /> <Compile Include="Api\Commands\GetAsyncCommandBase.cs" />
@ -53,6 +54,8 @@
<Compile Include="Api\Commands\UserApi\GetRecentScrobblesCommand.cs" /> <Compile Include="Api\Commands\UserApi\GetRecentScrobblesCommand.cs" />
<Compile Include="Api\Commands\UserApi\GetRecentStationsCommand.cs" /> <Compile Include="Api\Commands\UserApi\GetRecentStationsCommand.cs" />
<Compile Include="Api\Commands\UserApi\GetTopAlbumsCommand.cs" /> <Compile Include="Api\Commands\UserApi\GetTopAlbumsCommand.cs" />
<Compile Include="Api\Commands\UserApi\GetUserInfoCommand.cs" />
<Compile Include="Api\Commands\UserApi\GetUserShoutsCommand.cs" />
<Compile Include="Api\Helpers\ApiExtensions.cs" /> <Compile Include="Api\Helpers\ApiExtensions.cs" />
<Compile Include="Api\Helpers\ApiNameAttribute.cs" /> <Compile Include="Api\Helpers\ApiNameAttribute.cs" />
<Compile Include="Api\Auth.cs" /> <Compile Include="Api\Auth.cs" />
@ -67,6 +70,7 @@
<Compile Include="Api\Helpers\LastResponse{T}.cs" /> <Compile Include="Api\Helpers\LastResponse{T}.cs" />
<Compile Include="Api\Scrobble.cs" /> <Compile Include="Api\Scrobble.cs" />
<Compile Include="Api\TrackApi.cs" /> <Compile Include="Api\TrackApi.cs" />
<Compile Include="Objects\User.cs" />
<Compile Include="Api\UserApi.cs" /> <Compile Include="Api\UserApi.cs" />
<Compile Include="Json\LastFmBooleanConverter.cs" /> <Compile Include="Json\LastFmBooleanConverter.cs" />
<Compile Include="Api\IAuth.cs" /> <Compile Include="Api\IAuth.cs" />

View File

@ -49,10 +49,16 @@ internal static Album ParseJToken(JToken token)
a.Url = new Uri(token.Value<string>("url"), UriKind.Absolute); a.Url = new Uri(token.Value<string>("url"), UriKind.Absolute);
var tracksToken = token.SelectToken("tracks").SelectToken("track"); var tracksToken = token.SelectToken("tracks").SelectToken("track");
a.Tracks = tracksToken.Children().Select(trackToken => Track.ParseJToken(trackToken, a.Name)); if (tracksToken != null)
{
a.Tracks = tracksToken.Children().Select(trackToken => Track.ParseJToken(trackToken, a.Name));
}
var tagsToken = token.SelectToken("toptags").SelectToken("tag"); var tagsToken = token.SelectToken("toptags").SelectToken("tag");
a.TopTags = tagsToken.Children().Select(Tag.ParseJToken); if (tagsToken != null)
{
a.TopTags = tagsToken.Children().Select(Tag.ParseJToken);
}
return a; return a;
} }

View File

@ -1,5 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using IF.Lastfm.Core.Api.Helpers;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace IF.Lastfm.Core.Objects namespace IF.Lastfm.Core.Objects
@ -36,5 +39,32 @@ public static Shout ParseJToken(JToken token)
return s; return s;
} }
public static PageResponse<Shout> ParsePageJToken(JToken token)
{
var shoutsToken = token.SelectToken("shout");
var pageresponse = PageResponse<Shout>.CreateSuccessResponse();
pageresponse.AddPageInfoFromJToken(token.SelectToken("@attr"));
var shouts = new List<Shout>();
if (shoutsToken != null && pageresponse.TotalItems > 0)
{
if (pageresponse.Page == pageresponse.TotalPages
&& pageresponse.TotalItems % pageresponse.PageSize == 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));
}
}
pageresponse.Content = shouts;
return pageresponse;
}
} }
} }

View File

@ -0,0 +1,62 @@
using System;
using IF.Lastfm.Core.Api.Enums;
using Newtonsoft.Json.Linq;
namespace IF.Lastfm.Core.Objects
{
public class User
{
#region Properties
public string Name { get; set; }
public string FullName { get; set; }
public LastImageCollection Avatar { get; set; }
public string Id { get; set; }
public int Age { get; set; }
public string Country { get; set; }
public Gender Gender { get; set; }
public bool IsSubscriber { get; set; }
public int Playcount { get; set; }
public DateTime TimeRegistered { get; set; }
#endregion
/// <summary>
/// TODO
/// "gender": "m",
//"playcount": "79972",
//"playlists": "4",
//"bootstrap": "0",
//"registered": {
// "#text": "2002-11-20 11:50",
// "unixtime": "1037793040"
//},
//"type": "alumni"
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
internal static User ParseJToken(JToken token)
{
var u = new User();
u.Name = token.Value<string>("name");
u.FullName = token.Value<string>("realname");
u.Country = token.Value<string>("country");
u.Id = token.Value<string>("id");
var subscribed = token.SelectToken("subscriber");
if (subscribed != null)
{
u.IsSubscriber = Convert.ToBoolean(subscribed.Value<int>());
}
var images = token.SelectToken("image");
if (images != null)
{
u.Avatar = LastImageCollection.ParseJToken(images);
}
return u;
}
}
}