From 307d69945e59d28ecbee87a87634bf070e5f2d8c Mon Sep 17 00:00:00 2001 From: Jonas Dellinger Date: Mon, 9 Mar 2020 20:28:41 +0100 Subject: [PATCH] Added AddToQueue --- SpotifyAPI.Docs/docs/web/player.md | 18 + SpotifyAPI.Web/SpotifyWebAPI.cs | 5886 +++++++++++++-------------- SpotifyAPI.Web/SpotifyWebBuilder.cs | 2229 +++++----- 3 files changed, 4066 insertions(+), 4067 deletions(-) diff --git a/SpotifyAPI.Docs/docs/web/player.md b/SpotifyAPI.Docs/docs/web/player.md index 1d33ed3e..f901254a 100644 --- a/SpotifyAPI.Docs/docs/web/player.md +++ b/SpotifyAPI.Docs/docs/web/player.md @@ -217,3 +217,21 @@ ErrorResponse error = _spotify.SetVolume(50); ```csharp ErrorResponse error = _spotify.SetShuffle(false); ``` + +--- + +## AddToQueue +> Add an Item to the User's Playback Queue. BETA. + +**Parameters** + +|Name|Description|Example| +|--------------|-------------------------|-------------------------| +|uri|The uri of the item to add to the queue. Must be a track or an episode uri.| `spotify:track:7zrCVKp6x0AtolOsn2iMif` +|[deviceId]| The id of the device this command is targeting. If not supplied, the user's currently active device is the target. | `"XXXX-XXXX-XXXX-XXXX"` + +**Usage** + +```csharp +ErrorResponse error = _spotify.AddToQueue("spotify:track:7zrCVKp6x0AtolOsn2iMif"); +``` diff --git a/SpotifyAPI.Web/SpotifyWebAPI.cs b/SpotifyAPI.Web/SpotifyWebAPI.cs index 427db959..2c26e3b4 100644 --- a/SpotifyAPI.Web/SpotifyWebAPI.cs +++ b/SpotifyAPI.Web/SpotifyWebAPI.cs @@ -1,2973 +1,2941 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using SpotifyAPI.Web.Enums; -using SpotifyAPI.Web.Models; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SpotifyAPI.Web.Enums; +using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web { - // ReSharper disable once InconsistentNaming - public sealed class SpotifyWebAPI : IDisposable + // ReSharper disable once InconsistentNaming + public sealed class SpotifyWebAPI : IDisposable + { + private readonly SpotifyWebBuilder _builder; + + public SpotifyWebAPI() : this(null) { } + + public SpotifyWebAPI(ProxyConfig proxyConfig) { - private readonly SpotifyWebBuilder _builder; - - public SpotifyWebAPI() : this(null) + _builder = new SpotifyWebBuilder(); + UseAuth = true; + WebClient = new SpotifyWebClient(proxyConfig) + { + JsonSettings = + new JsonSerializerSettings { + NullValueHandling = NullValueHandling.Ignore } - - public SpotifyWebAPI(ProxyConfig proxyConfig) - { - _builder = new SpotifyWebBuilder(); - UseAuth = true; - WebClient = new SpotifyWebClient(proxyConfig) - { - JsonSettings = - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - } - }; - } - - public void Dispose() - { - WebClient.Dispose(); - GC.SuppressFinalize(this); - } - - #region Configuration - - /// - /// The type of the - /// - public string TokenType { get; set; } - - /// - /// A valid token issued by spotify. Used only when is true - /// - public string AccessToken { get; set; } - - /// - /// If true, an authorization header based on and will be used - /// - public bool UseAuth { get; set; } - - /// - /// A custom WebClient, used for Unit-Testing - /// - public IClient WebClient { get; set; } - - - /// - /// Specifies after how many miliseconds should a failed request be retried. - /// - public int RetryAfter { get; set; } = 50; - - /// - /// Should a failed request (specified by be automatically retried or not. - /// - public bool UseAutoRetry { get; set; } = false; - - /// - /// Maximum number of tries for one failed request. - /// - public int RetryTimes { get; set; } = 10; - - /// - /// Whether a failure of type "Too Many Requests" should use up one of the allocated retry attempts. - /// - public bool TooManyRequestsConsumesARetry { get; set; } = false; - - /// - /// Error codes that will trigger auto-retry if is enabled. - /// - public IEnumerable RetryErrorCodes { get; set; } = new[] { 500, 502, 503 }; - - #endregion Configuration - - #region Search - - /// - /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. - /// - /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. - /// A list of item types to search across. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first result to return. Default: 0 - /// An ISO 3166-1 alpha-2 country code or the string from_token. - /// - public SearchItem SearchItems(string q, SearchType type, int limit = 20, int offset = 0, string market = "") - { - return DownloadData(_builder.SearchItems(q, type, limit, offset, market)); - } - - /// - /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string asynchronously. - /// - /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. - /// A list of item types to search across. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first result to return. Default: 0 - /// An ISO 3166-1 alpha-2 country code or the string from_token. - /// - public Task SearchItemsAsync(string q, SearchType type, int limit = 20, int offset = 0, string market = "") - { - return DownloadDataAsync(_builder.SearchItems(q, type, limit, offset, market)); - } - - /// - /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. - /// - /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. (properly escaped) - /// A list of item types to search across. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first result to return. Default: 0 - /// An ISO 3166-1 alpha-2 country code or the string from_token. - /// - public SearchItem SearchItemsEscaped(string q, SearchType type, int limit = 20, int offset = 0, string market = "") - { - string escapedQuery = WebUtility.UrlEncode(q); - return DownloadData(_builder.SearchItems(escapedQuery, type, limit, offset, market)); - } - - /// - /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string asynchronously. - /// - /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. (properly escaped) - /// A list of item types to search across. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first result to return. Default: 0 - /// An ISO 3166-1 alpha-2 country code or the string from_token. - /// - public Task SearchItemsEscapedAsync(string q, SearchType type, int limit = 20, int offset = 0, string market = "") - { - string escapedQuery = WebUtility.UrlEncode(q); - return DownloadDataAsync(_builder.SearchItems(escapedQuery, type, limit, offset, market)); - } - - #endregion Search - - #region Albums - - /// - /// Get Spotify catalog information about an album’s tracks. Optional parameters can be used to limit the number of - /// tracks returned. - /// - /// The Spotify ID for the album. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first track to return. Default: 0 (the first object). - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public Paging GetAlbumTracks(string id, int limit = 20, int offset = 0, string market = "") - { - return DownloadData>(_builder.GetAlbumTracks(id, limit, offset, market)); - } - - /// - /// Get Spotify catalog information about an album’s tracks asynchronously. Optional parameters can be used to limit the number of - /// tracks returned. - /// - /// The Spotify ID for the album. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first track to return. Default: 0 (the first object). - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public Task> GetAlbumTracksAsync(string id, int limit = 20, int offset = 0, string market = "") - { - return DownloadDataAsync>(_builder.GetAlbumTracks(id, limit, offset, market)); - } - - /// - /// Get Spotify catalog information for a single album. - /// - /// The Spotify ID for the album. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public FullAlbum GetAlbum(string id, string market = "") - { - return DownloadData(_builder.GetAlbum(id, market)); - } - - /// - /// Get Spotify catalog information for a single album asynchronously. - /// - /// The Spotify ID for the album. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public Task GetAlbumAsync(string id, string market = "") - { - return DownloadDataAsync(_builder.GetAlbum(id, market)); - } - - /// - /// Get Spotify catalog information for multiple albums identified by their Spotify IDs. - /// - /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public SeveralAlbums GetSeveralAlbums(List ids, string market = "") - { - return DownloadData(_builder.GetSeveralAlbums(ids, market)); - } - - /// - /// Get Spotify catalog information for multiple albums identified by their Spotify IDs asynchrously. - /// - /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public Task GetSeveralAlbumsAsync(List ids, string market = "") - { - return DownloadDataAsync(_builder.GetSeveralAlbums(ids, market)); - } - - #endregion Albums - - #region Artists - - /// - /// Get Spotify catalog information for a single artist identified by their unique Spotify ID. - /// - /// The Spotify ID for the artist. - /// - public FullArtist GetArtist(string id) - { - return DownloadData(_builder.GetArtist(id)); - } - - /// - /// Get Spotify catalog information for a single artist identified by their unique Spotify ID asynchronously. - /// - /// The Spotify ID for the artist. - /// - public Task GetArtistAsync(string id) - { - return DownloadDataAsync(_builder.GetArtist(id)); - } - - /// - /// Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the - /// Spotify community’s listening history. - /// - /// The Spotify ID for the artist. - /// - public SeveralArtists GetRelatedArtists(string id) - { - return DownloadData(_builder.GetRelatedArtists(id)); - } - - /// - /// Get Spotify catalog information about artists similar to a given artist asynchronously. Similarity is based on analysis of the - /// Spotify community’s listening history. - /// - /// The Spotify ID for the artist. - /// - public Task GetRelatedArtistsAsync(string id) - { - return DownloadDataAsync(_builder.GetRelatedArtists(id)); - } - - /// - /// Get Spotify catalog information about an artist’s top tracks by country. - /// - /// The Spotify ID for the artist. - /// The country: an ISO 3166-1 alpha-2 country code. - /// - public SeveralTracks GetArtistsTopTracks(string id, string country) - { - return DownloadData(_builder.GetArtistsTopTracks(id, country)); - } - - /// - /// Get Spotify catalog information about an artist’s top tracks by country asynchronously. - /// - /// The Spotify ID for the artist. - /// The country: an ISO 3166-1 alpha-2 country code. - /// - public Task GetArtistsTopTracksAsync(string id, string country) - { - return DownloadDataAsync(_builder.GetArtistsTopTracks(id, country)); - } - - /// - /// Get Spotify catalog information about an artist’s albums. Optional parameters can be specified in the query string - /// to filter and sort the response. - /// - /// The Spotify ID for the artist. - /// - /// A list of keywords that will be used to filter the response. If not supplied, all album types will - /// be returned - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first album to return. Default: 0 - /// - /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular - /// geographical market - /// - /// - public Paging GetArtistsAlbums(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") - { - return DownloadData>(_builder.GetArtistsAlbums(id, type, limit, offset, market)); - } - - /// - /// Get Spotify catalog information about an artist’s albums asynchronously. Optional parameters can be specified in the query string - /// to filter and sort the response. - /// - /// The Spotify ID for the artist. - /// - /// A list of keywords that will be used to filter the response. If not supplied, all album types will - /// be returned - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first album to return. Default: 0 - /// - /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular - /// geographical market - /// - /// - public Task> GetArtistsAlbumsAsync(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") - { - return DownloadDataAsync>(_builder.GetArtistsAlbums(id, type, limit, offset, market)); - } - - /// - /// Get Spotify catalog information for several artists based on their Spotify IDs. - /// - /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. - /// - public SeveralArtists GetSeveralArtists(List ids) - { - return DownloadData(_builder.GetSeveralArtists(ids)); - } - - /// - /// Get Spotify catalog information for several artists based on their Spotify IDs asynchronously. - /// - /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. - /// - public Task GetSeveralArtistsAsync(List ids) - { - return DownloadDataAsync(_builder.GetSeveralArtists(ids)); - } - - #endregion Artists - - #region Browse - - /// - /// Get a list of Spotify featured playlists (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// - /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 - /// alpha-2 country code, joined by an underscore. - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// A timestamp in ISO 8601 format - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// AUTH NEEDED - public FeaturedPlaylists GetFeaturedPlaylists(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetFeaturedPlaylists"); - return DownloadData(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset)); - } - - /// - /// Get a list of Spotify featured playlists asynchronously (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// - /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 - /// alpha-2 country code, joined by an underscore. - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// A timestamp in ISO 8601 format - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// AUTH NEEDED - public Task GetFeaturedPlaylistsAsync(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetFeaturedPlaylists"); - return DownloadDataAsync(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset)); - } - - /// - /// Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public NewAlbumReleases GetNewAlbumReleases(string country = "", int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetNewAlbumReleases"); - return DownloadData(_builder.GetNewAlbumReleases(country, limit, offset)); - } - - /// - /// Get a list of new album releases featured in Spotify asynchronously (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public Task GetNewAlbumReleasesAsync(string country = "", int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetNewAlbumReleases"); - return DownloadDataAsync(_builder.GetNewAlbumReleases(country, limit, offset)); - } - - /// - /// Get a list of categories used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). - /// - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the - /// list of returned categories to those relevant to a particular country - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 (the first object). - /// - /// AUTH NEEDED - public CategoryList GetCategories(string country = "", string locale = "", int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetCategories"); - return DownloadData(_builder.GetCategories(country, locale, limit, offset)); - } - - /// - /// Get a list of categories used to tag items in Spotify asynchronously (on, for example, the Spotify player’s “Browse” tab). - /// - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the - /// list of returned categories to those relevant to a particular country - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 (the first object). - /// - /// AUTH NEEDED - public Task GetCategoriesAsync(string country = "", string locale = "", int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetCategories"); - return DownloadDataAsync(_builder.GetCategories(country, locale, limit, offset)); - } - - /// - /// Get a single category used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). - /// - /// The Spotify category ID for the category. - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category - /// exists for a particular country. - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// - /// AUTH NEEDED - public Category GetCategory(string categoryId, string country = "", string locale = "") - { - return DownloadData(_builder.GetCategory(categoryId, country, locale)); - } - - /// - /// Get a single category used to tag items in Spotify asynchronously (on, for example, the Spotify player’s “Browse” tab). - /// - /// The Spotify category ID for the category. - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category - /// exists for a particular country. - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// - /// AUTH NEEDED - public Task GetCategoryAsync(string categoryId, string country = "", string locale = "") - { - return DownloadDataAsync(_builder.GetCategory(categoryId, country, locale)); - } - - /// - /// Get a list of Spotify playlists tagged with a particular category. - /// - /// The Spotify category ID for the category. - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public CategoryPlaylist GetCategoryPlaylists(string categoryId, string country = "", int limit = 20, int offset = 0) - { - return DownloadData(_builder.GetCategoryPlaylists(categoryId, country, limit, offset)); - } - - /// - /// Get a list of Spotify playlists tagged with a particular category asynchronously. - /// - /// The Spotify category ID for the category. - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public Task GetCategoryPlaylistsAsync(string categoryId, string country = "", int limit = 20, int offset = 0) - { - return DownloadDataAsync(_builder.GetCategoryPlaylists(categoryId, country, limit, offset)); - } - - /// - /// Create a playlist-style listening experience based on seed artists, tracks and genres. - /// - /// A comma separated list of Spotify IDs for seed artists. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of any genres in the set of available genre seeds. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of Spotify IDs for a seed track. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// Tracks with the attribute values nearest to the target values will be preferred. - /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided - /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided - /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. - /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. - /// - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. - /// - /// AUTH NEEDED - public Recommendations GetRecommendations(List artistSeed = null, List genreSeed = null, List trackSeed = null, - TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") - { - return DownloadData(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market)); - } - - /// - /// Create a playlist-style listening experience based on seed artists, tracks and genres asynchronously. - /// - /// A comma separated list of Spotify IDs for seed artists. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of any genres in the set of available genre seeds. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of Spotify IDs for a seed track. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// Tracks with the attribute values nearest to the target values will be preferred. - /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided - /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided - /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. - /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. - /// - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. - /// - /// AUTH NEEDED - public Task GetRecommendationsAsync(List artistSeed = null, List genreSeed = null, List trackSeed = null, - TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") - { - return DownloadDataAsync(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market)); - } - - /// - /// Retrieve a list of available genres seed parameter values for recommendations. - /// - /// - /// AUTH NEEDED - public RecommendationSeedGenres GetRecommendationSeedsGenres() - { - return DownloadData(_builder.GetRecommendationSeedsGenres()); - } - - /// - /// Retrieve a list of available genres seed parameter values for recommendations asynchronously. - /// - /// - /// AUTH NEEDED - public Task GetRecommendationSeedsGenresAsync() - { - return DownloadDataAsync(_builder.GetRecommendationSeedsGenres()); - } - - #endregion Browse - - #region Follow - - /// - /// Get the current user’s followed artists. - /// - /// The ID type: currently only artist is supported. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The last artist ID retrieved from the previous request. - /// - /// AUTH NEEDED - public FollowedArtists GetFollowedArtists(FollowType followType, int limit = 20, string after = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetFollowedArtists"); - return DownloadData(_builder.GetFollowedArtists(limit, after)); - } - - /// - /// Get the current user’s followed artists asynchronously. - /// - /// The ID type: currently only artist is supported. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The last artist ID retrieved from the previous request. - /// - /// AUTH NEEDED - public Task GetFollowedArtistsAsync(FollowType followType, int limit = 20, string after = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetFollowedArtists"); - return DownloadDataAsync(_builder.GetFollowedArtists(limit, after)); - } - - /// - /// Add the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs - /// - /// AUTH NEEDED - public ErrorResponse Follow(FollowType followType, List ids) - { - JObject ob = new JObject - { - {"ids", new JArray(ids)} - }; - return UploadData(_builder.Follow(followType), ob.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); - } - - /// - /// Add the current user as a follower of one or more artists or other Spotify users asynchronously. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs - /// - /// AUTH NEEDED - public async Task FollowAsync(FollowType followType, List ids) - { - JObject ob = new JObject - { - {"ids", new JArray(ids)} - }; - return await UploadDataAsync(_builder.Follow(followType), - ob.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Add the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public ErrorResponse Follow(FollowType followType, string id) - { - return Follow(followType, new List { id }); - } - - /// - /// Add the current user as a follower of one or more artists or other Spotify users asynchronously. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public Task FollowAsync(FollowType followType, string id) - { - return FollowAsync(followType, new List { id }); - } - - /// - /// Remove the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs - /// - /// AUTH NEEDED - public ErrorResponse Unfollow(FollowType followType, List ids) - { - JObject ob = new JObject - { - {"ids", new JArray(ids)} - }; - return UploadData(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); - } - - /// - /// Remove the current user as a follower of one or more artists or other Spotify users asynchronously. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs - /// - /// AUTH NEEDED - public async Task UnfollowAsync(FollowType followType, List ids) - { - JObject ob = new JObject - { - {"ids", new JArray(ids)} - }; - return await UploadDataAsync(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Remove the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public ErrorResponse Unfollow(FollowType followType, string id) - { - return Unfollow(followType, new List { id }); - } - - /// - /// Remove the current user as a follower of one or more artists or other Spotify users asynchronously. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public Task UnfollowAsync(FollowType followType, string id) - { - return UnfollowAsync(followType, new List { id }); - } - - /// - /// Check to see if the current user is following one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs to check - /// - /// AUTH NEEDED - public ListResponse IsFollowing(FollowType followType, List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for IsFollowing"); - - string url = _builder.IsFollowing(followType, ids); - return DownloadList(url); - } - - - - /// - /// Check to see if the current user is following one or more artists or other Spotify users asynchronously. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs to check - /// - /// AUTH NEEDED - public Task> IsFollowingAsync(FollowType followType, List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for IsFollowing"); - - string url = _builder.IsFollowing(followType, ids); - return DownloadListAsync(url); - } - - /// - /// Check to see if the current user is following one artist or another Spotify user. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public ListResponse IsFollowing(FollowType followType, string id) - { - return IsFollowing(followType, new List { id }); - } - - /// - /// Check to see if the current user is following one artist or another Spotify user asynchronously. - /// - /// The ID type: either artist or user. - /// Artists or the Users Spotify ID - /// - /// AUTH NEEDED - public Task> IsFollowingAsync(FollowType followType, string id) - { - return IsFollowingAsync(followType, new List { id }); - } - - /// - /// Add the current user as a follower of a playlist. - /// - /// - /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private - /// status, as long as you know its playlist ID. - /// - /// - /// If true the playlist will be included in user's public playlists, if false it will remain - /// private. - /// - /// - /// AUTH NEEDED - public ErrorResponse FollowPlaylist(string ownerId, string playlistId, bool showPublic = true) - { - JObject body = new JObject - { - {"public", showPublic} - }; - return UploadData(_builder.FollowPlaylist(playlistId), body.ToString(Formatting.None), "PUT"); - } - - /// - /// Add the current user as a follower of a playlist asynchronously. - /// - /// - /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private - /// status, as long as you know its playlist ID. - /// - /// - /// If true the playlist will be included in user's public playlists, if false it will remain - /// private. - /// - /// - /// AUTH NEEDED - public Task FollowPlaylistAsync(string playlistId, bool showPublic = true) - { - JObject body = new JObject - { - {"public", showPublic} - }; - return UploadDataAsync(_builder.FollowPlaylist(playlistId), body.ToString(Formatting.None), "PUT"); - } - - /// - /// Remove the current user as a follower of a playlist. - /// - /// The Spotify ID of the playlist that is to be no longer followed. - /// - /// AUTH NEEDED - public ErrorResponse UnfollowPlaylist(string playlistId) - { - return UploadData(_builder.UnfollowPlaylist(playlistId), "", "DELETE"); - } - - /// - /// Remove the current user as a follower of a playlist asynchronously. - /// - /// The Spotify user ID of the person who owns the playlist. - /// The Spotify ID of the playlist that is to be no longer followed. - /// - /// AUTH NEEDED - public Task UnfollowPlaylistAsync(string playlistId) - { - return UploadDataAsync(_builder.UnfollowPlaylist(playlistId), "", "DELETE"); - } - - /// - /// Check to see if one or more Spotify users are following a specified playlist. - /// - /// The Spotify ID of the playlist. - /// A list of Spotify User IDs - /// - /// AUTH NEEDED - public ListResponse IsFollowingPlaylist(string playlistId, List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); - - string url = _builder.IsFollowingPlaylist(playlistId, ids); - return DownloadList(url); - } - - /// - /// Check to see if one or more Spotify users are following a specified playlist asynchronously. - /// - /// The Spotify ID of the playlist. - /// A list of Spotify User IDs - /// - /// AUTH NEEDED - public Task> IsFollowingPlaylistAsync(string playlistId, List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); - - string url = _builder.IsFollowingPlaylist(playlistId, ids); - return DownloadListAsync(url); - } - - /// - /// Check to see if one or more Spotify users are following a specified playlist. - /// - /// The Spotify ID of the playlist. - /// A Spotify User ID - /// - /// AUTH NEEDED - public ListResponse IsFollowingPlaylist( string playlistId, string id) - { - return IsFollowingPlaylist(playlistId, new List { id }); - } - - /// - /// Check to see if one or more Spotify users are following a specified playlist asynchronously. - /// - /// The Spotify ID of the playlist. - /// A Spotify User ID - /// - /// AUTH NEEDED - public Task> IsFollowingPlaylistAsync(string playlistId, string id) - { - return IsFollowingPlaylistAsync( playlistId, new List { id }); - } - - #endregion Follow - - #region Library - - /// - /// Save one or more tracks to the current user’s “Your Music” library. - /// - /// A list of the Spotify IDs - /// - /// AUTH NEEDED - public ErrorResponse SaveTracks(List ids) - { - JArray array = new JArray(ids); - return UploadData(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); - } - - /// - /// Save one or more tracks to the current user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs - /// - /// AUTH NEEDED - public async Task SaveTracksAsync(List ids) - { - JArray array = new JArray(ids); - return await UploadDataAsync(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Save one track to the current user’s “Your Music” library. - /// - /// A Spotify ID - /// - /// AUTH NEEDED - public ErrorResponse SaveTrack(string id) - { - return SaveTracks(new List { id }); - } - - /// - /// Save one track to the current user’s “Your Music” library asynchronously. - /// - /// A Spotify ID - /// - /// AUTH NEEDED - public Task SaveTrackAsync(string id) - { - return SaveTracksAsync(new List { id }); - } - - /// - /// Get a list of the songs saved in the current Spotify user’s “Your Music” library. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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 Paging GetSavedTracks(int limit = 20, int offset = 0, string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetSavedTracks"); - return DownloadData>(_builder.GetSavedTracks(limit, offset, market)); - } - - /// - /// Get a list of the songs saved in the current Spotify user’s “Your Music” library asynchronously. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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> GetSavedTracksAsync(int limit = 20, int offset = 0, string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetSavedTracks"); - return DownloadDataAsync>(_builder.GetSavedTracks(limit, offset, market)); - } - - /// - /// Remove one or more tracks from the current user’s “Your Music” library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public ErrorResponse RemoveSavedTracks(List ids) - { - JArray array = new JArray(ids); - return UploadData(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); - } - - /// - /// Remove one or more tracks from the current user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public async Task RemoveSavedTracksAsync(List ids) - { - JArray array = new JArray(ids); - return await UploadDataAsync(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public ListResponse CheckSavedTracks(List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for CheckSavedTracks"); - - string url = _builder.CheckSavedTracks(ids); - return DownloadList(url); - } - - /// - /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public Task> CheckSavedTracksAsync(List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for CheckSavedTracks"); - string url = _builder.CheckSavedTracks(ids); - return DownloadListAsync(url); - } - - /// - /// Save one or more albums to the current user’s “Your Music” library. - /// - /// A list of the Spotify IDs - /// - /// AUTH NEEDED - public ErrorResponse SaveAlbums(List ids) - { - JArray array = new JArray(ids); - return UploadData(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); - } - - /// - /// Save one or more albums to the current user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs - /// - /// AUTH NEEDED - public async Task SaveAlbumsAsync(List ids) - { - JArray array = new JArray(ids); - return await UploadDataAsync(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Save one album to the current user’s “Your Music” library. - /// - /// A Spotify ID - /// - /// AUTH NEEDED - public ErrorResponse SaveAlbum(string id) - { - return SaveAlbums(new List { id }); - } - - /// - /// Save one album to the current user’s “Your Music” library asynchronously. - /// - /// A Spotify ID - /// - /// AUTH NEEDED - public Task SaveAlbumAsync(string id) - { - return SaveAlbumsAsync(new List { id }); - } - - /// - /// Get a list of the albums saved in the current Spotify user’s “Your Music” library. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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 Paging GetSavedAlbums(int limit = 20, int offset = 0, string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetSavedAlbums"); - return DownloadData>(_builder.GetSavedAlbums(limit, offset, market)); - } - - /// - /// Get a list of the albums saved in the current Spotify user’s “Your Music” library asynchronously. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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> GetSavedAlbumsAsync(int limit = 20, int offset = 0, string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetSavedAlbumsAsync"); - return DownloadDataAsync>(_builder.GetSavedAlbums(limit, offset, market)); - } - - /// - /// Remove one or more albums from the current user’s “Your Music” library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public ErrorResponse RemoveSavedAlbums(List ids) - { - JArray array = new JArray(ids); - return UploadData(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); - } - - /// - /// Remove one or more albums from the current user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public async Task RemoveSavedAlbumsAsync(List ids) - { - JArray array = new JArray(ids); - return await UploadDataAsync(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); - } - - /// - /// Check if one or more albums is already saved in the current Spotify user’s “Your Music” library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public ListResponse CheckSavedAlbums(List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for CheckSavedTracks"); - - string url = _builder.CheckSavedAlbums(ids); - return DownloadList(url); - } - - /// - /// Check if one or more albums is already saved in the current Spotify user’s “Your Music” library asynchronously. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public Task> CheckSavedAlbumsAsync(List ids) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for CheckSavedAlbumsAsync"); - string url = _builder.CheckSavedAlbums(ids); - return DownloadListAsync(url); - } - - #endregion Library - - #region Personalization - - /// - /// Get the current user’s top tracks based on calculated affinity. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public Paging GetUsersTopTracks(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - return DownloadData>(_builder.GetUsersTopTracks(timeRange, limit, offest)); - } - - /// - /// Get the current user’s top tracks based on calculated affinity asynchronously. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public Task> GetUsersTopTracksAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - return DownloadDataAsync>(_builder.GetUsersTopTracks(timeRange, limit, offest)); - } - - /// - /// Get the current user’s top artists based on calculated affinity. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public Paging GetUsersTopArtists(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - return DownloadData>(_builder.GetUsersTopArtists(timeRange, limit, offest)); - } - - /// - /// Get the current user’s top artists based on calculated affinity asynchronously. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public Task> GetUsersTopArtistsAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - return DownloadDataAsync>(_builder.GetUsersTopArtists(timeRange, limit, offest)); - } - - /// - /// Get tracks from the current user’s recent play history. - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. - /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. - /// - /// AUTH NEEDED - public CursorPaging GetUsersRecentlyPlayedTracks(int limit = 20, DateTime? after = null, - DateTime? before = null) - { - return DownloadData>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before)); - } - - /// - /// Get tracks from the current user’s recent play history asynchronously - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. - /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. - /// - /// AUTH NEEDED - public Task> GetUsersRecentlyPlayedTracksAsync(int limit = 20, DateTime? after = null, - DateTime? before = null) - { - return DownloadDataAsync>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before)); - } - - #endregion - - #region Playlists - - /// - /// Get a list of the playlists owned or followed by a Spotify user. - /// - /// 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 Paging GetUserPlaylists(string userId, int limit = 20, int offset = 0) - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetUserPlaylists"); - 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)); - } - - /// - /// 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. - /// - /// 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 FullPlaylist GetPlaylist(string playlistId, string fields = "", string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetPlaylist"); - 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. - /// - /// 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 playlistId, string fields = "", string market = "") - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetPlaylist"); - 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. - /// - /// 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 Paging GetPlaylistTracks(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(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. - /// - /// 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 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(playlistId, fields, limit, offset, market)); - } - - /// - /// Create a playlist for a Spotify user. (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. - /// - /// 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 - public FullPlaylist CreatePlaylist(string userId, string playlistName, bool isPublic = true, bool isCollaborative = false, string playlistDescription = "") - { - JObject body = new JObject - { - {"name", playlistName}, - {"public", isPublic}, - {"collaborative", isCollaborative}, - {"description", playlistDescription} - }; - 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. - /// - /// 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 - public Task CreatePlaylistAsync(string userId, string playlistName, bool isPublic = true, bool isCollaborative = false, string playlistDescription = "") - { - JObject body = new JObject - { - {"name", playlistName}, - {"public", isPublic}, - {"collaborative", isCollaborative}, - {"description", playlistDescription} - }; - 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.) - /// - /// 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 - public ErrorResponse UpdatePlaylist(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(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.) - /// - /// 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 - public async Task UpdatePlaylistAsync(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(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.) - /// - /// The Spotify ID for the playlist. - /// The image as a base64 encoded string - /// - /// AUTH NEEDED - public ErrorResponse UploadPlaylistImage(string playlistId, string base64EncodedJpgImage) - { - return UploadData(_builder.UploadPlaylistImage(playlistId), base64EncodedJpgImage, "PUT") ?? new ErrorResponse(); - } - - /// - /// Change a playlist’s name and public/private state asynchronously. (The user must, of course, own the playlist.) - /// - /// The Spotify ID for the playlist. - /// The image as a base64 encoded string - /// - /// AUTH NEEDED - public async Task UploadPlaylistImageAsync(string playlistId, string base64EncodedJpgImage) - { - return await UploadDataAsync(_builder.UploadPlaylistImage(playlistId), - 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. - /// - /// 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 ErrorResponse ReplacePlaylistTracks(string playlistId, List uris) - { - JObject body = new JObject - { - {"uris", new JArray(uris.Take(100))} - }; - 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. - /// - /// 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 async Task ReplacePlaylistTracksAsync(string playlistId, List uris) - { - JObject body = new JObject - { - {"uris", new JArray(uris.Take(100))} - }; - 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. - /// - /// 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 ErrorResponse RemovePlaylistTracks(string playlistId, List uris) - { - JObject body = new JObject - { - {"tracks", JArray.FromObject(uris.Take(100))} - }; - 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. - /// - /// 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 async Task RemovePlaylistTracksAsync(string playlistId, List uris) - { - JObject body = new JObject - { - {"tracks", JArray.FromObject(uris.Take(100))} - }; - 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. - /// - /// The Spotify ID for the playlist. - /// Spotify URI - /// - /// AUTH NEEDED - public ErrorResponse RemovePlaylistTrack(string playlistId, DeleteTrackUri uri) - { - 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. - /// - /// The Spotify ID for the playlist. - /// Spotify URI - /// - /// AUTH NEEDED - public Task RemovePlaylistTrackAsync(string playlistId, DeleteTrackUri uri) - { - 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. - /// - /// 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 ErrorResponse AddPlaylistTracks(string playlistId, List uris, int? position = null) - { - JObject body = new JObject - { - {"uris", JArray.FromObject(uris.Take(100))} - }; - 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. - /// - /// 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 async Task AddPlaylistTracksAsync(string playlistId, List uris, int? position = null) - { - JObject body = new JObject - { - {"uris", JArray.FromObject(uris.Take(100))} - }; - 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. - /// - /// The Spotify ID for the playlist. - /// A Spotify Track URI - /// The position to insert the tracks, a zero-based index - /// - /// AUTH NEEDED - public ErrorResponse AddPlaylistTrack(string playlistId, string uri, int? position = null) - { - 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. - /// - /// 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 playlistId, string uri, int? position = null) - { - 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. - /// - /// 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 Snapshot ReorderPlaylist(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(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. - /// - /// 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 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(playlistId), body.ToString(Formatting.None), "PUT"); - } - - #endregion Playlists - - #region Profiles - - /// - /// Get detailed profile information about the current user (including the current user’s username). - /// - /// - /// AUTH NEEDED - public PrivateProfile GetPrivateProfile() - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for GetPrivateProfile"); - 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()); - } - - /// - /// Get public profile information about a Spotify user. - /// - /// The user's Spotify user ID. - /// - public PublicProfile GetPublicProfile(string 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 - - #region Tracks - - /// - /// Get Spotify catalog information for multiple tracks based on their Spotify IDs. - /// - /// 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 SeveralTracks GetSeveralTracks(List ids, string market = "") - { - 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)); - } - - /// - /// Get Spotify catalog information for a single track identified by its unique Spotify ID. - /// - /// 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 FullTrack GetTrack(string id, string 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)); - } - - /// - /// Get a detailed audio analysis for a single track identified by its unique Spotify ID. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public AudioAnalysis GetAudioAnalysis(string id) - { - return DownloadData(_builder.GetAudioAnalysis(id)); - } - - /// - /// Get a detailed audio analysis for a single track identified by its unique Spotify ID asynchronously. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public Task GetAudioAnalysisAsync(string id) - { - return DownloadDataAsync(_builder.GetAudioAnalysis(id)); - } - - /// - /// Get audio feature information for a single track identified by its unique Spotify ID. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public AudioFeatures GetAudioFeatures(string id) - { - return DownloadData(_builder.GetAudioFeatures(id)); - } - - /// - /// Get audio feature information for a single track identified by its unique Spotify ID asynchronously. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public Task GetAudioFeaturesAsync(string id) - { - return DownloadDataAsync(_builder.GetAudioFeatures(id)); - } - - /// - /// Get audio features for multiple tracks based on their Spotify IDs. - /// - /// A list of Spotify Track-IDs. Maximum: 100 IDs. - /// - /// AUTH NEEDED - public SeveralAudioFeatures GetSeveralAudioFeatures(List ids) - { - return DownloadData(_builder.GetSeveralAudioFeatures(ids)); - } - - /// - /// Get audio features for multiple tracks based on their Spotify IDs asynchronously. - /// - /// A list of Spotify Track-IDs. Maximum: 100 IDs. - /// - /// AUTH NEEDED - public Task GetSeveralAudioFeaturesAsync(List ids) - { - return DownloadDataAsync(_builder.GetSeveralAudioFeatures(ids)); - } - - #endregion Tracks - - #region Player - - /// - /// Get information about a user’s available devices. - /// - /// - public AvailabeDevices GetDevices() - { - return DownloadData(_builder.GetDevices()); - } - - /// - /// Get information about a user’s available devices. - /// - /// - public Task GetDevicesAsync() - { - return DownloadDataAsync(_builder.GetDevices()); - } - - /// - /// 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. - /// - public PlaybackContext GetPlayback(string market = "") - { - return DownloadData(_builder.GetPlayback(market)); - } - - /// - /// 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. - /// - public Task GetPlaybackAsync(string market = "") - { - return DownloadDataAsync(_builder.GetPlayback(market)); - } - - /// - /// 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. - /// - public PlaybackContext GetPlayingTrack(string market = "") - { - return DownloadData(_builder.GetPlayingTrack(market)); - } - - /// - /// 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. - /// - public Task GetPlayingTrackAsync(string market = "") - { - return DownloadDataAsync(_builder.GetPlayingTrack(market)); - } - - /// - /// Transfer playback to a new device and determine if it should start playing. - /// - /// ID of the device on which playback should be started/transferred to - /// - /// true: ensure playback happens on new device. - /// false or not provided: keep the current playback state. - /// - /// - public ErrorResponse TransferPlayback(string deviceId, bool play = false) => TransferPlayback( - new List { deviceId }, play); - - /// - /// Transfer playback to a new device and determine if it should start playing. - /// - /// ID of the device on which playback should be started/transferred to - /// - /// true: ensure playback happens on new device. - /// false or not provided: keep the current playback state. - /// - /// - public Task TransferPlaybackAsync(string deviceId, bool play = false) => TransferPlaybackAsync( - new List { deviceId }, play); - - /// - /// Transfer playback to a new device and determine if it should start playing. - /// NOTE: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request - /// - /// A array containing the ID of the device on which playback should be started/transferred. - /// - /// true: ensure playback happens on new device. - /// false or not provided: keep the current playback state. - /// - /// - public ErrorResponse TransferPlayback(List deviceIds, bool play = false) - { - JObject ob = new JObject - { - { "play", play }, - { "device_ids", new JArray(deviceIds) } - }; - return UploadData(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Transfer playback to a new device and determine if it should start playing. - /// NOTE: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request - /// - /// A array containing the ID of the device on which playback should be started/transferred. - /// - /// true: ensure playback happens on new device. - /// false or not provided: keep the current playback state. - /// - /// - public Task TransferPlaybackAsync(List deviceIds, bool play = false) - { - JObject ob = new JObject - { - { "play", play }, - { "device_ids", new JArray(deviceIds) } - }; - return UploadDataAsync(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Start a new context or resume current playback on the user’s active device. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// Spotify URI of the context to play. - /// A JSON array of the Spotify track URIs to play. - /// Indicates from where in the context playback should start. - /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. - /// The starting time to seek the track to - /// - public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List uris = null, - int? offset = null, int positionMs = 0) - { - JObject ob = new JObject(); - if(!string.IsNullOrEmpty(contextUri)) - ob.Add("context_uri", contextUri); - if(uris != null) - ob.Add("uris", new JArray(uris)); - if(offset != null) - ob.Add("offset", new JObject { { "position", offset } }); - if (positionMs > 0) - ob.Add("position_ms", positionMs); - return UploadData(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Start a new context or resume current playback on the user’s active device. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// Spotify URI of the context to play. - /// A JSON array of the Spotify track URIs to play. - /// Indicates from where in the context playback should start. - /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. - /// The starting time to seek the track to - /// - public Task ResumePlaybackAsync(string deviceId = "", string contextUri = "", List uris = null, - int? offset = null, int positionMs = 0) - { - JObject ob = new JObject(); - if (!string.IsNullOrEmpty(contextUri)) - ob.Add("context_uri", contextUri); - if (uris != null) - ob.Add("uris", new JArray(uris)); - if (offset != null) - ob.Add("offset", new JObject { { "position", offset } }); - if (positionMs > 0) - ob.Add("position_ms", positionMs); - return UploadDataAsync(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Start a new context or resume current playback on the user’s active device. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// Spotify URI of the context to play. - /// A JSON array of the Spotify track URIs to play. - /// Indicates from where in the context playback should start. - /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. - /// The starting time to seek the track to - /// - public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List uris = null, - string offset = "", int positionMs = 0) - { - JObject ob = new JObject(); - if (!string.IsNullOrEmpty(contextUri)) - ob.Add("context_uri", contextUri); - if (uris != null) - ob.Add("uris", new JArray(uris)); - if (!string.IsNullOrEmpty(offset)) - ob.Add("offset", new JObject {{"uri", offset}}); - if (positionMs > 0) - ob.Add("position_ms", positionMs); - return UploadData(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Start a new context or resume current playback on the user’s active device. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// Spotify URI of the context to play. - /// A JSON array of the Spotify track URIs to play. - /// Indicates from where in the context playback should start. - /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. - /// The starting time to seek the track to - /// - public Task ResumePlaybackAsync(string deviceId = "", string contextUri = "", List uris = null, - string offset = "", int positionMs = 0) - { - JObject ob = new JObject(); - if (!string.IsNullOrEmpty(contextUri)) - ob.Add("context_uri", contextUri); - if (uris != null) - ob.Add("uris", new JArray(uris)); - if (!string.IsNullOrEmpty(offset)) - ob.Add("offset", new JObject { { "uri", offset } }); - if (positionMs > 0) - ob.Add("position_ms", positionMs); - return UploadDataAsync(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); - } - - /// - /// Pause playback on the user’s account. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse PausePlayback(string deviceId = "") - { - return UploadData(_builder.PausePlayback(deviceId), string.Empty, "PUT"); - } - - /// - /// Pause playback on the user’s account. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task PausePlaybackAsync(string deviceId = "") - { - return UploadDataAsync(_builder.PausePlayback(deviceId), string.Empty, "PUT"); - } - - /// - /// Skips to next track in the user’s queue. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SkipPlaybackToNext(string deviceId = "") - { - return UploadData(_builder.SkipPlaybackToNext(deviceId), string.Empty); - } - - /// - /// Skips to next track in the user’s queue. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SkipPlaybackToNextAsync(string deviceId = "") - { - return UploadDataAsync(_builder.SkipPlaybackToNext(deviceId), string.Empty); - } - - /// - /// Skips to previous track in the user’s queue. - /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. - /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SkipPlaybackToPrevious(string deviceId = "") - { - return UploadData(_builder.SkipPlaybackToPrevious(deviceId), string.Empty); - } - - /// - /// Skips to previous track in the user’s queue. - /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. - /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SkipPlaybackToPreviousAsync(string deviceId = "") - { - return UploadDataAsync(_builder.SkipPlaybackToPrevious(deviceId), string.Empty); - } - - /// - /// Seeks to the given position in the user’s currently playing track. - /// - /// The position in milliseconds to seek to. Must be a positive number. - /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SeekPlayback(int positionMs, string deviceId = "") - { - return UploadData(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT"); - } - - /// - /// Seeks to the given position in the user’s currently playing track. - /// - /// The position in milliseconds to seek to. Must be a positive number. - /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SeekPlaybackAsync(int positionMs, string deviceId = "") - { - return UploadDataAsync(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT"); - } - - /// - /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. - /// - /// track, context or off. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SetRepeatMode(RepeatState state, string deviceId = "") - { - return UploadData(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT"); - } - - /// - /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. - /// - /// track, context or off. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SetRepeatModeAsync(RepeatState state, string deviceId = "") - { - return UploadDataAsync(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT"); - } - - /// - /// Set the volume for the user’s current playback device. - /// - /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SetVolume(int volumePercent, string deviceId = "") - { - return UploadData(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT"); - } - - /// - /// Set the volume for the user’s current playback device. - /// - /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SetVolumeAsync(int volumePercent, string deviceId = "") - { - return UploadDataAsync(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT"); - } - - /// - /// Toggle shuffle on or off for user’s playback. - /// - /// True or False - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public ErrorResponse SetShuffle(bool shuffle, string deviceId = "") - { - return UploadData(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT"); - } - - /// - /// Toggle shuffle on or off for user’s playback. - /// - /// True or False - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public Task SetShuffleAsync(bool shuffle, string deviceId = "") - { - return UploadDataAsync(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT"); - } - - #endregion - - #region Util - - public TOut GetNextPage(Paging paging) where TOut : BasicModel - { - if (!paging.HasNextPage()) - throw new InvalidOperationException("This Paging-Object has no Next-Page"); - return DownloadData(paging.Next); - } - - public TOut GetNextPage(CursorPaging paging) where TOut : BasicModel - { - if (!paging.HasNext()) - throw new InvalidOperationException("This CursorPaging-Object has no Next-Page"); - return DownloadData(paging.Next); - } - - public Paging GetNextPage(Paging paging) - { - return GetNextPage, T>(paging); - } - - public CursorPaging GetNextPage(CursorPaging paging) - { - return GetNextPage, T>(paging); - } - - public Task GetNextPageAsync(Paging paging) where TOut : BasicModel - { - if (!paging.HasNextPage()) - throw new InvalidOperationException("This Paging-Object has no Next-Page"); - return DownloadDataAsync(paging.Next); - } - - public Task GetNextPageAsync(CursorPaging paging) where TOut : BasicModel - { - if (!paging.HasNext()) - throw new InvalidOperationException("This Paging-Object has no Next-Page"); - return DownloadDataAsync(paging.Next); - } - - public Task> GetNextPageAsync(Paging paging) - { - return GetNextPageAsync, T>(paging); - } - - public Task> GetNextPageAsync(CursorPaging paging) - { - return GetNextPageAsync, T>(paging); - } - - public TOut GetPreviousPage(Paging paging) where TOut : BasicModel - { - if (!paging.HasPreviousPage()) - throw new InvalidOperationException("This Paging-Object has no Previous-Page"); - return DownloadData(paging.Previous); - } - - public Paging GetPreviousPage(Paging paging) - { - return GetPreviousPage, T>(paging); - } - - public Task GetPreviousPageAsync(Paging paging) where TOut : BasicModel - { - if (!paging.HasPreviousPage()) - throw new InvalidOperationException("This Paging-Object has no Previous-Page"); - return DownloadDataAsync(paging.Previous); - } - - public Task> GetPreviousPageAsync(Paging paging) - { - return GetPreviousPageAsync, T>(paging); - } - - private ListResponse DownloadList(string url) - { - int triesLeft = RetryTimes + 1; - Error lastError; - - ListResponse data = null; - do - { - if (data != null) { Thread.Sleep(RetryAfter); } - Tuple res = DownloadDataAlt(url); - data = ExtractDataToListResponse(res); - - lastError = data.Error; - - triesLeft -= 1; - - } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); - - return data; - } - - private async Task> DownloadListAsync(string url) - { - int triesLeft = RetryTimes + 1; - Error lastError; - - ListResponse data = null; - do - { - if (data != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); } - Tuple res = await DownloadDataAltAsync(url).ConfigureAwait(false); - data = ExtractDataToListResponse(res); - - lastError = data.Error; - - triesLeft -= 1; - - } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); - - return data; - } - - private static ListResponse ExtractDataToListResponse(Tuple res) - { - ListResponse ret; - if (res.Item2 is JArray) - { - ret = new ListResponse - { - List = res.Item2.ToObject>(), - Error = null - }; - } - else - { - ret = new ListResponse - { - List = null, - Error = res.Item2["error"].ToObject() - }; - } - ret.AddResponseInfo(res.Item1); - return ret; - } - - public T UploadData(string url, string uploadData, string method = "POST") where T : BasicModel - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for all Upload-Actions"); - int triesLeft = RetryTimes + 1; - Error lastError; - - Tuple response = null; - do - { - Dictionary headers = new Dictionary - { - { "Authorization", TokenType + " " + AccessToken}, - { "Content-Type", "application/json" } - }; - - if (response != null) { Thread.Sleep(RetryAfter); } - response = WebClient.UploadJson(url, uploadData, method, headers); - - response.Item2.AddResponseInfo(response.Item1); - lastError = response.Item2.Error; - triesLeft -= 1; - - } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); - - return response.Item2; - } - - public async Task UploadDataAsync(string url, string uploadData, string method = "POST") where T : BasicModel - { - if (!UseAuth) - throw new InvalidOperationException("Auth is required for all Upload-Actions"); - - int triesLeft = RetryTimes + 1; - Error lastError; - - Tuple response = null; - do - { - Dictionary headers = new Dictionary - { - { "Authorization", TokenType + " " + AccessToken}, - { "Content-Type", "application/json" } - }; - - if (response != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); } - response = await WebClient.UploadJsonAsync(url, uploadData, method, headers).ConfigureAwait(false); - - response.Item2.AddResponseInfo(response.Item1); - lastError = response.Item2.Error; - - triesLeft -= 1; - - } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); - - return response.Item2; - } - - public T DownloadData(string url) where T : BasicModel - { - int triesLeft = RetryTimes + 1; - Error lastError; - - Tuple response = null; - do - { - if(response != null) { Thread.Sleep(RetryAfter); } - response = DownloadDataAlt(url); - - response.Item2.AddResponseInfo(response.Item1); - lastError = response.Item2.Error; - - triesLeft -= 1; - - } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); - - - return response.Item2; - } - - /// - /// Retrieves whether request had a "TooManyRequests" error, and get the amount Spotify recommends waiting before another request. - /// - /// Info object to analyze. - /// Seconds to wait before making another request. -1 if no error. - /// AUTH NEEDED - private int GetTooManyRequests(ResponseInfo info) - { - // 429 is "TooManyRequests" value specified in Spotify API - if (429 != (int)info.StatusCode) - { - return -1; - } - if (!int.TryParse(info.Headers.Get("Retry-After"), out int secondsToWait)) - { - return -1; - } - return secondsToWait; - } - - public async Task DownloadDataAsync(string url) where T : BasicModel - { - int triesLeft = RetryTimes + 1; - Error lastError; - - Tuple response = null; - do - { - if (response != null) - { - int msToWait = RetryAfter; - int secondsToWait = GetTooManyRequests(response.Item1); - if (secondsToWait > 0) - { - msToWait = secondsToWait * 1000; - } - await Task.Delay(msToWait).ConfigureAwait(false); - } - response = await DownloadDataAltAsync(url).ConfigureAwait(false); - - response.Item2.AddResponseInfo(response.Item1); - lastError = response.Item2.Error; - - if (TooManyRequestsConsumesARetry || GetTooManyRequests(response.Item1) == -1) - { - triesLeft -= 1; - } - - } while (UseAutoRetry - && triesLeft > 0 - && (GetTooManyRequests(response.Item1) != -1 - || lastError != null && RetryErrorCodes.Contains(lastError.Status))); - - - return response.Item2; - } - - private Tuple DownloadDataAlt(string url) - { - Dictionary headers = new Dictionary(); - if (UseAuth) - headers.Add("Authorization", TokenType + " " + AccessToken); - return WebClient.DownloadJson(url, headers); - } - - private Task> DownloadDataAltAsync(string url) - { - Dictionary headers = new Dictionary(); - if (UseAuth) - headers.Add("Authorization", TokenType + " " + AccessToken); - return WebClient.DownloadJsonAsync(url, headers); - } - - #endregion Util + }; } + + public void Dispose() + { + WebClient.Dispose(); + GC.SuppressFinalize(this); + } + + #region Configuration + + /// + /// The type of the + /// + public string TokenType { get; set; } + + /// + /// A valid token issued by spotify. Used only when is true + /// + public string AccessToken { get; set; } + + /// + /// If true, an authorization header based on and will be used + /// + public bool UseAuth { get; set; } + + /// + /// A custom WebClient, used for Unit-Testing + /// + public IClient WebClient { get; set; } + + /// + /// Specifies after how many miliseconds should a failed request be retried. + /// + public int RetryAfter { get; set; } = 50; + + /// + /// Should a failed request (specified by be automatically retried or not. + /// + public bool UseAutoRetry { get; set; } = false; + + /// + /// Maximum number of tries for one failed request. + /// + public int RetryTimes { get; set; } = 10; + + /// + /// Whether a failure of type "Too Many Requests" should use up one of the allocated retry attempts. + /// + public bool TooManyRequestsConsumesARetry { get; set; } = false; + + /// + /// Error codes that will trigger auto-retry if is enabled. + /// + public IEnumerable RetryErrorCodes { get; set; } = new [] { 500, 502, 503 }; + + #endregion Configuration + + #region Search + + /// + /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. + /// + /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. + /// A list of item types to search across. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first result to return. Default: 0 + /// An ISO 3166-1 alpha-2 country code or the string from_token. + /// + public SearchItem SearchItems(string q, SearchType type, int limit = 20, int offset = 0, string market = "") + { + return DownloadData(_builder.SearchItems(q, type, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string asynchronously. + /// + /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. + /// A list of item types to search across. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first result to return. Default: 0 + /// An ISO 3166-1 alpha-2 country code or the string from_token. + /// + public Task SearchItemsAsync(string q, SearchType type, int limit = 20, int offset = 0, string market = "") + { + return DownloadDataAsync(_builder.SearchItems(q, type, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. + /// + /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. (properly escaped) + /// A list of item types to search across. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first result to return. Default: 0 + /// An ISO 3166-1 alpha-2 country code or the string from_token. + /// + public SearchItem SearchItemsEscaped(string q, SearchType type, int limit = 20, int offset = 0, string market = "") + { + string escapedQuery = WebUtility.UrlEncode(q); + return DownloadData(_builder.SearchItems(escapedQuery, type, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string asynchronously. + /// + /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. (properly escaped) + /// A list of item types to search across. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first result to return. Default: 0 + /// An ISO 3166-1 alpha-2 country code or the string from_token. + /// + public Task SearchItemsEscapedAsync(string q, SearchType type, int limit = 20, int offset = 0, string market = "") + { + string escapedQuery = WebUtility.UrlEncode(q); + return DownloadDataAsync(_builder.SearchItems(escapedQuery, type, limit, offset, market)); + } + + #endregion Search + + #region Albums + + /// + /// Get Spotify catalog information about an album’s tracks. Optional parameters can be used to limit the number of + /// tracks returned. + /// + /// The Spotify ID for the album. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first track to return. Default: 0 (the first object). + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Paging GetAlbumTracks(string id, int limit = 20, int offset = 0, string market = "") + { + return DownloadData>(_builder.GetAlbumTracks(id, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about an album’s tracks asynchronously. Optional parameters can be used to limit the number of + /// tracks returned. + /// + /// The Spotify ID for the album. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first track to return. Default: 0 (the first object). + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task> GetAlbumTracksAsync(string id, int limit = 20, int offset = 0, string market = "") + { + return DownloadDataAsync>(_builder.GetAlbumTracks(id, limit, offset, market)); + } + + /// + /// Get Spotify catalog information for a single album. + /// + /// The Spotify ID for the album. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public FullAlbum GetAlbum(string id, string market = "") + { + return DownloadData(_builder.GetAlbum(id, market)); + } + + /// + /// Get Spotify catalog information for a single album asynchronously. + /// + /// The Spotify ID for the album. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetAlbumAsync(string id, string market = "") + { + return DownloadDataAsync(_builder.GetAlbum(id, market)); + } + + /// + /// Get Spotify catalog information for multiple albums identified by their Spotify IDs. + /// + /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public SeveralAlbums GetSeveralAlbums(List ids, string market = "") + { + return DownloadData(_builder.GetSeveralAlbums(ids, market)); + } + + /// + /// Get Spotify catalog information for multiple albums identified by their Spotify IDs asynchrously. + /// + /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public Task GetSeveralAlbumsAsync(List ids, string market = "") + { + return DownloadDataAsync(_builder.GetSeveralAlbums(ids, market)); + } + + #endregion Albums + + #region Artists + + /// + /// Get Spotify catalog information for a single artist identified by their unique Spotify ID. + /// + /// The Spotify ID for the artist. + /// + public FullArtist GetArtist(string id) + { + return DownloadData(_builder.GetArtist(id)); + } + + /// + /// Get Spotify catalog information for a single artist identified by their unique Spotify ID asynchronously. + /// + /// The Spotify ID for the artist. + /// + public Task GetArtistAsync(string id) + { + return DownloadDataAsync(_builder.GetArtist(id)); + } + + /// + /// Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the + /// Spotify community’s listening history. + /// + /// The Spotify ID for the artist. + /// + public SeveralArtists GetRelatedArtists(string id) + { + return DownloadData(_builder.GetRelatedArtists(id)); + } + + /// + /// Get Spotify catalog information about artists similar to a given artist asynchronously. Similarity is based on analysis of the + /// Spotify community’s listening history. + /// + /// The Spotify ID for the artist. + /// + public Task GetRelatedArtistsAsync(string id) + { + return DownloadDataAsync(_builder.GetRelatedArtists(id)); + } + + /// + /// Get Spotify catalog information about an artist’s top tracks by country. + /// + /// The Spotify ID for the artist. + /// The country: an ISO 3166-1 alpha-2 country code. + /// + public SeveralTracks GetArtistsTopTracks(string id, string country) + { + return DownloadData(_builder.GetArtistsTopTracks(id, country)); + } + + /// + /// Get Spotify catalog information about an artist’s top tracks by country asynchronously. + /// + /// The Spotify ID for the artist. + /// The country: an ISO 3166-1 alpha-2 country code. + /// + public Task GetArtistsTopTracksAsync(string id, string country) + { + return DownloadDataAsync(_builder.GetArtistsTopTracks(id, country)); + } + + /// + /// Get Spotify catalog information about an artist’s albums. Optional parameters can be specified in the query string + /// to filter and sort the response. + /// + /// The Spotify ID for the artist. + /// + /// A list of keywords that will be used to filter the response. If not supplied, all album types will + /// be returned + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first album to return. Default: 0 + /// + /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular + /// geographical market + /// + /// + public Paging GetArtistsAlbums(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") + { + return DownloadData>(_builder.GetArtistsAlbums(id, type, limit, offset, market)); + } + + /// + /// Get Spotify catalog information about an artist’s albums asynchronously. Optional parameters can be specified in the query string + /// to filter and sort the response. + /// + /// The Spotify ID for the artist. + /// + /// A list of keywords that will be used to filter the response. If not supplied, all album types will + /// be returned + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first album to return. Default: 0 + /// + /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular + /// geographical market + /// + /// + public Task> GetArtistsAlbumsAsync(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") + { + return DownloadDataAsync>(_builder.GetArtistsAlbums(id, type, limit, offset, market)); + } + + /// + /// Get Spotify catalog information for several artists based on their Spotify IDs. + /// + /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. + /// + public SeveralArtists GetSeveralArtists(List ids) + { + return DownloadData(_builder.GetSeveralArtists(ids)); + } + + /// + /// Get Spotify catalog information for several artists based on their Spotify IDs asynchronously. + /// + /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. + /// + public Task GetSeveralArtistsAsync(List ids) + { + return DownloadDataAsync(_builder.GetSeveralArtists(ids)); + } + + #endregion Artists + + #region Browse + + /// + /// Get a list of Spotify featured playlists (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// + /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 + /// alpha-2 country code, joined by an underscore. + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// A timestamp in ISO 8601 format + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// AUTH NEEDED + public FeaturedPlaylists GetFeaturedPlaylists(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetFeaturedPlaylists"); + return DownloadData(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset)); + } + + /// + /// Get a list of Spotify featured playlists asynchronously (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// + /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 + /// alpha-2 country code, joined by an underscore. + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// A timestamp in ISO 8601 format + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// AUTH NEEDED + public Task GetFeaturedPlaylistsAsync(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetFeaturedPlaylists"); + return DownloadDataAsync(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset)); + } + + /// + /// Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public NewAlbumReleases GetNewAlbumReleases(string country = "", int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetNewAlbumReleases"); + return DownloadData(_builder.GetNewAlbumReleases(country, limit, offset)); + } + + /// + /// Get a list of new album releases featured in Spotify asynchronously (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public Task GetNewAlbumReleasesAsync(string country = "", int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetNewAlbumReleases"); + return DownloadDataAsync(_builder.GetNewAlbumReleases(country, limit, offset)); + } + + /// + /// Get a list of categories used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). + /// + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the + /// list of returned categories to those relevant to a particular country + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 (the first object). + /// + /// AUTH NEEDED + public CategoryList GetCategories(string country = "", string locale = "", int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetCategories"); + return DownloadData(_builder.GetCategories(country, locale, limit, offset)); + } + + /// + /// Get a list of categories used to tag items in Spotify asynchronously (on, for example, the Spotify player’s “Browse” tab). + /// + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the + /// list of returned categories to those relevant to a particular country + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 (the first object). + /// + /// AUTH NEEDED + public Task GetCategoriesAsync(string country = "", string locale = "", int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetCategories"); + return DownloadDataAsync(_builder.GetCategories(country, locale, limit, offset)); + } + + /// + /// Get a single category used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). + /// + /// The Spotify category ID for the category. + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category + /// exists for a particular country. + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// + /// AUTH NEEDED + public Category GetCategory(string categoryId, string country = "", string locale = "") + { + return DownloadData(_builder.GetCategory(categoryId, country, locale)); + } + + /// + /// Get a single category used to tag items in Spotify asynchronously (on, for example, the Spotify player’s “Browse” tab). + /// + /// The Spotify category ID for the category. + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category + /// exists for a particular country. + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// + /// AUTH NEEDED + public Task GetCategoryAsync(string categoryId, string country = "", string locale = "") + { + return DownloadDataAsync(_builder.GetCategory(categoryId, country, locale)); + } + + /// + /// Get a list of Spotify playlists tagged with a particular category. + /// + /// The Spotify category ID for the category. + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public CategoryPlaylist GetCategoryPlaylists(string categoryId, string country = "", int limit = 20, int offset = 0) + { + return DownloadData(_builder.GetCategoryPlaylists(categoryId, country, limit, offset)); + } + + /// + /// Get a list of Spotify playlists tagged with a particular category asynchronously. + /// + /// The Spotify category ID for the category. + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public Task GetCategoryPlaylistsAsync(string categoryId, string country = "", int limit = 20, int offset = 0) + { + return DownloadDataAsync(_builder.GetCategoryPlaylists(categoryId, country, limit, offset)); + } + + /// + /// Create a playlist-style listening experience based on seed artists, tracks and genres. + /// + /// A comma separated list of Spotify IDs for seed artists. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of any genres in the set of available genre seeds. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of Spotify IDs for a seed track. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// Tracks with the attribute values nearest to the target values will be preferred. + /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided + /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided + /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. + /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. + /// + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. + /// + /// AUTH NEEDED + public Recommendations GetRecommendations(List artistSeed = null, List genreSeed = null, List trackSeed = null, + TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") + { + return DownloadData(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market)); + } + + /// + /// Create a playlist-style listening experience based on seed artists, tracks and genres asynchronously. + /// + /// A comma separated list of Spotify IDs for seed artists. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of any genres in the set of available genre seeds. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of Spotify IDs for a seed track. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// Tracks with the attribute values nearest to the target values will be preferred. + /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided + /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided + /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. + /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. + /// + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. + /// + /// AUTH NEEDED + public Task GetRecommendationsAsync(List artistSeed = null, List genreSeed = null, List trackSeed = null, + TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") + { + return DownloadDataAsync(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market)); + } + + /// + /// Retrieve a list of available genres seed parameter values for recommendations. + /// + /// + /// AUTH NEEDED + public RecommendationSeedGenres GetRecommendationSeedsGenres() + { + return DownloadData(_builder.GetRecommendationSeedsGenres()); + } + + /// + /// Retrieve a list of available genres seed parameter values for recommendations asynchronously. + /// + /// + /// AUTH NEEDED + public Task GetRecommendationSeedsGenresAsync() + { + return DownloadDataAsync(_builder.GetRecommendationSeedsGenres()); + } + + #endregion Browse + + #region Follow + + /// + /// Get the current user’s followed artists. + /// + /// The ID type: currently only artist is supported. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The last artist ID retrieved from the previous request. + /// + /// AUTH NEEDED + public FollowedArtists GetFollowedArtists(FollowType followType, int limit = 20, string after = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetFollowedArtists"); + return DownloadData(_builder.GetFollowedArtists(limit, after)); + } + + /// + /// Get the current user’s followed artists asynchronously. + /// + /// The ID type: currently only artist is supported. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The last artist ID retrieved from the previous request. + /// + /// AUTH NEEDED + public Task GetFollowedArtistsAsync(FollowType followType, int limit = 20, string after = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetFollowedArtists"); + return DownloadDataAsync(_builder.GetFollowedArtists(limit, after)); + } + + /// + /// Add the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs + /// + /// AUTH NEEDED + public ErrorResponse Follow(FollowType followType, List ids) + { + JObject ob = new JObject + { { "ids", new JArray(ids) } + }; + return UploadData(_builder.Follow(followType), ob.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + } + + /// + /// Add the current user as a follower of one or more artists or other Spotify users asynchronously. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs + /// + /// AUTH NEEDED + public async Task FollowAsync(FollowType followType, List ids) + { + JObject ob = new JObject + { { "ids", new JArray(ids) } + }; + return await UploadDataAsync(_builder.Follow(followType), + ob.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Add the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public ErrorResponse Follow(FollowType followType, string id) + { + return Follow(followType, new List { id }); + } + + /// + /// Add the current user as a follower of one or more artists or other Spotify users asynchronously. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public Task FollowAsync(FollowType followType, string id) + { + return FollowAsync(followType, new List { id }); + } + + /// + /// Remove the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs + /// + /// AUTH NEEDED + public ErrorResponse Unfollow(FollowType followType, List ids) + { + JObject ob = new JObject + { { "ids", new JArray(ids) } + }; + return UploadData(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); + } + + /// + /// Remove the current user as a follower of one or more artists or other Spotify users asynchronously. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs + /// + /// AUTH NEEDED + public async Task UnfollowAsync(FollowType followType, List ids) + { + JObject ob = new JObject + { { "ids", new JArray(ids) } + }; + return await UploadDataAsync(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Remove the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public ErrorResponse Unfollow(FollowType followType, string id) + { + return Unfollow(followType, new List { id }); + } + + /// + /// Remove the current user as a follower of one or more artists or other Spotify users asynchronously. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public Task UnfollowAsync(FollowType followType, string id) + { + return UnfollowAsync(followType, new List { id }); + } + + /// + /// Check to see if the current user is following one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs to check + /// + /// AUTH NEEDED + public ListResponse IsFollowing(FollowType followType, List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for IsFollowing"); + + string url = _builder.IsFollowing(followType, ids); + return DownloadList(url); + } + + /// + /// Check to see if the current user is following one or more artists or other Spotify users asynchronously. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs to check + /// + /// AUTH NEEDED + public Task> IsFollowingAsync(FollowType followType, List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for IsFollowing"); + + string url = _builder.IsFollowing(followType, ids); + return DownloadListAsync(url); + } + + /// + /// Check to see if the current user is following one artist or another Spotify user. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public ListResponse IsFollowing(FollowType followType, string id) + { + return IsFollowing(followType, new List { id }); + } + + /// + /// Check to see if the current user is following one artist or another Spotify user asynchronously. + /// + /// The ID type: either artist or user. + /// Artists or the Users Spotify ID + /// + /// AUTH NEEDED + public Task> IsFollowingAsync(FollowType followType, string id) + { + return IsFollowingAsync(followType, new List { id }); + } + + /// + /// Add the current user as a follower of a playlist. + /// + /// + /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private + /// status, as long as you know its playlist ID. + /// + /// + /// If true the playlist will be included in user's public playlists, if false it will remain + /// private. + /// + /// + /// AUTH NEEDED + public ErrorResponse FollowPlaylist(string ownerId, string playlistId, bool showPublic = true) + { + JObject body = new JObject + { { "public", showPublic } + }; + return UploadData(_builder.FollowPlaylist(playlistId), body.ToString(Formatting.None), "PUT"); + } + + /// + /// Add the current user as a follower of a playlist asynchronously. + /// + /// + /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private + /// status, as long as you know its playlist ID. + /// + /// + /// If true the playlist will be included in user's public playlists, if false it will remain + /// private. + /// + /// + /// AUTH NEEDED + public Task FollowPlaylistAsync(string playlistId, bool showPublic = true) + { + JObject body = new JObject + { { "public", showPublic } + }; + return UploadDataAsync(_builder.FollowPlaylist(playlistId), body.ToString(Formatting.None), "PUT"); + } + + /// + /// Remove the current user as a follower of a playlist. + /// + /// The Spotify ID of the playlist that is to be no longer followed. + /// + /// AUTH NEEDED + public ErrorResponse UnfollowPlaylist(string playlistId) + { + return UploadData(_builder.UnfollowPlaylist(playlistId), "", "DELETE"); + } + + /// + /// Remove the current user as a follower of a playlist asynchronously. + /// + /// The Spotify user ID of the person who owns the playlist. + /// The Spotify ID of the playlist that is to be no longer followed. + /// + /// AUTH NEEDED + public Task UnfollowPlaylistAsync(string playlistId) + { + return UploadDataAsync(_builder.UnfollowPlaylist(playlistId), "", "DELETE"); + } + + /// + /// Check to see if one or more Spotify users are following a specified playlist. + /// + /// The Spotify ID of the playlist. + /// A list of Spotify User IDs + /// + /// AUTH NEEDED + public ListResponse IsFollowingPlaylist(string playlistId, List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); + + string url = _builder.IsFollowingPlaylist(playlistId, ids); + return DownloadList(url); + } + + /// + /// Check to see if one or more Spotify users are following a specified playlist asynchronously. + /// + /// The Spotify ID of the playlist. + /// A list of Spotify User IDs + /// + /// AUTH NEEDED + public Task> IsFollowingPlaylistAsync(string playlistId, List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for IsFollowingPlaylist"); + + string url = _builder.IsFollowingPlaylist(playlistId, ids); + return DownloadListAsync(url); + } + + /// + /// Check to see if one or more Spotify users are following a specified playlist. + /// + /// The Spotify ID of the playlist. + /// A Spotify User ID + /// + /// AUTH NEEDED + public ListResponse IsFollowingPlaylist(string playlistId, string id) + { + return IsFollowingPlaylist(playlistId, new List { id }); + } + + /// + /// Check to see if one or more Spotify users are following a specified playlist asynchronously. + /// + /// The Spotify ID of the playlist. + /// A Spotify User ID + /// + /// AUTH NEEDED + public Task> IsFollowingPlaylistAsync(string playlistId, string id) + { + return IsFollowingPlaylistAsync(playlistId, new List { id }); + } + + #endregion Follow + + #region Library + + /// + /// Save one or more tracks to the current user’s “Your Music” library. + /// + /// A list of the Spotify IDs + /// + /// AUTH NEEDED + public ErrorResponse SaveTracks(List ids) + { + JArray array = new JArray(ids); + return UploadData(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + } + + /// + /// Save one or more tracks to the current user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs + /// + /// AUTH NEEDED + public async Task SaveTracksAsync(List ids) + { + JArray array = new JArray(ids); + return await UploadDataAsync(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Save one track to the current user’s “Your Music” library. + /// + /// A Spotify ID + /// + /// AUTH NEEDED + public ErrorResponse SaveTrack(string id) + { + return SaveTracks(new List { id }); + } + + /// + /// Save one track to the current user’s “Your Music” library asynchronously. + /// + /// A Spotify ID + /// + /// AUTH NEEDED + public Task SaveTrackAsync(string id) + { + return SaveTracksAsync(new List { id }); + } + + /// + /// Get a list of the songs saved in the current Spotify user’s “Your Music” library. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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 Paging GetSavedTracks(int limit = 20, int offset = 0, string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetSavedTracks"); + return DownloadData>(_builder.GetSavedTracks(limit, offset, market)); + } + + /// + /// Get a list of the songs saved in the current Spotify user’s “Your Music” library asynchronously. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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> GetSavedTracksAsync(int limit = 20, int offset = 0, string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetSavedTracks"); + return DownloadDataAsync>(_builder.GetSavedTracks(limit, offset, market)); + } + + /// + /// Remove one or more tracks from the current user’s “Your Music” library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public ErrorResponse RemoveSavedTracks(List ids) + { + JArray array = new JArray(ids); + return UploadData(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); + } + + /// + /// Remove one or more tracks from the current user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public async Task RemoveSavedTracksAsync(List ids) + { + JArray array = new JArray(ids); + return await UploadDataAsync(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public ListResponse CheckSavedTracks(List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for CheckSavedTracks"); + + string url = _builder.CheckSavedTracks(ids); + return DownloadList(url); + } + + /// + /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public Task> CheckSavedTracksAsync(List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for CheckSavedTracks"); + string url = _builder.CheckSavedTracks(ids); + return DownloadListAsync(url); + } + + /// + /// Save one or more albums to the current user’s “Your Music” library. + /// + /// A list of the Spotify IDs + /// + /// AUTH NEEDED + public ErrorResponse SaveAlbums(List ids) + { + JArray array = new JArray(ids); + return UploadData(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse(); + } + + /// + /// Save one or more albums to the current user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs + /// + /// AUTH NEEDED + public async Task SaveAlbumsAsync(List ids) + { + JArray array = new JArray(ids); + return await UploadDataAsync(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Save one album to the current user’s “Your Music” library. + /// + /// A Spotify ID + /// + /// AUTH NEEDED + public ErrorResponse SaveAlbum(string id) + { + return SaveAlbums(new List { id }); + } + + /// + /// Save one album to the current user’s “Your Music” library asynchronously. + /// + /// A Spotify ID + /// + /// AUTH NEEDED + public Task SaveAlbumAsync(string id) + { + return SaveAlbumsAsync(new List { id }); + } + + /// + /// Get a list of the albums saved in the current Spotify user’s “Your Music” library. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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 Paging GetSavedAlbums(int limit = 20, int offset = 0, string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetSavedAlbums"); + return DownloadData>(_builder.GetSavedAlbums(limit, offset, market)); + } + + /// + /// Get a list of the albums saved in the current Spotify user’s “Your Music” library asynchronously. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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> GetSavedAlbumsAsync(int limit = 20, int offset = 0, string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetSavedAlbumsAsync"); + return DownloadDataAsync>(_builder.GetSavedAlbums(limit, offset, market)); + } + + /// + /// Remove one or more albums from the current user’s “Your Music” library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public ErrorResponse RemoveSavedAlbums(List ids) + { + JArray array = new JArray(ids); + return UploadData(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse(); + } + + /// + /// Remove one or more albums from the current user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public async Task RemoveSavedAlbumsAsync(List ids) + { + JArray array = new JArray(ids); + return await UploadDataAsync(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false) ?? new ErrorResponse(); + } + + /// + /// Check if one or more albums is already saved in the current Spotify user’s “Your Music” library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public ListResponse CheckSavedAlbums(List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for CheckSavedTracks"); + + string url = _builder.CheckSavedAlbums(ids); + return DownloadList(url); + } + + /// + /// Check if one or more albums is already saved in the current Spotify user’s “Your Music” library asynchronously. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public Task> CheckSavedAlbumsAsync(List ids) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for CheckSavedAlbumsAsync"); + string url = _builder.CheckSavedAlbums(ids); + return DownloadListAsync(url); + } + + #endregion Library + + #region Personalization + + /// + /// Get the current user’s top tracks based on calculated affinity. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public Paging GetUsersTopTracks(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + return DownloadData>(_builder.GetUsersTopTracks(timeRange, limit, offest)); + } + + /// + /// Get the current user’s top tracks based on calculated affinity asynchronously. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public Task> GetUsersTopTracksAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + return DownloadDataAsync>(_builder.GetUsersTopTracks(timeRange, limit, offest)); + } + + /// + /// Get the current user’s top artists based on calculated affinity. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public Paging GetUsersTopArtists(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + return DownloadData>(_builder.GetUsersTopArtists(timeRange, limit, offest)); + } + + /// + /// Get the current user’s top artists based on calculated affinity asynchronously. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public Task> GetUsersTopArtistsAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + return DownloadDataAsync>(_builder.GetUsersTopArtists(timeRange, limit, offest)); + } + + /// + /// Get tracks from the current user’s recent play history. + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. + /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. + /// + /// AUTH NEEDED + public CursorPaging GetUsersRecentlyPlayedTracks(int limit = 20, DateTime? after = null, + DateTime? before = null) + { + return DownloadData>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before)); + } + + /// + /// Get tracks from the current user’s recent play history asynchronously + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. + /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. + /// + /// AUTH NEEDED + public Task> GetUsersRecentlyPlayedTracksAsync(int limit = 20, DateTime? after = null, + DateTime? before = null) + { + return DownloadDataAsync>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before)); + } + + #endregion + + #region Playlists + + /// + /// Get a list of the playlists owned or followed by a Spotify user. + /// + /// 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 Paging GetUserPlaylists(string userId, int limit = 20, int offset = 0) + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetUserPlaylists"); + 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)); + } + + /// + /// 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. + /// + /// 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 FullPlaylist GetPlaylist(string playlistId, string fields = "", string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPlaylist"); + 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. + /// + /// 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 playlistId, string fields = "", string market = "") + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPlaylist"); + 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. + /// + /// 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 Paging GetPlaylistTracks(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(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. + /// + /// 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 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(playlistId, fields, limit, offset, market)); + } + + /// + /// Create a playlist for a Spotify user. (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. + /// + /// 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 + public FullPlaylist CreatePlaylist(string userId, string playlistName, bool isPublic = true, bool isCollaborative = false, string playlistDescription = "") + { + JObject body = new JObject + { { "name", playlistName }, { "public", isPublic }, { "collaborative", isCollaborative }, { "description", playlistDescription } + }; + 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. + /// + /// 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 + public Task CreatePlaylistAsync(string userId, string playlistName, bool isPublic = true, bool isCollaborative = false, string playlistDescription = "") + { + JObject body = new JObject + { { "name", playlistName }, { "public", isPublic }, { "collaborative", isCollaborative }, { "description", playlistDescription } + }; + 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.) + /// + /// 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 + public ErrorResponse UpdatePlaylist(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(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.) + /// + /// 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 + public async Task UpdatePlaylistAsync(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(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.) + /// + /// The Spotify ID for the playlist. + /// The image as a base64 encoded string + /// + /// AUTH NEEDED + public ErrorResponse UploadPlaylistImage(string playlistId, string base64EncodedJpgImage) + { + return UploadData(_builder.UploadPlaylistImage(playlistId), base64EncodedJpgImage, "PUT") ?? new ErrorResponse(); + } + + /// + /// Change a playlist’s name and public/private state asynchronously. (The user must, of course, own the playlist.) + /// + /// The Spotify ID for the playlist. + /// The image as a base64 encoded string + /// + /// AUTH NEEDED + public async Task UploadPlaylistImageAsync(string playlistId, string base64EncodedJpgImage) + { + return await UploadDataAsync(_builder.UploadPlaylistImage(playlistId), + 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. + /// + /// 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 ErrorResponse ReplacePlaylistTracks(string playlistId, List uris) + { + JObject body = new JObject + { { "uris", new JArray(uris.Take(100)) } + }; + 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. + /// + /// 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 async Task ReplacePlaylistTracksAsync(string playlistId, List uris) + { + JObject body = new JObject + { { "uris", new JArray(uris.Take(100)) } + }; + 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. + /// + /// 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 ErrorResponse RemovePlaylistTracks(string playlistId, List uris) + { + JObject body = new JObject + { { "tracks", JArray.FromObject(uris.Take(100)) } + }; + 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. + /// + /// 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 async Task RemovePlaylistTracksAsync(string playlistId, List uris) + { + JObject body = new JObject + { { "tracks", JArray.FromObject(uris.Take(100)) } + }; + 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. + /// + /// The Spotify ID for the playlist. + /// Spotify URI + /// + /// AUTH NEEDED + public ErrorResponse RemovePlaylistTrack(string playlistId, DeleteTrackUri uri) + { + 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. + /// + /// The Spotify ID for the playlist. + /// Spotify URI + /// + /// AUTH NEEDED + public Task RemovePlaylistTrackAsync(string playlistId, DeleteTrackUri uri) + { + 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. + /// + /// 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 ErrorResponse AddPlaylistTracks(string playlistId, List uris, int? position = null) + { + JObject body = new JObject + { { "uris", JArray.FromObject(uris.Take(100)) } + }; + 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. + /// + /// 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 async Task AddPlaylistTracksAsync(string playlistId, List uris, int? position = null) + { + JObject body = new JObject + { { "uris", JArray.FromObject(uris.Take(100)) } + }; + 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. + /// + /// The Spotify ID for the playlist. + /// A Spotify Track URI + /// The position to insert the tracks, a zero-based index + /// + /// AUTH NEEDED + public ErrorResponse AddPlaylistTrack(string playlistId, string uri, int? position = null) + { + 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. + /// + /// 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 playlistId, string uri, int? position = null) + { + 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. + /// + /// 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 Snapshot ReorderPlaylist(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(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. + /// + /// 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 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(playlistId), body.ToString(Formatting.None), "PUT"); + } + + #endregion Playlists + + #region Profiles + + /// + /// Get detailed profile information about the current user (including the current user’s username). + /// + /// + /// AUTH NEEDED + public PrivateProfile GetPrivateProfile() + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for GetPrivateProfile"); + 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()); + } + + /// + /// Get public profile information about a Spotify user. + /// + /// The user's Spotify user ID. + /// + public PublicProfile GetPublicProfile(string 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 + + #region Tracks + + /// + /// Get Spotify catalog information for multiple tracks based on their Spotify IDs. + /// + /// 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 SeveralTracks GetSeveralTracks(List ids, string market = "") + { + 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)); + } + + /// + /// Get Spotify catalog information for a single track identified by its unique Spotify ID. + /// + /// 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 FullTrack GetTrack(string id, string 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)); + } + + /// + /// Get a detailed audio analysis for a single track identified by its unique Spotify ID. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public AudioAnalysis GetAudioAnalysis(string id) + { + return DownloadData(_builder.GetAudioAnalysis(id)); + } + + /// + /// Get a detailed audio analysis for a single track identified by its unique Spotify ID asynchronously. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public Task GetAudioAnalysisAsync(string id) + { + return DownloadDataAsync(_builder.GetAudioAnalysis(id)); + } + + /// + /// Get audio feature information for a single track identified by its unique Spotify ID. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public AudioFeatures GetAudioFeatures(string id) + { + return DownloadData(_builder.GetAudioFeatures(id)); + } + + /// + /// Get audio feature information for a single track identified by its unique Spotify ID asynchronously. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public Task GetAudioFeaturesAsync(string id) + { + return DownloadDataAsync(_builder.GetAudioFeatures(id)); + } + + /// + /// Get audio features for multiple tracks based on their Spotify IDs. + /// + /// A list of Spotify Track-IDs. Maximum: 100 IDs. + /// + /// AUTH NEEDED + public SeveralAudioFeatures GetSeveralAudioFeatures(List ids) + { + return DownloadData(_builder.GetSeveralAudioFeatures(ids)); + } + + /// + /// Get audio features for multiple tracks based on their Spotify IDs asynchronously. + /// + /// A list of Spotify Track-IDs. Maximum: 100 IDs. + /// + /// AUTH NEEDED + public Task GetSeveralAudioFeaturesAsync(List ids) + { + return DownloadDataAsync(_builder.GetSeveralAudioFeatures(ids)); + } + + #endregion Tracks + + #region Player + + /// + /// Get information about a user’s available devices. + /// + /// + public AvailabeDevices GetDevices() + { + return DownloadData(_builder.GetDevices()); + } + + /// + /// Get information about a user’s available devices. + /// + /// + public Task GetDevicesAsync() + { + return DownloadDataAsync(_builder.GetDevices()); + } + + /// + /// 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. + /// + public PlaybackContext GetPlayback(string market = "") + { + return DownloadData(_builder.GetPlayback(market)); + } + + /// + /// 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. + /// + public Task GetPlaybackAsync(string market = "") + { + return DownloadDataAsync(_builder.GetPlayback(market)); + } + + /// + /// 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. + /// + public PlaybackContext GetPlayingTrack(string market = "") + { + return DownloadData(_builder.GetPlayingTrack(market)); + } + + /// + /// 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. + /// + public Task GetPlayingTrackAsync(string market = "") + { + return DownloadDataAsync(_builder.GetPlayingTrack(market)); + } + + /// + /// Transfer playback to a new device and determine if it should start playing. + /// + /// ID of the device on which playback should be started/transferred to + /// + /// true: ensure playback happens on new device. + /// false or not provided: keep the current playback state. + /// + /// + public ErrorResponse TransferPlayback(string deviceId, bool play = false) => TransferPlayback( + new List { deviceId }, play); + + /// + /// Transfer playback to a new device and determine if it should start playing. + /// + /// ID of the device on which playback should be started/transferred to + /// + /// true: ensure playback happens on new device. + /// false or not provided: keep the current playback state. + /// + /// + public Task TransferPlaybackAsync(string deviceId, bool play = false) => TransferPlaybackAsync( + new List { deviceId }, play); + + /// + /// Transfer playback to a new device and determine if it should start playing. + /// NOTE: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request + /// + /// A array containing the ID of the device on which playback should be started/transferred. + /// + /// true: ensure playback happens on new device. + /// false or not provided: keep the current playback state. + /// + /// + public ErrorResponse TransferPlayback(List deviceIds, bool play = false) + { + JObject ob = new JObject + { { "play", play }, { "device_ids", new JArray(deviceIds) } + }; + return UploadData(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Transfer playback to a new device and determine if it should start playing. + /// NOTE: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request + /// + /// A array containing the ID of the device on which playback should be started/transferred. + /// + /// true: ensure playback happens on new device. + /// false or not provided: keep the current playback state. + /// + /// + public Task TransferPlaybackAsync(List deviceIds, bool play = false) + { + JObject ob = new JObject + { { "play", play }, { "device_ids", new JArray(deviceIds) } + }; + return UploadDataAsync(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Start a new context or resume current playback on the user’s active device. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// Spotify URI of the context to play. + /// A JSON array of the Spotify track URIs to play. + /// Indicates from where in the context playback should start. + /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. + /// The starting time to seek the track to + /// + public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List uris = null, + int? offset = null, int positionMs = 0) + { + JObject ob = new JObject(); + if (!string.IsNullOrEmpty(contextUri)) + ob.Add("context_uri", contextUri); + if (uris != null) + ob.Add("uris", new JArray(uris)); + if (offset != null) + ob.Add("offset", new JObject { { "position", offset } }); + if (positionMs > 0) + ob.Add("position_ms", positionMs); + return UploadData(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Start a new context or resume current playback on the user’s active device. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// Spotify URI of the context to play. + /// A JSON array of the Spotify track URIs to play. + /// Indicates from where in the context playback should start. + /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. + /// The starting time to seek the track to + /// + public Task ResumePlaybackAsync(string deviceId = "", string contextUri = "", List uris = null, + int? offset = null, int positionMs = 0) + { + JObject ob = new JObject(); + if (!string.IsNullOrEmpty(contextUri)) + ob.Add("context_uri", contextUri); + if (uris != null) + ob.Add("uris", new JArray(uris)); + if (offset != null) + ob.Add("offset", new JObject { { "position", offset } }); + if (positionMs > 0) + ob.Add("position_ms", positionMs); + return UploadDataAsync(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Start a new context or resume current playback on the user’s active device. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// Spotify URI of the context to play. + /// A JSON array of the Spotify track URIs to play. + /// Indicates from where in the context playback should start. + /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. + /// The starting time to seek the track to + /// + public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List uris = null, + string offset = "", int positionMs = 0) + { + JObject ob = new JObject(); + if (!string.IsNullOrEmpty(contextUri)) + ob.Add("context_uri", contextUri); + if (uris != null) + ob.Add("uris", new JArray(uris)); + if (!string.IsNullOrEmpty(offset)) + ob.Add("offset", new JObject { { "uri", offset } }); + if (positionMs > 0) + ob.Add("position_ms", positionMs); + return UploadData(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Start a new context or resume current playback on the user’s active device. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// Spotify URI of the context to play. + /// A JSON array of the Spotify track URIs to play. + /// Indicates from where in the context playback should start. + /// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used. + /// The starting time to seek the track to + /// + public Task ResumePlaybackAsync(string deviceId = "", string contextUri = "", List uris = null, + string offset = "", int positionMs = 0) + { + JObject ob = new JObject(); + if (!string.IsNullOrEmpty(contextUri)) + ob.Add("context_uri", contextUri); + if (uris != null) + ob.Add("uris", new JArray(uris)); + if (!string.IsNullOrEmpty(offset)) + ob.Add("offset", new JObject { { "uri", offset } }); + if (positionMs > 0) + ob.Add("position_ms", positionMs); + return UploadDataAsync(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT"); + } + + /// + /// Pause playback on the user’s account. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse PausePlayback(string deviceId = "") + { + return UploadData(_builder.PausePlayback(deviceId), string.Empty, "PUT"); + } + + /// + /// Pause playback on the user’s account. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task PausePlaybackAsync(string deviceId = "") + { + return UploadDataAsync(_builder.PausePlayback(deviceId), string.Empty, "PUT"); + } + + /// + /// Skips to next track in the user’s queue. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SkipPlaybackToNext(string deviceId = "") + { + return UploadData(_builder.SkipPlaybackToNext(deviceId), string.Empty); + } + + /// + /// Skips to next track in the user’s queue. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SkipPlaybackToNextAsync(string deviceId = "") + { + return UploadDataAsync(_builder.SkipPlaybackToNext(deviceId), string.Empty); + } + + /// + /// Skips to previous track in the user’s queue. + /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. + /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SkipPlaybackToPrevious(string deviceId = "") + { + return UploadData(_builder.SkipPlaybackToPrevious(deviceId), string.Empty); + } + + /// + /// Skips to previous track in the user’s queue. + /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. + /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SkipPlaybackToPreviousAsync(string deviceId = "") + { + return UploadDataAsync(_builder.SkipPlaybackToPrevious(deviceId), string.Empty); + } + + /// + /// Seeks to the given position in the user’s currently playing track. + /// + /// The position in milliseconds to seek to. Must be a positive number. + /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SeekPlayback(int positionMs, string deviceId = "") + { + return UploadData(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT"); + } + + /// + /// Seeks to the given position in the user’s currently playing track. + /// + /// The position in milliseconds to seek to. Must be a positive number. + /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SeekPlaybackAsync(int positionMs, string deviceId = "") + { + return UploadDataAsync(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT"); + } + + /// + /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. + /// + /// track, context or off. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SetRepeatMode(RepeatState state, string deviceId = "") + { + return UploadData(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT"); + } + + /// + /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. + /// + /// track, context or off. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SetRepeatModeAsync(RepeatState state, string deviceId = "") + { + return UploadDataAsync(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT"); + } + + /// + /// Set the volume for the user’s current playback device. + /// + /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SetVolume(int volumePercent, string deviceId = "") + { + return UploadData(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT"); + } + + /// + /// Set the volume for the user’s current playback device. + /// + /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SetVolumeAsync(int volumePercent, string deviceId = "") + { + return UploadDataAsync(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT"); + } + + /// + /// Toggle shuffle on or off for user’s playback. + /// + /// True or False + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public ErrorResponse SetShuffle(bool shuffle, string deviceId = "") + { + return UploadData(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT"); + } + + /// + /// Toggle shuffle on or off for user’s playback. + /// + /// True or False + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public Task SetShuffleAsync(bool shuffle, string deviceId = "") + { + return UploadDataAsync(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT"); + } + + /// + /// Add an Item to the User's Playback Queue. BETA + /// + /// The uri of the item to add to the queue. Must be a track or an episode uri. + /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. + /// + public ErrorResponse AddToQueue(string uri, string deviceId = "") + { + return UploadData(_builder.AddToQueue(uri, deviceId), string.Empty); + } + + /// + /// Add an Item to the User's Playback Queue. BETA + /// + /// The uri of the item to add to the queue. Must be a track or an episode uri. + /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. + /// + public Task AddToQueueAsync(string uri, string deviceId = "") + { + return UploadDataAsync(_builder.AddToQueue(uri, deviceId), string.Empty); + } + + #endregion + + #region Util + + public TOut GetNextPage(Paging paging) where TOut : BasicModel + { + if (!paging.HasNextPage()) + throw new InvalidOperationException("This Paging-Object has no Next-Page"); + return DownloadData(paging.Next); + } + + public TOut GetNextPage(CursorPaging paging) where TOut : BasicModel + { + if (!paging.HasNext()) + throw new InvalidOperationException("This CursorPaging-Object has no Next-Page"); + return DownloadData(paging.Next); + } + + public Paging GetNextPage(Paging paging) + { + return GetNextPage, T>(paging); + } + + public CursorPaging GetNextPage(CursorPaging paging) + { + return GetNextPage, T>(paging); + } + + public Task GetNextPageAsync(Paging paging) where TOut : BasicModel + { + if (!paging.HasNextPage()) + throw new InvalidOperationException("This Paging-Object has no Next-Page"); + return DownloadDataAsync(paging.Next); + } + + public Task GetNextPageAsync(CursorPaging paging) where TOut : BasicModel + { + if (!paging.HasNext()) + throw new InvalidOperationException("This Paging-Object has no Next-Page"); + return DownloadDataAsync(paging.Next); + } + + public Task> GetNextPageAsync(Paging paging) + { + return GetNextPageAsync, T>(paging); + } + + public Task> GetNextPageAsync(CursorPaging paging) + { + return GetNextPageAsync, T>(paging); + } + + public TOut GetPreviousPage(Paging paging) where TOut : BasicModel + { + if (!paging.HasPreviousPage()) + throw new InvalidOperationException("This Paging-Object has no Previous-Page"); + return DownloadData(paging.Previous); + } + + public Paging GetPreviousPage(Paging paging) + { + return GetPreviousPage, T>(paging); + } + + public Task GetPreviousPageAsync(Paging paging) where TOut : BasicModel + { + if (!paging.HasPreviousPage()) + throw new InvalidOperationException("This Paging-Object has no Previous-Page"); + return DownloadDataAsync(paging.Previous); + } + + public Task> GetPreviousPageAsync(Paging paging) + { + return GetPreviousPageAsync, T>(paging); + } + + private ListResponse DownloadList(string url) + { + int triesLeft = RetryTimes + 1; + Error lastError; + + ListResponse data = null; + do + { + if (data != null) { Thread.Sleep(RetryAfter); } + Tuple res = DownloadDataAlt(url); + data = ExtractDataToListResponse(res); + + lastError = data.Error; + + triesLeft -= 1; + + } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); + + return data; + } + + private async Task> DownloadListAsync(string url) + { + int triesLeft = RetryTimes + 1; + Error lastError; + + ListResponse data = null; + do + { + if (data != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); } + Tuple res = await DownloadDataAltAsync(url).ConfigureAwait(false); + data = ExtractDataToListResponse(res); + + lastError = data.Error; + + triesLeft -= 1; + + } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); + + return data; + } + + private static ListResponse ExtractDataToListResponse(Tuple res) + { + ListResponse ret; + if (res.Item2 is JArray) + { + ret = new ListResponse + { + List = res.Item2.ToObject>(), + Error = null + }; + } + else + { + ret = new ListResponse + { + List = null, + Error = res.Item2["error"].ToObject() + }; + } + ret.AddResponseInfo(res.Item1); + return ret; + } + + public T UploadData(string url, string uploadData, string method = "POST") where T : BasicModel + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for all Upload-Actions"); + int triesLeft = RetryTimes + 1; + Error lastError; + + Tuple response = null; + do + { + Dictionary headers = new Dictionary + { { "Authorization", TokenType + " " + AccessToken }, + { "Content-Type", "application/json" } + }; + + if (response != null) { Thread.Sleep(RetryAfter); } + response = WebClient.UploadJson(url, uploadData, method, headers); + + response.Item2.AddResponseInfo(response.Item1); + lastError = response.Item2.Error; + triesLeft -= 1; + + } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); + + return response.Item2; + } + + public async Task UploadDataAsync(string url, string uploadData, string method = "POST") where T : BasicModel + { + if (!UseAuth) + throw new InvalidOperationException("Auth is required for all Upload-Actions"); + + int triesLeft = RetryTimes + 1; + Error lastError; + + Tuple response = null; + do + { + Dictionary headers = new Dictionary + { { "Authorization", TokenType + " " + AccessToken }, + { "Content-Type", "application/json" } + }; + + if (response != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); } + response = await WebClient.UploadJsonAsync(url, uploadData, method, headers).ConfigureAwait(false); + + response.Item2.AddResponseInfo(response.Item1); + lastError = response.Item2.Error; + + triesLeft -= 1; + + } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); + + return response.Item2; + } + + public T DownloadData(string url) where T : BasicModel + { + int triesLeft = RetryTimes + 1; + Error lastError; + + Tuple response = null; + do + { + if (response != null) { Thread.Sleep(RetryAfter); } + response = DownloadDataAlt(url); + + response.Item2.AddResponseInfo(response.Item1); + lastError = response.Item2.Error; + + triesLeft -= 1; + + } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status)); + + return response.Item2; + } + + /// + /// Retrieves whether request had a "TooManyRequests" error, and get the amount Spotify recommends waiting before another request. + /// + /// Info object to analyze. + /// Seconds to wait before making another request. -1 if no error. + /// AUTH NEEDED + private int GetTooManyRequests(ResponseInfo info) + { + // 429 is "TooManyRequests" value specified in Spotify API + if (429 != (int) info.StatusCode) + { + return -1; + } + if (!int.TryParse(info.Headers.Get("Retry-After"), out int secondsToWait)) + { + return -1; + } + return secondsToWait; + } + + public async Task DownloadDataAsync(string url) where T : BasicModel + { + int triesLeft = RetryTimes + 1; + Error lastError; + + Tuple response = null; + do + { + if (response != null) + { + int msToWait = RetryAfter; + int secondsToWait = GetTooManyRequests(response.Item1); + if (secondsToWait > 0) + { + msToWait = secondsToWait * 1000; + } + await Task.Delay(msToWait).ConfigureAwait(false); + } + response = await DownloadDataAltAsync(url).ConfigureAwait(false); + + response.Item2.AddResponseInfo(response.Item1); + lastError = response.Item2.Error; + + if (TooManyRequestsConsumesARetry || GetTooManyRequests(response.Item1) == -1) + { + triesLeft -= 1; + } + + } while (UseAutoRetry && + triesLeft > 0 && + (GetTooManyRequests(response.Item1) != -1 || + lastError != null && RetryErrorCodes.Contains(lastError.Status))); + + return response.Item2; + } + + private Tuple DownloadDataAlt(string url) + { + Dictionary headers = new Dictionary(); + if (UseAuth) + headers.Add("Authorization", TokenType + " " + AccessToken); + return WebClient.DownloadJson(url, headers); + } + + private Task> DownloadDataAltAsync(string url) + { + Dictionary headers = new Dictionary(); + if (UseAuth) + headers.Add("Authorization", TokenType + " " + AccessToken); + return WebClient.DownloadJsonAsync(url, headers); + } + + #endregion Util + } } diff --git a/SpotifyAPI.Web/SpotifyWebBuilder.cs b/SpotifyAPI.Web/SpotifyWebBuilder.cs index a4ba513f..8cbe3383 100644 --- a/SpotifyAPI.Web/SpotifyWebBuilder.cs +++ b/SpotifyAPI.Web/SpotifyWebBuilder.cs @@ -7,1116 +7,1129 @@ using SpotifyAPI.Web.Models; namespace SpotifyAPI.Web { + /// + /// SpotifyAPI URL-Generator + /// + public class SpotifyWebBuilder + { + public const string APIBase = "https://api.spotify.com/v1"; + + #region Search + /// - /// SpotifyAPI URL-Generator + /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. /// - public class SpotifyWebBuilder + /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. + /// A list of item types to search across. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first result to return. Default: 0 + /// An ISO 3166-1 alpha-2 country code or the string from_token. + /// + public string SearchItems(string q, SearchType type, int limit = 20, int offset = 0, string market = "") { - public const string APIBase = "https://api.spotify.com/v1"; - - #region Search - - /// - /// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string. - /// - /// The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues. - /// A list of item types to search across. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first result to return. Default: 0 - /// An ISO 3166-1 alpha-2 country code or the string from_token. - /// - public string SearchItems(string q, SearchType type, int limit = 20, int offset = 0, string market = "") - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder(APIBase + "/search"); - builder.Append("?q=" + q); - builder.Append("&type=" + type.GetStringAttribute(",")); - builder.Append("&limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - #endregion Search - - #region Albums - - /// - /// Get Spotify catalog information about an album’s tracks. Optional parameters can be used to limit the number of - /// tracks returned. - /// - /// The Spotify ID for the album. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first track to return. Default: 0 (the first object). - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public string GetAlbumTracks(string id, int limit = 20, int offset = 0, string market = "") - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/albums/" + id + "/tracks"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Get Spotify catalog information for a single album. - /// - /// The Spotify ID for the album. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public string GetAlbum(string id, string market = "") - { - return string.IsNullOrEmpty(market) ? $"{APIBase}/albums/{id}" : $"{APIBase}/albums/{id}?market={market}"; - } - - /// - /// Get Spotify catalog information for multiple albums identified by their Spotify IDs. - /// - /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// - public string GetSeveralAlbums(List ids, string market = "") - { - return string.IsNullOrEmpty(market) - ? $"{APIBase}/albums?ids={string.Join(",", ids.Take(20))}" - : $"{APIBase}/albums?market={market}&ids={string.Join(",", ids.Take(20))}"; - } - - #endregion Albums - - #region Artists - - /// - /// Get Spotify catalog information for a single artist identified by their unique Spotify ID. - /// - /// The Spotify ID for the artist. - /// - public string GetArtist(string id) - { - return $"{APIBase}/artists/{id}"; - } - - /// - /// Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the - /// Spotify community’s listening history. - /// - /// The Spotify ID for the artist. - /// - public string GetRelatedArtists(string id) - { - return $"{APIBase}/artists/{id}/related-artists"; - } - - /// - /// Get Spotify catalog information about an artist’s top tracks by country. - /// - /// The Spotify ID for the artist. - /// The country: an ISO 3166-1 alpha-2 country code. - /// - public string GetArtistsTopTracks(string id, string country) - { - return $"{APIBase}/artists/{id}/top-tracks?country={country}"; - } - - /// - /// Get Spotify catalog information about an artist’s albums. Optional parameters can be specified in the query string - /// to filter and sort the response. - /// - /// The Spotify ID for the artist. - /// - /// A list of keywords that will be used to filter the response. If not supplied, all album types will - /// be returned - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first album to return. Default: 0 - /// - /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular - /// geographical market - /// - /// - public string GetArtistsAlbums(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/artists/" + id + "/albums"); - builder.Append("?album_type=" + type.GetStringAttribute(",")); - builder.Append("&limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Get Spotify catalog information for several artists based on their Spotify IDs. - /// - /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. - /// - public string GetSeveralArtists(List ids) - { - return $"{APIBase}/artists?ids={string.Join(",", ids.Take(50))}"; - } - - #endregion Artists - - #region Browse - - /// - /// Get a list of Spotify featured playlists (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// - /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 - /// alpha-2 country code, joined by an underscore. - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// A timestamp in ISO 8601 format - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// AUTH NEEDED - public string GetFeaturedPlaylists(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/browse/featured-playlists"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(locale)) - builder.Append("&locale=" + locale); - if (!string.IsNullOrEmpty(country)) - builder.Append("&country=" + country); - if (timestamp != default(DateTime)) - builder.Append("×tamp=" + timestamp.ToString("yyyy-MM-ddTHH:mm:ss")); - return builder.ToString(); - } - - /// - /// Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab). - /// - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public string GetNewAlbumReleases(string country = "", int limit = 20, int offset = 0) - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/browse/new-releases"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(country)) - builder.Append("&country=" + country); - return builder.ToString(); - } - - /// - /// Get a list of categories used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). - /// - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the - /// list of returned categories to those relevant to a particular country - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 (the first object). - /// - /// AUTH NEEDED - public string GetCategories(string country = "", string locale = "", int limit = 20, int offset = 0) - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder(APIBase + "/browse/categories"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(country)) - builder.Append("&country=" + country); - if (!string.IsNullOrEmpty(locale)) - builder.Append("&locale=" + locale); - return builder.ToString(); - } - - /// - /// Get a single category used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). - /// - /// The Spotify category ID for the category. - /// - /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category - /// exists for a particular country. - /// - /// - /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country - /// code, joined by an underscore - /// - /// - /// AUTH NEEDED - public string GetCategory(string categoryId, string country = "", string locale = "") - { - StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId); - if (!string.IsNullOrEmpty(country)) - builder.Append("?country=" + country); - if (!string.IsNullOrEmpty(locale)) - builder.Append((country == "" ? "?locale=" : "&locale=") + locale); - return builder.ToString(); - } - - /// - /// Get a list of Spotify playlists tagged with a particular category. - /// - /// The Spotify category ID for the category. - /// A country: an ISO 3166-1 alpha-2 country code. - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The index of the first item to return. Default: 0 - /// - /// AUTH NEEDED - public string GetCategoryPlaylists(string categoryId, string country = "", int limit = 20, int offset = 0) - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId + "/playlists"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(country)) - builder.Append("&country=" + country); - return builder.ToString(); - } - - /// - /// Create a playlist-style listening experience based on seed artists, tracks and genres. - /// - /// A comma separated list of Spotify IDs for seed artists. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of any genres in the set of available genre seeds. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// A comma separated list of Spotify IDs for a seed track. - /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. - /// - /// Tracks with the attribute values nearest to the target values will be preferred. - /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided - /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided - /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. - /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. - /// - /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. - /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. - /// - /// AUTH NEEDED - public string GetRecommendations(List artistSeed = null, List genreSeed = null, List trackSeed = null, - TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") - { - limit = Math.Min(100, limit); - StringBuilder builder = new StringBuilder($"{APIBase}/recommendations"); - builder.Append("?limit=" + limit); - if (artistSeed?.Count > 0) - builder.Append("&seed_artists=" + string.Join(",", artistSeed)); - if (genreSeed?.Count > 0) - builder.Append("&seed_genres=" + string.Join(",", genreSeed)); - if (trackSeed?.Count > 0) - builder.Append("&seed_tracks=" + string.Join(",", trackSeed)); - if (target != null) - builder.Append(target.BuildUrlParams("target")); - if (min != null) - builder.Append(min.BuildUrlParams("min")); - if (max != null) - builder.Append(max.BuildUrlParams("max")); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Retrieve a list of available genres seed parameter values for recommendations. - /// - /// - /// AUTH NEEDED - public string GetRecommendationSeedsGenres() - { - return $"{APIBase}/recommendations/available-genre-seeds"; - } - - #endregion Browse - - #region Follow - - /// - /// Get the current user’s followed artists. - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// The last artist ID retrieved from the previous request. - /// - /// AUTH NEEDED - public string GetFollowedArtists(int limit = 20, string after = "") - { - limit = Math.Min(limit, 50); - const FollowType followType = FollowType.Artist; //currently only artist is supported. - StringBuilder builder = new StringBuilder(APIBase + "/me/following?type=" + followType.GetStringAttribute()); - builder.Append("&limit=" + limit); - if (!string.IsNullOrEmpty(after)) - builder.Append("&after=" + after); - return builder.ToString(); - } - - /// - /// Add the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// - /// AUTH NEEDED - public string Follow(FollowType followType) - { - return $"{APIBase}/me/following?type={followType.GetStringAttribute()}"; - } - - /// - /// Remove the current user as a follower of one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// - /// AUTH NEEDED - public string Unfollow(FollowType followType) - { - return $"{APIBase}/me/following?type={followType.GetStringAttribute()}"; - } - - /// - /// Check to see if the current user is following one or more artists or other Spotify users. - /// - /// The ID type: either artist or user. - /// A list of the artist or the user Spotify IDs to check - /// - /// AUTH NEEDED - public string IsFollowing(FollowType followType, List ids) - { - return $"{APIBase}/me/following/contains?type={followType.GetStringAttribute()}&ids={string.Join(",", ids)}"; - } - - /// - /// Add the current user as a follower of a playlist. - /// - /// - /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private - /// status, as long as you know its playlist ID. - /// - /// - /// AUTH NEEDED - public string FollowPlaylist(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}/followers"; - } - - /// - /// Remove the current user as a follower of a playlist. - /// - /// The Spotify ID of the playlist that is to be no longer followed. - /// - /// AUTH NEEDED - public string UnfollowPlaylist(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}/followers"; - } - - /// - /// Check to see if one or more Spotify users are following a specified playlist. - /// - /// The Spotify ID of the playlist. - /// A list of Spotify User IDs - /// - /// AUTH NEEDED - public string IsFollowingPlaylist(string playlistId, List ids) - { - return $"{APIBase}/playlists/{playlistId}/followers/contains?ids={string.Join(",", ids)}"; - } - - #endregion Follow - - #region Library - - /// - /// Save one or more tracks to the current user’s “Your Music” library. - /// - /// - /// AUTH NEEDED - public string SaveTracks() - { - return APIBase + "/me/tracks/"; - } - - /// - /// Get a list of the songs saved in the current Spotify user’s “Your Music” library. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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 GetSavedTracks(int limit = 20, int offset = 0, string market = "") - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/me/tracks"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Remove one or more tracks from the current user’s “Your Music” library. - /// - /// - /// AUTH NEEDED - public string RemoveSavedTracks() - { - return APIBase + "/me/tracks/"; - } - - /// - /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public string CheckSavedTracks(List ids) - { - return APIBase + "/me/tracks/contains?ids=" + string.Join(",", ids); - } - - /// - /// Save one or more albums to the current user’s "Your Music" library. - /// - /// - /// AUTH NEEDED - public string SaveAlbums() - { - return $"{APIBase}/me/albums"; - } - - /// - /// Get a list of the albums saved in the current Spotify user’s "Your Music" library. - /// - /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. - /// 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 GetSavedAlbums(int limit = 20, int offset = 0, string market = "") - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/me/albums"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Remove one or more albums from the current user’s "Your Music" library. - /// - /// - /// AUTH NEEDED - public string RemoveSavedAlbums() - { - return APIBase + "/me/albums/"; - } - - /// - /// Check if one or more albums is already saved in the current Spotify user’s "Your Music" library. - /// - /// A list of the Spotify IDs. - /// - /// AUTH NEEDED - public string CheckSavedAlbums(List ids) - { - return APIBase + "/me/albums/contains?ids=" + string.Join(",", ids); - } - - #endregion Library - - #region Personalization - - /// - /// Get the current user’s top tracks based on calculated affinity. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public string GetUsersTopTracks(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder($"{APIBase}/me/top/tracks"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offest); - builder.Append("&time_range=" + timeRange.GetStringAttribute()); - return builder.ToString(); - } - - /// - /// Get the current user’s top artists based on calculated affinity. - /// - /// 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). - /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 - /// 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. - /// - /// AUTH NEEDED - public string GetUsersTopArtists(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder($"{APIBase}/me/top/artists"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offest); - builder.Append("&time_range=" + timeRange.GetStringAttribute()); - return builder.ToString(); - } - - /// - /// Get tracks from the current user’s recent play history. - /// - /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. - /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. - /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. - /// - /// AUTH NEEDED - public string GetUsersRecentlyPlayedTracks(int limit = 20, DateTime? after = null, DateTime? before = null) - { - limit = Math.Min(50, limit); - StringBuilder builder = new StringBuilder($"{APIBase}/me/player/recently-played"); - builder.Append("?limit=" + limit); - if (after.HasValue) - builder.Append("&after=" + after.Value.ToUnixTimeMillisecondsPoly()); - if (before.HasValue) - builder.Append("&before=" + before.Value.ToUnixTimeMillisecondsPoly()); - return builder.ToString(); - } - - #endregion - - #region Playlists - - /// - /// Get a list of the playlists owned or followed by a Spotify user. - /// - /// 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 string GetUserPlaylists(string userId, int limit = 20, int offset = 0) - { - limit = Math.Min(limit, 50); - StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists"); - builder.Append("?limit=" + limit); - builder.Append("&offset=" + offset); - return builder.ToString(); - } - - /// - /// 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 - 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 = "") - { - 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); - return builder.ToString(); - } - - /// - /// Get full details of the tracks of 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. - /// - /// 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 playlistId, string fields = "", int limit = 100, int offset = 0, string market = "") - { - limit = Math.Min(limit, 100); - StringBuilder builder = new StringBuilder(APIBase + "/playlists/" + playlistId + "/tracks"); - builder.Append("?fields=" + fields); - builder.Append("&limit=" + limit); - builder.Append("&offset=" + offset); - if (!string.IsNullOrEmpty(market)) - builder.Append("&market=" + market); - return builder.ToString(); - } - - /// - /// Create a playlist for a Spotify user. (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 string CreatePlaylist(string userId, string playlistName, bool isPublic = true) - { - return $"{APIBase}/users/{userId}/playlists"; - } - - /// - /// 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. - /// - /// AUTH NEEDED - public string UpdatePlaylist(string userId, string playlistId) - { - return $"{APIBase}/users/{userId}/playlists/{playlistId}"; - } - - /// - /// Change a playlist’s name and public/private state. (The user must, of course, own the playlist.) - /// - /// The Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string UpdatePlaylist(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}"; - } - - /// - /// 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. - /// - /// AUTH NEEDED - public string ReplacePlaylistTracks(string userId, string playlistId) - { - return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; - } - - /// - /// 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 Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string ReplacePlaylistTracks(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}/tracks"; - } - - /// - /// 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 - public string RemovePlaylistTracks(string userId, string playlistId, List uris) - { - return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; - } - - /// - /// Remove one or more tracks from a user’s playlist. - /// - /// 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 string RemovePlaylistTracks(string playlistId, List uris) - { - return $"{APIBase}/playlists/{playlistId}/tracks"; - } - - /// - /// 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 - public string AddPlaylistTracks(string userId, string playlistId, List uris, int? position = null) - { - return position == null - ? $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks" - : $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks?position={position}"; - } - - /// - /// Add one or more tracks to a user’s playlist. - /// - /// 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 string AddPlaylistTracks(string playlistId, List uris, int? position = null) - { - return position == null - ? $"{APIBase}/playlists/{playlistId}/tracks" - : $"{APIBase}/playlists/{playlistId}/tracks?position={position}"; - } - - /// - /// Reorder a track or a group of tracks in a playlist. - /// - /// The user's Spotify user ID. - /// The Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string ReorderPlaylist(string userId, string playlistId) - { - return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; - } - - /// - /// Reorder a track or a group of tracks in a playlist. - /// - /// The Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string ReorderPlaylist(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}/tracks"; - } - - /// - /// Upload an image for a playlist. - /// - /// The user's Spotify user ID. - /// The Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string UploadPlaylistImage(string userId, string playlistId) - { - return $"{APIBase}/users/{userId}/playlists/{playlistId}/images"; - } - - /// - /// Upload an image for a playlist. - /// - /// The Spotify ID for the playlist. - /// - /// AUTH NEEDED - public string UploadPlaylistImage(string playlistId) - { - return $"{APIBase}/playlists/{playlistId}/images"; - } - - #endregion Playlists - - #region Profiles - - /// - /// Get detailed profile information about the current user (including the current user’s username). - /// - /// - /// AUTH NEEDED - public string GetPrivateProfile() - { - return $"{APIBase}/me"; - } - - /// - /// Get public profile information about a Spotify user. - /// - /// The user's Spotify user ID. - /// - public string GetPublicProfile(string userId) - { - return $"{APIBase}/users/{userId}"; - } - - #endregion Profiles - - #region Tracks - - /// - /// Get Spotify catalog information for multiple tracks based on their Spotify IDs. - /// - /// 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 string GetSeveralTracks(List ids, string market = "") - { - return string.IsNullOrEmpty(market) - ? $"{APIBase}/tracks?ids={string.Join(",", ids.Take(50))}" - : $"{APIBase}/tracks?market={market}&ids={string.Join(",", ids.Take(50))}"; - } - - /// - /// Get Spotify catalog information for a single track identified by its unique Spotify ID. - /// - /// 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 string GetTrack(string id, string market = "") - { - return string.IsNullOrEmpty(market) ? $"{APIBase}/tracks/{id}" : $"{APIBase}/tracks/{id}?market={market}"; - } - - /// - /// Get a detailed audio analysis for a single track identified by its unique Spotify ID. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public string GetAudioAnalysis(string id) - { - return $"{APIBase}/audio-analysis/{id}"; - } - - /// - /// Get audio feature information for a single track identified by its unique Spotify ID. - /// - /// The Spotify ID for the track. - /// - /// AUTH NEEDED - public string GetAudioFeatures(string id) - { - return $"{APIBase}/audio-features/{id}"; - } - - /// - /// Get audio features for multiple tracks based on their Spotify IDs. - /// - /// A list of Spotify Track-IDs. Maximum: 100 IDs. - /// - /// AUTH NEEDED - public string GetSeveralAudioFeatures(List ids) - { - return $"{APIBase}/audio-features?ids={string.Join(",", ids.Take(100))}"; - } - - #endregion Tracks - - #region Player - - /// - /// Get information about a user’s available devices. - /// - /// - public string GetDevices() - { - return $"{APIBase}/me/player/devices"; - } - - /// - /// 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. - /// - public string GetPlayback(string market = "") - { - return string.IsNullOrEmpty(market) ? $"{APIBase}/me/player" : $"{APIBase}/me/player?market={market}"; - } - - /// - /// 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. - /// - public string GetPlayingTrack(string market = "") - { - return string.IsNullOrEmpty(market) - ? $"{APIBase}/me/player/currently-playing" - : $"{APIBase}/me/player/currently-playing?market={market}"; - } - - /// - /// Transfer playback to a new device and determine if it should start playing. - /// - /// - public string TransferPlayback() - { - return $"{APIBase}/me/player"; - } - - /// - /// Start a new context or resume current playback on the user’s active device. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string ResumePlayback(string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/play" - : $"{APIBase}/me/player/play?device_id={deviceId}"; - } - - /// - /// Pause playback on the user’s account. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string PausePlayback(string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/pause" - : $"{APIBase}/me/player/pause?device_id={deviceId}"; - } - - /// - /// Skips to next track in the user’s queue. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SkipPlaybackToNext(string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/next" - : $"{APIBase}/me/player/next?device_id={deviceId}"; - } - - /// - /// Skips to previous track in the user’s queue. - /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. - /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. - /// - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SkipPlaybackToPrevious(string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/previous" - : $"{APIBase}/me/player/previous?device_id={deviceId}"; - } - - /// - /// Seeks to the given position in the user’s currently playing track. - /// - /// The position in milliseconds to seek to. Must be a positive number. - /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SeekPlayback(int positionMs, string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/seek?position_ms={positionMs}" - : $"{APIBase}/me/player/seek?position_ms={positionMs}&device_id={deviceId}"; - } - - /// - /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. - /// - /// track, context or off. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SetRepeatMode(RepeatState repeatState, string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/repeat?state={repeatState.GetStringAttribute()}" - : $"{APIBase}/me/player/repeat?state={repeatState.GetStringAttribute()}&device_id={deviceId}"; - } - - /// - /// Set the volume for the user’s current playback device. - /// - /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SetVolume(int volumePercent, string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/volume?volume_percent={volumePercent}" - : $"{APIBase}/me/player/volume?volume_percent={volumePercent}&device_id={deviceId}"; - } - - /// - /// Toggle shuffle on or off for user’s playback. - /// - /// True of False. - /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. - /// - public string SetShuffle(bool shuffle, string deviceId = "") - { - return string.IsNullOrEmpty(deviceId) - ? $"{APIBase}/me/player/shuffle?state={shuffle}" - : $"{APIBase}/me/player/shuffle?state={shuffle}&device_id={deviceId}"; - } - #endregion + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder(APIBase + "/search"); + builder.Append("?q=" + q); + builder.Append("&type=" + type.GetStringAttribute(",")); + builder.Append("&limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); } + + #endregion Search + + #region Albums + + /// + /// Get Spotify catalog information about an album’s tracks. Optional parameters can be used to limit the number of + /// tracks returned. + /// + /// The Spotify ID for the album. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first track to return. Default: 0 (the first object). + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetAlbumTracks(string id, int limit = 20, int offset = 0, string market = "") + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/albums/" + id + "/tracks"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Get Spotify catalog information for a single album. + /// + /// The Spotify ID for the album. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetAlbum(string id, string market = "") + { + return string.IsNullOrEmpty(market) ? $"{APIBase}/albums/{id}" : $"{APIBase}/albums/{id}?market={market}"; + } + + /// + /// Get Spotify catalog information for multiple albums identified by their Spotify IDs. + /// + /// A list of the Spotify IDs for the albums. Maximum: 20 IDs. + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// + public string GetSeveralAlbums(List ids, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/albums?ids={string.Join(",", ids.Take(20))}" : + $"{APIBase}/albums?market={market}&ids={string.Join(",", ids.Take(20))}"; + } + + #endregion Albums + + #region Artists + + /// + /// Get Spotify catalog information for a single artist identified by their unique Spotify ID. + /// + /// The Spotify ID for the artist. + /// + public string GetArtist(string id) + { + return $"{APIBase}/artists/{id}"; + } + + /// + /// Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the + /// Spotify community’s listening history. + /// + /// The Spotify ID for the artist. + /// + public string GetRelatedArtists(string id) + { + return $"{APIBase}/artists/{id}/related-artists"; + } + + /// + /// Get Spotify catalog information about an artist’s top tracks by country. + /// + /// The Spotify ID for the artist. + /// The country: an ISO 3166-1 alpha-2 country code. + /// + public string GetArtistsTopTracks(string id, string country) + { + return $"{APIBase}/artists/{id}/top-tracks?country={country}"; + } + + /// + /// Get Spotify catalog information about an artist’s albums. Optional parameters can be specified in the query string + /// to filter and sort the response. + /// + /// The Spotify ID for the artist. + /// + /// A list of keywords that will be used to filter the response. If not supplied, all album types will + /// be returned + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first album to return. Default: 0 + /// + /// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular + /// geographical market + /// + /// + public string GetArtistsAlbums(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "") + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/artists/" + id + "/albums"); + builder.Append("?album_type=" + type.GetStringAttribute(",")); + builder.Append("&limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Get Spotify catalog information for several artists based on their Spotify IDs. + /// + /// A list of the Spotify IDs for the artists. Maximum: 50 IDs. + /// + public string GetSeveralArtists(List ids) + { + return $"{APIBase}/artists?ids={string.Join(",", ids.Take(50))}"; + } + + #endregion Artists + + #region Browse + + /// + /// Get a list of Spotify featured playlists (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// + /// The desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 + /// alpha-2 country code, joined by an underscore. + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// A timestamp in ISO 8601 format + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// AUTH NEEDED + public string GetFeaturedPlaylists(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0) + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/browse/featured-playlists"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(locale)) + builder.Append("&locale=" + locale); + if (!string.IsNullOrEmpty(country)) + builder.Append("&country=" + country); + if (timestamp != default(DateTime)) + builder.Append("×tamp=" + timestamp.ToString("yyyy-MM-ddTHH:mm:ss")); + return builder.ToString(); + } + + /// + /// Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab). + /// + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public string GetNewAlbumReleases(string country = "", int limit = 20, int offset = 0) + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/browse/new-releases"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(country)) + builder.Append("&country=" + country); + return builder.ToString(); + } + + /// + /// Get a list of categories used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). + /// + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want to narrow the + /// list of returned categories to those relevant to a particular country + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 (the first object). + /// + /// AUTH NEEDED + public string GetCategories(string country = "", string locale = "", int limit = 20, int offset = 0) + { + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder(APIBase + "/browse/categories"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(country)) + builder.Append("&country=" + country); + if (!string.IsNullOrEmpty(locale)) + builder.Append("&locale=" + locale); + return builder.ToString(); + } + + /// + /// Get a single category used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab). + /// + /// The Spotify category ID for the category. + /// + /// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category + /// exists for a particular country. + /// + /// + /// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country + /// code, joined by an underscore + /// + /// + /// AUTH NEEDED + public string GetCategory(string categoryId, string country = "", string locale = "") + { + StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId); + if (!string.IsNullOrEmpty(country)) + builder.Append("?country=" + country); + if (!string.IsNullOrEmpty(locale)) + builder.Append((country == "" ? "?locale=" : "&locale=") + locale); + return builder.ToString(); + } + + /// + /// Get a list of Spotify playlists tagged with a particular category. + /// + /// The Spotify category ID for the category. + /// A country: an ISO 3166-1 alpha-2 country code. + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The index of the first item to return. Default: 0 + /// + /// AUTH NEEDED + public string GetCategoryPlaylists(string categoryId, string country = "", int limit = 20, int offset = 0) + { + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder(APIBase + "/browse/categories/" + categoryId + "/playlists"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(country)) + builder.Append("&country=" + country); + return builder.ToString(); + } + + /// + /// Create a playlist-style listening experience based on seed artists, tracks and genres. + /// + /// A comma separated list of Spotify IDs for seed artists. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of any genres in the set of available genre seeds. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// A comma separated list of Spotify IDs for a seed track. + /// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres. + /// + /// Tracks with the attribute values nearest to the target values will be preferred. + /// For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided + /// For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided + /// The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100. + /// For seeds with unusually small pools or when highly restrictive filtering is applied, it may be impossible to generate the requested number of recommended tracks. + /// + /// An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking. + /// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied. + /// + /// AUTH NEEDED + public string GetRecommendations(List artistSeed = null, List genreSeed = null, List trackSeed = null, + TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "") + { + limit = Math.Min(100, limit); + StringBuilder builder = new StringBuilder($"{APIBase}/recommendations"); + builder.Append("?limit=" + limit); + if (artistSeed?.Count > 0) + builder.Append("&seed_artists=" + string.Join(",", artistSeed)); + if (genreSeed?.Count > 0) + builder.Append("&seed_genres=" + string.Join(",", genreSeed)); + if (trackSeed?.Count > 0) + builder.Append("&seed_tracks=" + string.Join(",", trackSeed)); + if (target != null) + builder.Append(target.BuildUrlParams("target")); + if (min != null) + builder.Append(min.BuildUrlParams("min")); + if (max != null) + builder.Append(max.BuildUrlParams("max")); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Retrieve a list of available genres seed parameter values for recommendations. + /// + /// + /// AUTH NEEDED + public string GetRecommendationSeedsGenres() + { + return $"{APIBase}/recommendations/available-genre-seeds"; + } + + #endregion Browse + + #region Follow + + /// + /// Get the current user’s followed artists. + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// The last artist ID retrieved from the previous request. + /// + /// AUTH NEEDED + public string GetFollowedArtists(int limit = 20, string after = "") + { + limit = Math.Min(limit, 50); + const FollowType followType = FollowType.Artist; //currently only artist is supported. + StringBuilder builder = new StringBuilder(APIBase + "/me/following?type=" + followType.GetStringAttribute()); + builder.Append("&limit=" + limit); + if (!string.IsNullOrEmpty(after)) + builder.Append("&after=" + after); + return builder.ToString(); + } + + /// + /// Add the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// + /// AUTH NEEDED + public string Follow(FollowType followType) + { + return $"{APIBase}/me/following?type={followType.GetStringAttribute()}"; + } + + /// + /// Remove the current user as a follower of one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// + /// AUTH NEEDED + public string Unfollow(FollowType followType) + { + return $"{APIBase}/me/following?type={followType.GetStringAttribute()}"; + } + + /// + /// Check to see if the current user is following one or more artists or other Spotify users. + /// + /// The ID type: either artist or user. + /// A list of the artist or the user Spotify IDs to check + /// + /// AUTH NEEDED + public string IsFollowing(FollowType followType, List ids) + { + return $"{APIBase}/me/following/contains?type={followType.GetStringAttribute()}&ids={string.Join(",", ids)}"; + } + + /// + /// Add the current user as a follower of a playlist. + /// + /// + /// The Spotify ID of the playlist. Any playlist can be followed, regardless of its public/private + /// status, as long as you know its playlist ID. + /// + /// + /// AUTH NEEDED + public string FollowPlaylist(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}/followers"; + } + + /// + /// Remove the current user as a follower of a playlist. + /// + /// The Spotify ID of the playlist that is to be no longer followed. + /// + /// AUTH NEEDED + public string UnfollowPlaylist(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}/followers"; + } + + /// + /// Check to see if one or more Spotify users are following a specified playlist. + /// + /// The Spotify ID of the playlist. + /// A list of Spotify User IDs + /// + /// AUTH NEEDED + public string IsFollowingPlaylist(string playlistId, List ids) + { + return $"{APIBase}/playlists/{playlistId}/followers/contains?ids={string.Join(",", ids)}"; + } + + #endregion Follow + + #region Library + + /// + /// Save one or more tracks to the current user’s “Your Music” library. + /// + /// + /// AUTH NEEDED + public string SaveTracks() + { + return APIBase + "/me/tracks/"; + } + + /// + /// Get a list of the songs saved in the current Spotify user’s “Your Music” library. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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 GetSavedTracks(int limit = 20, int offset = 0, string market = "") + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/me/tracks"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Remove one or more tracks from the current user’s “Your Music” library. + /// + /// + /// AUTH NEEDED + public string RemoveSavedTracks() + { + return APIBase + "/me/tracks/"; + } + + /// + /// Check if one or more tracks is already saved in the current Spotify user’s “Your Music” library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public string CheckSavedTracks(List ids) + { + return APIBase + "/me/tracks/contains?ids=" + string.Join(",", ids); + } + + /// + /// Save one or more albums to the current user’s "Your Music" library. + /// + /// + /// AUTH NEEDED + public string SaveAlbums() + { + return $"{APIBase}/me/albums"; + } + + /// + /// Get a list of the albums saved in the current Spotify user’s "Your Music" library. + /// + /// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50. + /// 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 GetSavedAlbums(int limit = 20, int offset = 0, string market = "") + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/me/albums"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Remove one or more albums from the current user’s "Your Music" library. + /// + /// + /// AUTH NEEDED + public string RemoveSavedAlbums() + { + return APIBase + "/me/albums/"; + } + + /// + /// Check if one or more albums is already saved in the current Spotify user’s "Your Music" library. + /// + /// A list of the Spotify IDs. + /// + /// AUTH NEEDED + public string CheckSavedAlbums(List ids) + { + return APIBase + "/me/albums/contains?ids=" + string.Join(",", ids); + } + + #endregion Library + + #region Personalization + + /// + /// Get the current user’s top tracks based on calculated affinity. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public string GetUsersTopTracks(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder($"{APIBase}/me/top/tracks"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offest); + builder.Append("&time_range=" + timeRange.GetStringAttribute()); + return builder.ToString(); + } + + /// + /// Get the current user’s top artists based on calculated affinity. + /// + /// 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). + /// The number of entities to return. Default: 20. Minimum: 1. Maximum: 50 + /// 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. + /// + /// AUTH NEEDED + public string GetUsersTopArtists(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0) + { + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder($"{APIBase}/me/top/artists"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offest); + builder.Append("&time_range=" + timeRange.GetStringAttribute()); + return builder.ToString(); + } + + /// + /// Get tracks from the current user’s recent play history. + /// + /// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + /// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified. + /// A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified. + /// + /// AUTH NEEDED + public string GetUsersRecentlyPlayedTracks(int limit = 20, DateTime? after = null, DateTime? before = null) + { + limit = Math.Min(50, limit); + StringBuilder builder = new StringBuilder($"{APIBase}/me/player/recently-played"); + builder.Append("?limit=" + limit); + if (after.HasValue) + builder.Append("&after=" + after.Value.ToUnixTimeMillisecondsPoly()); + if (before.HasValue) + builder.Append("&before=" + before.Value.ToUnixTimeMillisecondsPoly()); + return builder.ToString(); + } + + #endregion + + #region Playlists + + /// + /// Get a list of the playlists owned or followed by a Spotify user. + /// + /// 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 string GetUserPlaylists(string userId, int limit = 20, int offset = 0) + { + limit = Math.Min(limit, 50); + StringBuilder builder = new StringBuilder(APIBase + "/users/" + userId + "/playlists"); + builder.Append("?limit=" + limit); + builder.Append("&offset=" + offset); + return builder.ToString(); + } + + /// + /// 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 + 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 = "") + { + 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); + return builder.ToString(); + } + + /// + /// Get full details of the tracks of 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. + /// + /// 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 playlistId, string fields = "", int limit = 100, int offset = 0, string market = "") + { + limit = Math.Min(limit, 100); + StringBuilder builder = new StringBuilder(APIBase + "/playlists/" + playlistId + "/tracks"); + builder.Append("?fields=" + fields); + builder.Append("&limit=" + limit); + builder.Append("&offset=" + offset); + if (!string.IsNullOrEmpty(market)) + builder.Append("&market=" + market); + return builder.ToString(); + } + + /// + /// Create a playlist for a Spotify user. (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 string CreatePlaylist(string userId, string playlistName, bool isPublic = true) + { + return $"{APIBase}/users/{userId}/playlists"; + } + + /// + /// 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. + /// + /// AUTH NEEDED + public string UpdatePlaylist(string userId, string playlistId) + { + return $"{APIBase}/users/{userId}/playlists/{playlistId}"; + } + + /// + /// Change a playlist’s name and public/private state. (The user must, of course, own the playlist.) + /// + /// The Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string UpdatePlaylist(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}"; + } + + /// + /// 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. + /// + /// AUTH NEEDED + public string ReplacePlaylistTracks(string userId, string playlistId) + { + return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; + } + + /// + /// 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 Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string ReplacePlaylistTracks(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}/tracks"; + } + + /// + /// 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 + public string RemovePlaylistTracks(string userId, string playlistId, List uris) + { + return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; + } + + /// + /// Remove one or more tracks from a user’s playlist. + /// + /// 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 string RemovePlaylistTracks(string playlistId, List uris) + { + return $"{APIBase}/playlists/{playlistId}/tracks"; + } + + /// + /// 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 + public string AddPlaylistTracks(string userId, string playlistId, List uris, int? position = null) + { + return position == null ? + $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks" : + $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks?position={position}"; + } + + /// + /// Add one or more tracks to a user’s playlist. + /// + /// 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 string AddPlaylistTracks(string playlistId, List uris, int? position = null) + { + return position == null ? + $"{APIBase}/playlists/{playlistId}/tracks" : + $"{APIBase}/playlists/{playlistId}/tracks?position={position}"; + } + + /// + /// Reorder a track or a group of tracks in a playlist. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string ReorderPlaylist(string userId, string playlistId) + { + return $"{APIBase}/users/{userId}/playlists/{playlistId}/tracks"; + } + + /// + /// Reorder a track or a group of tracks in a playlist. + /// + /// The Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string ReorderPlaylist(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}/tracks"; + } + + /// + /// Upload an image for a playlist. + /// + /// The user's Spotify user ID. + /// The Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string UploadPlaylistImage(string userId, string playlistId) + { + return $"{APIBase}/users/{userId}/playlists/{playlistId}/images"; + } + + /// + /// Upload an image for a playlist. + /// + /// The Spotify ID for the playlist. + /// + /// AUTH NEEDED + public string UploadPlaylistImage(string playlistId) + { + return $"{APIBase}/playlists/{playlistId}/images"; + } + + #endregion Playlists + + #region Profiles + + /// + /// Get detailed profile information about the current user (including the current user’s username). + /// + /// + /// AUTH NEEDED + public string GetPrivateProfile() + { + return $"{APIBase}/me"; + } + + /// + /// Get public profile information about a Spotify user. + /// + /// The user's Spotify user ID. + /// + public string GetPublicProfile(string userId) + { + return $"{APIBase}/users/{userId}"; + } + + #endregion Profiles + + #region Tracks + + /// + /// Get Spotify catalog information for multiple tracks based on their Spotify IDs. + /// + /// 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 string GetSeveralTracks(List ids, string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/tracks?ids={string.Join(",", ids.Take(50))}" : + $"{APIBase}/tracks?market={market}&ids={string.Join(",", ids.Take(50))}"; + } + + /// + /// Get Spotify catalog information for a single track identified by its unique Spotify ID. + /// + /// 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 string GetTrack(string id, string market = "") + { + return string.IsNullOrEmpty(market) ? $"{APIBase}/tracks/{id}" : $"{APIBase}/tracks/{id}?market={market}"; + } + + /// + /// Get a detailed audio analysis for a single track identified by its unique Spotify ID. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public string GetAudioAnalysis(string id) + { + return $"{APIBase}/audio-analysis/{id}"; + } + + /// + /// Get audio feature information for a single track identified by its unique Spotify ID. + /// + /// The Spotify ID for the track. + /// + /// AUTH NEEDED + public string GetAudioFeatures(string id) + { + return $"{APIBase}/audio-features/{id}"; + } + + /// + /// Get audio features for multiple tracks based on their Spotify IDs. + /// + /// A list of Spotify Track-IDs. Maximum: 100 IDs. + /// + /// AUTH NEEDED + public string GetSeveralAudioFeatures(List ids) + { + return $"{APIBase}/audio-features?ids={string.Join(",", ids.Take(100))}"; + } + + #endregion Tracks + + #region Player + + /// + /// Get information about a user’s available devices. + /// + /// + public string GetDevices() + { + return $"{APIBase}/me/player/devices"; + } + + /// + /// 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. + /// + public string GetPlayback(string market = "") + { + return string.IsNullOrEmpty(market) ? $"{APIBase}/me/player" : $"{APIBase}/me/player?market={market}"; + } + + /// + /// 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. + /// + public string GetPlayingTrack(string market = "") + { + return string.IsNullOrEmpty(market) ? + $"{APIBase}/me/player/currently-playing" : + $"{APIBase}/me/player/currently-playing?market={market}"; + } + + /// + /// Transfer playback to a new device and determine if it should start playing. + /// + /// + public string TransferPlayback() + { + return $"{APIBase}/me/player"; + } + + /// + /// Start a new context or resume current playback on the user’s active device. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string ResumePlayback(string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/play" : + $"{APIBase}/me/player/play?device_id={deviceId}"; + } + + /// + /// Pause playback on the user’s account. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string PausePlayback(string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/pause" : + $"{APIBase}/me/player/pause?device_id={deviceId}"; + } + + /// + /// Skips to next track in the user’s queue. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SkipPlaybackToNext(string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/next" : + $"{APIBase}/me/player/next?device_id={deviceId}"; + } + + /// + /// Skips to previous track in the user’s queue. + /// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress. + /// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint. + /// + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SkipPlaybackToPrevious(string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/previous" : + $"{APIBase}/me/player/previous?device_id={deviceId}"; + } + + /// + /// Seeks to the given position in the user’s currently playing track. + /// + /// The position in milliseconds to seek to. Must be a positive number. + /// Passing in a position that is greater than the length of the track will cause the player to start playing the next song. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SeekPlayback(int positionMs, string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/seek?position_ms={positionMs}" : + $"{APIBase}/me/player/seek?position_ms={positionMs}&device_id={deviceId}"; + } + + /// + /// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off. + /// + /// track, context or off. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SetRepeatMode(RepeatState repeatState, string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/repeat?state={repeatState.GetStringAttribute()}" : + $"{APIBase}/me/player/repeat?state={repeatState.GetStringAttribute()}&device_id={deviceId}"; + } + + /// + /// Set the volume for the user’s current playback device. + /// + /// Integer. The volume to set. Must be a value from 0 to 100 inclusive. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SetVolume(int volumePercent, string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/volume?volume_percent={volumePercent}" : + $"{APIBase}/me/player/volume?volume_percent={volumePercent}&device_id={deviceId}"; + } + + /// + /// Toggle shuffle on or off for user’s playback. + /// + /// True of False. + /// The id of the device this command is targeting. If not supplied, the user's currently active device is the target. + /// + public string SetShuffle(bool shuffle, string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/shuffle?state={shuffle}" : + $"{APIBase}/me/player/shuffle?state={shuffle}&device_id={deviceId}"; + } + + /// + /// Add an Item to the User's Playback Queue. + /// + /// The uri of the item to add to the queue. Must be a track or an episode uri. + /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. + /// + public string AddToQueue(string uri, string deviceId = "") + { + return string.IsNullOrEmpty(deviceId) ? + $"{APIBase}/me/player/queue?uri={uri}" : + $"{APIBase}/me/player/queue?uri={uri}&device_id={deviceId}"; + } + #endregion + } }