Added Episodes Client and restructured config #451

This commit is contained in:
Jonas Dellinger 2020-05-11 18:43:52 +02:00
parent 0cd3027c28
commit cc42c3971f
9 changed files with 153 additions and 47 deletions

View File

@ -0,0 +1,33 @@
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;
using URLs = SpotifyAPI.Web.SpotifyUrls;
namespace SpotifyAPI.Web
{
public class EpisodesClient : APIClient, IEpisodesClient
{
public EpisodesClient(IAPIConnector apiConnector) : base(apiConnector) { }
public Task<FullEpisode> Get(string episodeId)
{
Ensure.ArgumentNotNullOrEmptyString(episodeId, nameof(episodeId));
return API.Get<FullEpisode>(URLs.Episode(episodeId));
}
public Task<FullEpisode> Get(string episodeId, EpisodeRequest request)
{
Ensure.ArgumentNotNullOrEmptyString(episodeId, nameof(episodeId));
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<FullEpisode>(URLs.Episode(episodeId), request.BuildQueryParams());
}
public Task<EpisodesResponse> GetSeveral(EpisodesRequest request)
{
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<EpisodesResponse>(URLs.Episodes(), request.BuildQueryParams());
}
}
}

View File

@ -0,0 +1,15 @@
using System.Threading.Tasks;
namespace SpotifyAPI.Web
{
public interface IEpisodesClient
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<FullEpisode> Get(string episodeId);
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<FullEpisode> Get(string episodeId, EpisodeRequest request);
Task<EpisodesResponse> GetSeveral(EpisodesRequest request);
}
}

View File

@ -30,6 +30,8 @@ namespace SpotifyAPI.Web
IPersonalizationClient Personalization { get; }
IEpisodesClient Episodes { get; }
Task<List<T>> Paginate<T>(Paging<T> firstPage);
Task<List<T>> Paginate<T, TNext>(Paging<T, TNext> firstPage, Func<TNext, Paging<T, TNext>> mapper);
Task<List<T>> Paginate<T>(Func<Task<Paging<T>>> getFirstPage);

View File

@ -18,7 +18,7 @@ namespace SpotifyAPI.Web
Ensure.ArgumentNotNull(config, nameof(config));
_apiConnector = config.CreateAPIConnector();
DefaultPaginator = config.Paginator;
DefaultPaginator = config.DefaultPaginator;
UserProfile = new UserProfileClient(_apiConnector);
Browse = new BrowseClient(_apiConnector);
Shows = new ShowsClient(_apiConnector);
@ -30,6 +30,7 @@ namespace SpotifyAPI.Web
Albums = new AlbumsClient(_apiConnector);
Artists = new ArtistsClient(_apiConnector);
Personalization = new PersonalizationClient(_apiConnector);
Episodes = new EpisodesClient(_apiConnector);
}
public IPaginator DefaultPaginator { get; }
@ -56,6 +57,8 @@ namespace SpotifyAPI.Web
public IPersonalizationClient Personalization { get; }
public IEpisodesClient Episodes { get; }
public Task<List<T>> Paginate<T>(Paging<T> firstPage)
{
return DefaultPaginator.Paginate(firstPage, _apiConnector);

View File

@ -5,19 +5,16 @@ namespace SpotifyAPI.Web
{
public class SpotifyClientConfig
{
public Uri BaseAddress { get; }
public IAuthenticator Authenticator { get; }
public IJSONSerializer JSONSerializer { get; }
public IHTTPClient HTTPClient { get; }
public IHTTPLogger HTTPLogger { get; }
public IPaginator Paginator { get; set; }
public IRetryHandler RetryHandler { get; }
public Uri BaseAddress { get; private set; }
public IAuthenticator Authenticator { get; private set; }
public IJSONSerializer JSONSerializer { get; private set; }
public IHTTPClient HTTPClient { get; private set; }
public IHTTPLogger HTTPLogger { get; private set; }
public IRetryHandler RetryHandler { get; private set; }
public IPaginator DefaultPaginator { get; private set; }
/// <summary>
/// This config spefies the internal parts of the SpotifyClient.
/// In apps where multiple different access tokens are used, one should create a default config and then use
/// <see cref="WithToken" /> or <see cref="WithAuthenticator" /> to specify the auth details.
/// </summary>
/// <param name="baseAddress"></param>
/// <param name="authenticator"></param>
@ -42,77 +39,92 @@ namespace SpotifyAPI.Web
HTTPClient = httpClient;
RetryHandler = retryHandler;
HTTPLogger = httpLogger;
Paginator = paginator;
DefaultPaginator = paginator;
}
internal IAPIConnector CreateAPIConnector()
{
Ensure.ArgumentNotNull(BaseAddress, nameof(BaseAddress));
Ensure.ArgumentNotNull(Authenticator, nameof(Authenticator));
Ensure.ArgumentNotNull(JSONSerializer, nameof(JSONSerializer));
Ensure.ArgumentNotNull(HTTPClient, nameof(HTTPClient));
return new APIConnector(BaseAddress, Authenticator, JSONSerializer, HTTPClient, RetryHandler, HTTPLogger);
return new APIConnector(
BaseAddress,
Authenticator,
JSONSerializer,
HTTPClient,
RetryHandler,
HTTPLogger
);
}
public SpotifyClientConfig WithToken(string token, string tokenType = "Bearer")
public void AddToken(string token, string tokenType = "Bearer")
{
Ensure.ArgumentNotNull(token, nameof(token));
return WithAuthenticator(new TokenHeaderAuthenticator(token, tokenType));
Authenticator = new TokenHeaderAuthenticator(token, tokenType);
}
public SpotifyClientConfig WithRetryHandler(IRetryHandler retryHandler)
public void AddRetryHandler(IRetryHandler retryHandler)
{
return new SpotifyClientConfig(
BaseAddress, Authenticator, JSONSerializer, HTTPClient, retryHandler, HTTPLogger, Paginator);
RetryHandler = retryHandler;
}
public SpotifyClientConfig WithAuthenticator(IAuthenticator authenticator)
public void AddAuthenticator(IAuthenticator authenticator)
{
return new SpotifyClientConfig(
BaseAddress, authenticator, JSONSerializer, HTTPClient, RetryHandler, HTTPLogger, Paginator);
Ensure.ArgumentNotNull(authenticator, nameof(authenticator));
Authenticator = authenticator;
}
public SpotifyClientConfig WithHTTPLogger(IHTTPLogger httpLogger)
public void AddHTTPLogger(IHTTPLogger httpLogger)
{
return new SpotifyClientConfig(
BaseAddress, Authenticator, JSONSerializer, HTTPClient, RetryHandler, httpLogger, Paginator);
HTTPLogger = httpLogger;
}
public SpotifyClientConfig WithPaginator(IPaginator paginator)
public void AddHTTPClient(IHTTPClient httpClient)
{
return new SpotifyClientConfig(
BaseAddress, Authenticator, JSONSerializer, HTTPClient, RetryHandler, HTTPLogger, paginator);
Ensure.ArgumentNotNull(httpClient, nameof(httpClient));
HTTPClient = httpClient;
}
public void AddJSONSerializer(IJSONSerializer jsonSerializer)
{
Ensure.ArgumentNotNull(jsonSerializer, nameof(jsonSerializer));
JSONSerializer = jsonSerializer;
}
public void AddDefaultPaginator(IPaginator paginator)
{
DefaultPaginator = paginator;
}
public static SpotifyClientConfig CreateDefault(string token, string tokenType = "Bearer")
{
Ensure.ArgumentNotNull(token, nameof(token));
return CreateDefault(new TokenHeaderAuthenticator(token, tokenType));
return CreateDefault(options =>
{
options.AddToken(token, tokenType);
});
}
/// <summary>
/// Creates a default configuration, which is not useable without calling <see cref="WithToken" /> or
/// <see cref="WithAuthenticator" />
/// </summary>
public static SpotifyClientConfig CreateDefault()
public static SpotifyClientConfig CreateDefault(Action<SpotifyClientConfig> optionsCallback)
{
return CreateDefault(null);
}
Ensure.ArgumentNotNull(optionsCallback, nameof(optionsCallback));
public static SpotifyClientConfig CreateDefault(IAuthenticator authenticator)
{
return new SpotifyClientConfig(
var config = new SpotifyClientConfig(
SpotifyUrls.APIV1,
authenticator,
null,
new NewtonsoftJSONSerializer(),
new NetHttpClient(),
null,
null,
new SimplePaginator()
);
optionsCallback(config);
if (config.Authenticator == null)
{
throw new NullReferenceException("The authenticator was not set after the options callback was run. Please specify a token with AddToken or AddAuthenticator");
}
return config;
}
}
}

View File

@ -0,0 +1,8 @@
namespace SpotifyAPI.Web
{
public class EpisodeRequest : RequestParams
{
[QueryParam("market")]
public string Market { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
namespace SpotifyAPI.Web
{
public class EpisodesRequest : RequestParams
{
public EpisodesRequest(IList<string> ids)
{
Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids));
Ids = ids;
}
[QueryParam("ids")]
public IList<string> Ids { get; set; }
[QueryParam("market")]
public string Market { get; set; }
}
}

View File

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace SpotifyAPI.Web
{
public class EpisodesResponse
{
public List<FullEpisode> Episodes { get; set; }
}
}

View File

@ -105,6 +105,10 @@ namespace SpotifyAPI.Web
public static Uri PersonalizationTop(string type) => EUri($"me/top/{type}");
public static Uri Episode(string episodeId) => EUri($"episodes/{episodeId}");
public static Uri Episodes() => EUri($"episodes");
private static Uri EUri(FormattableString path) => new Uri(path.ToString(_provider), UriKind.Relative);
}
}