From a6c3d33abc34390bd4463efe08f3c01d0dc90354 Mon Sep 17 00:00:00 2001 From: Jimmy Appelt Date: Fri, 6 Nov 2015 19:21:30 +0100 Subject: [PATCH] Added Async Methods for Playlists/Profiles/Tracks --- SpotifyAPI/Web/SpotifyWebAPI.cs | 296 ++++++++++++++++++++++++++++---- 1 file changed, 262 insertions(+), 34 deletions(-) diff --git a/SpotifyAPI/Web/SpotifyWebAPI.cs b/SpotifyAPI/Web/SpotifyWebAPI.cs index a327ce2a..c39b1771 100644 --- a/SpotifyAPI/Web/SpotifyWebAPI.cs +++ b/SpotifyAPI/Web/SpotifyWebAPI.cs @@ -951,11 +951,22 @@ namespace SpotifyAPI.Web { if (!UseAuth) throw new InvalidOperationException("Auth is required for GetUserPlaylists"); - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - return DownloadData>(builder.ToString()); + return DownloadData>(_builder.GetUserPlaylists(userId, limit, offset)); + } + + /// + /// Get a list of the playlists owned or followed by a Spotify user asynchronously. + /// + /// The user's Spotify user ID. + /// The maximum number of playlists to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first playlist to return. Default: 0 (the first object) + /// + /// AUTH NEEDED + public Task> GetUserPlaylistsAsync(String userId, int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetUserPlaylists"); + return DownloadDataAsync>(_builder.GetUserPlaylists(userId, limit, offset)); } /// @@ -974,11 +985,26 @@ namespace SpotifyAPI.Web { if (!UseAuth) throw new InvalidOperationException("Auth is required for GetPlaylist"); - StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists/" + playlistId); - builder.Append("?fields=" + fields); - if (!String.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return DownloadData(builder.ToString()); + return DownloadData(_builder.GetPlaylist(userId, playlistId, fields, market)); + } + + /// + /// Get a playlist owned by a Spotify user asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// + /// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are + /// returned. + /// + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + /// AUTH NEEDED + public Task GetPlaylistAsync(String userId, String playlistId, String fields = "", String market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPlaylist"); + return DownloadDataAsync(_builder.GetPlaylist(userId, playlistId, fields, market)); } /// @@ -999,14 +1025,28 @@ namespace SpotifyAPI.Web { if (!UseAuth) throw new InvalidOperationException("Auth is required for GetPlaylistTracks"); - limit = Math.Max(limit, 100); - StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks"); - builder.Append("?fields=" + fields); - builder.Append("&limit=" + limit); - builder.Append("&offset=" + offset); - if (!String.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return DownloadData>(builder.ToString()); + return DownloadData>(_builder.GetPlaylistTracks(userId, playlistId, fields, limit, offset, market)); + } + + /// + /// Get full details of the tracks of a playlist owned by a Spotify user asyncronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// + /// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are + /// returned. + /// + /// The maximum number of tracks to return. Default: 100. Minimum: 1. Maximum: 100. + /// The index of the first object to return. Default: 0 (i.e., the first object) + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + /// AUTH NEEDED + public Task> GetPlaylistTracksAsync(String userId, String playlistId, String fields = "", int limit = 100, int offset = 0, String market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPlaylistTracks"); + return DownloadDataAsync>(_builder.GetPlaylistTracks(userId, playlistId, fields, limit, offset, market)); } /// @@ -1030,7 +1070,31 @@ namespace SpotifyAPI.Web {"name", playlistName}, {"public", isPublic} }; - return UploadData(APIBase + "/users/" + userId + "/playlists", body.ToString(Formatting.None)); + return UploadData(_builder.CreatePlaylist(userId, playlistName, isPublic), body.ToString(Formatting.None)); + } + + /// + /// Create a playlist for a Spotify user asynchronously. (The playlist will be empty until you add tracks.) + /// + /// The user's Spotify user ID. + /// + /// The name for the new playlist, for example "Your Coolest Playlist". This name does not need + /// to be unique. + /// + /// + /// default true. If true the playlist will be public, if false it will be private. To be able to + /// create private playlists, the user must have granted the playlist-modify-private scope. + /// + /// + /// AUTH NEEDED + public Task CreatePlaylistAsync(String userId, String playlistName, Boolean isPublic = true) + { + JObject body = new JObject + { + {"name", playlistName}, + {"public", isPublic} + }; + return UploadDataAsync(_builder.CreatePlaylist(userId, playlistName, isPublic), body.ToString(Formatting.None)); } /// @@ -1049,7 +1113,26 @@ namespace SpotifyAPI.Web body.Add("name", newName); if (newPublic != null) body.Add("public", newPublic); - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId, body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + return UploadData(_builder.UpdatePlaylist(userId, playlistId, newName, newPublic), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + } + + /// + /// Change a playlist’s name and public/private state asynchronously. (The user must, of course, own the playlist.) + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// The new name for the playlist, for example "My New Playlist Title". + /// If true the playlist will be public, if false it will be private. + /// + /// AUTH NEEDED + public Task UpdatePlaylistAsync(String userId, String playlistId, String newName = null, Boolean? newPublic = null) + { + JObject body = new JObject(); + if (newName != null) + body.Add("name", newName); + if (newPublic != null) + body.Add("public", newPublic); + return UploadDataAsync(_builder.UpdatePlaylist(userId, playlistId, newName, newPublic), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); } /// @@ -1067,7 +1150,25 @@ namespace SpotifyAPI.Web { {"uris", new JArray(uris.Take(100))} }; - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + return UploadData(_builder.ReplacePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + } + + /// + /// Replace all the tracks in a playlist asynchronously, overwriting its existing tracks. This powerful request can be useful for + /// replacing tracks, re-ordering existing tracks, or clearing the playlist. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// A list of Spotify track URIs to set. A maximum of 100 tracks can be set in one request. + /// + /// AUTH NEEDED + public Task ReplacePlaylistTracksAsync(String userId, String playlistId, List uris) + { + JObject body = new JObject + { + {"uris", new JArray(uris.Take(100))} + }; + return UploadDataAsync(_builder.ReplacePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); } /// @@ -1087,7 +1188,27 @@ namespace SpotifyAPI.Web { {"tracks", JArray.FromObject(uris.Take(100))} }; - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); + return UploadData(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); + } + + /// + /// Remove one or more tracks from a user’s playlist asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// + /// array of objects containing Spotify URI strings (and their position in the playlist). A maximum of + /// 100 objects can be sent at once. + /// + /// + /// AUTH NEEDED + public Task RemovePlaylistTracksAsync(String userId, String playlistId, List uris) + { + JObject body = new JObject + { + {"tracks", JArray.FromObject(uris.Take(100))} + }; + return UploadDataAsync(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); } /// @@ -1103,6 +1224,19 @@ namespace SpotifyAPI.Web return RemovePlaylistTracks(userId, playlistId, new List { uri }); } + /// + /// Remove one or more tracks from a user’s playlist asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// Spotify URI + /// + /// AUTH NEEDED + public Task RemovePlaylistTrackAsync(String userId, String playlistId, DeleteTrackUri uri) + { + return RemovePlaylistTracksAsync(userId, playlistId, new List { uri }); + } + /// /// Add one or more tracks to a user’s playlist. /// @@ -1118,9 +1252,27 @@ namespace SpotifyAPI.Web { {"uris", JArray.FromObject(uris.Take(100))} }; - if (position == null) - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None)) ?? new ErrorResponse(); - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks?position=" + position, body.ToString(Formatting.None)) ?? new ErrorResponse(); + return UploadData(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)) ?? new ErrorResponse(); + + } + + /// + /// Add one or more tracks to a user’s playlist asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// A list of Spotify track URIs to add + /// The position to insert the tracks, a zero-based index + /// + /// AUTH NEEDED + public Task AddPlaylistTracksAsync(String userId, String playlistId, List uris, int? position = null) + { + JObject body = new JObject + { + {"uris", JArray.FromObject(uris.Take(100))} + }; + return UploadDataAsync(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)) ?? new ErrorResponse(); + } /// @@ -1137,6 +1289,20 @@ namespace SpotifyAPI.Web return AddPlaylistTracks(userId, playlistId, new List { uri }, position); } + /// + /// Add one or more tracks to a user’s playlist asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// A Spotify Track URI + /// The position to insert the tracks, a zero-based index + /// + /// AUTH NEEDED + public Task AddPlaylistTrackAsync(String userId, String playlistId, String uri, int? position = null) + { + return AddPlaylistTracksAsync(userId, playlistId, new List { uri }, position); + } + /// /// Reorder a track or a group of tracks in a playlist. /// @@ -1158,7 +1324,29 @@ namespace SpotifyAPI.Web }; if (!String.IsNullOrEmpty(snapshotId)) body.Add("snapshot_id", snapshotId); - return UploadData(APIBase + "/users/" + userId + "/playlists/" + playlistId + "/tracks", body.ToString(Formatting.None), "PUT"); + return UploadData(_builder.ReorderPlaylist(userId, playlistId, rangeStart, insertBefore, rangeLength, snapshotId), body.ToString(Formatting.None), "PUT"); + } + + /// + /// Reorder a track or a group of tracks in a playlist asynchronously. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// The position of the first track to be reordered. + /// The position where the tracks should be inserted. + /// The amount of tracks to be reordered. Defaults to 1 if not set. + /// The playlist's snapshot ID against which you want to make the changes. + /// + /// AUTH NEEDED + public Task ReorderPlaylistAsync(String userId, String playlistId, int rangeStart, int insertBefore, int rangeLength = 1, String snapshotId = "") + { + JObject body = new JObject + { + {"range_start", rangeStart}, + {"range_length", rangeLength}, + {"insert_before", insertBefore} + }; + return UploadDataAsync(_builder.ReorderPlaylist(userId, playlistId, rangeStart, insertBefore, rangeLength, snapshotId), body.ToString(Formatting.None), "PUT"); } #endregion Playlists @@ -1174,7 +1362,19 @@ namespace SpotifyAPI.Web { if (!UseAuth) throw new InvalidOperationException("Auth is required for GetPrivateProfile"); - return DownloadData(APIBase + "/me"); + return DownloadData(_builder.GetPrivateProfile()); + } + + /// + /// Get detailed profile information about the current user asynchronously (including the current user’s username). + /// + /// + /// AUTH NEEDED + public Task GetPrivateProfileAsync() + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPrivateProfile"); + return DownloadDataAsync(_builder.GetPrivateProfile()); } /// @@ -1184,7 +1384,17 @@ namespace SpotifyAPI.Web /// public PublicProfile GetPublicProfile(String userId) { - return DownloadData(APIBase + "/users/" + userId); + return DownloadData(_builder.GetPublicProfile(userId)); + } + + /// + /// Get public profile information about a Spotify user asynchronously. + /// + /// The user's Spotify user ID. + /// + public Task GetPublicProfileAsync(String userId) + { + return DownloadDataAsync(_builder.GetPublicProfile(userId)); } #endregion Profiles @@ -1199,9 +1409,18 @@ namespace SpotifyAPI.Web /// public SeveralTracks GetSeveralTracks(List ids, String market = "") { - if (String.IsNullOrEmpty(market)) - return DownloadData(APIBase + "/tracks?ids=" + string.Join(",", ids.Take(50))); - return DownloadData(APIBase + "/tracks?market=" + market + "&ids=" + string.Join(",", ids.Take(50))); + return DownloadData(_builder.GetSeveralTracks(ids, market)); + } + + /// + /// Get Spotify catalog information for multiple tracks based on their Spotify IDs asynchronously. + /// + /// A list of the Spotify IDs for the tracks. Maximum: 50 IDs. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetSeveralTracksAsync(List ids, String market = "") + { + return DownloadDataAsync(_builder.GetSeveralTracks(ids, market)); } /// @@ -1212,9 +1431,18 @@ namespace SpotifyAPI.Web /// public FullTrack GetTrack(String id, String market = "") { - if (String.IsNullOrEmpty(market)) - return DownloadData(APIBase + "/tracks/" + id); - return DownloadData(APIBase + "/tracks/" + id + "?market=" + market); + return DownloadData(_builder.GetTrack(id, market)); + } + + /// + /// Get Spotify catalog information for a single track identified by its unique Spotify ID asynchronously. + /// + /// The Spotify ID for the track. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetTrackAsync(String id, String market = "") + { + return DownloadDataAsync(_builder.GetTrack(id, market)); } #endregion Tracks