More Docs and spotify.LastResponse #451

This commit is contained in:
Jonas Dellinger 2020-05-30 23:20:42 +02:00
parent 0ef07bed0b
commit 5da15c1c29
18 changed files with 334 additions and 25 deletions

View File

@ -2,6 +2,9 @@ using System.Threading.Tasks;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
/// <summary>
/// An OAuth Client, which allows to get inital and updated tokens from the Spotify Service
/// </summary>
public interface IOAuthClient public interface IOAuthClient
{ {
/// <summary> /// <summary>
@ -9,6 +12,9 @@ namespace SpotifyAPI.Web
/// If the token is expired, simply call the funtion again to get a new token /// If the token is expired, simply call the funtion again to get a new token
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <remarks>
/// https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow
/// </remarks>
/// <returns></returns> /// <returns></returns>
Task<CredentialsTokenResponse> RequestToken(ClientCredentialsRequest request); Task<CredentialsTokenResponse> RequestToken(ClientCredentialsRequest request);
@ -16,8 +22,20 @@ namespace SpotifyAPI.Web
/// Refresh an already received token via Authorization Code Auth /// Refresh an already received token via Authorization Code Auth
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <remarks>
/// https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
/// </remarks>
/// <returns></returns> /// <returns></returns>
Task<AuthorizationCodeRefreshResponse> RequestToken(AuthorizationCodeRefreshRequest request); Task<AuthorizationCodeRefreshResponse> RequestToken(AuthorizationCodeRefreshRequest request);
/// <summary>
/// Reequest an initial token via Authorization Code Auth
/// </summary>
/// <param name="request"></param>
/// <remarks>
/// https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
/// </remarks>
/// <returns></returns>
Task<AuthorizationCodeTokenResponse> RequestToken(AuthorizationCodeTokenRequest request); Task<AuthorizationCodeTokenResponse> RequestToken(AuthorizationCodeTokenRequest request);
} }
} }

View File

@ -6,17 +6,62 @@ using SpotifyAPI.Web.Http;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
/// <summary>
/// A paginator allows to cycle through all resources of the spotify API
/// </summary>
public interface IPaginator public interface IPaginator
{ {
Task<List<T>> PaginateAll<T>(Paging<T> firstPage, IAPIConnector connector); /// <summary>
Task<List<T>> PaginateAll<T, TNext>( /// Fetches all pages and returns them grouped in a list
/// </summary>
/// <param name="firstPage">The first page. Will be included in the result list!</param>
/// <param name="connector">An API Connector to make requests to spotify</param>
/// <typeparam name="T">Paging Type</typeparam>
/// <returns>A list containing all pages, including the firstPage</returns>
Task<IList<T>> PaginateAll<T>(Paging<T> firstPage, IAPIConnector connector);
/// <summary>
/// Fetches all pages and returns them grouped in a list.
/// Supports a mapping method which takes care of JSON mapping problems.
/// To give an example, the Search method always returns the paging objects nested in a key. The mapper functions
/// tells the paginate function where to find the actual paging object in the response.
/// </summary>
/// <param name="firstPage">The first page. Will be included in the result list!</param>
/// <param name="mapper">A function which returns the actual paging object in another response object</param>
/// <param name="connector">An API Connector to make requests to spotify</param>
/// <typeparam name="T">Paging Type</typeparam>
/// <typeparam name="TNext">Outer response Type</typeparam>
/// <returns>A list containing all pages, including the firstPage</returns>
Task<IList<T>> PaginateAll<T, TNext>(
Paging<T, TNext> firstPage, Paging<T, TNext> firstPage,
Func<TNext, Paging<T, TNext>> mapper, Func<TNext, Paging<T, TNext>> mapper,
IAPIConnector connector IAPIConnector connector
); );
#if NETSTANDARD2_1 #if NETSTANDARD2_1
/// <summary>
/// Fetches all pages and returns one by one using IAsyncEnumerable
/// </summary>
/// <param name="firstPage">The first page. Will be included in the result list!</param>
/// <param name="connector">An API Connector to make requests to spotify</param>
/// <param name="cancel">A CancellationToken</param>
/// <typeparam name="T">Paging Type</typeparam>
/// <returns></returns>
IAsyncEnumerable<T> Paginate<T>(Paging<T> firstPage, IAPIConnector connector, CancellationToken cancel = default); IAsyncEnumerable<T> Paginate<T>(Paging<T> firstPage, IAPIConnector connector, CancellationToken cancel = default);
/// <summary>
/// Fetches all pages and returns them grouped in a list.
/// Supports a mapping method which takes care of JSON mapping problems.
/// To give an example, the Search method always returns the paging objects nested in a key. The mapper functions
/// tells the paginate function where to find the actual paging object in the response.
/// </summary>
/// <param name="firstPage">The first page. Will be included in the result list!</param>
/// <param name="mapper">A function which returns the actual paging object in another response object</param>
/// <param name="connector">An API Connector to make requests to spotify</param>
/// <param name="cancel">A CancellationToken</param>
/// <typeparam name="T">Paging Type</typeparam>
/// <typeparam name="TNext">Outer response Type</typeparam>
/// <returns></returns>
IAsyncEnumerable<T> Paginate<T, TNext>( IAsyncEnumerable<T> Paginate<T, TNext>(
Paging<T, TNext> firstPage, Paging<T, TNext> firstPage,
Func<TNext, Paging<T, TNext>> mapper, Func<TNext, Paging<T, TNext>> mapper,

View File

@ -4,10 +4,42 @@ namespace SpotifyAPI.Web
{ {
public interface IPersonalizationClient public interface IPersonalizationClient
{ {
/// <summary>
/// Get the current users top tracks based on calculated affinity.
/// </summary>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-users-top-artists-and-tracks
/// </remarks>
/// <returns></returns>
Task<Paging<FullTrack>> GetTopTracks(); Task<Paging<FullTrack>> GetTopTracks();
/// <summary>
/// Get the current users top tracks based on calculated affinity.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-users-top-artists-and-tracks
/// </remarks>
/// <returns></returns>
Task<Paging<FullTrack>> GetTopTracks(PersonalizationTopRequest request); Task<Paging<FullTrack>> GetTopTracks(PersonalizationTopRequest request);
/// <summary>
/// Get the current users top artists based on calculated affinity.
/// </summary>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-users-top-artists-and-tracks
/// </remarks>
/// <returns></returns>
Task<Paging<FullArtist>> GetTopArtists(); Task<Paging<FullArtist>> GetTopArtists();
/// <summary>
/// Get the current users top artists based on calculated affinity.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-users-top-artists-and-tracks
/// </remarks>
/// <returns></returns>
Task<Paging<FullArtist>> GetTopArtists(PersonalizationTopRequest request); Task<Paging<FullArtist>> GetTopArtists(PersonalizationTopRequest request);
} }
} }

View File

@ -5,16 +5,72 @@ namespace SpotifyAPI.Web
{ {
public interface IPlayerClient public interface IPlayerClient
{ {
/// <summary>
/// Skips to next track in the users queue.
/// </summary>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-skip-users-playback-to-next-track
/// </remarks>
/// <returns></returns>
Task<bool> SkipNext(); Task<bool> SkipNext();
/// <summary>
/// Skips to next track in the users queue.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-skip-users-playback-to-next-track
/// </remarks>
/// <returns></returns>
Task<bool> SkipNext(PlayerSkipNextRequest request); Task<bool> SkipNext(PlayerSkipNextRequest request);
/// <summary>
/// Set the repeat mode for the users playback. Options are repeat-track, repeat-context, and off.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-set-repeat-mode-on-users-playback
/// </remarks>
/// <returns></returns>
Task<bool> SetRepeat(PlayerSetRepeatRequest request); Task<bool> SetRepeat(PlayerSetRepeatRequest request);
/// <summary>
/// Transfer playback to a new device and determine if it should start playing.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-transfer-a-users-playback
/// </remarks>
/// <returns></returns>
Task<bool> TransferPlayback(PlayerTransferPlaybackRequest request); Task<bool> TransferPlayback(PlayerTransferPlaybackRequest request);
/// <summary>
/// Get the object currently being played on the users Spotify account.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-the-users-currently-playing-track
/// </remarks>
/// <returns></returns>
Task<CurrentlyPlaying> GetCurrentlyPlaying(PlayerCurrentlyPlayingRequest request); Task<CurrentlyPlaying> GetCurrentlyPlaying(PlayerCurrentlyPlayingRequest request);
/// <summary>
/// Get information about the users current playback state, including track or episode, progress, and active device.
/// </summary>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-information-about-the-users-current-playback
/// </remarks>
/// <returns></returns>
Task<CurrentlyPlayingContext> GetCurrentPlayback(); Task<CurrentlyPlayingContext> GetCurrentPlayback();
/// <summary>
/// Get information about the users current playback state, including track or episode, progress, and active device.
/// </summary>
/// <param name="request">The request-model which contains required and optional parameters.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-information-about-the-users-current-playback
/// </remarks>
/// <returns></returns>
Task<CurrentlyPlayingContext> GetCurrentPlayback(PlayerCurrentPlaybackRequest request); Task<CurrentlyPlayingContext> GetCurrentPlayback(PlayerCurrentPlaybackRequest request);
Task<bool> SeekTo(PlayerSeekToRequest request); Task<bool> SeekTo(PlayerSeekToRequest request);

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using SpotifyAPI.Web.Http;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
@ -34,15 +35,17 @@ namespace SpotifyAPI.Web
ILibraryClient Library { get; } ILibraryClient Library { get; }
Task<List<T>> PaginateAll<T>(Paging<T> firstPage); IResponse? LastResponse { get; }
Task<List<T>> PaginateAll<T>(Paging<T> firstPage, IPaginator paginator);
Task<List<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage);
Task<List<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator);
Task<List<T>> PaginateAll<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper); Task<IList<T>> PaginateAll<T>(Paging<T> firstPage);
Task<List<T>> PaginateAll<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper, IPaginator paginator); Task<IList<T>> PaginateAll<T>(Paging<T> firstPage, IPaginator paginator);
Task<List<T>> PaginateAll<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper); Task<IList<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage);
Task<List<T>> PaginateAll<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper, IPaginator paginator); Task<IList<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator);
Task<IList<T>> PaginateAll<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper);
Task<IList<T>> PaginateAll<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper, IPaginator paginator);
Task<IList<T>> PaginateAll<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper);
Task<IList<T>> PaginateAll<T, TNext>(Func<Task<Paging<T, TNext>>> getFirstPage, Func<TNext, Paging<T, TNext>> mapper, IPaginator paginator);
#if NETSTANDARD2_1 #if NETSTANDARD2_1
IAsyncEnumerable<T> Paginate<T>(Paging<T> firstPage); IAsyncEnumerable<T> Paginate<T>(Paging<T> firstPage);

View File

@ -18,7 +18,7 @@ namespace SpotifyAPI.Web
return Task.FromResult(true); return Task.FromResult(true);
} }
public async Task<List<T>> PaginateAll<T>(Paging<T> firstPage, IAPIConnector connector) public async Task<IList<T>> PaginateAll<T>(Paging<T> firstPage, IAPIConnector connector)
{ {
Ensure.ArgumentNotNull(firstPage, nameof(firstPage)); Ensure.ArgumentNotNull(firstPage, nameof(firstPage));
Ensure.ArgumentNotNull(connector, nameof(connector)); Ensure.ArgumentNotNull(connector, nameof(connector));
@ -35,7 +35,7 @@ namespace SpotifyAPI.Web
return results; return results;
} }
public async Task<List<T>> PaginateAll<T, TNext>( public async Task<IList<T>> PaginateAll<T, TNext>(
Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper, IAPIConnector connector Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper, IAPIConnector connector
) )
{ {

View File

@ -29,6 +29,11 @@ namespace SpotifyAPI.Web
config.RetryHandler, config.RetryHandler,
config.HTTPLogger config.HTTPLogger
); );
_apiConnector.ResponseReceived += (sender, response) =>
{
LastResponse = response;
};
DefaultPaginator = config.DefaultPaginator; DefaultPaginator = config.DefaultPaginator;
UserProfile = new UserProfileClient(_apiConnector); UserProfile = new UserProfileClient(_apiConnector);
Browse = new BrowseClient(_apiConnector); Browse = new BrowseClient(_apiConnector);
@ -73,19 +78,21 @@ namespace SpotifyAPI.Web
public ILibraryClient Library { get; } public ILibraryClient Library { get; }
public Task<List<T>> PaginateAll<T>(Paging<T> firstPage) public IResponse? LastResponse { get; private set; }
public Task<IList<T>> PaginateAll<T>(Paging<T> firstPage)
{ {
return DefaultPaginator.PaginateAll(firstPage, _apiConnector); return DefaultPaginator.PaginateAll(firstPage, _apiConnector);
} }
public Task<List<T>> PaginateAll<T>(Paging<T> firstPage, IPaginator paginator) public Task<IList<T>> PaginateAll<T>(Paging<T> firstPage, IPaginator paginator)
{ {
Ensure.ArgumentNotNull(paginator, nameof(paginator)); Ensure.ArgumentNotNull(paginator, nameof(paginator));
return paginator.PaginateAll(firstPage, _apiConnector); return paginator.PaginateAll(firstPage, _apiConnector);
} }
public async Task<List<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage) public async Task<IList<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage)
{ {
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage)); Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
@ -94,7 +101,7 @@ namespace SpotifyAPI.Web
).ConfigureAwait(false); ).ConfigureAwait(false);
} }
public async Task<List<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator) public async Task<IList<T>> PaginateAll<T>(Func<Task<Paging<T>>> getFirstPage, IPaginator paginator)
{ {
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage)); Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
Ensure.ArgumentNotNull(paginator, nameof(paginator)); Ensure.ArgumentNotNull(paginator, nameof(paginator));
@ -104,7 +111,7 @@ namespace SpotifyAPI.Web
).ConfigureAwait(false); ).ConfigureAwait(false);
} }
public Task<List<T>> PaginateAll<T, TNext>( public Task<IList<T>> PaginateAll<T, TNext>(
Paging<T, TNext> firstPage, Paging<T, TNext> firstPage,
Func<TNext, Paging<T, TNext>> mapper Func<TNext, Paging<T, TNext>> mapper
) )
@ -112,7 +119,7 @@ namespace SpotifyAPI.Web
return DefaultPaginator.PaginateAll(firstPage, mapper, _apiConnector); return DefaultPaginator.PaginateAll(firstPage, mapper, _apiConnector);
} }
public async Task<List<T>> PaginateAll<T, TNext>( public async Task<IList<T>> PaginateAll<T, TNext>(
Func<Task<Paging<T, TNext>>> getFirstPage, Func<Task<Paging<T, TNext>>> getFirstPage,
Func<TNext, Paging<T, TNext>> mapper Func<TNext, Paging<T, TNext>> mapper
) )
@ -122,7 +129,7 @@ namespace SpotifyAPI.Web
return await DefaultPaginator.PaginateAll(await getFirstPage().ConfigureAwait(false), mapper, _apiConnector).ConfigureAwait(false); return await DefaultPaginator.PaginateAll(await getFirstPage().ConfigureAwait(false), mapper, _apiConnector).ConfigureAwait(false);
} }
public Task<List<T>> PaginateAll<T, TNext>( public Task<IList<T>> PaginateAll<T, TNext>(
Paging<T, TNext> firstPage, Paging<T, TNext> firstPage,
Func<TNext, Paging<T, TNext>> mapper, Func<TNext, Paging<T, TNext>> mapper,
IPaginator paginator) IPaginator paginator)
@ -132,7 +139,7 @@ namespace SpotifyAPI.Web
return paginator.PaginateAll(firstPage, mapper, _apiConnector); return paginator.PaginateAll(firstPage, mapper, _apiConnector);
} }
public async Task<List<T>> PaginateAll<T, TNext>( public async Task<IList<T>> PaginateAll<T, TNext>(
Func<Task<Paging<T, TNext>>> getFirstPage, Func<Task<Paging<T, TNext>>> getFirstPage,
Func<TNext, Paging<T, TNext>> mapper, Func<TNext, Paging<T, TNext>> mapper,
IPaginator paginator IPaginator paginator

View File

@ -15,6 +15,8 @@ namespace SpotifyAPI.Web.Http
private readonly IRetryHandler? _retryHandler; private readonly IRetryHandler? _retryHandler;
private readonly IHTTPLogger? _httpLogger; private readonly IHTTPLogger? _httpLogger;
public event EventHandler<IResponse>? ResponseReceived;
public APIConnector(Uri baseAddress, IAuthenticator authenticator) : public APIConnector(Uri baseAddress, IAuthenticator authenticator) :
this(baseAddress, authenticator, new NewtonsoftJSONSerializer(), new NetHttpClient(), null, null) this(baseAddress, authenticator, new NewtonsoftJSONSerializer(), new NetHttpClient(), null, null)
{ } { }
@ -198,6 +200,7 @@ namespace SpotifyAPI.Web.Http
_httpLogger?.OnRequest(request); _httpLogger?.OnRequest(request);
IResponse response = await _httpClient.DoRequest(request).ConfigureAwait(false); IResponse response = await _httpClient.DoRequest(request).ConfigureAwait(false);
_httpLogger?.OnResponse(response); _httpLogger?.OnResponse(response);
ResponseReceived?.Invoke(this, response);
if (_retryHandler != null) if (_retryHandler != null)
{ {
response = await _retryHandler.HandleRetry(request, response, async (newRequest) => response = await _retryHandler.HandleRetry(request, response, async (newRequest) =>
@ -205,6 +208,7 @@ namespace SpotifyAPI.Web.Http
await ApplyAuthenticator(request).ConfigureAwait(false); await ApplyAuthenticator(request).ConfigureAwait(false);
var newResponse = await _httpClient.DoRequest(request).ConfigureAwait(false); var newResponse = await _httpClient.DoRequest(request).ConfigureAwait(false);
_httpLogger?.OnResponse(newResponse); _httpLogger?.OnResponse(newResponse);
ResponseReceived?.Invoke(this, response);
return newResponse; return newResponse;
}).ConfigureAwait(false); }).ConfigureAwait(false);
} }

View File

@ -14,6 +14,8 @@ namespace SpotifyAPI.Web.Http
// IHTTPClient HTTPClient { get; } // IHTTPClient HTTPClient { get; }
event EventHandler<IResponse>? ResponseReceived;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<T> Get<T>(Uri uri); Task<T> Get<T>(Uri uri);
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]

View File

@ -5,6 +5,12 @@ namespace SpotifyAPI.Web
/// </summary> /// </summary>
public class AuthorizationCodeRefreshRequest public class AuthorizationCodeRefreshRequest
{ {
/// <summary>
///
/// </summary>
/// <param name="clientId">The Client ID of your Spotify Application (See Spotify Dev Dashboard)</param>
/// <param name="clientSecret">The Client Secret of your Spotify Application (See Spotify Dev Dashboard)</param>
/// <param name="refreshToken">The refresh token received from an earlier authorization code grant</param>
public AuthorizationCodeRefreshRequest(string clientId, string clientSecret, string refreshToken) public AuthorizationCodeRefreshRequest(string clientId, string clientSecret, string refreshToken)
{ {
Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId)); Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId));
@ -16,8 +22,22 @@ namespace SpotifyAPI.Web
RefreshToken = refreshToken; RefreshToken = refreshToken;
} }
/// <summary>
/// The refresh token received from an earlier authorization code grant
/// </summary>
/// <value></value>
public string RefreshToken { get; } public string RefreshToken { get; }
/// <summary>
/// The Client ID of your Spotify Application (See Spotify Dev Dashboard)
/// </summary>
/// <value></value>
public string ClientId { get; } public string ClientId { get; }
/// <summary>
/// The Client Secret of your Spotify Application (See Spotify Dev Dashboard)
/// </summary>
/// <value></value>
public string ClientSecret { get; } public string ClientSecret { get; }
} }
} }

View File

@ -6,6 +6,13 @@ namespace SpotifyAPI.Web
/// </summary> /// </summary>
public class AuthorizationCodeTokenRequest public class AuthorizationCodeTokenRequest
{ {
/// <summary>
///
/// </summary>
/// <param name="clientId">The Client ID of your Spotify Application (See Spotify Dev Dashboard).</param>
/// <param name="clientSecret">The Client Secret of your Spotify Application (See Spotify Dev Dashboard).</param>
/// <param name="code">The code received from the spotify response.</param>
/// <param name="redirectUri">The redirectUri which was used to initiate the authentication.</param>
public AuthorizationCodeTokenRequest(string clientId, string clientSecret, string code, Uri redirectUri) public AuthorizationCodeTokenRequest(string clientId, string clientSecret, string code, Uri redirectUri)
{ {
Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId)); Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId));
@ -19,9 +26,28 @@ namespace SpotifyAPI.Web
RedirectUri = redirectUri; RedirectUri = redirectUri;
} }
/// <summary>
/// The Client ID of your Spotify Application (See Spotify Dev Dashboard).
/// </summary>
/// <value></value>
public string ClientId { get; } public string ClientId { get; }
/// <summary>
/// The Client Secret of your Spotify Application (See Spotify Dev Dashboard).
/// </summary>
/// <value></value>
public string ClientSecret { get; } public string ClientSecret { get; }
/// <summary>
/// The code received from the spotify response.
/// </summary>
/// <value></value>
public string Code { get; } public string Code { get; }
/// <summary>
/// The redirectUri which was used to initiate the authentication.
/// </summary>
/// <value></value>
public Uri RedirectUri { get; } public Uri RedirectUri { get; }
} }
} }

View File

@ -5,6 +5,11 @@ namespace SpotifyAPI.Web
/// </summary> /// </summary>
public class ClientCredentialsRequest public class ClientCredentialsRequest
{ {
/// <summary>
///
/// </summary>
/// <param name="clientId">The Client ID of your Spotify Application (See Spotify Dev Dashboard)</param>
/// <param name="clientSecret">The Client Secret of your Spotify Application (See Spotify Dev Dashboard)</param>
public ClientCredentialsRequest(string clientId, string clientSecret) public ClientCredentialsRequest(string clientId, string clientSecret)
{ {
Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId)); Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId));
@ -13,7 +18,17 @@ namespace SpotifyAPI.Web
ClientId = clientId; ClientId = clientId;
ClientSecret = clientSecret; ClientSecret = clientSecret;
} }
/// <summary>
/// The Client ID of your Spotify Application (See Spotify Dev Dashboard)
/// </summary>
/// <value></value>
public string ClientId { get; } public string ClientId { get; }
/// <summary>
/// The Client Secret of your Spotify Application (See Spotify Dev Dashboard)
/// </summary>
/// <value></value>
public string ClientSecret { get; } public string ClientSecret { get; }
} }
} }

View File

@ -2,12 +2,26 @@ namespace SpotifyAPI.Web
{ {
public class PersonalizationTopRequest : RequestParams public class PersonalizationTopRequest : RequestParams
{ {
/// <summary>
/// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50. For example: limit=2
/// </summary>
/// <value></value>
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
/// <summary>
/// The index of the first entity to return. Default: 0 (i.e., the first track). Use with limit to get the next set of entities.
/// </summary>
/// <value></value>
[QueryParam("offset")] [QueryParam("offset")]
public int? Offset { get; set; } public int? Offset { get; set; }
/// <summary>
/// Over what time frame the affinities are computed. Valid values: long_term
/// (calculated from several years of data and including all new data as it becomes available),
/// medium_term (approximately last 6 months), short_term (approximately last 4 weeks). Default: medium_term
/// </summary>
/// <value></value>
[QueryParam("time_range")] [QueryParam("time_range")]
public TimeRange? TimeRangeParam { get; set; } public TimeRange? TimeRangeParam { get; set; }

View File

@ -4,6 +4,17 @@ namespace SpotifyAPI.Web
{ {
public class PlayerCurrentPlaybackRequest : RequestParams public class PlayerCurrentPlaybackRequest : RequestParams
{ {
/// <summary>
///
/// </summary>
/// <param name="types">
/// A comma-separated list of item types that your client supports besides the default track type.
/// Valid types are: track and episode. An unsupported type in the response is expected to be represented
/// as null value in the item field. Note: This parameter was introduced to allow existing clients to
/// maintain their current behaviour and might be deprecated in the future. In addition to providing
/// this parameter, make sure that your client properly handles cases of new types in the future by
/// checking against the currently_playing_type field.
/// </param>
public PlayerCurrentPlaybackRequest(AdditionalTypes types = AdditionalTypes.All) public PlayerCurrentPlaybackRequest(AdditionalTypes types = AdditionalTypes.All)
{ {
Ensure.ArgumentNotNull(types, nameof(types)); Ensure.ArgumentNotNull(types, nameof(types));

View File

@ -4,20 +4,38 @@ namespace SpotifyAPI.Web
{ {
public class PlayerCurrentlyPlayingRequest : RequestParams public class PlayerCurrentlyPlayingRequest : RequestParams
{ {
public PlayerCurrentlyPlayingRequest(string market, AdditionalTypes types = AdditionalTypes.All)
/// <summary>
/// A comma-separated list of item types that your client supports besides the default track type.
/// Valid types are: track and episode. An unsupported type in the response is expected to be represented
/// as null value in the item field. Note: This parameter was introduced to allow existing clients to
/// maintain their current behaviour and might be deprecated in the future. In addition to providing
/// this parameter, make sure that your client properly handles cases of new types in the future by
/// checking against the currently_playing_type field. Defaults to AdditionalTypes.All
/// </summary>
/// <param name="types"></param>
public PlayerCurrentlyPlayingRequest(AdditionalTypes types = AdditionalTypes.All)
{ {
Ensure.ArgumentNotNullOrEmptyString(market, nameof(market));
Ensure.ArgumentNotNull(types, nameof(types)); Ensure.ArgumentNotNull(types, nameof(types));
Market = market;
AdditionalTypesParam = types; AdditionalTypesParam = types;
} }
/// <summary>
/// An ISO 3166-1 alpha-2 country code or the string from_token.
/// Provide this parameter if you want to apply Track Relinking.
/// </summary>
/// <value></value>
[QueryParam("market")] [QueryParam("market")]
public string Market { get; } public string? Market { get; set; }
/// <summary> /// <summary>
/// This is set to `"track", "episode"` by default. /// A comma-separated list of item types that your client supports besides the default track type.
/// Valid types are: track and episode. An unsupported type in the response is expected to be represented
/// as null value in the item field. Note: This parameter was introduced to allow existing clients to
/// maintain their current behaviour and might be deprecated in the future. In addition to providing
/// this parameter, make sure that your client properly handles cases of new types in the future by
/// checking against the currently_playing_type field. Defaults to AdditionalTypes.All
/// </summary> /// </summary>
/// <value></value> /// <value></value>
[QueryParam("additional_types")] [QueryParam("additional_types")]

View File

@ -2,6 +2,11 @@ namespace SpotifyAPI.Web
{ {
public class PlayerSetRepeatRequest : RequestParams public class PlayerSetRepeatRequest : RequestParams
{ {
/// <summary></summary>
/// <param name="state">
/// track, context or off. track will repeat the current track. context will repeat the current context.
/// off will turn repeat off.
/// </param>
public PlayerSetRepeatRequest(State state) public PlayerSetRepeatRequest(State state)
{ {
Ensure.ArgumentNotNull(state, nameof(state)); Ensure.ArgumentNotNull(state, nameof(state));
@ -9,9 +14,18 @@ namespace SpotifyAPI.Web
StateParam = state; StateParam = state;
} }
/// <summary>
/// The id of the device this command is targeting. If not supplied, the users currently active device is the target.
/// </summary>
/// <value></value>
[QueryParam("device_id")] [QueryParam("device_id")]
public string? DeviceId { get; set; } public string? DeviceId { get; set; }
/// <summary>
/// track, context or off. track will repeat the current track. context will repeat the current context.
/// off will turn repeat off.
/// </summary>
/// <value></value>
[QueryParam("state")] [QueryParam("state")]
public State StateParam { get; } public State StateParam { get; }

View File

@ -2,6 +2,10 @@ namespace SpotifyAPI.Web
{ {
public class PlayerSkipNextRequest : RequestParams public class PlayerSkipNextRequest : RequestParams
{ {
/// <summary>
/// The id of the device this command is targeting. If not supplied, the users currently active device is the target.
/// </summary>
/// <value></value>
[QueryParam("device_id")] [QueryParam("device_id")]
public string? DeviceId { get; set; } public string? DeviceId { get; set; }
} }

View File

@ -4,6 +4,15 @@ namespace SpotifyAPI.Web
{ {
public class PlayerTransferPlaybackRequest : RequestParams public class PlayerTransferPlaybackRequest : RequestParams
{ {
/// <summary>
///
/// </summary>
/// <param name="deviceIds">
/// A JSON array containing the ID of the device on which playback should be started/transferred.
/// For example:{device_ids:["74ASZWbe4lXaubB36ztrGX"]}
/// Note: Although an array is accepted, only a single device_id is currently supported.
/// Supplying more than one will return 400 Bad Request
/// </param>
public PlayerTransferPlaybackRequest(IList<string> deviceIds) public PlayerTransferPlaybackRequest(IList<string> deviceIds)
{ {
Ensure.ArgumentNotNullOrEmptyList(deviceIds, nameof(deviceIds)); Ensure.ArgumentNotNullOrEmptyList(deviceIds, nameof(deviceIds));
@ -11,9 +20,20 @@ namespace SpotifyAPI.Web
DeviceIds = deviceIds; DeviceIds = deviceIds;
} }
/// <summary>
/// A JSON array containing the ID of the device on which playback should be started/transferred.
/// For example:{device_ids:["74ASZWbe4lXaubB36ztrGX"]}
/// Note: Although an array is accepted, only a single device_id is currently supported.
/// Supplying more than one will return 400 Bad Request
/// </summary>
/// <value></value>
[BodyParam("device_ids")] [BodyParam("device_ids")]
public IList<string> DeviceIds { get; } public IList<string> DeviceIds { get; }
/// <summary>
/// true: ensure playback happens on new device. false or not provided: keep the current playback state.
/// </summary>
/// <value></value>
[BodyParam("play")] [BodyParam("play")]
public bool? Play { get; set; } public bool? Play { get; set; }
} }