Spotify.NET/SpotifyAPI.Web/SpotifyWebAPI.cs

2579 lines
130 KiB
C#
Raw Normal View History

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SpotifyAPI.Web.Enums;
using SpotifyAPI.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
2016-08-24 12:17:46 +01:00
using System.Threading;
2015-11-05 20:20:22 +00:00
using System.Threading.Tasks;
namespace SpotifyAPI.Web
{
2016-04-01 12:23:11 +01:00
// ReSharper disable once InconsistentNaming
public sealed class SpotifyWebAPI : IDisposable
{
2015-11-05 20:20:22 +00:00
private readonly SpotifyWebBuilder _builder;
public SpotifyWebAPI() : this(null)
{
}
public SpotifyWebAPI(ProxyConfig proxyConfig)
{
2015-11-05 20:20:22 +00:00
_builder = new SpotifyWebBuilder();
UseAuth = true;
WebClient = new SpotifyWebClient(proxyConfig)
{
JsonSettings =
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.All
}
};
}
public void Dispose()
{
WebClient.Dispose();
GC.SuppressFinalize(this);
}
2016-08-14 02:24:09 +01:00
#region Configuration
2016-08-24 12:17:46 +01:00
/// <summary>
/// The type of the <see cref="AccessToken"/>
/// </summary>
public string TokenType { get; set; }
/// <summary>
/// A valid token issued by spotify. Used only when <see cref="UseAuth"/> is true
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// If true, an authorization header based on <see cref="TokenType"/> and <see cref="AccessToken"/> will be used
/// </summary>
public bool UseAuth { get; set; }
2016-08-14 02:24:09 +01:00
/// <summary>
2016-08-24 12:17:46 +01:00
/// A custom WebClient, used for Unit-Testing
/// </summary>
public IClient WebClient { get; set; }
/// <summary>
/// Specifies after how many miliseconds should a failed request be retried.
2016-08-14 02:24:09 +01:00
/// </summary>
public int RetryAfter { get; set; } = 50;
/// <summary>
2016-08-24 12:17:46 +01:00
/// Should a failed request (specified by <see cref="RetryErrorCodes"/> be automatically retried or not.
2016-08-14 02:24:09 +01:00
/// </summary>
2016-08-14 03:29:01 +01:00
public bool UseAutoRetry { get; set; } = false;
2016-08-14 02:24:09 +01:00
/// <summary>
2016-08-24 12:17:46 +01:00
/// Maximum number of tries for one failed request.
2016-08-14 02:24:09 +01:00
/// </summary>
public int RetryTimes { get; set; } = 10;
/// <summary>
/// Whether a failure of type "Too Many Requests" should use up one of the allocated retry attempts.
/// </summary>
public bool TooManyRequestsConsumesARetry { get; set; } = false;
2016-08-23 18:18:04 +01:00
/// <summary>
2016-08-24 12:17:46 +01:00
/// Error codes that will trigger auto-retry if <see cref="UseAutoRetry"/> is enabled.
2016-08-23 18:18:04 +01:00
/// </summary>
2016-08-24 12:17:46 +01:00
public IEnumerable<int> RetryErrorCodes { get; set; } = new[] { 500, 502, 503 };
2016-08-14 02:24:09 +01:00
#endregion Configuration
#region Search
/// <summary>
/// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string.
/// </summary>
/// <param name="q">The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues.</param>
/// <param name="type">A list of item types to search across.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first result to return. Default: 0</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code or the string from_token.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SearchItem SearchItems(string q, SearchType type, int limit = 20, int offset = 0, string market = "")
{
2015-11-05 20:20:22 +00:00
return DownloadData<SearchItem>(_builder.SearchItems(q, type, limit, offset, market));
}
/// <summary>
/// Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string asynchronously.
/// </summary>
/// <param name="q">The search query's keywords (and optional field filters and operators), for example q=roadhouse+blues.</param>
/// <param name="type">A list of item types to search across.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first result to return. Default: 0</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code or the string from_token.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SearchItem> SearchItemsAsync(string q, SearchType type, int limit = 20, int offset = 0, string market = "")
2015-11-05 20:20:22 +00:00
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SearchItem>(_builder.SearchItems(q, type, limit, offset, market));
}
#endregion Search
2015-07-15 16:35:32 +01:00
#region Albums
/// <summary>
/// Get Spotify catalog information about an albums tracks. Optional parameters can be used to limit the number of
/// tracks returned.
/// </summary>
2015-07-15 16:35:32 +01:00
/// <param name="id">The Spotify ID for the album.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first track to return. Default: 0 (the first object).</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public Paging<SimpleTrack> GetAlbumTracks(string id, int limit = 20, int offset = 0, string market = "")
2015-07-15 16:35:32 +01:00
{
return DownloadData<Paging<SimpleTrack>>(_builder.GetAlbumTracks(id, limit, offset, market));
}
/// <summary>
/// Get Spotify catalog information about an albums tracks asynchronously. Optional parameters can be used to limit the number of
/// tracks returned.
/// </summary>
/// <param name="id">The Spotify ID for the album.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first track to return. Default: 0 (the first object).</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<Paging<SimpleTrack>> GetAlbumTracksAsync(string id, int limit = 20, int offset = 0, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<SimpleTrack>>(_builder.GetAlbumTracks(id, limit, offset, market));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information for a single album.
/// </summary>
/// <param name="id">The Spotify ID for the album.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public FullAlbum GetAlbum(string id, string market = "")
2015-07-15 16:35:32 +01:00
{
return DownloadData<FullAlbum>(_builder.GetAlbum(id, market));
}
/// <summary>
/// Get Spotify catalog information for a single album asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the album.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<FullAlbum> GetAlbumAsync(string id, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FullAlbum>(_builder.GetAlbum(id, market));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information for multiple albums identified by their Spotify IDs.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the albums. Maximum: 20 IDs.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SeveralAlbums GetSeveralAlbums(List<string> ids, string market = "")
2015-07-15 16:35:32 +01:00
{
return DownloadData<SeveralAlbums>(_builder.GetSeveralAlbums(ids, market));
}
/// <summary>
/// Get Spotify catalog information for multiple albums identified by their Spotify IDs asynchrously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the albums. Maximum: 20 IDs.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SeveralAlbums> GetSeveralAlbumsAsync(List<string> ids, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralAlbums>(_builder.GetSeveralAlbums(ids, market));
2015-07-15 16:35:32 +01:00
}
#endregion Albums
2015-07-15 16:35:32 +01:00
#region Artists
/// <summary>
/// Get Spotify catalog information for a single artist identified by their unique Spotify ID.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public FullArtist GetArtist(string id)
2015-07-15 16:35:32 +01:00
{
return DownloadData<FullArtist>(_builder.GetArtist(id));
}
/// <summary>
/// Get Spotify catalog information for a single artist identified by their unique Spotify ID asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<FullArtist> GetArtistAsync(string id)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FullArtist>(_builder.GetArtist(id));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the
/// Spotify communitys listening history.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SeveralArtists GetRelatedArtists(string id)
2015-07-15 16:35:32 +01:00
{
return DownloadData<SeveralArtists>(_builder.GetRelatedArtists(id));
}
/// <summary>
/// Get Spotify catalog information about artists similar to a given artist asynchronously. Similarity is based on analysis of the
/// Spotify communitys listening history.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SeveralArtists> GetRelatedArtistsAsync(string id)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralArtists>(_builder.GetRelatedArtists(id));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information about an artists top tracks by country.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <param name="country">The country: an ISO 3166-1 alpha-2 country code.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SeveralTracks GetArtistsTopTracks(string id, string country)
2015-07-15 16:35:32 +01:00
{
return DownloadData<SeveralTracks>(_builder.GetArtistsTopTracks(id, country));
}
/// <summary>
/// Get Spotify catalog information about an artists top tracks by country asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <param name="country">The country: an ISO 3166-1 alpha-2 country code.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SeveralTracks> GetArtistsTopTracksAsync(string id, string country)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralTracks>(_builder.GetArtistsTopTracks(id, country));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information about an artists albums. Optional parameters can be specified in the query string
/// to filter and sort the response.
2015-07-15 16:35:32 +01:00
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <param name="type">
/// A list of keywords that will be used to filter the response. If not supplied, all album types will
/// be returned
/// </param>
2015-07-15 16:35:32 +01:00
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first album to return. Default: 0</param>
/// <param name="market">
/// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular
/// geographical market
/// </param>
2015-07-15 16:35:32 +01:00
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public Paging<SimpleAlbum> GetArtistsAlbums(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "")
2015-07-15 16:35:32 +01:00
{
return DownloadData<Paging<SimpleAlbum>>(_builder.GetArtistsAlbums(id, type, limit, offset, market));
}
/// <summary>
/// Get Spotify catalog information about an artists albums asynchronously. Optional parameters can be specified in the query string
/// to filter and sort the response.
/// </summary>
/// <param name="id">The Spotify ID for the artist.</param>
/// <param name="type">
/// A list of keywords that will be used to filter the response. If not supplied, all album types will
/// be returned
/// </param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first album to return. Default: 0</param>
/// <param name="market">
/// An ISO 3166-1 alpha-2 country code. Supply this parameter to limit the response to one particular
/// geographical market
/// </param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<Paging<SimpleAlbum>> GetArtistsAlbumsAsync(string id, AlbumType type = AlbumType.All, int limit = 20, int offset = 0, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<SimpleAlbum>>(_builder.GetArtistsAlbums(id, type, limit, offset, market));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get Spotify catalog information for several artists based on their Spotify IDs.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the artists. Maximum: 50 IDs.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SeveralArtists GetSeveralArtists(List<string> ids)
2015-07-15 16:35:32 +01:00
{
return DownloadData<SeveralArtists>(_builder.GetSeveralArtists(ids));
}
/// <summary>
/// Get Spotify catalog information for several artists based on their Spotify IDs asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the artists. Maximum: 50 IDs.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SeveralArtists> GetSeveralArtistsAsync(List<string> ids)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralArtists>(_builder.GetSeveralArtists(ids));
2015-07-15 16:35:32 +01:00
}
#endregion Artists
2015-07-15 16:35:32 +01:00
#region Browse
/// <summary>
/// Get a list of Spotify featured playlists (shown, for example, on a Spotify players “Browse” tab).
/// </summary>
/// <param name="locale">
/// 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.
/// </param>
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="timestamp">A timestamp in ISO 8601 format</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public FeaturedPlaylists GetFeaturedPlaylists(string locale = "", string country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0)
{
if (!UseAuth)
2015-07-15 16:35:32 +01:00
throw new InvalidOperationException("Auth is required for GetFeaturedPlaylists");
return DownloadData<FeaturedPlaylists>(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset));
}
/// <summary>
/// Get a list of Spotify featured playlists asynchronously (shown, for example, on a Spotify players “Browse” tab).
/// </summary>
/// <param name="locale">
/// 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.
/// </param>
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="timestamp">A timestamp in ISO 8601 format</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<FeaturedPlaylists> 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");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FeaturedPlaylists>(_builder.GetFeaturedPlaylists(locale, country, timestamp, limit, offset));
}
/// <summary>
2015-07-15 16:35:32 +01:00
/// Get a list of new album releases featured in Spotify (shown, for example, on a Spotify players “Browse” tab).
/// </summary>
2015-07-15 16:35:32 +01:00
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public NewAlbumReleases GetNewAlbumReleases(string country = "", int limit = 20, int offset = 0)
{
2015-07-15 16:35:32 +01:00
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetNewAlbumReleases");
return DownloadData<NewAlbumReleases>(_builder.GetNewAlbumReleases(country, limit, offset));
}
/// <summary>
/// Get a list of new album releases featured in Spotify asynchronously (shown, for example, on a Spotify players “Browse” tab).
/// </summary>
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<NewAlbumReleases> GetNewAlbumReleasesAsync(string country = "", int limit = 20, int offset = 0)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetNewAlbumReleases");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<NewAlbumReleases>(_builder.GetNewAlbumReleases(country, limit, offset));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get a list of categories used to tag items in Spotify (on, for example, the Spotify players “Browse” tab).
/// </summary>
/// <param name="country">
/// 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
/// </param>
/// <param name="locale">
/// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country
/// code, joined by an underscore
/// </param>
2015-07-15 16:35:32 +01:00
/// <param name="limit">The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="offset">The index of the first item to return. Default: 0 (the first object).</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public CategoryList GetCategories(string country = "", string locale = "", int limit = 20, int offset = 0)
2015-07-15 16:35:32 +01:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetCategories");
return DownloadData<CategoryList>(_builder.GetCategories(country, locale, limit, offset));
}
/// <summary>
/// Get a list of categories used to tag items in Spotify asynchronously (on, for example, the Spotify players “Browse” tab).
/// </summary>
/// <param name="country">
/// 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
/// </param>
/// <param name="locale">
/// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country
/// code, joined by an underscore
/// </param>
/// <param name="limit">The maximum number of categories to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="offset">The index of the first item to return. Default: 0 (the first object).</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<CategoryList> GetCategoriesAsync(string country = "", string locale = "", int limit = 20, int offset = 0)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetCategories");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<CategoryList>(_builder.GetCategories(country, locale, limit, offset));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get a single category used to tag items in Spotify (on, for example, the Spotify players “Browse” tab).
/// </summary>
/// <param name="categoryId">The Spotify category ID for the category.</param>
/// <param name="country">
/// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category
/// exists for a particular country.
/// </param>
/// <param name="locale">
/// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country
/// code, joined by an underscore
/// </param>
2015-07-15 16:35:32 +01:00
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public Category GetCategory(string categoryId, string country = "", string locale = "")
2015-07-15 16:35:32 +01:00
{
return DownloadData<Category>(_builder.GetCategory(categoryId, country, locale));
}
/// <summary>
/// Get a single category used to tag items in Spotify asynchronously (on, for example, the Spotify players “Browse” tab).
/// </summary>
/// <param name="categoryId">The Spotify category ID for the category.</param>
/// <param name="country">
/// A country: an ISO 3166-1 alpha-2 country code. Provide this parameter to ensure that the category
/// exists for a particular country.
/// </param>
/// <param name="locale">
/// The desired language, consisting of an ISO 639 language code and an ISO 3166-1 alpha-2 country
/// code, joined by an underscore
/// </param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Category> GetCategoryAsync(string categoryId, string country = "", string locale = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Category>(_builder.GetCategory(categoryId, country, locale));
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Get a list of Spotify playlists tagged with a particular category.
/// </summary>
/// <param name="categoryId">The Spotify category ID for the category.</param>
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public CategoryPlaylist GetCategoryPlaylists(string categoryId, string country = "", int limit = 20, int offset = 0)
2015-07-15 16:35:32 +01:00
{
return DownloadData<CategoryPlaylist>(_builder.GetCategoryPlaylists(categoryId, country, limit, offset));
}
/// <summary>
/// Get a list of Spotify playlists tagged with a particular category asynchronously.
/// </summary>
/// <param name="categoryId">The Spotify category ID for the category.</param>
/// <param name="country">A country: an ISO 3166-1 alpha-2 country code.</param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first item to return. Default: 0</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<CategoryPlaylist> GetCategoryPlaylistsAsync(string categoryId, string country = "", int limit = 20, int offset = 0)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<CategoryPlaylist>(_builder.GetCategoryPlaylists(categoryId, country, limit, offset));
}
2016-04-01 12:23:11 +01:00
/// <summary>
/// Create a playlist-style listening experience based on seed artists, tracks and genres.
/// </summary>
/// <param name="artistSeed">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.
/// </param>
/// <param name="genreSeed">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.
/// </param>
/// <param name="trackSeed">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.
/// </param>
/// <param name="target">Tracks with the attribute values nearest to the target values will be preferred.</param>
/// <param name="min">For each tunable track attribute, a hard floor on the selected track attributes value can be provided</param>
/// <param name="max">For each tunable track attribute, a hard ceiling on the selected track attributes value can be provided</param>
/// <param name="limit">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.
/// </param>
/// <param name="market">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Recommendations GetRecommendations(List<string> artistSeed = null, List<string> genreSeed = null, List<string> trackSeed = null,
TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "")
{
return DownloadData<Recommendations>(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market));
}
/// <summary>
/// Create a playlist-style listening experience based on seed artists, tracks and genres asynchronously.
/// </summary>
/// <param name="artistSeed">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.
/// </param>
/// <param name="genreSeed">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.
/// </param>
/// <param name="trackSeed">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.
/// </param>
/// <param name="target">Tracks with the attribute values nearest to the target values will be preferred.</param>
/// <param name="min">For each tunable track attribute, a hard floor on the selected track attributes value can be provided</param>
/// <param name="max">For each tunable track attribute, a hard ceiling on the selected track attributes value can be provided</param>
/// <param name="limit">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.
/// </param>
/// <param name="market">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Recommendations> GetRecommendationsAsync(List<string> artistSeed = null, List<string> genreSeed = null, List<string> trackSeed = null,
2016-04-01 12:23:11 +01:00
TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Recommendations>(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market));
2016-04-01 12:23:11 +01:00
}
/// <summary>
/// Retrieve a list of available genres seed parameter values for recommendations.
/// </summary>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public RecommendationSeedGenres GetRecommendationSeedsGenres()
{
return DownloadData<RecommendationSeedGenres>(_builder.GetRecommendationSeedsGenres());
}
/// <summary>
/// Retrieve a list of available genres seed parameter values for recommendations asynchronously.
/// </summary>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<RecommendationSeedGenres> GetRecommendationSeedsGenresAsync()
2016-04-01 12:23:11 +01:00
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<RecommendationSeedGenres>(_builder.GetRecommendationSeedsGenres());
2016-04-01 12:23:11 +01:00
}
#endregion Browse
2015-07-15 16:35:32 +01:00
#region Follow
/// <summary>
/// Get the current users followed artists.
/// </summary>
/// <param name="followType">The ID type: currently only artist is supported. </param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="after">The last artist ID retrieved from the previous request.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public FollowedArtists GetFollowedArtists(FollowType followType, int limit = 20, string after = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetFollowedArtists");
2015-11-06 19:57:03 +00:00
return DownloadData<FollowedArtists>(_builder.GetFollowedArtists(limit, after));
}
/// <summary>
/// Get the current users followed artists asynchronously.
/// </summary>
/// <param name="followType">The ID type: currently only artist is supported. </param>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="after">The last artist ID retrieved from the previous request.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<FollowedArtists> GetFollowedArtistsAsync(FollowType followType, int limit = 20, string after = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetFollowedArtists");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FollowedArtists>(_builder.GetFollowedArtists(limit, after));
}
/// <summary>
/// Add the current user as a follower of one or more artists or other Spotify users.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse Follow(FollowType followType, List<string> ids)
{
JObject ob = new JObject
{
{"ids", new JArray(ids)}
};
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.Follow(followType), ob.ToString(Formatting.None), "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Add the current user as a follower of one or more artists or other Spotify users asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> FollowAsync(FollowType followType, List<string> ids)
{
JObject ob = new JObject
{
{"ids", new JArray(ids)}
};
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.Follow(followType),
ob.ToString(Formatting.None), "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Add the current user as a follower of one or more artists or other Spotify users.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse Follow(FollowType followType, string id)
{
return Follow(followType, new List<string> { id });
}
/// <summary>
/// Add the current user as a follower of one or more artists or other Spotify users asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> FollowAsync(FollowType followType, string id)
{
2016-09-08 07:30:33 +01:00
return FollowAsync(followType, new List<string> { id });
}
/// <summary>
/// Remove the current user as a follower of one or more artists or other Spotify users.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse Unfollow(FollowType followType, List<string> ids)
{
JObject ob = new JObject
{
{"ids", new JArray(ids)}
};
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE") ?? new ErrorResponse();
}
/// <summary>
/// Remove the current user as a follower of one or more artists or other Spotify users asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> UnfollowAsync(FollowType followType, List<string> ids)
{
JObject ob = new JObject
{
{"ids", new JArray(ids)}
};
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.Unfollow(followType), ob.ToString(Formatting.None), "DELETE").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Remove the current user as a follower of one or more artists or other Spotify users.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse Unfollow(FollowType followType, string id)
{
return Unfollow(followType, new List<string> { id });
}
/// <summary>
/// Remove the current user as a follower of one or more artists or other Spotify users asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> UnfollowAsync(FollowType followType, string id)
{
2016-09-08 07:30:33 +01:00
return UnfollowAsync(followType, new List<string> { id });
}
/// <summary>
/// Check to see if the current user is following one or more artists or other Spotify users.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs to check</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> IsFollowing(FollowType followType, List<string> ids)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowing");
var url = _builder.IsFollowing(followType, ids);
2016-08-23 18:13:11 +01:00
return DownloadList<bool>(url);
}
/// <summary>
/// Check to see if the current user is following one or more artists or other Spotify users asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="ids">A list of the artist or the user Spotify IDs to check</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> IsFollowingAsync(FollowType followType, List<string> ids)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowing");
var url = _builder.IsFollowing(followType, ids);
2016-09-08 07:30:33 +01:00
return DownloadListAsync<bool>(url);
}
/// <summary>
/// Check to see if the current user is following one artist or another Spotify user.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> IsFollowing(FollowType followType, string id)
{
return IsFollowing(followType, new List<string> { id });
}
/// <summary>
/// Check to see if the current user is following one artist or another Spotify user asynchronously.
/// </summary>
/// <param name="followType">The ID type: either artist or user.</param>
/// <param name="id">Artists or the Users Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> IsFollowingAsync(FollowType followType, string id)
{
2016-09-08 07:30:33 +01:00
return IsFollowingAsync(followType, new List<string> { id });
}
/// <summary>
2015-07-15 16:35:32 +01:00
/// Add the current user as a follower of a playlist.
/// </summary>
2015-07-15 16:35:32 +01:00
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">
/// 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.
/// </param>
/// <param name="showPublic">
/// If true the playlist will be included in user's public playlists, if false it will remain
/// private.
/// </param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse FollowPlaylist(string ownerId, string playlistId, bool showPublic = true)
{
2015-07-15 16:35:32 +01:00
JObject body = new JObject
{
{"public", showPublic}
};
return UploadData<ErrorResponse>(_builder.FollowPlaylist(ownerId, playlistId, showPublic), body.ToString(Formatting.None), "PUT");
}
/// <summary>
/// Add the current user as a follower of a playlist asynchronously.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">
/// 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.
/// </param>
/// <param name="showPublic">
/// If true the playlist will be included in user's public playlists, if false it will remain
/// private.
/// </param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> FollowPlaylistAsync(string ownerId, string playlistId, bool showPublic = true)
{
JObject body = new JObject
{
{"public", showPublic}
};
2016-09-08 07:30:33 +01:00
return UploadDataAsync<ErrorResponse>(_builder.FollowPlaylist(ownerId, playlistId, showPublic), body.ToString(Formatting.None), "PUT");
}
/// <summary>
2015-07-15 16:35:32 +01:00
/// Remove the current user as a follower of a playlist.
/// </summary>
2015-07-15 16:35:32 +01:00
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist that is to be no longer followed.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse UnfollowPlaylist(string ownerId, string playlistId)
{
return UploadData<ErrorResponse>(_builder.UnfollowPlaylist(ownerId, playlistId), "", "DELETE");
}
/// <summary>
/// Remove the current user as a follower of a playlist asynchronously.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist that is to be no longer followed.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> UnfollowPlaylistAsync(string ownerId, string playlistId)
{
2016-09-08 07:30:33 +01:00
return UploadDataAsync<ErrorResponse>(_builder.UnfollowPlaylist(ownerId, playlistId), "", "DELETE");
}
/// <summary>
2015-07-15 16:35:32 +01:00
/// Check to see if one or more Spotify users are following a specified playlist.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist.</param>
/// <param name="ids">A list of Spotify User IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> IsFollowingPlaylist(string ownerId, string playlistId, List<string> ids)
2015-07-15 16:35:32 +01:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowingPlaylist");
var url = _builder.IsFollowingPlaylist(ownerId, playlistId, ids);
2016-08-23 18:13:11 +01:00
return DownloadList<bool>(url);
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Check to see if one or more Spotify users are following a specified playlist asynchronously.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist.</param>
/// <param name="ids">A list of Spotify User IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> IsFollowingPlaylistAsync(string ownerId, string playlistId, List<string> ids)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for IsFollowingPlaylist");
var url = _builder.IsFollowingPlaylist(ownerId, playlistId, ids);
2016-09-08 07:30:33 +01:00
return DownloadListAsync<bool>(url);
}
2015-07-15 16:35:32 +01:00
/// <summary>
/// Check to see if one or more Spotify users are following a specified playlist.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist.</param>
/// <param name="id">A Spotify User ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> IsFollowingPlaylist(string ownerId, string playlistId, string id)
2015-07-15 16:35:32 +01:00
{
return IsFollowingPlaylist(ownerId, playlistId, new List<string> { id });
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Check to see if one or more Spotify users are following a specified playlist asynchronously.
/// </summary>
/// <param name="ownerId">The Spotify user ID of the person who owns the playlist.</param>
/// <param name="playlistId">The Spotify ID of the playlist.</param>
/// <param name="id">A Spotify User ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> IsFollowingPlaylistAsync(string ownerId, string playlistId, string id)
{
2016-09-08 07:30:33 +01:00
return IsFollowingPlaylistAsync(ownerId, playlistId, new List<string> { id });
}
#endregion Follow
2015-07-15 16:35:32 +01:00
#region Library
/// <summary>
/// Save one or more tracks to the current users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse SaveTracks(List<string> ids)
2015-07-15 16:35:32 +01:00
{
JArray array = new JArray(ids);
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Save one or more tracks to the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> SaveTracksAsync(List<string> ids)
{
JArray array = new JArray(ids);
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.SaveTracks(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Save one track to the current users “Your Music” library.
/// </summary>
/// <param name="id">A Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse SaveTrack(string id)
2015-07-15 16:35:32 +01:00
{
return SaveTracks(new List<string> { id });
2015-07-15 16:35:32 +01:00
}
/// <summary>
/// Save one track to the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="id">A Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> SaveTrackAsync(string id)
{
2016-09-08 07:30:33 +01:00
return SaveTracksAsync(new List<string> { id });
}
2015-07-15 16:35:32 +01:00
/// <summary>
/// Get a list of the songs saved in the current Spotify users “Your Music” library.
/// </summary>
/// <param name="limit">The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public Paging<SavedTrack> GetSavedTracks(int limit = 20, int offset = 0, string market = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetSavedTracks");
return DownloadData<Paging<SavedTrack>>(_builder.GetSavedTracks(limit, offset, market));
}
/// <summary>
/// Get a list of the songs saved in the current Spotify users “Your Music” library asynchronously.
/// </summary>
/// <param name="limit">The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<SavedTrack>> GetSavedTracksAsync(int limit = 20, int offset = 0, string market = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetSavedTracks");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<SavedTrack>>(_builder.GetSavedTracks(limit, offset, market));
}
/// <summary>
/// Remove one or more tracks from the current users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse RemoveSavedTracks(List<string> ids)
{
JArray array = new JArray(ids);
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse();
}
/// <summary>
/// Remove one or more tracks from the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> RemoveSavedTracksAsync(List<string> ids)
{
JArray array = new JArray(ids);
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.RemoveSavedTracks(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Check if one or more tracks is already saved in the current Spotify users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> CheckSavedTracks(List<string> ids)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks");
var url = _builder.CheckSavedTracks(ids);
2016-08-23 18:13:11 +01:00
return DownloadList<bool>(url);
}
/// <summary>
/// Check if one or more tracks is already saved in the current Spotify users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> CheckSavedTracksAsync(List<string> ids)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks");
var url = _builder.CheckSavedTracks(ids);
2016-09-08 07:30:33 +01:00
return DownloadListAsync<bool>(url);
}
2015-12-07 13:08:23 +00:00
/// <summary>
/// Save one or more albums to the current users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse SaveAlbums(List<string> ids)
2015-12-07 13:08:23 +00:00
{
JArray array = new JArray(ids);
return UploadData<ErrorResponse>(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Save one or more albums to the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> SaveAlbumsAsync(List<string> ids)
2015-12-07 13:08:23 +00:00
{
JArray array = new JArray(ids);
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.SaveAlbums(), array.ToString(Formatting.None), "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Save one album to the current users “Your Music” library.
/// </summary>
/// <param name="id">A Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse SaveAlbum(string id)
2015-12-07 13:08:23 +00:00
{
return SaveAlbums(new List<string> { id });
}
/// <summary>
/// Save one album to the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="id">A Spotify ID</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> SaveAlbumAsync(string id)
2015-12-07 13:08:23 +00:00
{
2016-09-08 07:30:33 +01:00
return SaveAlbumsAsync(new List<string> { id });
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Get a list of the albums saved in the current Spotify users “Your Music” library.
/// </summary>
/// <param name="limit">The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public Paging<SavedAlbum> GetSavedAlbums(int limit = 20, int offset = 0, string market = "")
2015-12-07 13:08:23 +00:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetSavedAlbums");
2015-12-07 13:13:24 +00:00
return DownloadData<Paging<SavedAlbum>>(_builder.GetSavedAlbums(limit, offset, market));
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Get a list of the albums saved in the current Spotify users “Your Music” library asynchronously.
/// </summary>
/// <param name="limit">The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<SavedAlbum>> GetSavedAlbumsAsync(int limit = 20, int offset = 0, string market = "")
2015-12-07 13:08:23 +00:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetSavedAlbumsAsync");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<SavedAlbum>>(_builder.GetSavedAlbums(limit, offset, market));
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Remove one or more albums from the current users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse RemoveSavedAlbums(List<string> ids)
2015-12-07 13:08:23 +00:00
{
JArray array = new JArray(ids);
return UploadData<ErrorResponse>(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE") ?? new ErrorResponse();
}
/// <summary>
/// Remove one or more albums from the current users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> RemoveSavedAlbumsAsync(List<string> ids)
2015-12-07 13:08:23 +00:00
{
JArray array = new JArray(ids);
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.RemoveSavedAlbums(), array.ToString(Formatting.None), "DELETE").ConfigureAwait(false)) ?? new ErrorResponse();
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Check if one or more albums is already saved in the current Spotify users “Your Music” library.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-07-07 20:23:36 +01:00
public ListResponse<bool> CheckSavedAlbums(List<string> ids)
2015-12-07 13:08:23 +00:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedTracks");
var url = _builder.CheckSavedAlbums(ids);
2016-08-23 18:13:11 +01:00
return DownloadList<bool>(url);
2015-12-07 13:08:23 +00:00
}
/// <summary>
/// Check if one or more albums is already saved in the current Spotify users “Your Music” library asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ListResponse<bool>> CheckSavedAlbumsAsync(List<string> ids)
2015-12-07 13:08:23 +00:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for CheckSavedAlbumsAsync");
var url = _builder.CheckSavedAlbums(ids);
2016-09-08 07:30:33 +01:00
return DownloadListAsync<bool>(url);
2015-12-07 13:08:23 +00:00
}
#endregion Library
2016-04-01 13:08:06 +01:00
#region Personalization
/// <summary>
/// Get the current users top tracks based on calculated affinity.
/// </summary>
/// <param name="timeRange">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). </param>
/// <param name="limit">The number of entities to return. Default: 20. Minimum: 1. Maximum: 50</param>
/// <param name="offest">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Paging<FullTrack> GetUsersTopTracks(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0)
{
return DownloadData<Paging<FullTrack>>(_builder.GetUsersTopTracks(timeRange, limit, offest));
}
/// <summary>
/// Get the current users top tracks based on calculated affinity asynchronously.
/// </summary>
/// <param name="timeRange">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). </param>
/// <param name="limit">The number of entities to return. Default: 20. Minimum: 1. Maximum: 50</param>
/// <param name="offest">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<FullTrack>> GetUsersTopTracksAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0)
2016-04-01 13:08:06 +01:00
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<FullTrack>>(_builder.GetUsersTopTracks(timeRange, limit, offest));
2016-04-01 13:08:06 +01:00
}
/// <summary>
/// Get the current users top artists based on calculated affinity.
/// </summary>
/// <param name="timeRange">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). </param>
/// <param name="limit">The number of entities to return. Default: 20. Minimum: 1. Maximum: 50</param>
/// <param name="offest">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Paging<FullArtist> GetUsersTopArtists(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0)
{
return DownloadData<Paging<FullArtist>>(_builder.GetUsersTopArtists(timeRange, limit, offest));
}
/// <summary>
/// Get the current users top artists based on calculated affinity asynchronously.
/// </summary>
/// <param name="timeRange">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). </param>
/// <param name="limit">The number of entities to return. Default: 20. Minimum: 1. Maximum: 50</param>
/// <param name="offest">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.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<FullArtist>> GetUsersTopArtistsAsync(TimeRangeType timeRange = TimeRangeType.MediumTerm, int limit = 20, int offest = 0)
2016-04-01 13:08:06 +01:00
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<FullArtist>>(_builder.GetUsersTopArtists(timeRange, limit, offest));
2016-04-01 13:08:06 +01:00
}
2017-03-02 21:28:55 +00:00
/// <summary>
/// Get tracks from the current users recent play history.
/// </summary>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="after">A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified.</param>
/// <param name="before">A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public CursorPaging<PlayHistory> GetUsersRecentlyPlayedTracks(int limit = 20, DateTime? after = null,
DateTime? before = null)
{
return DownloadData<CursorPaging<PlayHistory>>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before));
}
/// <summary>
/// Get tracks from the current users recent play history asynchronously
/// </summary>
/// <param name="limit">The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="after">A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position. If after is specified, before must not be specified.</param>
/// <param name="before">A Unix timestamp in milliseconds. Returns all items before (but not including) this cursor position. If before is specified, after must not be specified.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Task<CursorPaging<PlayHistory>> GetUsersRecentlyPlayedTracksAsync(int limit = 20, DateTime? after = null,
DateTime? before = null)
{
return DownloadDataAsync<CursorPaging<PlayHistory>>(_builder.GetUsersRecentlyPlayedTracks(limit, after, before));
}
2016-04-01 13:08:06 +01:00
#endregion
2015-07-15 16:35:32 +01:00
#region Playlists
/// <summary>
/// Get a list of the playlists owned or followed by a Spotify user.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="limit">The maximum number of playlists to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="offset">The index of the first playlist to return. Default: 0 (the first object)</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public Paging<SimplePlaylist> GetUserPlaylists(string userId, int limit = 20, int offset = 0)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetUserPlaylists");
return DownloadData<Paging<SimplePlaylist>>(_builder.GetUserPlaylists(userId, limit, offset));
}
/// <summary>
/// Get a list of the playlists owned or followed by a Spotify user asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="limit">The maximum number of playlists to return. Default: 20. Minimum: 1. Maximum: 50. </param>
/// <param name="offset">The index of the first playlist to return. Default: 0 (the first object)</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<SimplePlaylist>> GetUserPlaylistsAsync(string userId, int limit = 20, int offset = 0)
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetUserPlaylists");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<SimplePlaylist>>(_builder.GetUserPlaylists(userId, limit, offset));
}
/// <summary>
/// Get a playlist owned by a Spotify user.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="fields">
/// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are
/// returned.
/// </param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public FullPlaylist GetPlaylist(string userId, string playlistId, string fields = "", string market = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetPlaylist");
return DownloadData<FullPlaylist>(_builder.GetPlaylist(userId, playlistId, fields, market));
}
/// <summary>
/// Get a playlist owned by a Spotify user asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="fields">
/// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are
/// returned.
/// </param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<FullPlaylist> GetPlaylistAsync(string userId, string playlistId, string fields = "", string market = "")
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetPlaylist");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FullPlaylist>(_builder.GetPlaylist(userId, playlistId, fields, market));
}
/// <summary>
/// Get full details of the tracks of a playlist owned by a Spotify user.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="fields">
/// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are
/// returned.
/// </param>
/// <param name="limit">The maximum number of tracks to return. Default: 100. Minimum: 1. Maximum: 100.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public Paging<PlaylistTrack> 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<Paging<PlaylistTrack>>(_builder.GetPlaylistTracks(userId, playlistId, fields, limit, offset, market));
}
/// <summary>
/// Get full details of the tracks of a playlist owned by a Spotify user asyncronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="fields">
/// Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are
/// returned.
/// </param>
/// <param name="limit">The maximum number of tracks to return. Default: 100. Minimum: 1. Maximum: 100.</param>
/// <param name="offset">The index of the first object to return. Default: 0 (i.e., the first object)</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Paging<PlaylistTrack>> 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");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<Paging<PlaylistTrack>>(_builder.GetPlaylistTracks(userId, playlistId, fields, limit, offset, market));
}
/// <summary>
/// Create a playlist for a Spotify user. (The playlist will be empty until you add tracks.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistName">
/// The name for the new playlist, for example "Your Coolest Playlist". This name does not need
/// to be unique.
/// </param>
/// <param name="isPublic">
/// 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.
/// </param>
/// <param name="isCollaborative">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.</param>
/// <param name="playlistDescription">Value for playlist description as displayed in Spotify Clients and in the Web API.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
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<FullPlaylist>(_builder.CreatePlaylist(userId, playlistName, isPublic), body.ToString(Formatting.None));
}
/// <summary>
/// Create a playlist for a Spotify user asynchronously. (The playlist will be empty until you add tracks.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistName">
/// The name for the new playlist, for example "Your Coolest Playlist". This name does not need
/// to be unique.
/// </param>
/// <param name="isPublic">
/// 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.
/// </param>
/// <param name="isCollaborative">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.</param>
/// <param name="playlistDescription">Value for playlist description as displayed in Spotify Clients and in the Web API.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Task<FullPlaylist> 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}
};
2016-09-08 07:30:33 +01:00
return UploadDataAsync<FullPlaylist>(_builder.CreatePlaylist(userId, playlistName, isPublic), body.ToString(Formatting.None));
}
/// <summary>
/// Change a playlists name and public/private state. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="newName">The new name for the playlist, for example "My New Playlist Title".</param>
/// <param name="newPublic">If true the playlist will be public, if false it will be private.</param>
/// <param name="newCollaborative">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.</param>
/// <param name="newDescription">Value for playlist description as displayed in Spotify Clients and in the Web API.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
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);
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.UpdatePlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Change a playlists name and public/private state asynchronously. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="newName">The new name for the playlist, for example "My New Playlist Title".</param>
/// <param name="newPublic">If true the playlist will be public, if false it will be private.</param>
/// <param name="newCollaborative">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.</param>
/// <param name="newDescription">Value for playlist description as displayed in Spotify Clients and in the Web API.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public async Task<ErrorResponse> 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);
2016-09-08 07:30:33 +01:00
return (await UploadDataAsync<ErrorResponse>(_builder.UpdatePlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Change a playlists name and public/private state. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="base64EncodedJpgImage">The image as a base64 encoded string</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public ErrorResponse UploadPlaylistImage(string userId, string playlistId, string base64EncodedJpgImage)
{
return UploadData<ErrorResponse>(_builder.UploadPlaylistImage(userId, playlistId), base64EncodedJpgImage, "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Change a playlists name and public/private state asynchronously. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="base64EncodedJpgImage">The image as a base64 encoded string</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public async Task<ErrorResponse> UploadPlaylistImageAsync(string userId, string playlistId, string base64EncodedJpgImage)
{
return (await UploadDataAsync<ErrorResponse>(_builder.UploadPlaylistImage(userId, playlistId), base64EncodedJpgImage, "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Change a playlists name and public/private state. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="base64EncodedJpgImage">The image as a base64 encoded string</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public ErrorResponse UploadPlaylistImage(string playlistId, string base64EncodedJpgImage)
{
return UploadData<ErrorResponse>(_builder.UploadPlaylistImage(playlistId), base64EncodedJpgImage, "PUT") ?? new ErrorResponse();
}
/// <summary>
/// Change a playlists name and public/private state asynchronously. (The user must, of course, own the playlist.)
/// </summary>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="base64EncodedJpgImage">The image as a base64 encoded string</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public async Task<ErrorResponse> UploadPlaylistImageAsync(string playlistId, string base64EncodedJpgImage)
{
return (await UploadDataAsync<ErrorResponse>(_builder.UploadPlaylistImage(playlistId), base64EncodedJpgImage, "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// 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.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">A list of Spotify track URIs to set. A maximum of 100 tracks can be set in one request.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse ReplacePlaylistTracks(string userId, string playlistId, List<string> uris)
{
JObject body = new JObject
{
{"uris", new JArray(uris.Take(100))}
};
2015-11-06 19:57:03 +00:00
return UploadData<ErrorResponse>(_builder.ReplacePlaylistTracks(userId, playlistId), body.ToString(Formatting.None), "PUT") ?? new ErrorResponse();
}
/// <summary>
/// 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.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">A list of Spotify track URIs to set. A maximum of 100 tracks can be set in one request.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> ReplacePlaylistTracksAsync(string userId, string playlistId, List<string> uris)
{
JObject body = new JObject
{
{"uris", new JArray(uris.Take(100))}
};
2016-09-08 07:30:33 +01:00
return await (UploadDataAsync<ErrorResponse>(_builder.ReplacePlaylistTracks(userId, playlistId), body.ToString(Formatting.None), "PUT").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Remove one or more tracks from a users playlist.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">
/// array of objects containing Spotify URI strings (and their position in the playlist). A maximum of
/// 100 objects can be sent at once.
/// </param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse RemovePlaylistTracks(string userId, string playlistId, List<DeleteTrackUri> uris)
{
JObject body = new JObject
{
{"tracks", JArray.FromObject(uris.Take(100))}
};
return UploadData<ErrorResponse>(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE") ?? new ErrorResponse();
}
/// <summary>
/// Remove one or more tracks from a users playlist asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">
/// array of objects containing Spotify URI strings (and their position in the playlist). A maximum of
/// 100 objects can be sent at once.
/// </param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> RemovePlaylistTracksAsync(string userId, string playlistId, List<DeleteTrackUri> uris)
{
JObject body = new JObject
{
{"tracks", JArray.FromObject(uris.Take(100))}
};
2016-09-08 07:30:33 +01:00
return await (UploadDataAsync<ErrorResponse>(_builder.RemovePlaylistTracks(userId, playlistId, uris), body.ToString(Formatting.None), "DELETE").ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Remove a track from a users playlist.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uri">Spotify URI</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse RemovePlaylistTrack(string userId, string playlistId, DeleteTrackUri uri)
{
return RemovePlaylistTracks(userId, playlistId, new List<DeleteTrackUri> { uri });
}
/// <summary>
/// Remove a track from a users playlist asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uri">Spotify URI</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> RemovePlaylistTrackAsync(string userId, string playlistId, DeleteTrackUri uri)
{
2016-09-08 07:30:33 +01:00
return RemovePlaylistTracksAsync(userId, playlistId, new List<DeleteTrackUri> { uri });
}
/// <summary>
/// Add one or more tracks to a users playlist.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">A list of Spotify track URIs to add</param>
/// <param name="position">The position to insert the tracks, a zero-based index</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse AddPlaylistTracks(string userId, string playlistId, List<string> uris, int? position = null)
{
JObject body = new JObject
{
{"uris", JArray.FromObject(uris.Take(100))}
};
return UploadData<ErrorResponse>(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)) ?? new ErrorResponse();
}
/// <summary>
/// Add one or more tracks to a users playlist asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uris">A list of Spotify track URIs to add</param>
/// <param name="position">The position to insert the tracks, a zero-based index</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public async Task<ErrorResponse> AddPlaylistTracksAsync(string userId, string playlistId, List<string> uris, int? position = null)
{
JObject body = new JObject
{
{"uris", JArray.FromObject(uris.Take(100))}
};
2016-09-08 07:30:33 +01:00
return await (UploadDataAsync<ErrorResponse>(_builder.AddPlaylistTracks(userId, playlistId, uris, position), body.ToString(Formatting.None)).ConfigureAwait(false)) ?? new ErrorResponse();
}
/// <summary>
/// Add a track to a users playlist.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uri">A Spotify Track URI</param>
/// <param name="position">The position to insert the tracks, a zero-based index</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
public ErrorResponse AddPlaylistTrack(string userId, string playlistId, string uri, int? position = null)
{
return AddPlaylistTracks(userId, playlistId, new List<string> { uri }, position);
}
/// <summary>
/// Add a track to a users playlist asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="uri">A Spotify Track URI</param>
/// <param name="position">The position to insert the tracks, a zero-based index</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<ErrorResponse> AddPlaylistTrackAsync(string userId, string playlistId, string uri, int? position = null)
{
2016-09-08 07:30:33 +01:00
return AddPlaylistTracksAsync(userId, playlistId, new List<string> { uri }, position);
}
/// <summary>
/// Reorder a track or a group of tracks in a playlist.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="rangeStart">The position of the first track to be reordered.</param>
/// <param name="insertBefore">The position where the tracks should be inserted. </param>
/// <param name="rangeLength">The amount of tracks to be reordered. Defaults to 1 if not set.</param>
/// <param name="snapshotId">The playlist's snapshot ID against which you want to make the changes.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-03-31 11:08:23 +01:00
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}
};
2016-03-31 11:08:23 +01:00
if (!string.IsNullOrEmpty(snapshotId))
body.Add("snapshot_id", snapshotId);
2015-11-06 19:57:03 +00:00
return UploadData<Snapshot>(_builder.ReorderPlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT");
}
/// <summary>
/// Reorder a track or a group of tracks in a playlist asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <param name="playlistId">The Spotify ID for the playlist.</param>
/// <param name="rangeStart">The position of the first track to be reordered.</param>
/// <param name="insertBefore">The position where the tracks should be inserted. </param>
/// <param name="rangeLength">The amount of tracks to be reordered. Defaults to 1 if not set.</param>
/// <param name="snapshotId">The playlist's snapshot ID against which you want to make the changes.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<Snapshot> ReorderPlaylistAsync(string userId, string playlistId, int rangeStart, int insertBefore, int rangeLength = 1, string snapshotId = "")
{
JObject body = new JObject
{
{"range_start", rangeStart},
{"range_length", rangeLength},
2015-11-06 19:57:03 +00:00
{"insert_before", insertBefore},
{"snapshot_id", snapshotId}
};
2016-03-31 11:08:23 +01:00
if (!string.IsNullOrEmpty(snapshotId))
2015-11-06 19:57:03 +00:00
body.Add("snapshot_id", snapshotId);
2016-09-08 07:30:33 +01:00
return UploadDataAsync<Snapshot>(_builder.ReorderPlaylist(userId, playlistId), body.ToString(Formatting.None), "PUT");
}
#endregion Playlists
2015-07-15 16:35:32 +01:00
#region Profiles
/// <summary>
2015-07-15 16:35:32 +01:00
/// Get detailed profile information about the current user (including the current users username).
/// </summary>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2015-07-15 16:35:32 +01:00
public PrivateProfile GetPrivateProfile()
{
if (!UseAuth)
2015-07-15 16:35:32 +01:00
throw new InvalidOperationException("Auth is required for GetPrivateProfile");
return DownloadData<PrivateProfile>(_builder.GetPrivateProfile());
}
/// <summary>
/// Get detailed profile information about the current user asynchronously (including the current users username).
/// </summary>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<PrivateProfile> GetPrivateProfileAsync()
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for GetPrivateProfile");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<PrivateProfile>(_builder.GetPrivateProfile());
}
/// <summary>
2015-07-15 16:35:32 +01:00
/// Get public profile information about a Spotify user.
/// </summary>
2015-07-15 16:35:32 +01:00
/// <param name="userId">The user's Spotify user ID.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public PublicProfile GetPublicProfile(string userId)
{
return DownloadData<PublicProfile>(_builder.GetPublicProfile(userId));
}
/// <summary>
/// Get public profile information about a Spotify user asynchronously.
/// </summary>
/// <param name="userId">The user's Spotify user ID.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<PublicProfile> GetPublicProfileAsync(string userId)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<PublicProfile>(_builder.GetPublicProfile(userId));
}
#endregion Profiles
2015-07-15 16:35:32 +01:00
#region Tracks
/// <summary>
/// Get Spotify catalog information for multiple tracks based on their Spotify IDs.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the tracks. Maximum: 50 IDs.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public SeveralTracks GetSeveralTracks(List<string> ids, string market = "")
{
return DownloadData<SeveralTracks>(_builder.GetSeveralTracks(ids, market));
}
/// <summary>
/// Get Spotify catalog information for multiple tracks based on their Spotify IDs asynchronously.
/// </summary>
/// <param name="ids">A list of the Spotify IDs for the tracks. Maximum: 50 IDs.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<SeveralTracks> GetSeveralTracksAsync(List<string> ids, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralTracks>(_builder.GetSeveralTracks(ids, market));
}
/// <summary>
/// Get Spotify catalog information for a single track identified by its unique Spotify ID.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-03-31 11:08:23 +01:00
public FullTrack GetTrack(string id, string market = "")
{
return DownloadData<FullTrack>(_builder.GetTrack(id, market));
}
/// <summary>
/// Get Spotify catalog information for a single track identified by its unique Spotify ID asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
2016-09-08 07:30:33 +01:00
public Task<FullTrack> GetTrackAsync(string id, string market = "")
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<FullTrack>(_builder.GetTrack(id, market));
}
/// <summary>
/// Get a detailed audio analysis for a single track identified by its unique Spotify ID.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public AudioAnalysis GetAudioAnalysis(string id)
{
return DownloadData<AudioAnalysis>(_builder.GetAudioAnalysis(id));
}
/// <summary>
/// Get a detailed audio analysis for a single track identified by its unique Spotify ID asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public Task<AudioAnalysis> GetAudioAnalysisAsync(string id)
{
return DownloadDataAsync<AudioAnalysis>(_builder.GetAudioAnalysis(id));
}
/// <summary>
/// Get audio feature information for a single track identified by its unique Spotify ID.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public AudioFeatures GetAudioFeatures(string id)
{
return DownloadData<AudioFeatures>(_builder.GetAudioFeatures(id));
}
/// <summary>
/// Get audio feature information for a single track identified by its unique Spotify ID asynchronously.
/// </summary>
/// <param name="id">The Spotify ID for the track.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<AudioFeatures> GetAudioFeaturesAsync(string id)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<AudioFeatures>(_builder.GetAudioFeatures(id));
}
/// <summary>
/// Get audio features for multiple tracks based on their Spotify IDs.
/// </summary>
/// <param name="ids">A list of Spotify Track-IDs. Maximum: 100 IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
public SeveralAudioFeatures GetSeveralAudioFeatures(List<string> ids)
{
return DownloadData<SeveralAudioFeatures>(_builder.GetSeveralAudioFeatures(ids));
}
/// <summary>
/// Get audio features for multiple tracks based on their Spotify IDs asynchronously.
/// </summary>
/// <param name="ids">A list of Spotify Track-IDs. Maximum: 100 IDs.</param>
/// <returns></returns>
/// <remarks>AUTH NEEDED</remarks>
2016-09-08 07:30:33 +01:00
public Task<SeveralAudioFeatures> GetSeveralAudioFeaturesAsync(List<string> ids)
{
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<SeveralAudioFeatures>(_builder.GetSeveralAudioFeatures(ids));
}
#endregion Tracks
2017-05-29 22:17:15 +01:00
#region Player
/// <summary>
/// Get information about a users available devices.
/// </summary>
/// <returns></returns>
public AvailabeDevices GetDevices()
{
return DownloadData<AvailabeDevices>(_builder.GetDevices());
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Get information about a users available devices.
/// </summary>
/// <returns></returns>
public Task<AvailabeDevices> GetDevicesAsync()
{
return DownloadDataAsync<AvailabeDevices>(_builder.GetDevices());
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Get information about the users current playback state, including track, track progress, and active device.
/// </summary>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
public PlaybackContext GetPlayback(string market = "")
{
return DownloadData<PlaybackContext>(_builder.GetPlayback(market));
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Get information about the users current playback state, including track, track progress, and active device.
/// </summary>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
public Task<PlaybackContext> GetPlaybackAsync(string market = "")
{
return DownloadDataAsync<PlaybackContext>(_builder.GetPlayback(market));
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Get the object currently being played on the users Spotify account.
/// </summary>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
public PlaybackContext GetPlayingTrack(string market = "")
{
return DownloadData<PlaybackContext>(_builder.GetPlayingTrack(market));
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Get the object currently being played on the users Spotify account.
/// </summary>
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
/// <returns></returns>
public Task<PlaybackContext> GetPlayingTrackAsync(string market = "")
{
return DownloadDataAsync<PlaybackContext>(_builder.GetPlayingTrack(market));
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Transfer playback to a new device and determine if it should start playing.
/// </summary>
/// <param name="deviceId">ID of the device on which playback should be started/transferred to</param>
/// <param name="play">
/// true: ensure playback happens on new device.
/// false or not provided: keep the current playback state.
/// </param>
/// <returns></returns>
public ErrorResponse TransferPlayback(string deviceId, bool play = false) => TransferPlayback(
new List<string> { deviceId }, play);
2018-07-26 23:29:10 +01:00
/// <summary>
/// Transfer playback to a new device and determine if it should start playing.
/// </summary>
/// <param name="deviceId">ID of the device on which playback should be started/transferred to</param>
/// <param name="play">
/// true: ensure playback happens on new device.
/// false or not provided: keep the current playback state.
/// </param>
/// <returns></returns>
public Task<ErrorResponse> TransferPlaybackAsync(string deviceId, bool play = false) => TransferPlaybackAsync(
new List<string> { deviceId }, play);
2017-05-29 22:17:15 +01:00
/// <summary>
/// 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
/// </summary>
/// <param name="deviceIds">A array containing the ID of the device on which playback should be started/transferred.</param>
/// <param name="play">
/// true: ensure playback happens on new device.
/// false or not provided: keep the current playback state.
/// </param>
/// <returns></returns>
public ErrorResponse TransferPlayback(List<string> deviceIds, bool play = false)
{
JObject ob = new JObject()
{
{ "play", play },
{ "device_ids", new JArray(deviceIds) }
};
return UploadData<ErrorResponse>(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT");
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// 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
/// </summary>
/// <param name="deviceIds">A array containing the ID of the device on which playback should be started/transferred.</param>
/// <param name="play">
/// true: ensure playback happens on new device.
/// false or not provided: keep the current playback state.
/// </param>
/// <returns></returns>
public Task<ErrorResponse> TransferPlaybackAsync(List<string> deviceIds, bool play = false)
{
JObject ob = new JObject()
{
{ "play", play },
{ "device_ids", new JArray(deviceIds) }
};
return UploadDataAsync<ErrorResponse>(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Start a new context or resume current playback on the users active device.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <param name="contextUri">Spotify URI of the context to play.</param>
/// <param name="uris">A JSON array of the Spotify track URIs to play.</param>
/// <param name="offset">Indicates from where in the context playback should start.
/// <param name="positionMs">The starting time to seek the track to</param>
2017-05-29 22:17:15 +01:00
/// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used.</param>
/// <returns></returns>
public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List<string> uris = null,
int? offset = null, int positionMs = 0)
2017-05-29 22:17:15 +01:00
{
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<ErrorResponse>(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT");
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Start a new context or resume current playback on the users active device.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <param name="contextUri">Spotify URI of the context to play.</param>
/// <param name="uris">A JSON array of the Spotify track URIs to play.</param>
/// <param name="offset">Indicates from where in the context playback should start.
/// <param name="positionMs">The starting time to seek the track to</param>
2018-07-26 23:29:10 +01:00
/// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used.</param>
/// <returns></returns>
public Task<ErrorResponse> ResumePlaybackAsync(string deviceId = "", string contextUri = "", List<string> uris = null,
int? offset = null, int positionMs = 0)
2018-07-26 23:29:10 +01:00
{
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);
2018-07-26 23:29:10 +01:00
return UploadDataAsync<ErrorResponse>(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT");
}
/// <summary>
/// Start a new context or resume current playback on the users active device.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <param name="contextUri">Spotify URI of the context to play.</param>
/// <param name="uris">A JSON array of the Spotify track URIs to play.</param>
/// <param name="offset">Indicates from where in the context playback should start.
/// <param name="positionMs">The starting time to seek the track to</param>
/// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used.</param>
/// <returns></returns>
public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List<string> 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);
2017-05-29 22:17:15 +01:00
return UploadData<ErrorResponse>(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT");
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Start a new context or resume current playback on the users active device.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <param name="contextUri">Spotify URI of the context to play.</param>
/// <param name="uris">A JSON array of the Spotify track URIs to play.</param>
/// <param name="offset">Indicates from where in the context playback should start.
/// <param name="positionMs">The starting time to seek the track to</param>
2018-07-26 23:29:10 +01:00
/// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used.</param>
/// <returns></returns>
public Task<ErrorResponse> ResumePlaybackAsync(string deviceId = "", string contextUri = "", List<string> uris = null,
string offset = "", int positionMs = 0)
2018-07-26 23:29:10 +01:00
{
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);
2018-07-26 23:29:10 +01:00
return UploadDataAsync<ErrorResponse>(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Pause playback on the users account.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse PausePlayback(string deviceId = "")
{
return UploadData<ErrorResponse>(_builder.PausePlayback(deviceId), string.Empty, "PUT");
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Pause playback on the users account.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> PausePlaybackAsync(string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.PausePlayback(deviceId), string.Empty, "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Skips to next track in the users queue.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SkipPlaybackToNext(string deviceId = "")
{
return UploadData<ErrorResponse>(_builder.SkipPlaybackToNext(deviceId), string.Empty);
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Skips to next track in the users queue.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SkipPlaybackToNextAsync(string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SkipPlaybackToNext(deviceId), string.Empty);
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Skips to previous track in the users queue.
/// Note that this will ALWAYS skip to the previous track, regardless of the current tracks progress.
/// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SkipPlaybackToPrevious(string deviceId = "")
{
return UploadData<ErrorResponse>(_builder.SkipPlaybackToPrevious(deviceId), string.Empty);
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Skips to previous track in the users queue.
/// Note that this will ALWAYS skip to the previous track, regardless of the current tracks progress.
/// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint.
/// </summary>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SkipPlaybackToPreviousAsync(string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SkipPlaybackToPrevious(deviceId), string.Empty);
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Seeks to the given position in the users currently playing track.
/// </summary>
/// <param name="positionMs">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.</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SeekPlayback(int positionMs, string deviceId = "")
{
2017-10-27 16:23:45 +01:00
return UploadData<ErrorResponse>(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT");
2017-05-29 22:17:15 +01:00
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Seeks to the given position in the users currently playing track.
/// </summary>
/// <param name="positionMs">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.</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SeekPlaybackAsync(int positionMs, string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SeekPlayback(positionMs, deviceId), string.Empty, "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Set the repeat mode for the users playback. Options are repeat-track, repeat-context, and off.
/// </summary>
/// <param name="state">track, context or off. </param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SetRepeatMode(RepeatState state, string deviceId = "")
{
2017-07-16 21:28:56 +01:00
return UploadData<ErrorResponse>(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT");
2017-05-29 22:17:15 +01:00
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Set the repeat mode for the users playback. Options are repeat-track, repeat-context, and off.
/// </summary>
/// <param name="state">track, context or off. </param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SetRepeatModeAsync(RepeatState state, string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SetRepeatMode(state, deviceId), string.Empty, "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Set the volume for the users current playback device.
/// </summary>
/// <param name="volumePercent">Integer. The volume to set. Must be a value from 0 to 100 inclusive.</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SetVolume(int volumePercent, string deviceId = "")
{
2017-07-16 21:28:56 +01:00
return UploadData<ErrorResponse>(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT");
2017-05-29 22:17:15 +01:00
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Set the volume for the users current playback device.
/// </summary>
/// <param name="volumePercent">Integer. The volume to set. Must be a value from 0 to 100 inclusive.</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SetVolumeAsync(int volumePercent, string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SetVolume(volumePercent, deviceId), string.Empty, "PUT");
}
2017-05-29 22:17:15 +01:00
/// <summary>
/// Toggle shuffle on or off for users playback.
/// </summary>
/// <param name="shuffle">True or False</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public ErrorResponse SetShuffle(bool shuffle, string deviceId = "")
{
2017-07-16 21:28:56 +01:00
return UploadData<ErrorResponse>(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT");
2017-05-29 22:17:15 +01:00
}
2018-07-26 23:29:10 +01:00
/// <summary>
/// Toggle shuffle on or off for users playback.
/// </summary>
/// <param name="shuffle">True or False</param>
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
/// <returns></returns>
public Task<ErrorResponse> SetShuffleAsync(bool shuffle, string deviceId = "")
{
return UploadDataAsync<ErrorResponse>(_builder.SetShuffle(shuffle, deviceId), string.Empty, "PUT");
}
2017-05-29 22:17:15 +01:00
#endregion
#region Util
2016-07-07 20:23:36 +01:00
public TOut GetNextPage<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
2015-11-06 19:57:03 +00:00
{
if (!paging.HasNextPage())
throw new InvalidOperationException("This Paging-Object has no Next-Page");
return DownloadData<TOut>(paging.Next);
2015-11-06 19:57:03 +00:00
}
public Paging<T> GetNextPage<T>(Paging<T> paging)
{
return GetNextPage<Paging<T>, T>(paging);
}
2016-09-08 07:30:33 +01:00
public Task<TOut> GetNextPageAsync<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
2015-11-06 19:57:03 +00:00
{
if (!paging.HasNextPage())
throw new InvalidOperationException("This Paging-Object has no Next-Page");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<TOut>(paging.Next);
}
2016-09-08 07:30:33 +01:00
public Task<Paging<T>> GetNextPageAsync<T>(Paging<T> paging)
{
2016-09-08 07:30:33 +01:00
return GetNextPageAsync<Paging<T>, T>(paging);
}
2016-07-07 20:23:36 +01:00
public TOut GetPreviousPage<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{
if (!paging.HasPreviousPage())
throw new InvalidOperationException("This Paging-Object has no Previous-Page");
return DownloadData<TOut>(paging.Previous);
2015-11-06 19:57:03 +00:00
}
public Paging<T> GetPreviousPage<T>(Paging<T> paging)
{
return GetPreviousPage<Paging<T>, T>(paging);
}
2016-09-08 07:30:33 +01:00
public Task<TOut> GetPreviousPageAsync<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel
{
if (!paging.HasPreviousPage())
throw new InvalidOperationException("This Paging-Object has no Previous-Page");
2016-09-08 07:30:33 +01:00
return DownloadDataAsync<TOut>(paging.Previous);
}
2016-09-08 07:30:33 +01:00
public Task<Paging<T>> GetPreviousPageAsync<T>(Paging<T> paging)
{
2016-09-08 07:30:33 +01:00
return GetPreviousPageAsync<Paging<T>, T>(paging);
}
2016-08-23 18:13:11 +01:00
private ListResponse<T> DownloadList<T>(string url)
{
int triesLeft = RetryTimes + 1;
2016-08-24 12:17:46 +01:00
Error lastError;
2016-08-23 18:13:11 +01:00
ListResponse<T> data = null;
do
{
2016-08-24 12:17:46 +01:00
if (data != null) { Thread.Sleep(RetryAfter); }
Tuple<ResponseInfo, JToken> res = DownloadDataAlt<JToken>(url);
2016-08-23 18:13:11 +01:00
data = ExtractDataToListResponse<T>(res);
lastError = data.Error;
triesLeft -= 1;
} while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status));
return data;
}
2016-08-23 18:13:11 +01:00
private async Task<ListResponse<T>> DownloadListAsync<T>(string url)
{
int triesLeft = RetryTimes + 1;
2016-08-24 12:17:46 +01:00
Error lastError;
2016-08-23 18:13:11 +01:00
ListResponse<T> data = null;
do
{
2016-09-08 07:30:33 +01:00
if (data != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); }
Tuple<ResponseInfo, JToken> res = await DownloadDataAltAsync<JToken>(url).ConfigureAwait(false);
2016-08-23 18:13:11 +01:00
data = ExtractDataToListResponse<T>(res);
lastError = data.Error;
triesLeft -= 1;
} while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status));
return data;
}
2016-08-23 18:13:11 +01:00
private static ListResponse<T> ExtractDataToListResponse<T>(Tuple<ResponseInfo, JToken> res)
2016-08-14 02:49:39 +01:00
{
2016-08-24 12:17:46 +01:00
ListResponse<T> ret;
2016-08-14 02:49:39 +01:00
if (res.Item2 is JArray)
2016-08-23 18:13:11 +01:00
{
ret = new ListResponse<T>
2016-08-14 02:49:39 +01:00
{
2016-08-23 18:13:11 +01:00
List = res.Item2.ToObject<List<T>>(),
2016-08-14 02:49:39 +01:00
Error = null
};
2016-08-23 18:13:11 +01:00
}
2016-08-14 02:49:39 +01:00
else
2016-08-23 18:13:11 +01:00
{
ret = new ListResponse<T>
2016-08-14 02:49:39 +01:00
{
List = null,
Error = res.Item2["error"].ToObject<Error>()
};
2016-08-23 18:13:11 +01:00
}
2016-08-14 02:49:39 +01:00
ret.AddResponseInfo(res.Item1);
return ret;
}
2016-07-07 20:23:36 +01:00
public T UploadData<T>(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;
2016-08-24 12:17:46 +01:00
Error lastError;
Tuple<ResponseInfo, T> response = null;
do
{
2017-05-31 16:25:56 +01:00
Dictionary<string, string> headers = new Dictionary<string, string>
{
{ "Authorization", TokenType + " " + AccessToken},
{ "Content-Type", "application/json" }
};
2016-08-24 12:17:46 +01:00
if (response != null) { Thread.Sleep(RetryAfter); }
2017-05-31 16:25:56 +01:00
response = WebClient.UploadJson<T>(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));
2016-07-07 20:23:36 +01:00
return response.Item2;
}
2016-07-07 20:23:36 +01:00
public async Task<T> UploadDataAsync<T>(string url, string uploadData, string method = "POST") where T : BasicModel
2015-11-05 20:20:22 +00:00
{
if (!UseAuth)
throw new InvalidOperationException("Auth is required for all Upload-Actions");
2016-07-07 20:23:36 +01:00
int triesLeft = RetryTimes + 1;
2016-08-24 12:17:46 +01:00
Error lastError;
Tuple<ResponseInfo, T> response = null;
do
{
2017-05-31 16:25:56 +01:00
Dictionary<string, string> headers = new Dictionary<string, string>
{
{ "Authorization", TokenType + " " + AccessToken},
{ "Content-Type", "application/json" }
};
2016-09-08 07:30:33 +01:00
if (response != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); }
2017-05-31 16:25:56 +01:00
response = await WebClient.UploadJsonAsync<T>(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));
2016-07-07 20:23:36 +01:00
return response.Item2;
}
public T DownloadData<T>(string url) where T : BasicModel
{
int triesLeft = RetryTimes + 1;
2016-08-24 12:17:46 +01:00
Error lastError;
Tuple<ResponseInfo, T> response = null;
do
{
2016-08-24 12:17:46 +01:00
if(response != null) { Thread.Sleep(RetryAfter); }
response = DownloadDataAlt<T>(url);
response.Item2.AddResponseInfo(response.Item1);
lastError = response.Item2.Error;
triesLeft -= 1;
} while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status));
2016-07-07 20:23:36 +01:00
return response.Item2;
}
/// <summary>
/// Retrieves whether request had a "TooManyRequests" error, and get the amount Spotify recommends waiting before another request.
/// </summary>
/// <param name="info">Info object to analyze.</param>
/// <returns>Seconds to wait before making another request. -1 if no error.</returns>
/// <remarks>AUTH NEEDED</remarks>
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 var secondsToWait))
{
return -1;
}
return secondsToWait;
}
2016-07-07 20:23:36 +01:00
public async Task<T> DownloadDataAsync<T>(string url) where T : BasicModel
{
int triesLeft = RetryTimes + 1;
2016-08-24 12:17:46 +01:00
Error lastError;
Tuple<ResponseInfo, T> response = null;
do
{
if (response != null)
{
int msToWait = RetryAfter;
var secondsToWait = GetTooManyRequests(response.Item1);
if (secondsToWait > 0)
{
msToWait = secondsToWait * 1000;
}
await Task.Delay(msToWait).ConfigureAwait(false);
}
2016-09-08 07:30:33 +01:00
response = await DownloadDataAltAsync<T>(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))));
2016-07-07 20:23:36 +01:00
return response.Item2;
2015-11-05 20:20:22 +00:00
}
2016-07-07 20:23:36 +01:00
private Tuple<ResponseInfo, T> DownloadDataAlt<T>(string url)
{
2017-05-31 16:25:56 +01:00
Dictionary<string, string> headers = new Dictionary<string, string>();
if (UseAuth)
2017-05-31 16:25:56 +01:00
headers.Add("Authorization", TokenType + " " + AccessToken);
return WebClient.DownloadJson<T>(url, headers);
}
2016-07-07 20:23:36 +01:00
private Task<Tuple<ResponseInfo, T>> DownloadDataAltAsync<T>(string url)
2015-11-05 20:20:22 +00:00
{
2017-05-31 16:25:56 +01:00
Dictionary<string, string> headers = new Dictionary<string, string>();
2015-11-05 20:20:22 +00:00
if (UseAuth)
2017-05-31 16:25:56 +01:00
headers.Add("Authorization", TokenType + " " + AccessToken);
return WebClient.DownloadJsonAsync<T>(url, headers);
2015-11-05 20:20:22 +00:00
}
#endregion Util
}
2017-07-16 21:28:56 +01:00
}