From 3695866e55307be255672c58f316b97b9748bc3c Mon Sep 17 00:00:00 2001 From: Jonas Dellinger Date: Sat, 30 May 2020 23:56:57 +0200 Subject: [PATCH] Feature/shows and episodes (#437) Co-authored-by: shayo --- .../Properties/launchSettings.json | 6 +- .../Converters/PlaybackContextConverter.cs | 52 ++ .../Converters/PlaylistTrackConverter.cs | 46 ++ SpotifyAPI.Web/Enums/Scope.cs | 8 +- SpotifyAPI.Web/Enums/SearchType.cs | 12 +- SpotifyAPI.Web/Models/FullEpisode.cs | 63 ++ SpotifyAPI.Web/Models/FullTrack.cs | 4 +- SpotifyAPI.Web/Models/GeneralModels.cs | 12 +- SpotifyAPI.Web/Models/PlaybackContext.cs | 7 +- SpotifyAPI.Web/Models/ResumePointObject.cs | 14 + SpotifyAPI.Web/Models/SearchItem.cs | 8 +- SpotifyAPI.Web/Models/SeveralShows.cs | 11 + SpotifyAPI.Web/Models/SimpleEpisode.cs | 60 ++ SpotifyAPI.Web/Models/SimpleShow.cs | 54 ++ SpotifyAPI.Web/Models/SimpleTrack.cs | 15 + SpotifyAPI.Web/Models/TrackLink.cs | 23 + SpotifyAPI.Web/SpotifyWebAPI.cs | 546 ++++++------------ SpotifyAPI.Web/SpotifyWebBuilder.cs | 185 ++++-- 18 files changed, 680 insertions(+), 446 deletions(-) create mode 100644 SpotifyAPI.Web/Converters/PlaybackContextConverter.cs create mode 100644 SpotifyAPI.Web/Converters/PlaylistTrackConverter.cs create mode 100644 SpotifyAPI.Web/Models/FullEpisode.cs create mode 100644 SpotifyAPI.Web/Models/ResumePointObject.cs create mode 100644 SpotifyAPI.Web/Models/SeveralShows.cs create mode 100644 SpotifyAPI.Web/Models/SimpleEpisode.cs create mode 100644 SpotifyAPI.Web/Models/SimpleShow.cs create mode 100644 SpotifyAPI.Web/Models/TrackLink.cs diff --git a/SpotifyAPI.Web.Examples.ASP/Properties/launchSettings.json b/SpotifyAPI.Web.Examples.ASP/Properties/launchSettings.json index bf29a4fb..e61a30b8 100644 --- a/SpotifyAPI.Web.Examples.ASP/Properties/launchSettings.json +++ b/SpotifyAPI.Web.Examples.ASP/Properties/launchSettings.json @@ -1,4 +1,4 @@ -{ +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, @@ -18,10 +18,10 @@ "SpotifyAPI.Web.Examples.ASP": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "applicationUrl": "http://localhost:5000" } } } diff --git a/SpotifyAPI.Web/Converters/PlaybackContextConverter.cs b/SpotifyAPI.Web/Converters/PlaybackContextConverter.cs new file mode 100644 index 00000000..059b1a39 --- /dev/null +++ b/SpotifyAPI.Web/Converters/PlaybackContextConverter.cs @@ -0,0 +1,52 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SpotifyAPI.Web.Models; + +namespace SpotifyAPI.Web.Converters +{ + class PlaybackContextConverter : JsonConverter + { + public override bool CanConvert(Type objectType) => true; + + public override object ReadJson(JsonReader reader, Type objectType, + object existingValue, JsonSerializer serializer) + { + var token = JToken.ReadFrom(reader); + if (token.Type == JTokenType.Null) + { + return null; + } + + // Create an instance of MyClass, and set property as per "isFoo". + var obj = new PlaybackContext(); + + if (token["currently_playing_type"] != null) + { + var type = token["currently_playing_type"].Value(); + if (type == "track") + { + obj.Item = new FullTrack(); + } + else if (type == "episode") + { + obj.Item = new FullEpisode(); + } + else + { + throw new Exception($"Received unkown currently playing type: {type}"); + } + } + + // Populate properties + serializer.Populate(token.CreateReader(), obj); + return obj; + } + + public override void WriteJson(JsonWriter writer, object value, + JsonSerializer serializer) + { + throw new NotSupportedException(); + } + } +} diff --git a/SpotifyAPI.Web/Converters/PlaylistTrackConverter.cs b/SpotifyAPI.Web/Converters/PlaylistTrackConverter.cs new file mode 100644 index 00000000..6d95be50 --- /dev/null +++ b/SpotifyAPI.Web/Converters/PlaylistTrackConverter.cs @@ -0,0 +1,46 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SpotifyAPI.Web.Models; + +namespace SpotifyAPI.Web.Converters +{ + class PlaylistTrackConverter : JsonConverter + { + public override bool CanConvert(Type objectType) => true; + + public override object ReadJson(JsonReader reader, Type objectType, + object existingValue, JsonSerializer serializer) + { + var token = JToken.ReadFrom(reader); + if (token.Type == JTokenType.Null) + { + return null; + } + + var type = token["type"].Value(); + if (type == "track") + { + var obj = new FullTrack(); + serializer.Populate(token.CreateReader(), obj); + return obj; + } + else if (type == "episode") + { + var obj = new FullEpisode(); + serializer.Populate(token.CreateReader(), obj); + return obj; + } + else + { + throw new Exception($"Received unkown playlist track type: {type}"); + } + } + + public override void WriteJson(JsonWriter writer, object value, + JsonSerializer serializer) + { + throw new NotSupportedException(); + } + } +} diff --git a/SpotifyAPI.Web/Enums/Scope.cs b/SpotifyAPI.Web/Enums/Scope.cs index bc66bc2c..773ae376 100644 --- a/SpotifyAPI.Web/Enums/Scope.cs +++ b/SpotifyAPI.Web/Enums/Scope.cs @@ -63,6 +63,10 @@ namespace SpotifyAPI.Web.Enums AppRemoteControl = 262144, [String("ugc-image-upload")] - UgcImageUpload = 524288 + UgcImageUpload = 524288, + + [String("user-read-playback-position")] + UserReadPlaybackPosition = 1048576 + } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Enums/SearchType.cs b/SpotifyAPI.Web/Enums/SearchType.cs index abf24c0a..cd0c1df1 100644 --- a/SpotifyAPI.Web/Enums/SearchType.cs +++ b/SpotifyAPI.Web/Enums/SearchType.cs @@ -17,7 +17,13 @@ namespace SpotifyAPI.Web.Enums [String("playlist")] Playlist = 8, - [String("track,album,artist,playlist")] - All = 16 + [String("show")] + Show = 16, + + [String("episode")] + Episode = 32, + + [String("track,album,artist,playlist,show,episode")] + All = 64 } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Models/FullEpisode.cs b/SpotifyAPI.Web/Models/FullEpisode.cs new file mode 100644 index 00000000..eb40904c --- /dev/null +++ b/SpotifyAPI.Web/Models/FullEpisode.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class FullEpisode : BasicModel, ITyped + { + [JsonProperty("audio_preview_url")] + public string AudioPreviewUrl { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("duration_ms")] + public int DurationMs { get; set; } + + [JsonProperty("explicit")] + public bool Explicit { get; set; } + + [JsonProperty("external_urls")] + public Dictionary ExternalUrls { get; set; } + + [JsonProperty("href")] + public string Href { get; set; } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("images")] + public List Images { get; set; } + + [JsonProperty("is_externally_hosted")] + public bool IsExternallyHosted { get; set; } + + [JsonProperty("is_playable")] + public bool IsPlayable { get; set; } + + [JsonProperty("languages")] + public List Languages { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("release_date")] + public string ReleaseDate { get; set; } + + [JsonProperty("release_date_precision")] + public string ReleaseDatePrecision { get; set; } + + [JsonProperty("resume_point")] + public ResumePointObject ResumePoint { get; set; } + + [JsonProperty("show")] + public SimpleShow Show { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + + } +} diff --git a/SpotifyAPI.Web/Models/FullTrack.cs b/SpotifyAPI.Web/Models/FullTrack.cs index d75c8d00..cb1e038d 100644 --- a/SpotifyAPI.Web/Models/FullTrack.cs +++ b/SpotifyAPI.Web/Models/FullTrack.cs @@ -3,7 +3,7 @@ using Newtonsoft.Json; namespace SpotifyAPI.Web.Models { - public class FullTrack : BasicModel + public class FullTrack : BasicModel, ITyped { [JsonProperty("album")] public SimpleAlbum Album { get; set; } @@ -68,4 +68,4 @@ namespace SpotifyAPI.Web.Models [JsonProperty("linked_from")] public LinkedFrom LinkedFrom { get; set; } } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Models/GeneralModels.cs b/SpotifyAPI.Web/Models/GeneralModels.cs index b263aacb..706263cc 100644 --- a/SpotifyAPI.Web/Models/GeneralModels.cs +++ b/SpotifyAPI.Web/Models/GeneralModels.cs @@ -2,9 +2,16 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using SpotifyAPI.Web.Converters; namespace SpotifyAPI.Web.Models { + public interface ITyped + { + [JsonProperty("type")] + string Type { get; set; } + } + public class Image { [JsonProperty("url")] @@ -56,7 +63,8 @@ namespace SpotifyAPI.Web.Models public PublicProfile AddedBy { get; set; } [JsonProperty("track")] - public FullTrack Track { get; set; } + [JsonConverter(typeof(PlaylistTrackConverter))] + public ITyped Track { get; set; } [JsonProperty("is_local")] public bool IsLocal { get; set; } @@ -155,4 +163,4 @@ namespace SpotifyAPI.Web.Models [JsonProperty("uri")] public string Uri { get; set; } } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Models/PlaybackContext.cs b/SpotifyAPI.Web/Models/PlaybackContext.cs index 6636ba29..3cb8cc6f 100644 --- a/SpotifyAPI.Web/Models/PlaybackContext.cs +++ b/SpotifyAPI.Web/Models/PlaybackContext.cs @@ -1,9 +1,12 @@ +using System; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Converters; namespace SpotifyAPI.Web.Models { + [JsonConverter(typeof(PlaybackContextConverter))] public class PlaybackContext : BasicModel { [JsonProperty("device")] @@ -29,10 +32,10 @@ namespace SpotifyAPI.Web.Models public bool IsPlaying { get; set; } [JsonProperty("item")] - public FullTrack Item { get; set; } + public ITyped Item { get; set; } [JsonProperty("currently_playing_type")] [JsonConverter(typeof(StringEnumConverter))] public TrackType CurrentlyPlayingType { get; set; } } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Models/ResumePointObject.cs b/SpotifyAPI.Web/Models/ResumePointObject.cs new file mode 100644 index 00000000..d9a8aaab --- /dev/null +++ b/SpotifyAPI.Web/Models/ResumePointObject.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class ResumePointObject : BasicModel + { + [JsonProperty("fully_played")] + public bool FullyPlayed { get; set; } + + [JsonProperty("resume_position_ms")] + public int ResumePositionMs { get; set; } + } +} \ No newline at end of file diff --git a/SpotifyAPI.Web/Models/SearchItem.cs b/SpotifyAPI.Web/Models/SearchItem.cs index 447187b7..580be9f2 100644 --- a/SpotifyAPI.Web/Models/SearchItem.cs +++ b/SpotifyAPI.Web/Models/SearchItem.cs @@ -15,5 +15,11 @@ namespace SpotifyAPI.Web.Models [JsonProperty("playlists")] public Paging Playlists { get; set; } + + [JsonProperty("shows")] + public Paging Shows { get; set; } + + [JsonProperty("episodes")] + public Paging Episodes { get; set; } } -} \ No newline at end of file +} diff --git a/SpotifyAPI.Web/Models/SeveralShows.cs b/SpotifyAPI.Web/Models/SeveralShows.cs new file mode 100644 index 00000000..e7e88ae3 --- /dev/null +++ b/SpotifyAPI.Web/Models/SeveralShows.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class SeveralShows : BasicModel + { + [JsonProperty("shows")] + public List Shows { get; set; } + } +} \ No newline at end of file diff --git a/SpotifyAPI.Web/Models/SimpleEpisode.cs b/SpotifyAPI.Web/Models/SimpleEpisode.cs new file mode 100644 index 00000000..5a35e6f3 --- /dev/null +++ b/SpotifyAPI.Web/Models/SimpleEpisode.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class SimpleEpisode : BasicModel + { + [JsonProperty("audio_preview_url")] + public string AudioPreviewUrl { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("duration_ms")] + public int DurationMs { get; set; } + + [JsonProperty("explicit")] + public bool Explicit { get; set; } + + [JsonProperty("external_urls")] + public Dictionary ExternalUrls { get; set; } + + [JsonProperty("href")] + public string Href { get; set; } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("images")] + public List Images { get; set; } + + [JsonProperty("is_externally_hosted")] + public bool IsExternallyHosted { get; set; } + + [JsonProperty("is_playable")] + public bool IsPlayable { get; set; } + + [JsonProperty("languages")] + public List Languages { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("release_date")] + public string ReleaseDate { get; set; } + + [JsonProperty("resume_point")] + public ResumePointObject ResumePoint { get; set; } + + [JsonProperty("show")] + public SimpleShow Show { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + + } +} \ No newline at end of file diff --git a/SpotifyAPI.Web/Models/SimpleShow.cs b/SpotifyAPI.Web/Models/SimpleShow.cs new file mode 100644 index 00000000..74384ca1 --- /dev/null +++ b/SpotifyAPI.Web/Models/SimpleShow.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class SimpleShow : BasicModel + { + [JsonProperty("available_markets")] + public List AvailableMarkets { get; set; } + + [JsonProperty("copyrights")] + public List Copyrights { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("explicit")] + public bool Explicit { get; set; } + + [JsonProperty("external_urls")] + public Dictionary ExternalUrls { get; set; } + + [JsonProperty("href")] + public string Href { get; set; } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("images")] + public List Images { get; set; } + + [JsonProperty("is_externally_hosted")] + public bool IsExternallyHosted { get; set; } + + [JsonProperty("languages")] + public List Languages { get; set; } + + [JsonProperty("media_type")] + public string MediaType { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("publisher")] + public string Publisher { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + + } +} \ No newline at end of file diff --git a/SpotifyAPI.Web/Models/SimpleTrack.cs b/SpotifyAPI.Web/Models/SimpleTrack.cs index aa4a8fe9..28d8770b 100644 --- a/SpotifyAPI.Web/Models/SimpleTrack.cs +++ b/SpotifyAPI.Web/Models/SimpleTrack.cs @@ -5,6 +5,9 @@ namespace SpotifyAPI.Web.Models { public class SimpleTrack : BasicModel { + [JsonProperty("album")] + public SimpleAlbum Album { get; set; } + [JsonProperty("artists")] public List Artists { get; set; } @@ -19,6 +22,9 @@ namespace SpotifyAPI.Web.Models [JsonProperty("explicit")] public bool Explicit { get; set; } + + [JsonProperty("external_ids")] + public Dictionary ExternIds { get; set; } [JsonProperty("external_urls")] public Dictionary ExternUrls { get; set; } @@ -29,9 +35,18 @@ namespace SpotifyAPI.Web.Models [JsonProperty("id")] public string Id { get; set; } + [JsonProperty("is_playable")] + public bool IsPlayable { get; set; } + + [JsonProperty("linked_from")] + public TrackLink LinkedFrom { get; set; } + [JsonProperty("name")] public string Name { get; set; } + [JsonProperty("popularity")] + public int Popularity { get; set; } + [JsonProperty("preview_url")] public string PreviewUrl { get; set; } diff --git a/SpotifyAPI.Web/Models/TrackLink.cs b/SpotifyAPI.Web/Models/TrackLink.cs new file mode 100644 index 00000000..3b984ab2 --- /dev/null +++ b/SpotifyAPI.Web/Models/TrackLink.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace SpotifyAPI.Web.Models +{ + public class TrackLink : BasicModel + { + [JsonProperty("external_urls")] + public Dictionary ExternalUrls { get; set; } + + [JsonProperty("href")] + public string Href { get; set; } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + } +} \ No newline at end of file diff --git a/SpotifyAPI.Web/SpotifyWebAPI.cs b/SpotifyAPI.Web/SpotifyWebAPI.cs index bf5e17ae..202ae53e 100644 --- a/SpotifyAPI.Web/SpotifyWebAPI.cs +++ b/SpotifyAPI.Web/SpotifyWebAPI.cs @@ -613,6 +613,54 @@ namespace SpotifyAPI.Web #endregion Browse + #region Episode + /// + /// Get Spotify catalog information for a single episode identified by its unique Spotify ID. + /// + /// The Spotify ID for the episode. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public FullEpisode GetEpisode(string id, string market = "") + { + return DownloadData(_builder.GetEpisode(id, market)); + } + /// + /// Get Spotify catalog information for a single episode identified by its unique Spotify ID. + /// + /// The Spotify ID for the episode. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetEpisodeAsync(string id, string market = "") + { + return DownloadDataAsync(_builder.GetEpisode(id, market)); + } + + /// + /// Get Spotify catalog information for multiple episodes based on their Spotify IDs. + /// + /// A Spotify ID for the episodes. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public ListResponse GetEpisodes(string id, string market = "") + { + return DownloadList(_builder.GetEpisode(id, market)); + } + + /// + /// Get Spotify catalog information for multiple episodes based on their Spotify IDs. + /// + /// A Spotify IDs for the episode. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public Task> GetEpisodesAsync(string id, string market = "") + { + return DownloadListAsync(_builder.GetEpisode(id, market)); + } + + + + #endregion Episode + #region Follow /// @@ -1319,26 +1367,6 @@ namespace SpotifyAPI.Web return DownloadDataAsync>(_builder.GetUserPlaylists(userId, limit, offset)); } - /// - /// Get a playlist owned by a Spotify user. - /// - /// 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 - [Obsolete("Calling GetPlaylist with a userId is deprecated, remove the parameter")] - public FullPlaylist GetPlaylist(string userId, string playlistId, string fields = "", string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetPlaylist"); - return DownloadData(_builder.GetPlaylist(userId, playlistId, fields, market)); - } - /// /// Get a playlist owned by a Spotify user. /// @@ -1357,26 +1385,6 @@ namespace SpotifyAPI.Web return DownloadData(_builder.GetPlaylist(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 - [Obsolete("Calling GetPlaylist with a userId is deprecated, remove the parameter")] - 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)); - } - /// /// Get a playlist owned by a Spotify user asynchronously. /// @@ -1395,27 +1403,6 @@ namespace SpotifyAPI.Web return DownloadDataAsync(_builder.GetPlaylist(playlistId, fields, market)); } - /// - /// Get full details of the tracks of a playlist owned by a Spotify user. - /// - /// 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 - [Obsolete("Calling GetPlaylistTracks with a userId is deprecated, remove the parameter")] - public Paging GetPlaylistTracks(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 DownloadData>(_builder.GetPlaylistTracks(userId, playlistId, fields, limit, offset, market)); - } /// /// Get full details of the tracks of a playlist owned by a Spotify user. @@ -1437,28 +1424,6 @@ namespace SpotifyAPI.Web return DownloadData>(_builder.GetPlaylistTracks(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 - [Obsolete("Calling GetPlaylistTracks with a userId is deprecated, remove the parameter")] - 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)); - } - /// /// Get full details of the tracks of a playlist owned by a Spotify user asyncronously. /// @@ -1529,33 +1494,6 @@ namespace SpotifyAPI.Web return UploadDataAsync(_builder.CreatePlaylist(userId, playlistName, isPublic), body.ToString(Formatting.None)); } - /// - /// Change a playlist’s name and public/private state. (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. - /// If true the playlist will become collaborative and other users will be able to modify the playlist in their Spotify client. - /// Note: You can only set collaborative to true on non-public playlists. - /// Value for playlist description as displayed in Spotify Clients and in the Web API. - /// - /// AUTH NEEDED - [Obsolete("Calling UpdatePlaylist with a userId is deprecated, remove the parameter")] - public ErrorResponse UpdatePlaylist(string userId, string playlistId, string newName = null, bool? newPublic = null, bool? newCollaborative = null, string newDescription = null) - { - JObject body = new JObject(); - if (newName != null) - body.Add("name", newName); - if (newPublic != null) - body.Add("public", newPublic); - if (newCollaborative != null) - body.Add("collaborative", newCollaborative); - if (newDescription != null) - body.Add("description", newDescription); - return UploadData(_builder.UpdatePlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); - } - /// /// Change a playlist’s name and public/private state. (The user must, of course, own the playlist.) /// @@ -1581,32 +1519,6 @@ namespace SpotifyAPI.Web return UploadData(_builder.UpdatePlaylist(playlistId), 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. - /// If true the playlist will become collaborative and other users will be able to modify the playlist in their Spotify client. Note: You can only set collaborative to true on non-public playlists. - /// Value for playlist description as displayed in Spotify Clients and in the Web API. - /// - /// AUTH NEEDED - [Obsolete("Calling UpdatePlaylist with a userId is deprecated, remove the parameter")] - public async Task UpdatePlaylistAsync(string userId, string playlistId, string newName = null, bool? newPublic = null, bool? newCollaborative = null, string newDescription = null) - { - JObject body = new JObject(); - if (newName != null) - body.Add("name", newName); - if (newPublic != null) - body.Add("public", newPublic); - if (newCollaborative != null) - body.Add("collaborative", newCollaborative); - if (newDescription != null) - body.Add("description", newDescription); - return await UploadDataAsync(_builder.UpdatePlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); - } - /// /// Change a playlist’s name and public/private state asynchronously. (The user must, of course, own the playlist.) /// @@ -1631,32 +1543,6 @@ namespace SpotifyAPI.Web return await UploadDataAsync(_builder.UpdatePlaylist(playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); } - /// - /// Change a playlist’s name and public/private state. (The user must, of course, own the playlist.) - /// - /// The user's Spotify user ID. - /// The Spotify ID for the playlist. - /// The image as a base64 encoded string - /// - /// AUTH NEEDED - public ErrorResponse UploadPlaylistImage(string userId, string playlistId, string base64EncodedJpgImage) - { - return UploadData(_builder.UploadPlaylistImage(userId, playlistId), base64EncodedJpgImage, "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 image as a base64 encoded string - /// - /// AUTH NEEDED - public async Task UploadPlaylistImageAsync(string userId, string playlistId, string base64EncodedJpgImage) - { - return await UploadDataAsync(_builder.UploadPlaylistImage(userId, playlistId), base64EncodedJpgImage, "PUT").ConfigureAwait(false) ?? new ErrorResponse(); - } - /// /// Change a playlist’s name and public/private state. (The user must, of course, own the playlist.) /// @@ -1682,24 +1568,6 @@ namespace SpotifyAPI.Web base64EncodedJpgImage, "PUT").ConfigureAwait(false) ?? new ErrorResponse(); } - /// - /// Replace all the tracks in a playlist, 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 - [Obsolete("Calling ReplacePlaylistTracks with a userId is deprecated, remove the parameter")] - public ErrorResponse ReplacePlaylistTracks(string userId, string playlistId, List uris) - { - JObject body = new JObject - { { "uris", new JArray(uris.Take(100)) } - }; - return UploadData(_builder.ReplacePlaylistTracks(userId, playlistId), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); - } - /// /// Replace all the tracks in a playlist, overwriting its existing tracks. This powerful request can be useful for /// replacing tracks, re-ordering existing tracks, or clearing the playlist. @@ -1716,24 +1584,6 @@ namespace SpotifyAPI.Web return UploadData(_builder.ReplacePlaylistTracks(playlistId), 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 - [Obsolete("Calling ReplacePlaylistTracks with a userId is deprecated, remove the parameter")] - public async Task ReplacePlaylistTracksAsync(string userId, string playlistId, List uris) - { - JObject body = new JObject - { { "uris", new JArray(uris.Take(100)) } - }; - return await UploadDataAsync(_builder.ReplacePlaylistTracks(userId, playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? 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. @@ -1750,26 +1600,6 @@ namespace SpotifyAPI.Web return await UploadDataAsync(_builder.ReplacePlaylistTracks(playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); } - /// - /// Remove one or more tracks from a user’s playlist. - /// - /// 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 - [Obsolete("Calling RemovePlaylistTracks with a userId is deprecated, remove the parameter")] - public ErrorResponse RemovePlaylistTracks(string userId, string playlistId, List uris) - { - JObject body = new JObject - { { "tracks", JArray.FromObject(uris.Take(100)) } - }; - return UploadData(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); - } - /// /// Remove one or more tracks from a user’s playlist. /// @@ -1788,26 +1618,6 @@ namespace SpotifyAPI.Web return UploadData(_builder.RemovePlaylistTracks(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 - [Obsolete("Calling RemovePlaylistTracks with a userId is deprecated, remove the parameter")] - public async Task RemovePlaylistTracksAsync(string userId, string playlistId, List uris) - { - JObject body = new JObject - { { "tracks", JArray.FromObject(uris.Take(100)) } - }; - return await UploadDataAsync(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); - } - /// /// Remove one or more tracks from a user’s playlist asynchronously. /// @@ -1826,20 +1636,6 @@ namespace SpotifyAPI.Web return await UploadDataAsync(_builder.RemovePlaylistTracks(playlistId, uris), body.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); } - /// - /// Remove a track from a user’s playlist. - /// - /// The user's Spotify user ID. - /// The Spotify ID for the playlist. - /// Spotify URI - /// - /// AUTH NEEDED - [Obsolete("Calling RemovePlaylistTrack with a userId is deprecated, remove the parameter")] - public ErrorResponse RemovePlaylistTrack(string userId, string playlistId, DeleteTrackUri uri) - { - return RemovePlaylistTracks(playlistId, new List { uri }); - } - /// /// Remove a track from a user’s playlist. /// @@ -1852,20 +1648,6 @@ namespace SpotifyAPI.Web return RemovePlaylistTracks(playlistId, new List { uri }); } - /// - /// Remove a track from a user’s playlist asynchronously. - /// - /// The user's Spotify user ID. - /// The Spotify ID for the playlist. - /// Spotify URI - /// - /// AUTH NEEDED - [Obsolete("Calling RemovePlaylistTrack with a userId is deprecated, remove the parameter")] - public Task RemovePlaylistTrackAsync(string userId, string playlistId, DeleteTrackUri uri) - { - return RemovePlaylistTracksAsync(playlistId, new List { uri }); - } - /// /// Remove a track from a user’s playlist asynchronously. /// @@ -1878,24 +1660,6 @@ namespace SpotifyAPI.Web return RemovePlaylistTracksAsync(playlistId, new List { uri }); } - /// - /// Add one or more tracks to a user’s playlist. - /// - /// 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 - [Obsolete("Calling AddPlaylistTracks with a userId is deprecated, remove the parameter")] - public ErrorResponse AddPlaylistTracks(string userId, string playlistId, List uris, int? position = null) - { - JObject body = new JObject - { { "uris", JArray.FromObject(uris.Take(100)) } - }; - return UploadData(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)) ?? new ErrorResponse(); - } - /// /// Add one or more tracks to a user’s playlist. /// @@ -1912,24 +1676,6 @@ namespace SpotifyAPI.Web return UploadData(_builder.AddPlaylistTracks(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 - [Obsolete("Calling AddPlaylistTracks with a userId is deprecated, remove the parameter")] - public async Task AddPlaylistTracksAsync(string userId, string playlistId, List uris, int? position = null) - { - JObject body = new JObject - { { "uris", JArray.FromObject(uris.Take(100)) } - }; - return await UploadDataAsync(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)).ConfigureAwait(false) ?? new ErrorResponse(); - } - /// /// Add one or more tracks to a user’s playlist asynchronously. /// @@ -1946,21 +1692,6 @@ namespace SpotifyAPI.Web return await UploadDataAsync(_builder.AddPlaylistTracks(playlistId, uris, position), body.ToString(Formatting.None)).ConfigureAwait(false) ?? new ErrorResponse(); } - /// - /// Add a track to a user’s playlist. - /// - /// 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 - [Obsolete("Calling AddPlaylistTrack with a userId is deprecated, remove the parameter")] - public ErrorResponse AddPlaylistTrack(string userId, string playlistId, string uri, int? position = null) - { - return AddPlaylistTracks(playlistId, new List { uri }, position); - } - /// /// Add a track to a user’s playlist. /// @@ -1974,21 +1705,6 @@ namespace SpotifyAPI.Web return AddPlaylistTracks(playlistId, new List { uri }, position); } - /// - /// Add a track 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 - [Obsolete("Calling AddPlaylistTrack with a userId is deprecated, remove the parameter")] - public Task AddPlaylistTrackAsync(string userId, string playlistId, string uri, int? position = null) - { - return AddPlaylistTracksAsync(userId, playlistId, new List { uri }, position); - } - /// /// Add a track to a user’s playlist asynchronously. /// @@ -2002,28 +1718,6 @@ namespace SpotifyAPI.Web return AddPlaylistTracksAsync(playlistId, new List { uri }, position); } - /// - /// Reorder a track or a group of tracks in a playlist. - /// - /// 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 - [Obsolete("Calling ReorderPlaylist with a userId is deprecated, remove the parameter")] - public Snapshot ReorderPlaylist(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 } - }; - if (!string.IsNullOrEmpty(snapshotId)) - body.Add("snapshot_id", snapshotId); - return UploadData(_builder.ReorderPlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT"); - } - /// /// Reorder a track or a group of tracks in a playlist. /// @@ -2044,28 +1738,6 @@ namespace SpotifyAPI.Web return UploadData(_builder.ReorderPlaylist(playlistId), 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 - [Obsolete("Calling ReorderPlaylist with a userId is deprecated, remove the parameter")] - 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 }, { "snapshot_id", snapshotId } - }; - if (!string.IsNullOrEmpty(snapshotId)) - body.Add("snapshot_id", snapshotId); - return UploadDataAsync(_builder.ReorderPlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT"); - } - /// /// Reorder a track or a group of tracks in a playlist asynchronously. /// @@ -2136,6 +1808,128 @@ namespace SpotifyAPI.Web #endregion Profiles + #region Shows + + /// + /// Get Spotify catalog information for a single show identified by its unique Spotify ID. + /// + /// The Spotify ID for the show. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public SimpleShow GetShow(string id, string market = "") + { + return DownloadData(_builder.GetShow(id, market)); + } + + /// + /// Get Spotify catalog information for a single show identified by its unique Spotify ID. + /// + /// The Spotify ID for the show. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetShowAsync(string id, string market = "") + { + return DownloadDataAsync(_builder.GetShow(id, market)); + } + + + /// + /// Get Spotify catalog information for multiple shows based on their Spotify IDs. + /// + /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 IDs. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public Task GetShowsAsync(List ids, string market = "") + { + return DownloadDataAsync(_builder.GetShows(ids, market)); + } + + /// + /// Get Spotify catalog information for multiple shows based on their Spotify IDs. + /// + /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 IDs. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public SeveralShows GetShows(List ids, string market = "") + { + return DownloadData(_builder.GetShows(ids, market)); + } + + /// + /// A Helper function that removes the spotify:XXX: prefix for several uris. + /// + /// A list of full spotify uris + /// A list of uris without the spotify prefix. + public List RemovePrefix(List uris) + { + List fixed_uris = new List(); + foreach (var uri in uris) + { + fixed_uris.Add(RemovePrefix(uri)); + } + return fixed_uris; + } + + /// + /// A Helper function that removes the spotify:XXX: prefix for a single uri. + /// + /// A spotify uri (e.g.,spotify:XXX:YYY). + /// Uri without the prefix (e.g. YYY). + + public string RemovePrefix(string uri) + { + if (uri.Contains("spotify:show:")) + { + return uri.Replace("spotify:show:", ""); + } + else if (uri.Contains("spotify:track:")) + { + return uri.Replace("spotify:track:", ""); + } + else if (uri.Contains("spotify:album:")) + { + return uri.Replace("spotify:album:", ""); + } + else if (uri.Contains("spotify:episode:")) + { + return uri.Replace("spotify:episode:", ""); + } + else if (uri.Contains("spotify:playlist:")) + { + return uri.Replace("spotify:playlist:", ""); + } + else + return uri; + } + + /// + /// Get Spotify catalog information about an show’s episodes. Optional parameters can be used to limit the number of episodes returned. + /// + /// A list of the Spotify IDs for the tracks. Maximum: 50 IDs. + /// The maximum number of episodes to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first episode to return. Default: 0 (the first object). Use with limit to get the next set of episodes. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Paging GetShowEpisodes(string id, int limit = 20, int offset = 0, string market = "") + { + return DownloadData>(_builder.GetShowEpisodes(id, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about an show’s episodes. Optional parameters can be used to limit the number of episodes returned. + /// + /// A list of the Spotify IDs for the tracks. Maximum: 50 IDs. + /// The maximum number of episodes to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first episode to return. Default: 0 (the first object). Use with limit to get the next set of episodes. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task> GetShowEpisodesAsync(string id, int limit = 20, int offset = 0, string market = "") + { + return DownloadDataAsync>(_builder.GetShowEpisodes(id, limit, offset, market)); + } + + #endregion Shows + #region Tracks /// diff --git a/SpotifyAPI.Web/SpotifyWebBuilder.cs b/SpotifyAPI.Web/SpotifyWebBuilder.cs index 120abef1..6ff0e5e3 100644 --- a/SpotifyAPI.Web/SpotifyWebBuilder.cs +++ b/SpotifyAPI.Web/SpotifyWebBuilder.cs @@ -339,6 +339,37 @@ namespace SpotifyAPI.Web #endregion Browse + + + #region Episode + /// + /// Get Spotify catalog information for a single episode identified by its unique Spotify ID. + /// + /// The Spotify ID for the episode. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetEpisode(string id, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/episodes/{id}" : + $"{APIBase}/episodes?market={market}&id={id}"; + } + + /// + /// Get Spotify catalog information for multiple episodes based on their Spotify IDs. + /// + /// A comma-separated list of the Spotify IDs for the episodes. Maximum: 50 IDs. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public string GetEpisodes(List ids, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/episodes?ids={string.Join(",", ids.Take(50))}" : + $"{APIBase}/episodes?market={market}&ids={string.Join(",", ids.Take(50))}"; + } + #endregion Episode + + #region Follow /// @@ -534,6 +565,39 @@ namespace SpotifyAPI.Web return APIBase + "/me/albums/contains?ids=" + string.Join(",", ids); } + /// + /// Save one or more shows to current Spotify user’s library. + /// + // A list of the Spotify IDs. + /// + /// AUTH NEEDED (user-library-modify) + public string SubscribeShows(List ids) + { + return $"{APIBase}/me/shows?ids={string.Join(",", ids.Take(50))}"; + } + + /// + /// Check if one or more shows is already saved in the current Spotify user’s library. + /// + // A list of the Spotify IDs. + /// + /// AUTH NEEDED (user-library-modify) + public string CheckSubscribedShows(List ids) + { + return $"{APIBase}/me/shows/contains?ids={string.Join(",", ids.Take(50))}"; + } + + /// + /// Delete one or more shows from current Spotify user’s library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED (user-library-modify) + public string UnsubscribeShows(List ids) + { + return $"{APIBase}/me/shows?ids={string.Join(",", ids.Take(50))}"; + } + #endregion Library #region Personalization @@ -622,7 +686,6 @@ namespace SpotifyAPI.Web /// /// Get a playlist owned by a Spotify user. /// - /// 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 @@ -631,58 +694,14 @@ namespace SpotifyAPI.Web /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. /// /// AUTH NEEDED - public string GetPlaylist(string userId, string playlistId, string fields = "", string market = "") - { - StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists/" + playlistId); - builder.Append("?fields=" + fields); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Get a playlist owned by a Spotify user. - /// - /// 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 string GetPlaylist(string playlistId, string fields = "", string market = "") + public string GetPlaylist(string playlistId, string fields = "", string market = "", string additionalTypes = "track,episode") { StringBuilder builder = new StringBuilder(APIBase + "/playlists/" + playlistId); builder.Append("?fields=" + fields); if (!string.IsNullOrEmpty(market)) builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Get full details of the tracks of a playlist owned by a Spotify user. - /// - /// 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 string GetPlaylistTracks(string userId, string playlistId, string fields = "", int limit = 100, int offset = 0, string market = "") - { - limit = Math.Min(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); + if (!string.IsNullOrEmpty(additionalTypes)) + builder.Append("&additional_types=" + additionalTypes); return builder.ToString(); } @@ -697,9 +716,10 @@ namespace SpotifyAPI.Web /// 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. + /// 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.. /// /// AUTH NEEDED - public string GetPlaylistTracks(string playlistId, string fields = "", int limit = 100, int offset = 0, string market = "") + public string GetPlaylistTracks(string playlistId, string fields = "", int limit = 100, int offset = 0, string market = "", string additional_types = "track,episode") { limit = Math.Min(limit, 100); StringBuilder builder = new StringBuilder(APIBase + "/playlists/" + playlistId + "/tracks"); @@ -707,7 +727,13 @@ namespace SpotifyAPI.Web builder.Append("&limit=" + limit); builder.Append("&offset=" + offset); if (!string.IsNullOrEmpty(market)) + { builder.Append("&market=" + market); + } + if (!string.IsNullOrEmpty(additional_types)) + { + builder.Append("&additional_types=" + additional_types); + } return builder.ToString(); } @@ -912,6 +938,53 @@ namespace SpotifyAPI.Web #endregion Profiles + #region Shows + + /// + /// Get Spotify catalog information for a single show identified by its unique Spotify ID. + /// + /// The Spotify ID for the show. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetShow(string id, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/shows/{id}" : + $"{APIBase}/shows?market={market}&id={id}"; + } + + /// + /// Get Spotify catalog information for multiple shows based on their Spotify IDs. + /// + /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 IDs. + /// Optional. An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes that are available in that market will be returned. If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter. Note: If neither market or user country are provided, the content is considered unavailable for the client.Users can view the country that is associated with their account in the account settings. + /// + public string GetShows(List ids, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/shows?ids={string.Join(",", ids.Take(50))}" : + $"{APIBase}/shows?market={market}&ids={string.Join(",", ids.Take(50))}"; + } + + /// + /// Get Spotify catalog information about an show’s episodes. Optional parameters can be used to limit the number of episodes returned. + /// + /// A list of the Spotify IDs for the tracks. Maximum: 50 IDs. + /// The maximum number of episodes to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first episode to return. Default: 0 (the first object). Use with limit to get the next set of episodes. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetShowEpisodes(string id, int limit = 20, int offset = 0, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/shows/{id}/episodes?offset={offset}&limit={limit}" : + $"{APIBase}/shows/{id}/episodes?market={market}&offset={offset}&limit={limit}"; + } + + #endregion Shows + + + #region Tracks /// @@ -988,22 +1061,24 @@ namespace SpotifyAPI.Web /// Get information about the user’s current playback state, including track, track progress, and active device. /// /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// 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.. /// - public string GetPlayback(string market = "") + public string GetPlayback(string market = "", string additional_types = "track,episode") { - return string.IsNullOrEmpty(market) ? $"{APIBase}/me/player" : $"{APIBase}/me/player?market={market}"; + return string.IsNullOrEmpty(market) ? $"{APIBase}/me/player?additional_types={additional_types}" : $"{APIBase}/me/player?market={market}&additional_types={additional_types}"; } /// /// Get the object currently being played on the user’s Spotify account. /// /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// 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.. /// - public string GetPlayingTrack(string market = "") + public string GetPlayingTrack(string market = "", string additional_types = "track,episode") { return string.IsNullOrEmpty(market) ? - $"{APIBase}/me/player/currently-playing" : - $"{APIBase}/me/player/currently-playing?market={market}"; + $"{APIBase}/me/player/currently-playing?additional_types={additional_types}" : + $"{APIBase}/me/player/currently-playing?market={market}&additional_types={additional_types}"; } /// @@ -1132,4 +1207,4 @@ namespace SpotifyAPI.Web } #endregion } -} \ No newline at end of file +}