2014-07-20 21:42:46 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2014-12-04 17:18:11 +00:00
|
|
|
|
using System.Diagnostics;
|
2014-07-20 21:42:46 +01:00
|
|
|
|
using System.Net;
|
|
|
|
|
using SpotifyAPI.SpotifyWebAPI;
|
|
|
|
|
using SpotifyAPI.SpotifyWebAPI.Models;
|
|
|
|
|
using Newtonsoft.Json;
|
2014-12-04 17:18:11 +00:00
|
|
|
|
using Newtonsoft.Json.Linq;
|
2014-07-20 21:42:46 +01:00
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace SpotifyAPI.SpotifyWebAPI
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public class SpotifyWebAPIClass : IDisposable
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
public String TokenType { get; set; }
|
|
|
|
|
public String AccessToken { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Set to false, if you want anonymous calls without auth
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Boolean UseAuth { get; set; }
|
|
|
|
|
|
|
|
|
|
WebClient webclient;
|
|
|
|
|
JsonSerializerSettings settings;
|
|
|
|
|
public SpotifyWebAPIClass()
|
|
|
|
|
{
|
|
|
|
|
UseAuth = true;
|
|
|
|
|
webclient = new WebClient();
|
|
|
|
|
webclient.Proxy = null;
|
2014-12-04 17:18:11 +00:00
|
|
|
|
settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.All };
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
|
|
|
|
|
#region User
|
|
|
|
|
|
2014-07-20 21:42:46 +01:00
|
|
|
|
public PrivateProfile GetPrivateProfile()
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<PrivateProfile>("https://api.spotify.com/v1/me");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public PublicProfile GetPublicProfile(String userId = "")
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
if (userId.Length == 0)
|
|
|
|
|
return DownloadData<PublicProfile>("https://api.spotify.com/v1/me");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
else
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<PublicProfile>("https://api.spotify.com/v1/users/" + userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region User-Library
|
|
|
|
|
public ErrorResponse SaveTracks(List<String> ids)
|
|
|
|
|
{
|
|
|
|
|
JArray array = new JArray(ids.ToArray());
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/me/tracks/", array.ToString(Formatting.None), "PUT");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public Paging<FullTrack> GetSavedTracks()
|
|
|
|
|
{
|
|
|
|
|
return DownloadData<Paging<FullTrack>>("https://api.spotify.com/v1/me/tracks");
|
|
|
|
|
}
|
|
|
|
|
public ErrorResponse RemoveSavedTracks(List<String> ids)
|
|
|
|
|
{
|
|
|
|
|
JArray array = new JArray(ids.ToArray());
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/me/tracks/", array.ToString(Formatting.None), "DELETE");
|
|
|
|
|
}
|
|
|
|
|
public CheckUserTracks CheckSavedTracks(List<String> ids)
|
|
|
|
|
{
|
|
|
|
|
String resp = DownloadString("https://api.spotify.com/v1/me/tracks/contains?ids=" + string.Join(",", ids));
|
|
|
|
|
JToken res = JToken.Parse(resp);
|
|
|
|
|
if (res is JArray)
|
|
|
|
|
{
|
|
|
|
|
return new CheckUserTracks { Checked = res.ToObject<List<Boolean>>(), ErrorResponse = null };
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new CheckUserTracks { Checked = null, ErrorResponse = res.ToObject<Error>() };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Playlist
|
2014-07-20 21:42:46 +01:00
|
|
|
|
public Paging<SimplePlaylist> GetUserPlaylists(String userId)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<Paging<SimplePlaylist>>("https://api.spotify.com/v1/users/" + userId + "/playlists");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public FullPlaylist GetPlaylist(String userId, String playlistId)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<FullPlaylist>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public Paging<PlaylistTrack> GetPlaylistTracks(String userId, String playlistId)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<Paging<PlaylistTrack>>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public FullPlaylist CreatePlaylist(String userId, String playlistName, Boolean isPublic = true)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
CreatePlaylistArgs args = new CreatePlaylistArgs()
|
|
|
|
|
{
|
|
|
|
|
Name = playlistName,
|
|
|
|
|
Public = isPublic
|
|
|
|
|
};
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return UploadData<FullPlaylist>("https://api.spotify.com/v1/users/" + userId + "/playlists", JsonConvert.SerializeObject(args));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public ErrorResponse UpdatePlaylist(String userId, String playlistId, String newName = null, Boolean? newPublic = null)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
JObject ob = new JObject();
|
|
|
|
|
if (newName != null)
|
|
|
|
|
ob.Add("name", newName);
|
|
|
|
|
if (newPublic != null)
|
|
|
|
|
ob.Add("public", newPublic);
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId, ob.ToString(Formatting.None), "PUT");
|
|
|
|
|
}
|
|
|
|
|
public ErrorResponse ReplacePlaylistTracks(String userId, String playlistId, List<String> uris)
|
|
|
|
|
{
|
|
|
|
|
JObject ob = new JObject();
|
|
|
|
|
ob.Add("uris", new JArray(uris));
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", ob.ToString(Formatting.None), "PUT");
|
|
|
|
|
}
|
|
|
|
|
public ErrorResponse DeletePlaylistTracks(String userId, String playlistId, List<DeleteTrackArg> args)
|
|
|
|
|
{
|
|
|
|
|
JObject ob = new JObject();
|
|
|
|
|
ob.Add("tracks", JArray.FromObject(args));
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", ob.ToString(Formatting.None), "DELETE");
|
|
|
|
|
}
|
|
|
|
|
public ErrorResponse AddTracks(String userId, String playlistId, List<String> uris, int position = int.MaxValue)
|
|
|
|
|
{
|
|
|
|
|
if (position == int.MaxValue)
|
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", JsonConvert.SerializeObject(uris));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
String tracks = string.Join(",", uris);
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return UploadData<ErrorResponse>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks?position=" + position
|
2014-07-20 21:42:46 +01:00
|
|
|
|
+ "&ids=" + tracks
|
|
|
|
|
, JsonConvert.SerializeObject(uris));
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public FeaturedPlaylists GetFeaturedPlaylists(String locale = "", String country = "", DateTime timestamp = default(DateTime), int limit = 20, int offset = 0)
|
|
|
|
|
{
|
|
|
|
|
limit = Math.Max(50, limit);
|
|
|
|
|
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/browse/featured-playlists");
|
|
|
|
|
builder.Append("?limit=" + limit);
|
|
|
|
|
builder.Append("&offset=" + offset);
|
|
|
|
|
if(locale != "")
|
|
|
|
|
builder.Append("&locale=" + locale);
|
|
|
|
|
if(country != "")
|
|
|
|
|
builder.Append("&country=" + country);
|
|
|
|
|
if (timestamp != default(DateTime))
|
|
|
|
|
builder.Append("×tamp=" + timestamp.ToString("yyyy-MM-ddTHH:mm:ss"));
|
|
|
|
|
return DownloadData<FeaturedPlaylists>(builder.ToString());
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Search and Fetch
|
|
|
|
|
public NewAlbumReleases GetNewAlbumReleases(String country = "", int limit = 50, int offset = 0)
|
|
|
|
|
{
|
|
|
|
|
limit = Math.Max(50, limit);
|
|
|
|
|
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/browse/new-releases");
|
|
|
|
|
builder.Append("?limit=" + limit);
|
|
|
|
|
builder.Append("&offset=" + offset);
|
|
|
|
|
if (country != "")
|
|
|
|
|
builder.Append("&country=" + country);
|
|
|
|
|
return DownloadData<NewAlbumReleases>(builder.ToString());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public SearchItem SearchItems(String q, SearchType type, int limit = 20, int offset = 0)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
limit = Math.Min(50, limit);
|
|
|
|
|
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/search");
|
|
|
|
|
builder.Append("?q=" + q);
|
|
|
|
|
builder.Append("&type=" + type.GetSearchValue(","));
|
|
|
|
|
builder.Append("&limit=" + limit);
|
|
|
|
|
builder.Append("&offset=" + offset);
|
|
|
|
|
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SearchItem>(builder.ToString());
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public SeveralTracks GetSeveralTracks(List<String> ids)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SeveralTracks>("https://api.spotify.com/v1/tracks?ids=" + string.Join(",", ids));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public SeveralAlbums GetSeveralAlbums(List<String> ids)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SeveralAlbums>("https://api.spotify.com/v1/albums?ids=" + string.Join(",", ids));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public SeveralArtists GetSeveralArtists(List<String> ids)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SeveralArtists>("https://api.spotify.com/v1/artists?ids=" + string.Join(",", ids));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public FullTrack GetTrack(String id)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<FullTrack>("https://api.spotify.com/v1/tracks/" + id);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public SeveralArtists GetRelatedArtists(String id)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SeveralArtists>("https://api.spotify.com/v1/artists/" + id + "/related-artists");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public SeveralTracks GetArtistsTopTracks(String id, String country)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<SeveralTracks>("https://api.spotify.com/v1/artists/" + id + "/top-tracks?country=" + country);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public Paging<SimpleAlbum> GetArtistsAlbums(String id, AlbumType type = AlbumType.ALL, String market = "", int limit = 20, int offset = 0)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
limit = Math.Min(50, limit);
|
|
|
|
|
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/artists/" + id + "/albums");
|
|
|
|
|
builder.Append("?type=" + type.GetAlbumValue(","));
|
|
|
|
|
builder.Append("&limit=" + limit);
|
|
|
|
|
builder.Append("&offset=" + offset);
|
2014-12-04 17:18:11 +00:00
|
|
|
|
if (market != "")
|
|
|
|
|
builder.Append("&market=" + market);
|
|
|
|
|
return DownloadData<Paging<SimpleAlbum>>(builder.ToString());
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
|
|
|
|
public FullArtist GetArtist(String id)
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<FullArtist>("https://api.spotify.com/v1/artists/" + id);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public Paging<SimpleTrack> GetAlbumTracks(String id, int limit = 20, int offset = 0)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
limit = Math.Min(50, limit);
|
|
|
|
|
StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/albums/" + id + "/tracks");
|
|
|
|
|
builder.Append("?limit=" + limit);
|
|
|
|
|
builder.Append("&offset=" + offset);
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<Paging<SimpleTrack>>(builder.ToString());
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public FullAlbum GetAlbum(String id)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
return DownloadData<FullAlbum>("https://api.spotify.com/v1/albums/" + id);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Util
|
|
|
|
|
public T UploadData<T>(String url, String uploadData, String method = "POST")
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
if (!UseAuth)
|
|
|
|
|
throw new Exception("UseAuth required for 'UploadData'");
|
|
|
|
|
webclient.Headers.Add("Authorization", TokenType + " " + AccessToken);
|
2014-12-04 17:18:11 +00:00
|
|
|
|
webclient.Headers.Add("Content-Type", "application/json");
|
2014-07-20 21:42:46 +01:00
|
|
|
|
String response = "";
|
|
|
|
|
try
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
byte[] data = webclient.UploadData(url, method, Encoding.UTF8.GetBytes(uploadData));
|
2014-07-20 21:42:46 +01:00
|
|
|
|
response = Encoding.UTF8.GetString(data);
|
|
|
|
|
}
|
|
|
|
|
catch (WebException e)
|
|
|
|
|
{
|
|
|
|
|
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
|
|
|
|
}
|
|
|
|
|
return JsonConvert.DeserializeObject<T>(response, settings);
|
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
public T DownloadData<T>(String url)
|
|
|
|
|
{
|
|
|
|
|
return JsonConvert.DeserializeObject<T>(DownloadString(url), settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String DownloadString(String url)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
if (UseAuth)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
webclient.Headers.Add("Authorization", TokenType + " " + AccessToken);
|
|
|
|
|
String response = "";
|
|
|
|
|
try
|
|
|
|
|
{
|
2014-12-04 17:18:11 +00:00
|
|
|
|
byte[] data = webclient.DownloadData(url);
|
2014-07-20 21:42:46 +01:00
|
|
|
|
response = Encoding.UTF8.GetString(data);
|
2014-12-04 17:18:11 +00:00
|
|
|
|
}
|
|
|
|
|
catch (WebException e)
|
2014-07-20 21:42:46 +01:00
|
|
|
|
{
|
|
|
|
|
response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
|
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
Debug.WriteLine(response);
|
|
|
|
|
return response;
|
2014-07-20 21:42:46 +01:00
|
|
|
|
}
|
2014-12-04 17:18:11 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2014-07-20 21:42:46 +01:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
webclient.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|