From cbd248a2fee103e0dbc1a6ba456ef73ff04eb869 Mon Sep 17 00:00:00 2001 From: "Johnny @PC" Date: Thu, 4 Dec 2014 18:18:11 +0100 Subject: [PATCH] - Updated. (Changelog-date: November 11th, 2014) - Improved HTTPServer - Ordered methods in SpotifyWebApiCass - Added various models for the new endpoints --- SpotifyAPI/SpotifyAPI.csproj | 4 +- SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs | 8 +- SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs | 4 +- .../SpotifyWebAPI/Models/FeaturedPlaylists.cs | 17 ++ SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs | 2 + SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs | 2 + SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs | 4 +- .../SpotifyWebAPI/Models/GeneralModels.cs | 38 +++- .../SpotifyWebAPI/Models/NewAlbumReleases.cs | 15 ++ .../SpotifyWebAPI/Models/PrivateProfile.cs | 2 + .../SpotifyWebAPI/Models/PublicProfile.cs | 6 + .../SpotifyWebAPI/Models/SimplePlaylist.cs | 2 + .../SpotifyWebAPI/Models/SimpleTrack.cs | 2 + SpotifyAPI/SpotifyWebAPI/Scope.cs | 10 +- SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs | 41 ++-- .../SpotifyWebAPI/SpotifyWebAPIClass.cs | 183 ++++++++++++++---- SpotifyWebAPIExample/Program.cs | 8 +- 17 files changed, 275 insertions(+), 73 deletions(-) create mode 100644 SpotifyAPI/SpotifyWebAPI/Models/FeaturedPlaylists.cs create mode 100644 SpotifyAPI/SpotifyWebAPI/Models/NewAlbumReleases.cs diff --git a/SpotifyAPI/SpotifyAPI.csproj b/SpotifyAPI/SpotifyAPI.csproj index ce45cb39..4adb37d7 100644 --- a/SpotifyAPI/SpotifyAPI.csproj +++ b/SpotifyAPI/SpotifyAPI.csproj @@ -7,7 +7,7 @@ {EBBE35E2-7B91-4D7D-B8FC-3A0472F5119D} Library Properties - SpotifyAPI.SpotifyLocalAPI + SpotifyAPI SpotifyAPI v4.5 512 @@ -65,9 +65,11 @@ + + diff --git a/SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs b/SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs index 96f25820..ab92529b 100644 --- a/SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs +++ b/SpotifyAPI/SpotifyWebAPI/ImplicitGrantAuth.cs @@ -58,13 +58,7 @@ namespace SpotifyAPI.SpotifyWebAPI } public void StopHttpServer() { - try - { - httpThread.Abort(); - }catch(ThreadAbortException e) - { - - } + httpServer.Dispose(); httpServer = null; } } diff --git a/SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs b/SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs index 76fc5227..5e0d11b6 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/BasicModel.cs @@ -10,11 +10,11 @@ namespace SpotifyAPI.SpotifyWebAPI.Models public abstract class BasicModel { [JsonProperty("error")] - public Error Error { get; set; } + public Error ErrorResponse { get; set; } public Boolean HasError() { - return Error != null; + return ErrorResponse != null; } } } diff --git a/SpotifyAPI/SpotifyWebAPI/Models/FeaturedPlaylists.cs b/SpotifyAPI/SpotifyWebAPI/Models/FeaturedPlaylists.cs new file mode 100644 index 00000000..45b6fff4 --- /dev/null +++ b/SpotifyAPI/SpotifyWebAPI/Models/FeaturedPlaylists.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace SpotifyAPI.SpotifyWebAPI.Models +{ + public class FeaturedPlaylists : BasicModel + { + [JsonProperty("message")] + public String Message { get; set; } + [JsonProperty("playlists")] + public Paging Playlists { get; set; } + } +} diff --git a/SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs b/SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs index 2613497e..0eab800d 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/FullAlbum.cs @@ -15,6 +15,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models public List Artists { get; set; } [JsonProperty("available_markets")] public List AvailableMarkets { get; set; } + [JsonProperty("copyrights")] + public List Copyrights { get; set; } [JsonProperty("external_ids")] public Dictionary ExternalIds { get; set; } [JsonProperty("external_urls")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs b/SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs index a0ce5677..a400eab0 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/FullArtist.cs @@ -11,6 +11,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models { [JsonProperty("external_urls")] public Dictionary ExternalUrls { get; set; } + [JsonProperty("followers")] + public Followers Followers { get; set; } [JsonProperty("genres")] public List Genres { get; set; } [JsonProperty("href")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs b/SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs index a1f97440..b5b21584 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/FullTrack.cs @@ -14,8 +14,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models /// [JsonProperty("album")] public SimpleAlbum Album { get; set; } - [JsonProperty("artist")] - public SimpleArtist Artist { get; set; } + [JsonProperty("artists")] + public List Artists { get; set; } [JsonProperty("available_markets")] public List AvailableMarkets { get; set; } [JsonProperty("disc_number")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs b/SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs index d554b321..7eeb9ff9 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/GeneralModels.cs @@ -16,6 +16,12 @@ namespace SpotifyAPI.SpotifyWebAPI.Models [JsonProperty("height")] public int Height { get; set; } } + public class ErrorResponse + { + [JsonProperty("error")] + public Error Error { get; set; } + } + public class Error { [JsonProperty("status")] @@ -46,13 +52,31 @@ namespace SpotifyAPI.SpotifyWebAPI.Models [JsonProperty("track")] public FullTrack Track { get; set; } } - internal class CreatePlaylistArgs + public class CreatePlaylistArgs { [JsonProperty("name")] public String Name { get; set; } [JsonProperty("public")] public Boolean Public { get; set; } } + public class DeleteTrackArg + { + [JsonProperty("uri")] + public String Uri { get; set; } + [JsonProperty("positions")] + public List Positions { get; set; } + + public DeleteTrackArg(String uri, params int[] positions) + { + this.Positions = positions.ToList(); + this.Uri = uri; + } + public bool ShouldSerializePositions() + { + // don't serialize the Manager property if an employee is their own manager + return (Positions.Count > 0); + } + } public class SeveralTracks { [JsonProperty("tracks")] @@ -68,4 +92,16 @@ namespace SpotifyAPI.SpotifyWebAPI.Models [JsonProperty("albums")] public List Albums { get; set; } } + public class Copyright + { + [JsonProperty("text")] + public String Text { get; set; } + [JsonProperty("type")] + public String Type { get; set; } + } + + public class CheckUserTracks : BasicModel + { + public List Checked { get; set; } + } } diff --git a/SpotifyAPI/SpotifyWebAPI/Models/NewAlbumReleases.cs b/SpotifyAPI/SpotifyWebAPI/Models/NewAlbumReleases.cs new file mode 100644 index 00000000..0ee06e52 --- /dev/null +++ b/SpotifyAPI/SpotifyWebAPI/Models/NewAlbumReleases.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace SpotifyAPI.SpotifyWebAPI.Models +{ + public class NewAlbumReleases : BasicModel + { + [JsonProperty("albums")] + public Paging Albums { get; set; } + } +} diff --git a/SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs b/SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs index 8c2f3a1f..7a88f9c9 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/PrivateProfile.cs @@ -15,6 +15,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models public String DisplayName { get; set; } [JsonProperty("external_urls")] public Dictionary ExternalUrls { get; set; } + [JsonProperty("followers")] + public Followers Followers { get; set; } [JsonProperty("href")] public String Href { get; set; } [JsonProperty("id")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs b/SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs index b2ef90dc..c8a0938d 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/PublicProfile.cs @@ -9,12 +9,18 @@ namespace SpotifyAPI.SpotifyWebAPI.Models { public class PublicProfile : BasicModel { + [JsonProperty("display_name")] + public String DisplayName { get; set; } [JsonProperty("external_urls")] public Dictionary ExternalUrls { get; set; } + [JsonProperty("followers")] + public Followers Followers { get; set; } [JsonProperty("href")] public String Href { get; set; } [JsonProperty("id")] public String Id { get; set; } + [JsonProperty("images")] + public List Images { get; set; } [JsonProperty("type")] public String Type { get; set; } [JsonProperty("uri")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs b/SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs index 3852ff1d..a9c50376 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/SimplePlaylist.cs @@ -17,6 +17,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models public String Href { get; set; } [JsonProperty("id")] public String Id { get; set; } + [JsonProperty("images")] + public List Images { get; set; } [JsonProperty("name")] public String Name { get; set; } [JsonProperty("owner")] diff --git a/SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs b/SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs index b77c000c..48f5a54e 100644 --- a/SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs +++ b/SpotifyAPI/SpotifyWebAPI/Models/SimpleTrack.cs @@ -11,6 +11,8 @@ namespace SpotifyAPI.SpotifyWebAPI.Models { [JsonProperty("artist")] public SimpleArtist Artist { get; set; } + [JsonProperty("available_markets")] + public List AvailableMarkets { get; set; } [JsonProperty("disc_number")] public int DiscNumber { get; set; } [JsonProperty("duration_ms")] diff --git a/SpotifyAPI/SpotifyWebAPI/Scope.cs b/SpotifyAPI/SpotifyWebAPI/Scope.cs index f9c825b2..0322d014 100644 --- a/SpotifyAPI/SpotifyWebAPI/Scope.cs +++ b/SpotifyAPI/SpotifyWebAPI/Scope.cs @@ -11,8 +11,8 @@ namespace SpotifyAPI.SpotifyWebAPI { [StringAttribute("")] NONE = 1, - [StringAttribute("playlist-modify")] - PLAYLIST_MODIFY = 2, + [StringAttribute("playlist-modify-public")] + PLAYLIST_MODIFY_PUBLIC = 2, [StringAttribute("playlist-modify-private")] PLAYLIST_MODIFY_PRIVATE = 4, [StringAttribute("playlist-read-private")] @@ -22,6 +22,10 @@ namespace SpotifyAPI.SpotifyWebAPI [StringAttribute("user-read-private")] USER_READ_PRIVATE = 32, [StringAttribute("user-read-email")] - USER_READ_EMAIL = 64 + USER_READ_EMAIL = 64, + [StringAttribute("user-library-read")] + USER_LIBRARAY_READ = 128, + [StringAttribute("user-library-modify")] + USER_LIBRARY_MODIFY = 256 } } diff --git a/SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs b/SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs index 84d2982b..070499d3 100644 --- a/SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs +++ b/SpotifyAPI/SpotifyWebAPI/SimpleHttpServer.cs @@ -162,32 +162,49 @@ namespace SpotifyAPI.SpotifyWebAPI } } - public abstract class HttpServer { + public abstract class HttpServer : IDisposable { protected int port; TcpListener listener; - bool is_active = true; + public bool IsActive { get; set; } - public HttpServer(int port) { + public HttpServer(int port) + { + this.IsActive = true; this.port = port; } public void listen() { - listener = new TcpListener(port); - listener.Start(); - while (is_active) { - TcpClient s = listener.AcceptTcpClient(); - HttpProcessor processor = new HttpProcessor(s, this); - Thread thread = new Thread(new ThreadStart(processor.process)); - thread.Start(); - Thread.Sleep(1); + try + { + listener = new TcpListener(port); + listener.Start(); + while (IsActive) + { + TcpClient s = listener.AcceptTcpClient(); + HttpProcessor processor = new HttpProcessor(s, this); + Thread thread = new Thread(new ThreadStart(processor.process)); + thread.Start(); + Thread.Sleep(1); + } + }catch(Exception) + { + } } + public void Dispose() + { + IsActive = false; + listener.Stop(); + } + public abstract void handleGETRequest(HttpProcessor p); public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData); - } + + +} public class SimpleHttpServer : HttpServer { diff --git a/SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs b/SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs index 231183dd..cc34708e 100644 --- a/SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs +++ b/SpotifyAPI/SpotifyWebAPI/SpotifyWebAPIClass.cs @@ -2,17 +2,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; +using System.Diagnostics; using System.Net; using SpotifyAPI.SpotifyWebAPI; using SpotifyAPI.SpotifyWebAPI.Models; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System.Collections.Specialized; using System.IO; namespace SpotifyAPI.SpotifyWebAPI { - public class SpotifyWebAPIClass + public class SpotifyWebAPIClass : IDisposable { public String TokenType { get; set; } public String AccessToken { get; set; } @@ -28,53 +29,139 @@ namespace SpotifyAPI.SpotifyWebAPI UseAuth = true; webclient = new WebClient(); webclient.Proxy = null; - settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.All }; } + + #region User + public PrivateProfile GetPrivateProfile() { - return DownloadString("https://api.spotify.com/v1/me"); + return DownloadData("https://api.spotify.com/v1/me"); } public PublicProfile GetPublicProfile(String userId = "") { - if(userId.Length == 0) - return DownloadString("https://api.spotify.com/v1/me"); + if (userId.Length == 0) + return DownloadData("https://api.spotify.com/v1/me"); else - return DownloadString("https://api.spotify.com/v1/users/" + userId); + return DownloadData("https://api.spotify.com/v1/users/" + userId); } + + #endregion + + #region User-Library + public ErrorResponse SaveTracks(List ids) + { + JArray array = new JArray(ids.ToArray()); + return UploadData("https://api.spotify.com/v1/me/tracks/", array.ToString(Formatting.None), "PUT"); + } + public Paging GetSavedTracks() + { + return DownloadData>("https://api.spotify.com/v1/me/tracks"); + } + public ErrorResponse RemoveSavedTracks(List ids) + { + JArray array = new JArray(ids.ToArray()); + return UploadData("https://api.spotify.com/v1/me/tracks/", array.ToString(Formatting.None), "DELETE"); + } + public CheckUserTracks CheckSavedTracks(List 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>(), ErrorResponse = null }; + } + else + { + return new CheckUserTracks { Checked = null, ErrorResponse = res.ToObject() }; + } + } + #endregion + + #region Playlist public Paging GetUserPlaylists(String userId) { - return DownloadString>("https://api.spotify.com/v1/users/" + userId + "/playlists"); + return DownloadData>("https://api.spotify.com/v1/users/" + userId + "/playlists"); } - public FullPlaylist GetPlaylist(String userId,String playlistId) + public FullPlaylist GetPlaylist(String userId, String playlistId) { - return DownloadString("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId); + return DownloadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId); } - public Paging GetPlaylistTracks(String userId,String playlistId) + public Paging GetPlaylistTracks(String userId, String playlistId) { - return DownloadString>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks"); + return DownloadData>("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks"); } - public FullPlaylist CreatePlaylist(String userId,String playlistName,Boolean isPublic = true) + public FullPlaylist CreatePlaylist(String userId, String playlistName, Boolean isPublic = true) { CreatePlaylistArgs args = new CreatePlaylistArgs() { Name = playlistName, Public = isPublic }; - return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists",JsonConvert.SerializeObject(args)); + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists", JsonConvert.SerializeObject(args)); } - public Error AddTracks(String userId,String playlistId,List uris,int position = int.MaxValue) + public ErrorResponse UpdatePlaylist(String userId, String playlistId, String newName = null, Boolean? newPublic = null) { - if(position == int.MaxValue) - return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", JsonConvert.SerializeObject(uris)); + JObject ob = new JObject(); + if (newName != null) + ob.Add("name", newName); + if (newPublic != null) + ob.Add("public", newPublic); + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId, ob.ToString(Formatting.None), "PUT"); + } + public ErrorResponse ReplacePlaylistTracks(String userId, String playlistId, List uris) + { + JObject ob = new JObject(); + ob.Add("uris", new JArray(uris)); + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", ob.ToString(Formatting.None), "PUT"); + } + public ErrorResponse DeletePlaylistTracks(String userId, String playlistId, List args) + { + JObject ob = new JObject(); + ob.Add("tracks", JArray.FromObject(args)); + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", ob.ToString(Formatting.None), "DELETE"); + } + public ErrorResponse AddTracks(String userId, String playlistId, List uris, int position = int.MaxValue) + { + if (position == int.MaxValue) + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", JsonConvert.SerializeObject(uris)); else { String tracks = string.Join(",", uris); - return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks?position=" + position + return UploadData("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks?position=" + position + "&ids=" + tracks , JsonConvert.SerializeObject(uris)); } } - public SearchItem SearchItems(String q,SearchType type,int limit = 20,int offset = 0) + 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(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(builder.ToString()); + + } + public SearchItem SearchItems(String q, SearchType type, int limit = 20, int offset = 0) { limit = Math.Min(50, limit); StringBuilder builder = new StringBuilder("https://api.spotify.com/v1/search"); @@ -83,67 +170,72 @@ namespace SpotifyAPI.SpotifyWebAPI builder.Append("&limit=" + limit); builder.Append("&offset=" + offset); - return DownloadString(builder.ToString()); + return DownloadData(builder.ToString()); } public SeveralTracks GetSeveralTracks(List ids) { - return DownloadString("https://api.spotify.com/v1/tracks?ids=" + string.Join(",",ids)); + return DownloadData("https://api.spotify.com/v1/tracks?ids=" + string.Join(",", ids)); } public SeveralAlbums GetSeveralAlbums(List ids) { - return DownloadString("https://api.spotify.com/v1/albums?ids=" + string.Join(",", ids)); + return DownloadData("https://api.spotify.com/v1/albums?ids=" + string.Join(",", ids)); } public SeveralArtists GetSeveralArtists(List ids) { - return DownloadString("https://api.spotify.com/v1/artists?ids=" + string.Join(",", ids)); + return DownloadData("https://api.spotify.com/v1/artists?ids=" + string.Join(",", ids)); } public FullTrack GetTrack(String id) { - return DownloadString("https://api.spotify.com/v1/tracks/" + id); + return DownloadData("https://api.spotify.com/v1/tracks/" + id); } public SeveralArtists GetRelatedArtists(String id) { - return DownloadString("https://api.spotify.com/v1/artists/" + id + "/related-artists"); + return DownloadData("https://api.spotify.com/v1/artists/" + id + "/related-artists"); } public SeveralTracks GetArtistsTopTracks(String id, String country) { - return DownloadString("https://api.spotify.com/v1/artists/" + id + "/top-tracks?country=" + country); + return DownloadData("https://api.spotify.com/v1/artists/" + id + "/top-tracks?country=" + country); } - public Paging GetArtistsAlbums(String id,AlbumType type = AlbumType.ALL,String country = "",int limit = 20,int offset = 0) + public Paging GetArtistsAlbums(String id, AlbumType type = AlbumType.ALL, String market = "", int limit = 20, int offset = 0) { 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); - return DownloadString>(builder.ToString()); + if (market != "") + builder.Append("&market=" + market); + return DownloadData>(builder.ToString()); } public FullArtist GetArtist(String id) { - return DownloadString("https://api.spotify.com/v1/artists/" + id); + return DownloadData("https://api.spotify.com/v1/artists/" + id); } - public Paging GetAlbumTracks(String id,int limit = 20,int offset = 0) + public Paging GetAlbumTracks(String id, int limit = 20, int offset = 0) { 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); - return DownloadString>(builder.ToString()); + return DownloadData>(builder.ToString()); } - public FullAlbum GetAlbum(String id ) + public FullAlbum GetAlbum(String id) { - return DownloadString("https://api.spotify.com/v1/albums/" + id); + return DownloadData("https://api.spotify.com/v1/albums/" + id); } - public T UploadData(String url,String uploadData) + #endregion + + #region Util + public T UploadData(String url, String uploadData, String method = "POST") { if (!UseAuth) throw new Exception("UseAuth required for 'UploadData'"); webclient.Headers.Add("Authorization", TokenType + " " + AccessToken); - webclient.Headers.Add("Content-Type","application/json"); + webclient.Headers.Add("Content-Type", "application/json"); String response = ""; try { - byte[] data = webclient.UploadData(url,Encoding.UTF8.GetBytes(uploadData)); + byte[] data = webclient.UploadData(url, method, Encoding.UTF8.GetBytes(uploadData)); response = Encoding.UTF8.GetString(data); } catch (WebException e) @@ -152,21 +244,30 @@ namespace SpotifyAPI.SpotifyWebAPI } return JsonConvert.DeserializeObject(response, settings); } - public T DownloadString(String url) + public T DownloadData(String url) { - if(UseAuth) + return JsonConvert.DeserializeObject(DownloadString(url), settings); + } + + public String DownloadString(String url) + { + if (UseAuth) webclient.Headers.Add("Authorization", TokenType + " " + AccessToken); String response = ""; try { - byte [] data = webclient.DownloadData(url); + byte[] data = webclient.DownloadData(url); response = Encoding.UTF8.GetString(data); - }catch(WebException e) + } + catch (WebException e) { response = new StreamReader(e.Response.GetResponseStream()).ReadToEnd(); } - return JsonConvert.DeserializeObject(response, settings); + Debug.WriteLine(response); + return response; } + #endregion + public void Dispose() { webclient.Dispose(); diff --git a/SpotifyWebAPIExample/Program.cs b/SpotifyWebAPIExample/Program.cs index ac845812..7e0bce1e 100644 --- a/SpotifyWebAPIExample/Program.cs +++ b/SpotifyWebAPIExample/Program.cs @@ -24,7 +24,7 @@ namespace SpotifyWebAPIExample //Set this to localhost if you want to use the built-in HTTP Server RedirectUri = "http://localhost", //How many permissions we need? - Scope = Scope.USER_READ_PRIVATE | Scope.USER_READ_EMAIL | Scope.PLAYLIST_READ_PRIVATE + Scope = Scope.USER_READ_PRIVATE | Scope.USER_READ_EMAIL | Scope.PLAYLIST_READ_PRIVATE | Scope.USER_LIBRARAY_READ | Scope.USER_LIBRARY_MODIFY | Scope.USER_READ_PRIVATE }; //Start the internal http server auth.StartHttpServer(); @@ -108,7 +108,7 @@ namespace SpotifyWebAPIExample Console.WriteLine(playlist.Name + " (" + playlist.Id + ")"); while(playlists.Next != null) { - playlists = spotify.DownloadString>(playlists.Next); + playlists = spotify.DownloadData>(playlists.Next); foreach (SimplePlaylist playlist in playlists.Items) Console.WriteLine(playlist.Name + " (" + playlist.Id + ")"); } @@ -127,7 +127,7 @@ namespace SpotifyWebAPIExample Paging col = spotify.GetPlaylistTracks(spotify.GetPrivateProfile().Id, id); if(col.HasError()) { - Console.WriteLine("ERROR: " + col.Error.Message); + Console.WriteLine("ERROR: " + col.ErrorResponse.Message); DisplayMenu(spotify); return; } @@ -135,7 +135,7 @@ namespace SpotifyWebAPIExample Console.WriteLine(track.Track.Name + " (" + track.Track.Id + ")"); while (col.Next != null) { - col = spotify.DownloadString>(col.Next); + col = spotify.DownloadData>(col.Next); foreach (PlaylistTrack track in col.Items) Console.WriteLine(track.Track.Name + " (" + track.Track.Id + ")"); }