diff --git a/SpotifyAPI.Web/Clients/Interfaces/IPlaylistsClient.cs b/SpotifyAPI.Web/Clients/Interfaces/IPlaylistsClient.cs index e8cac642..47a024d7 100644 --- a/SpotifyAPI.Web/Clients/Interfaces/IPlaylistsClient.cs +++ b/SpotifyAPI.Web/Clients/Interfaces/IPlaylistsClient.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading.Tasks; namespace SpotifyAPI.Web @@ -12,5 +13,9 @@ namespace SpotifyAPI.Web Task>> GetItems(string playlistId, PlaylistGetItemsRequest request); Task Create(string userId, PlaylistCreateRequest request); + + Task UploadCover(string playlistId, string base64JpgData); + + Task> GetCovers(string playlistId); } } diff --git a/SpotifyAPI.Web/Clients/PlaylistsClient.cs b/SpotifyAPI.Web/Clients/PlaylistsClient.cs index 827adab5..18601226 100644 --- a/SpotifyAPI.Web/Clients/PlaylistsClient.cs +++ b/SpotifyAPI.Web/Clients/PlaylistsClient.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Net; using System.Threading.Tasks; using SpotifyAPI.Web.Http; using URLs = SpotifyAPI.Web.SpotifyUrls; @@ -46,5 +48,21 @@ namespace SpotifyAPI.Web return API.Post(URLs.UserPlaylists(userId), null, request.BuildBodyParams()); } + + public async Task UploadCover(string playlistId, string base64Jpg) + { + Ensure.ArgumentNotNullOrEmptyString(playlistId, nameof(playlistId)); + Ensure.ArgumentNotNullOrEmptyString(base64Jpg, nameof(base64Jpg)); + + var response = await API.PutRaw(URLs.PlaylistImages(playlistId), null, base64Jpg); + return response == HttpStatusCode.Accepted; + } + + public Task> GetCovers(string playlistId) + { + Ensure.ArgumentNotNullOrEmptyString(playlistId, nameof(playlistId)); + + return API.Get>(URLs.PlaylistImages(playlistId)); + } } } diff --git a/SpotifyAPI.Web/Http/APIConnector.cs b/SpotifyAPI.Web/Http/APIConnector.cs index bf0bb114..7c514412 100644 --- a/SpotifyAPI.Web/Http/APIConnector.cs +++ b/SpotifyAPI.Web/Http/APIConnector.cs @@ -108,22 +108,30 @@ namespace SpotifyAPI.Web.Http return SendAPIRequest(uri, HttpMethod.Put, parameters, body); } + public async Task PutRaw(Uri uri, IDictionary parameters, object body) + { + Ensure.ArgumentNotNull(uri, nameof(uri)); + + var response = await SendRawRequest(uri, HttpMethod.Put, parameters, body); + return response.StatusCode; + } + public void SetRequestTimeout(TimeSpan timeout) { _httpClient.SetRequestTimeout(timeout); } - public async Task SendAPIRequest( + private IRequest CreateRequest( Uri uri, HttpMethod method, - IDictionary parameters = null, - object body = null + IDictionary parameters, + object body ) { Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(method, nameof(method)); - var request = new Request + return new Request { BaseAddress = _baseAddress, Parameters = parameters, @@ -131,8 +139,17 @@ namespace SpotifyAPI.Web.Http Method = method, Body = body }; + } + private async Task> SendSerializedRequest(IRequest request) + { _jsonSerializer.SerializeRequest(request); + var response = await SendRequest(request); + return _jsonSerializer.DeserializeResponse(response); + } + + private async Task SendRequest(IRequest request) + { await _authenticator.Apply(request).ConfigureAwait(false); IResponse response = await _httpClient.DoRequest(request).ConfigureAwait(false); if (_retryHandler != null) @@ -144,8 +161,29 @@ namespace SpotifyAPI.Web.Http }); } ProcessErrors(response); + return response; + } - IAPIResponse apiResponse = _jsonSerializer.DeserializeResponse(response); + public Task SendRawRequest( + Uri uri, + HttpMethod method, + IDictionary parameters = null, + object body = null + ) + { + var request = CreateRequest(uri, method, parameters, body); + return SendRequest(request); + } + + public async Task SendAPIRequest( + Uri uri, + HttpMethod method, + IDictionary parameters = null, + object body = null + ) + { + var request = CreateRequest(uri, method, parameters, body); + IAPIResponse apiResponse = await SendSerializedRequest(request); return apiResponse.Body; } diff --git a/SpotifyAPI.Web/Http/Interfaces/IAPIConnector.cs b/SpotifyAPI.Web/Http/Interfaces/IAPIConnector.cs index 33f9c930..2aa650b6 100644 --- a/SpotifyAPI.Web/Http/Interfaces/IAPIConnector.cs +++ b/SpotifyAPI.Web/Http/Interfaces/IAPIConnector.cs @@ -1,3 +1,4 @@ +using System.Net; using System; using System.Collections.Generic; using System.Net.Http; @@ -23,6 +24,7 @@ namespace SpotifyAPI.Web.Http Task Put(Uri uri); Task Put(Uri uri, IDictionary parameters); Task Put(Uri uri, IDictionary parameters, object body); + Task PutRaw(Uri uri, IDictionary parameters, object body); Task Delete(Uri uri); Task Delete(Uri uri, IDictionary parameters); diff --git a/SpotifyAPI.Web/Http/NewtonsoftJSONSerializer.cs b/SpotifyAPI.Web/Http/NewtonsoftJSONSerializer.cs index e19aeb7e..2d7de198 100644 --- a/SpotifyAPI.Web/Http/NewtonsoftJSONSerializer.cs +++ b/SpotifyAPI.Web/Http/NewtonsoftJSONSerializer.cs @@ -27,7 +27,7 @@ namespace SpotifyAPI.Web.Http { Ensure.ArgumentNotNull(response, nameof(response)); - if (response.ContentType?.Equals("application/json", StringComparison.Ordinal) is true) + if (response.ContentType?.Equals("application/json", StringComparison.Ordinal) is true || response.ContentType == null) { var body = JsonConvert.DeserializeObject(response.Body as string, _serializerSettings); return new APIResponse(response, body); diff --git a/SpotifyAPI.Web/SpotifyUrls.cs b/SpotifyAPI.Web/SpotifyUrls.cs index 0a3be900..bf14f82e 100644 --- a/SpotifyAPI.Web/SpotifyUrls.cs +++ b/SpotifyAPI.Web/SpotifyUrls.cs @@ -35,6 +35,8 @@ namespace SpotifyAPI.Web public static Uri UserPlaylists(string userId) => EUri($"users/{userId}/playlists"); + public static Uri PlaylistImages(string playlistId) => EUri($"playlists/{playlistId}/images"); + private static Uri EUri(FormattableString path) => new Uri(path.ToString(_provider), UriKind.Relative); } }