Merged headers branch

This commit is contained in:
Johnny @PC 2016-07-07 21:23:36 +02:00
parent 8bde0643c4
commit 15d8fd87e2
8 changed files with 294 additions and 116 deletions

View File

@ -4,7 +4,6 @@ using SpotifyAPI.Web.Enums;
using SpotifyAPI.Web.Models; using SpotifyAPI.Web.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;

View File

@ -50,7 +50,7 @@ namespace SpotifyAPI.Tests
public void ShouldGetPrivateProfile_WithAuth() public void ShouldGetPrivateProfile_WithAuth()
{ {
PrivateProfile profile = GetFixture<PrivateProfile>("private-user.json"); PrivateProfile profile = GetFixture<PrivateProfile>("private-user.json");
_mock.Setup(client => client.DownloadJson<PrivateProfile>(It.IsAny<string>())).Returns(profile); _mock.Setup(client => client.DownloadJson<PrivateProfile>(It.IsAny<string>())).Returns(new Tuple<ResponseInfo, PrivateProfile>(null, profile));
_spotify.UseAuth = true; _spotify.UseAuth = true;
Assert.AreEqual(profile, _spotify.GetPrivateProfile()); Assert.AreEqual(profile, _spotify.GetPrivateProfile());
@ -61,7 +61,7 @@ namespace SpotifyAPI.Tests
public void ShouldGetPublicProfile() public void ShouldGetPublicProfile()
{ {
PublicProfile profile = GetFixture<PublicProfile>("public-user.json"); PublicProfile profile = GetFixture<PublicProfile>("public-user.json");
_mock.Setup(client => client.DownloadJson<PublicProfile>(It.IsAny<string>())).Returns(profile); _mock.Setup(client => client.DownloadJson<PublicProfile>(It.IsAny<string>())).Returns(new Tuple<ResponseInfo, PublicProfile>(null, profile));
Assert.AreEqual(profile, _spotify.GetPublicProfile("wizzler")); Assert.AreEqual(profile, _spotify.GetPublicProfile("wizzler"));
_mock.Verify(client => client.DownloadJson<PublicProfile>(It.Is<string>(str => ContainsValues(str, "/users/wizzler"))), Times.Exactly(1)); _mock.Verify(client => client.DownloadJson<PublicProfile>(It.Is<string>(str => ContainsValues(str, "/users/wizzler"))), Times.Exactly(1));

View File

@ -92,6 +92,7 @@
<Compile Include="Web\Models\Recommendations.cs" /> <Compile Include="Web\Models\Recommendations.cs" />
<Compile Include="Web\Models\RecommendationSeed .cs" /> <Compile Include="Web\Models\RecommendationSeed .cs" />
<Compile Include="Web\Models\RecommendationSeedGenres.cs" /> <Compile Include="Web\Models\RecommendationSeedGenres.cs" />
<Compile Include="Web\Models\ResponseInfo.cs" />
<Compile Include="Web\Models\SearchItem.cs" /> <Compile Include="Web\Models\SearchItem.cs" />
<Compile Include="Web\Models\PrivateProfile.cs" /> <Compile Include="Web\Models\PrivateProfile.cs" />
<Compile Include="Web\Models\GeneralModels.cs" /> <Compile Include="Web\Models\GeneralModels.cs" />

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using SpotifyAPI.Web.Models;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
@ -14,28 +15,28 @@ namespace SpotifyAPI.Web
/// </summary> /// </summary>
/// <param name="url">An URL</param> /// <param name="url">An URL</param>
/// <returns></returns> /// <returns></returns>
string Download(string url); Tuple<ResponseInfo, string> Download(string url);
/// <summary> /// <summary>
/// Downloads data async from an URL and returns it /// Downloads data async from an URL and returns it
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <returns></returns> /// <returns></returns>
Task<string> DownloadAsync(string url); Task<Tuple<ResponseInfo, string>> DownloadAsync(string url);
/// <summary> /// <summary>
/// Downloads data from an URL and returns it /// Downloads data from an URL and returns it
/// </summary> /// </summary>
/// <param name="url">An URL</param> /// <param name="url">An URL</param>
/// <returns></returns> /// <returns></returns>
byte[] DownloadRaw(string url); Tuple<ResponseInfo, byte[]> DownloadRaw(string url);
/// <summary> /// <summary>
/// Downloads data async from an URL and returns it /// Downloads data async from an URL and returns it
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <returns></returns> /// <returns></returns>
Task<byte[]> DownloadRawAsync(string url); Task<Tuple<ResponseInfo, byte[]>> DownloadRawAsync(string url);
/// <summary> /// <summary>
/// Downloads data from an URL and converts it to an object /// Downloads data from an URL and converts it to an object
@ -43,7 +44,7 @@ namespace SpotifyAPI.Web
/// <typeparam name="T">The Type which the object gets converted to</typeparam> /// <typeparam name="T">The Type which the object gets converted to</typeparam>
/// <param name="url">An URL</param> /// <param name="url">An URL</param>
/// <returns></returns> /// <returns></returns>
T DownloadJson<T>(string url); Tuple<ResponseInfo, T> DownloadJson<T>(string url);
/// <summary> /// <summary>
/// Downloads data async from an URL and converts it to an object /// Downloads data async from an URL and converts it to an object
@ -51,7 +52,7 @@ namespace SpotifyAPI.Web
/// <typeparam name="T">The Type which the object gets converted to</typeparam> /// <typeparam name="T">The Type which the object gets converted to</typeparam>
/// <param name="url">An URL</param> /// <param name="url">An URL</param>
/// <returns></returns> /// <returns></returns>
Task<T> DownloadJsonAsync<T>(string url); Task<Tuple<ResponseInfo, T>> DownloadJsonAsync<T>(string url);
/// <summary> /// <summary>
/// Uploads data from an URL and returns the response /// Uploads data from an URL and returns the response
@ -60,7 +61,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
string Upload(string url, string body, string method); Tuple<ResponseInfo, string> Upload(string url, string body, string method);
/// <summary> /// <summary>
/// Uploads data async from an URL and returns the response /// Uploads data async from an URL and returns the response
@ -69,7 +70,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
Task<string> UploadAsync(string url, string body, string method); Task<Tuple<ResponseInfo, string>> UploadAsync(string url, string body, string method);
/// <summary> /// <summary>
/// Uploads data from an URL and returns the response /// Uploads data from an URL and returns the response
@ -78,7 +79,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
byte[] UploadRaw(string url, string body, string method); Tuple<ResponseInfo, byte[]> UploadRaw(string url, string body, string method);
/// <summary> /// <summary>
/// Uploads data async from an URL and returns the response /// Uploads data async from an URL and returns the response
@ -87,7 +88,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
Task<byte[]> UploadRawAsync(string url, string body, string method); Task<Tuple<ResponseInfo, byte[]>> UploadRawAsync(string url, string body, string method);
/// <summary> /// <summary>
/// Uploads data from an URL and converts the response to an object /// Uploads data from an URL and converts the response to an object
@ -97,7 +98,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
T UploadJson<T>(string url, string body, string method); Tuple<ResponseInfo, T> UploadJson<T>(string url, string body, string method);
/// <summary> /// <summary>
/// Uploads data async from an URL and converts the response to an object /// Uploads data async from an URL and converts the response to an object
@ -107,7 +108,7 @@ namespace SpotifyAPI.Web
/// <param name="body">The Body-Data (most likely a JSON String)</param> /// <param name="body">The Body-Data (most likely a JSON String)</param>
/// <param name="method">The Upload-method (POST,DELETE,PUT)</param> /// <param name="method">The Upload-method (POST,DELETE,PUT)</param>
/// <returns></returns> /// <returns></returns>
Task<T> UploadJsonAsync<T>(string url, string body, string method); Task<Tuple<ResponseInfo, T>> UploadJsonAsync<T>(string url, string body, string method);
/// <summary> /// <summary>
/// Sets a specific Header /// Sets a specific Header

View File

@ -1,5 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Net;
namespace SpotifyAPI.Web.Models namespace SpotifyAPI.Web.Models
{ {
@ -8,9 +9,14 @@ namespace SpotifyAPI.Web.Models
[JsonProperty("error")] [JsonProperty("error")]
public Error Error { get; set; } public Error Error { get; set; }
public Boolean HasError() private WebHeaderCollection _headers;
{
return Error != null; public bool HasError() => Error != null;
}
public void AddResponseInfo(ResponseInfo info) => _headers = info.Headers;
public string Header(string key) => _headers?.Get(key);
public WebHeaderCollection Headers() => _headers;
} }
} }

View File

@ -0,0 +1,9 @@
using System.Net;
namespace SpotifyAPI.Web.Models
{
public class ResponseInfo
{
public WebHeaderCollection Headers { get; set; }
}
}

View File

@ -35,7 +35,7 @@ namespace SpotifyAPI.Web
public string TokenType { get; set; } public string TokenType { get; set; }
public string AccessToken { get; set; } public string AccessToken { get; set; }
public Boolean UseAuth { get; set; } public bool UseAuth { get; set; }
public IClient WebClient { get; set; } public IClient WebClient { get; set; }
public void Dispose() public void Dispose()
@ -693,14 +693,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the artist or the user Spotify IDs to check</param> /// <param name="ids">A list of the artist or the user Spotify IDs to check</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> IsFollowing(FollowType followType, List<string> ids) public ListResponse<bool> IsFollowing(FollowType followType, List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowing"); throw new InvalidOperationException("Auth is required for IsFollowing");
JToken res = DownloadData<JToken>(_builder.IsFollowing(followType, ids)); Tuple<ResponseInfo, JToken> res = DownloadDataAlt<JToken>(_builder.IsFollowing(followType, ids));
if (res is JArray) ListResponse<bool> ret;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -710,14 +722,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the artist or the user Spotify IDs to check</param> /// <param name="ids">A list of the artist or the user Spotify IDs to check</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> IsFollowingAsync(FollowType followType, List<string> ids) public async Task<ListResponse<bool>> IsFollowingAsync(FollowType followType, List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowing"); throw new InvalidOperationException("Auth is required for IsFollowing");
JToken res = await DownloadDataAsync<JToken>(_builder.IsFollowing(followType, ids)); Tuple<ResponseInfo, JToken> res = await DownloadDataAltAsync<JToken>(_builder.IsFollowing(followType, ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -727,7 +751,7 @@ namespace SpotifyAPI.Web
/// <param name="id">Artists or the Users Spotify ID</param> /// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> IsFollowing(FollowType followType, string id) public ListResponse<bool> IsFollowing(FollowType followType, string id)
{ {
return IsFollowing(followType, new List<string> { id }); return IsFollowing(followType, new List<string> { id });
} }
@ -739,7 +763,7 @@ namespace SpotifyAPI.Web
/// <param name="id">Artists or the Users Spotify ID</param> /// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> IsFollowingAsync(FollowType followType, string id) public async Task<ListResponse<bool>> IsFollowingAsync(FollowType followType, string id)
{ {
return await IsFollowingAsync(followType, new List<string> { id }); return await IsFollowingAsync(followType, new List<string> { id });
} }
@ -822,14 +846,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of Spotify User IDs</param> /// <param name="ids">A list of Spotify User IDs</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> IsFollowingPlaylist(string ownerId, string playlistId, List<string> ids) public ListResponse<bool> IsFollowingPlaylist(string ownerId, string playlistId, List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); throw new InvalidOperationException("Auth is required for IsFollowingPlaylist");
JToken res = DownloadData<JToken>(_builder.IsFollowingPlaylist(ownerId, playlistId, ids)); Tuple<ResponseInfo, JToken> res = DownloadDataAlt<JToken>(_builder.IsFollowingPlaylist(ownerId, playlistId, ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -840,14 +876,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of Spotify User IDs</param> /// <param name="ids">A list of Spotify User IDs</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> IsFollowingPlaylistAsync(string ownerId, string playlistId, List<string> ids) public async Task<ListResponse<bool>> IsFollowingPlaylistAsync(string ownerId, string playlistId, List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); throw new InvalidOperationException("Auth is required for IsFollowingPlaylist");
JToken res = await DownloadDataAsync<JToken>(_builder.IsFollowingPlaylist(ownerId, playlistId, ids)); Tuple<ResponseInfo, JToken> res = await DownloadDataAltAsync<JToken>(_builder.IsFollowingPlaylist(ownerId, playlistId, ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -858,7 +906,7 @@ namespace SpotifyAPI.Web
/// <param name="id">A Spotify User ID</param> /// <param name="id">A Spotify User ID</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> IsFollowingPlaylist(string ownerId, string playlistId, string id) public ListResponse<bool> IsFollowingPlaylist(string ownerId, string playlistId, string id)
{ {
return IsFollowingPlaylist(ownerId, playlistId, new List<string> { id }); return IsFollowingPlaylist(ownerId, playlistId, new List<string> { id });
} }
@ -871,7 +919,7 @@ namespace SpotifyAPI.Web
/// <param name="id">A Spotify User ID</param> /// <param name="id">A Spotify User ID</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> IsFollowingPlaylistAsync(string ownerId, string playlistId, string id) public async Task<ListResponse<bool>> IsFollowingPlaylistAsync(string ownerId, string playlistId, string id)
{ {
return await IsFollowingPlaylistAsync(ownerId, playlistId, new List<string> { id }); return await IsFollowingPlaylistAsync(ownerId, playlistId, new List<string> { id });
} }
@ -986,14 +1034,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the Spotify IDs.</param> /// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> CheckSavedTracks(List<string> ids) public ListResponse<bool> CheckSavedTracks(List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks"); throw new InvalidOperationException("Auth is required for CheckSavedTracks");
JToken res = DownloadData<JToken>(_builder.CheckSavedTracks(ids)); Tuple<ResponseInfo, JToken> res = DownloadDataAlt<JToken>(_builder.CheckSavedTracks(ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -1002,14 +1062,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the Spotify IDs.</param> /// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> CheckSavedTracksAsync(List<string> ids) public async Task<ListResponse<bool>> CheckSavedTracksAsync(List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks"); throw new InvalidOperationException("Auth is required for CheckSavedTracks");
JToken res = await DownloadDataAsync<JToken>(_builder.CheckSavedTracks(ids)); Tuple<ResponseInfo, JToken> res = await DownloadDataAltAsync<JToken>(_builder.CheckSavedTracks(ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -1118,14 +1190,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the Spotify IDs.</param> /// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ListResponse<Boolean> CheckSavedAlbums(List<string> ids) public ListResponse<bool> CheckSavedAlbums(List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks"); throw new InvalidOperationException("Auth is required for CheckSavedTracks");
JToken res = DownloadData<JToken>(_builder.CheckSavedAlbums(ids)); Tuple<ResponseInfo, JToken> res = DownloadDataAlt<JToken>(_builder.CheckSavedAlbums(ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
/// <summary> /// <summary>
@ -1134,14 +1218,26 @@ namespace SpotifyAPI.Web
/// <param name="ids">A list of the Spotify IDs.</param> /// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ListResponse<Boolean>> CheckSavedAlbumsAsync(List<string> ids) public async Task<ListResponse<bool>> CheckSavedAlbumsAsync(List<string> ids)
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedAlbumsAsync"); throw new InvalidOperationException("Auth is required for CheckSavedAlbumsAsync");
JToken res = await DownloadDataAsync<JToken>(_builder.CheckSavedAlbums(ids)); Tuple<ResponseInfo, JToken> res = await DownloadDataAltAsync<JToken>(_builder.CheckSavedAlbums(ids));
if (res is JArray) ListResponse<bool> ret = null;
return new ListResponse<Boolean> { List = res.ToObject<List<Boolean>>(), Error = null }; if (res.Item2 is JArray)
return new ListResponse<Boolean> { List = null, Error = res["error"].ToObject<Error>() }; ret = new ListResponse<bool>
{
List = res.Item2.ToObject<List<bool>>(),
Error = null
};
else
ret = new ListResponse<bool>
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
ret.AddResponseInfo(res.Item1);
return ret;
} }
#endregion Library #endregion Library
@ -1336,7 +1432,7 @@ namespace SpotifyAPI.Web
/// </param> /// </param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public FullPlaylist CreatePlaylist(string userId, string playlistName, Boolean isPublic = true) public FullPlaylist CreatePlaylist(string userId, string playlistName, bool isPublic = true)
{ {
JObject body = new JObject JObject body = new JObject
{ {
@ -1360,7 +1456,7 @@ namespace SpotifyAPI.Web
/// </param> /// </param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<FullPlaylist> CreatePlaylistAsync(string userId, string playlistName, Boolean isPublic = true) public async Task<FullPlaylist> CreatePlaylistAsync(string userId, string playlistName, bool isPublic = true)
{ {
JObject body = new JObject JObject body = new JObject
{ {
@ -1379,7 +1475,7 @@ namespace SpotifyAPI.Web
/// <param name="newPublic">If true the playlist will be public, if false it will be private.</param> /// <param name="newPublic">If true the playlist will be public, if false it will be private.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public ErrorResponse UpdatePlaylist(string userId, string playlistId, string newName = null, Boolean? newPublic = null) public ErrorResponse UpdatePlaylist(string userId, string playlistId, string newName = null, bool? newPublic = null)
{ {
JObject body = new JObject(); JObject body = new JObject();
if (newName != null) if (newName != null)
@ -1398,7 +1494,7 @@ namespace SpotifyAPI.Web
/// <param name="newPublic">If true the playlist will be public, if false it will be private.</param> /// <param name="newPublic">If true the playlist will be public, if false it will be private.</param>
/// <returns></returns> /// <returns></returns>
/// <remarks>AUTH NEEDED</remarks> /// <remarks>AUTH NEEDED</remarks>
public async Task<ErrorResponse> UpdatePlaylistAsync(string userId, string playlistId, string newName = null, Boolean? newPublic = null) public async Task<ErrorResponse> UpdatePlaylistAsync(string userId, string playlistId, string newName = null, bool? newPublic = null)
{ {
JObject body = new JObject(); JObject body = new JObject();
if (newName != null) if (newName != null)
@ -1767,7 +1863,7 @@ namespace SpotifyAPI.Web
#region Util #region Util
public TOut GetNextPage<TOut, TIn>(Paging<TIn> paging) public TOut GetNextPage<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{ {
if (!paging.HasNextPage()) if (!paging.HasNextPage())
throw new InvalidOperationException("This Paging-Object has no Next-Page"); throw new InvalidOperationException("This Paging-Object has no Next-Page");
@ -1779,7 +1875,7 @@ namespace SpotifyAPI.Web
return GetNextPage<Paging<T>, T>(paging); return GetNextPage<Paging<T>, T>(paging);
} }
public async Task<TOut> GetNextPageAsync<TOut, TIn>(Paging<TIn> paging) public async Task<TOut> GetNextPageAsync<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{ {
if (!paging.HasNextPage()) if (!paging.HasNextPage())
throw new InvalidOperationException("This Paging-Object has no Next-Page"); throw new InvalidOperationException("This Paging-Object has no Next-Page");
@ -1791,7 +1887,7 @@ namespace SpotifyAPI.Web
return await GetNextPageAsync<Paging<T>, T>(paging); return await GetNextPageAsync<Paging<T>, T>(paging);
} }
public TOut GetPreviousPage<TOut, TIn>(Paging<TIn> paging) public TOut GetPreviousPage<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{ {
if (!paging.HasPreviousPage()) if (!paging.HasPreviousPage())
throw new InvalidOperationException("This Paging-Object has no Previous-Page"); throw new InvalidOperationException("This Paging-Object has no Previous-Page");
@ -1803,7 +1899,7 @@ namespace SpotifyAPI.Web
return GetPreviousPage<Paging<T>, T>(paging); return GetPreviousPage<Paging<T>, T>(paging);
} }
public async Task<TOut> GetPreviousPageAsync<TOut, TIn>(Paging<TIn> paging) public async Task<TOut> GetPreviousPageAsync<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{ {
if (!paging.HasPreviousPage()) if (!paging.HasPreviousPage())
throw new InvalidOperationException("This Paging-Object has no Previous-Page"); throw new InvalidOperationException("This Paging-Object has no Previous-Page");
@ -1815,25 +1911,55 @@ namespace SpotifyAPI.Web
return await GetPreviousPageAsync<Paging<T>, T>(paging); return await GetPreviousPageAsync<Paging<T>, T>(paging);
} }
public T UploadData<T>(string url, string uploadData, string method = "POST") public T UploadData<T>(string url, string uploadData, string method = "POST") where T : BasicModel
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for all Upload-Actions"); throw new InvalidOperationException("Auth is required for all Upload-Actions");
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken); WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);
WebClient.SetHeader("Content-Type", "application/json"); WebClient.SetHeader("Content-Type", "application/json");
return WebClient.UploadJson<T>(url, uploadData, method);
Tuple<ResponseInfo, T> response = WebClient.UploadJson<T>(url, uploadData, method);
response.Item2.AddResponseInfo(response.Item1);
return response.Item2;
} }
public Task<T> UploadDataAsync<T>(string url, string uploadData, string method = "POST") public async Task<T> UploadDataAsync<T>(string url, string uploadData, string method = "POST") where T : BasicModel
{ {
if (!UseAuth) if (!UseAuth)
throw new InvalidOperationException("Auth is required for all Upload-Actions"); throw new InvalidOperationException("Auth is required for all Upload-Actions");
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken); WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);
WebClient.SetHeader("Content-Type", "application/json"); WebClient.SetHeader("Content-Type", "application/json");
return WebClient.UploadJsonAsync<T>(url, uploadData, method);
Tuple<ResponseInfo, T> response = await WebClient.UploadJsonAsync<T>(url, uploadData, method);
response.Item2.AddResponseInfo(response.Item1);
return response.Item2;
} }
public T DownloadData<T>(string url) public T DownloadData<T>(string url) where T : BasicModel
{
if (UseAuth)
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);
else
WebClient.RemoveHeader("Authorization");
Tuple<ResponseInfo, T> response = WebClient.DownloadJson<T>(url);
response.Item2.AddResponseInfo(response.Item1);
return response.Item2;
}
public async Task<T> DownloadDataAsync<T>(string url) where T : BasicModel
{
if (UseAuth)
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);
else
WebClient.RemoveHeader("Authorization");
Tuple<ResponseInfo, T> response = await WebClient.DownloadJsonAsync<T>(url);
response.Item2.AddResponseInfo(response.Item1);
return response.Item2;
}
private Tuple<ResponseInfo, T> DownloadDataAlt<T>(string url)
{ {
if (UseAuth) if (UseAuth)
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken); WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);
@ -1842,7 +1968,7 @@ namespace SpotifyAPI.Web
return WebClient.DownloadJson<T>(url); return WebClient.DownloadJson<T>(url);
} }
public Task<T> DownloadDataAsync<T>(string url) private Task<Tuple<ResponseInfo, T>> DownloadDataAltAsync<T>(string url)
{ {
if (UseAuth) if (UseAuth)
WebClient.SetHeader("Authorization", TokenType + " " + AccessToken); WebClient.SetHeader("Authorization", TokenType + " " + AccessToken);

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using SpotifyAPI.Web.Models;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
@ -30,130 +31,165 @@ namespace SpotifyAPI.Web
_webClient.Dispose(); _webClient.Dispose();
} }
public string Download(string url) public Tuple<ResponseInfo, string> Download(string url)
{ {
string response; Tuple<ResponseInfo, string> response;
try try
{ {
response = _encoding.GetString(DownloadRaw(url)); Tuple<ResponseInfo, byte[]> raw = DownloadRaw(url);
response = new Tuple<ResponseInfo, string>(raw.Item1, _encoding.GetString(raw.Item2));
} }
catch (WebException e) catch (WebException e)
{ {
using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
{ {
response = reader.ReadToEnd(); response = new Tuple<ResponseInfo, string>(new ResponseInfo
{
Headers = _webClient.ResponseHeaders
}, reader.ReadToEnd());
} }
} }
return response; return response;
} }
public async Task<string> DownloadAsync(string url) public async Task<Tuple<ResponseInfo, string>> DownloadAsync(string url)
{ {
string response; Tuple<ResponseInfo, string> response;
try try
{ {
response = _encoding.GetString(await DownloadRawAsync(url)); Tuple<ResponseInfo, byte[]> raw = await DownloadRawAsync(url);
response = new Tuple<ResponseInfo, string>(raw.Item1, _encoding.GetString(raw.Item2));
} }
catch (WebException e) catch (WebException e)
{ {
using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
{ {
response = reader.ReadToEnd(); response = new Tuple<ResponseInfo, string>(new ResponseInfo
{
Headers = _webClient.ResponseHeaders
}, reader.ReadToEnd());
} }
} }
return response; return response;
} }
public byte[] DownloadRaw(string url) public Tuple<ResponseInfo, byte[]> DownloadRaw(string url)
{ {
return _webClient.DownloadData(url); byte[] data = _webClient.DownloadData(url);
ResponseInfo info = new ResponseInfo()
{
Headers = _webClient.ResponseHeaders
};
return new Tuple<ResponseInfo, byte[]>(info, data);
} }
public async Task<byte[]> DownloadRawAsync(string url) public async Task<Tuple<ResponseInfo, byte[]>> DownloadRawAsync(string url)
{ {
using (WebClient webClient = new WebClient()) using (WebClient webClient = new WebClient())
{ {
webClient.Proxy = null; webClient.Proxy = null;
webClient.Encoding = _encoding; webClient.Encoding = _encoding;
webClient.Headers = _webClient.Headers; webClient.Headers = _webClient.Headers;
return await _webClient.DownloadDataTaskAsync(url);
byte[] data = await _webClient.DownloadDataTaskAsync(url);
ResponseInfo info = new ResponseInfo()
{
Headers = webClient.ResponseHeaders
};
return new Tuple<ResponseInfo, byte[]>(info, data);
} }
} }
public T DownloadJson<T>(string url) public Tuple<ResponseInfo, T> DownloadJson<T>(string url)
{ {
string response = Download(url); Tuple<ResponseInfo, string> response = Download(url);
return JsonConvert.DeserializeObject<T>(response, JsonSettings); return new Tuple<ResponseInfo, T>(response.Item1, JsonConvert.DeserializeObject<T>(response.Item2, JsonSettings));
} }
public async Task<T> DownloadJsonAsync<T>(string url) public async Task<Tuple<ResponseInfo, T>> DownloadJsonAsync<T>(string url)
{ {
string response = await DownloadAsync(url); Tuple<ResponseInfo, string> response = await DownloadAsync(url);
return JsonConvert.DeserializeObject<T>(response, JsonSettings); return new Tuple<ResponseInfo, T>(response.Item1, JsonConvert.DeserializeObject<T>(response.Item2, JsonSettings));
} }
public string Upload(string url, string body, string method) public Tuple<ResponseInfo, string> Upload(string url, string body, string method)
{ {
string response; Tuple<ResponseInfo, string> response;
try try
{ {
byte[] data = UploadRaw(url, body, method); Tuple<ResponseInfo, byte[]> data = UploadRaw(url, body, method);
response = _encoding.GetString(data); response = new Tuple<ResponseInfo, string>(data.Item1, _encoding.GetString(data.Item2));
} }
catch (WebException e) catch (WebException e)
{ {
using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
{ {
response = reader.ReadToEnd(); response = new Tuple<ResponseInfo, string>(new ResponseInfo
{
Headers = _webClient.ResponseHeaders
}, reader.ReadToEnd());
} }
} }
return response; return response;
} }
public async Task<string> UploadAsync(string url, string body, string method) public async Task<Tuple<ResponseInfo, string>> UploadAsync(string url, string body, string method)
{ {
string response; Tuple<ResponseInfo, string> response;
try try
{ {
byte[] data = await UploadRawAsync(url, body, method); Tuple<ResponseInfo, byte[]> data = await UploadRawAsync(url, body, method);
response = _encoding.GetString(data); response = new Tuple<ResponseInfo, string>(data.Item1, _encoding.GetString(data.Item2));
} }
catch (WebException e) catch (WebException e)
{ {
using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
{ {
response = reader.ReadToEnd(); response = new Tuple<ResponseInfo, string>(new ResponseInfo
{
Headers = _webClient.ResponseHeaders
}, reader.ReadToEnd());
} }
} }
return response; return response;
} }
public byte[] UploadRaw(string url, string body, string method) public Tuple<ResponseInfo, byte[]> UploadRaw(string url, string body, string method)
{ {
return _webClient.UploadData(url, method, _encoding.GetBytes(body)); byte[] data = _webClient.UploadData(url, method, _encoding.GetBytes(body));
ResponseInfo info = new ResponseInfo
{
Headers = _webClient.ResponseHeaders
};
return new Tuple<ResponseInfo, byte[]>(info, data);
} }
public async Task<byte[]> UploadRawAsync(string url, string body, string method) public async Task<Tuple<ResponseInfo, byte[]>> UploadRawAsync(string url, string body, string method)
{ {
using (WebClient webClient = new WebClient()) using (WebClient webClient = new WebClient())
{ {
webClient.Proxy = null; webClient.Proxy = null;
webClient.Encoding = _encoding; webClient.Encoding = _encoding;
webClient.Headers = _webClient.Headers; webClient.Headers = _webClient.Headers;
return await webClient.UploadDataTaskAsync(url, method, _encoding.GetBytes(body)); byte[] data = await _webClient.UploadDataTaskAsync(url, method, _encoding.GetBytes(body));
ResponseInfo info = new ResponseInfo
{
Headers = _webClient.ResponseHeaders
};
return new Tuple<ResponseInfo, byte[]>(info, data);
} }
} }
public T UploadJson<T>(string url, string body, string method) public Tuple<ResponseInfo, T> UploadJson<T>(string url, string body, string method)
{ {
string response = Upload(url, body, method); Tuple<ResponseInfo, string> response = Upload(url, body, method);
return JsonConvert.DeserializeObject<T>(response, JsonSettings); return new Tuple<ResponseInfo, T>(response.Item1, JsonConvert.DeserializeObject<T>(response.Item2, JsonSettings));
} }
public async Task<T> UploadJsonAsync<T>(string url, string body, string method) public async Task<Tuple<ResponseInfo, T>> UploadJsonAsync<T>(string url, string body, string method)
{ {
string response = await UploadAsync(url, body, method); Tuple<ResponseInfo, string> response = await UploadAsync(url, body, method);
return JsonConvert.DeserializeObject<T>(response, JsonSettings); return new Tuple<ResponseInfo, T>(response.Item1, JsonConvert.DeserializeObject<T>(response.Item2, JsonSettings));
} }
public void SetHeader(string header, string value) public void SetHeader(string header, string value)