Skip to content

Commit 8c0d765

Browse files
author
Johnny @PC
committed
Added Recommendation Endpoints
1 parent 7bb0cc6 commit 8c0d765

8 files changed

Lines changed: 271 additions & 0 deletions

File tree

‎SpotifyAPI.Example/WebControl.cs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using SpotifyAPI.Web.Models;
55
using System;
66
using System.Collections.Generic;
7+
using System.Diagnostics;
78
using System.IO;
89
using System.Linq;
910
using System.Net;
@@ -68,6 +69,15 @@ private async void InitialSetup()
6869
return;
6970
}
7071

72+
TuneableTrack asd = new TuneableTrack
73+
{
74+
Acousticness = 0.0029f
75+
};
76+
List<string> artists = new List<string>() { "0daugAjUgbJSqdlyYNwIbT" };
77+
78+
Recommendations reco = _spotify.GetRecommendations(target:asd, artistSeed:artists);
79+
RecommendationSeedGenres genres = _spotify.GetRecommendationSeedsGenres();
80+
7181
authButton.Enabled = false;
7282
_profile = _spotify.GetPrivateProfile();
7383

‎SpotifyAPI/SpotifyAPI.csproj‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
<Compile Include="Web\Models\FullArtist.cs" />
8989
<Compile Include="Web\Models\FullTrack.cs" />
9090
<Compile Include="Web\Models\NewAlbumReleases.cs" />
91+
<Compile Include="Web\Models\Recommendations.cs" />
92+
<Compile Include="Web\Models\RecommendationSeed .cs" />
93+
<Compile Include="Web\Models\RecommendationSeedGenres.cs" />
9194
<Compile Include="Web\Models\SearchItem.cs" />
9295
<Compile Include="Web\Models\PrivateProfile.cs" />
9396
<Compile Include="Web\Models\GeneralModels.cs" />
@@ -106,6 +109,7 @@
106109
<Compile Include="Web\Models\Paging.cs" />
107110
<Compile Include="Web\Enums\Scope.cs" />
108111
<Compile Include="Web\Enums\SearchType.cs" />
112+
<Compile Include="Web\Models\TuneableTrack.cs" />
109113
<Compile Include="Web\SimpleHttpServer.cs" />
110114
<Compile Include="Web\SpotifyWebAPI.cs" />
111115
<Compile Include="Web\SpotifyWebBuilder.cs" />
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Newtonsoft.Json;
2+
3+
namespace SpotifyAPI.Web.Models
4+
{
5+
public class RecommendationSeed
6+
{
7+
[JsonProperty("afterFilteringSize")]
8+
public int AfterFilteringSize { get; set; }
9+
10+
[JsonProperty("afterRelinkingSize")]
11+
public int AfterRelinkingSize { get; set; }
12+
13+
[JsonProperty("href")]
14+
public string Href { get; set; }
15+
16+
[JsonProperty("id")]
17+
public string Id { get; set; }
18+
19+
[JsonProperty("initialPoolSize")]
20+
public int InitialPoolSize { get; set; }
21+
22+
[JsonProperty("type")]
23+
public string Type { get; set; }
24+
}
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace SpotifyAPI.Web.Models
5+
{
6+
public class RecommendationSeedGenres : BasicModel
7+
{
8+
[JsonProperty("genres")]
9+
public List<string> Genres { get; set; }
10+
}
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
5+
namespace SpotifyAPI.Web.Models
6+
{
7+
public class Recommendations : BasicModel
8+
{
9+
[JsonProperty("seeds")]
10+
public List<RecommendationSeed> Seeds { get; set; }
11+
12+
[JsonProperty("tracks")]
13+
public List<SimpleTrack> Tracks { get; set; }
14+
}
15+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Globalization;
5+
using System.Linq;
6+
using System.Reflection;
7+
using Newtonsoft.Json;
8+
9+
namespace SpotifyAPI.Web.Models
10+
{
11+
public class TuneableTrack
12+
{
13+
[String("acousticness")]
14+
public float? Acousticness { get; set; }
15+
16+
[String("danceability")]
17+
public float? Danceability { get; set; }
18+
19+
[String("duration_ms")]
20+
public int? DurationMs { get; set; }
21+
22+
[String("energy")]
23+
public float? Energy { get; set; }
24+
25+
[String("instrumentalness")]
26+
public float? Instrumentalness { get; set; }
27+
28+
[String("key")]
29+
public int? Key { get; set; }
30+
31+
[String("liveness")]
32+
public float? Liveness { get; set; }
33+
34+
[String("loudness")]
35+
public float? Loudness { get; set; }
36+
37+
[String("mode")]
38+
public int? Mode { get; set; }
39+
40+
[String("popularity")]
41+
public int? Popularity { get; set; }
42+
43+
[String("speechiness")]
44+
public float? Speechiness { get; set; }
45+
46+
[String("tempo")]
47+
public float? Tempo { get; set; }
48+
49+
[String("time_signature")]
50+
public int? TimeSignature { get; set; }
51+
52+
[String("valence")]
53+
public float? Valence { get; set; }
54+
55+
public string BuildUrlParams(string prefix)
56+
{
57+
List<string> urlParams = new List<string>();
58+
foreach (PropertyInfo info in GetType().GetProperties())
59+
{
60+
object value = info.GetValue(this);
61+
string name = info.GetCustomAttribute<StringAttribute>()?.Text;
62+
if(name == null || value == null)
63+
continue;
64+
if (value is float)
65+
urlParams.Add($"{prefix}_{name}={((float)value).ToString(CultureInfo.InvariantCulture)}");
66+
else
67+
urlParams.Add($"{prefix}_{name}={value}");
68+
}
69+
if (urlParams.Count > 0)
70+
return "&" + string.Join("&", urlParams);
71+
return "";
72+
}
73+
}
74+
}

‎SpotifyAPI/Web/SpotifyWebAPI.cs‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace SpotifyAPI.Web
1212
{
13+
// ReSharper disable once InconsistentNaming
1314
public sealed class SpotifyWebAPI : IDisposable
1415
{
1516
[Obsolete("This Property will be removed soon. Please use SpotifyWebBuilder.APIBase")]
@@ -461,6 +462,82 @@ public async Task<CategoryPlaylist> GetCategoryPlaylistsAsync(string categoryId,
461462
return await DownloadDataAsync<CategoryPlaylist>(_builder.GetCategoryPlaylists(categoryId, country, limit, offset));
462463
}
463464

465+
/// <summary>
466+
/// Create a playlist-style listening experience based on seed artists, tracks and genres.
467+
/// </summary>
468+
/// <param name="artistSeed">A comma separated list of Spotify IDs for seed artists.
469+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
470+
/// </param>
471+
/// <param name="genreSeed">A comma separated list of any genres in the set of available genre seeds.
472+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
473+
/// </param>
474+
/// <param name="trackSeed">A comma separated list of Spotify IDs for a seed track.
475+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
476+
/// </param>
477+
/// <param name="target">Tracks with the attribute values nearest to the target values will be preferred.</param>
478+
/// <param name="min">For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided</param>
479+
/// <param name="max">For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided</param>
480+
/// <param name="limit">The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100.
481+
/// 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.
482+
/// </param>
483+
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.
484+
/// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied.</param>
485+
/// <returns></returns>
486+
/// <remarks>AUTH NEEDED</remarks>
487+
public Recommendations GetRecommendations(List<string> artistSeed = null, List<string> genreSeed = null, List<string> trackSeed = null,
488+
TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "")
489+
{
490+
return DownloadData<Recommendations>(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market));
491+
}
492+
493+
/// <summary>
494+
/// Create a playlist-style listening experience based on seed artists, tracks and genres asynchronously.
495+
/// </summary>
496+
/// <param name="artistSeed">A comma separated list of Spotify IDs for seed artists.
497+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
498+
/// </param>
499+
/// <param name="genreSeed">A comma separated list of any genres in the set of available genre seeds.
500+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
501+
/// </param>
502+
/// <param name="trackSeed">A comma separated list of Spotify IDs for a seed track.
503+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
504+
/// </param>
505+
/// <param name="target">Tracks with the attribute values nearest to the target values will be preferred.</param>
506+
/// <param name="min">For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided</param>
507+
/// <param name="max">For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided</param>
508+
/// <param name="limit">The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100.
509+
/// 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.
510+
/// </param>
511+
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.
512+
/// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied.</param>
513+
/// <returns></returns>
514+
/// <remarks>AUTH NEEDED</remarks>
515+
public async Task<Recommendations> GetRecommendationsAsync(List<string> artistSeed = null, List<string> genreSeed = null, List<string> trackSeed = null,
516+
TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "")
517+
{
518+
return await DownloadDataAsync<Recommendations>(_builder.GetRecommendations(artistSeed, genreSeed, trackSeed, target, min, max, limit, market));
519+
}
520+
521+
/// <summary>
522+
/// Retrieve a list of available genres seed parameter values for recommendations.
523+
/// </summary>
524+
/// <returns></returns>
525+
/// <remarks>AUTH NEEDED</remarks>
526+
public RecommendationSeedGenres GetRecommendationSeedsGenres()
527+
{
528+
return DownloadData<RecommendationSeedGenres>(_builder.GetRecommendationSeedsGenres());
529+
}
530+
531+
/// <summary>
532+
/// Retrieve a list of available genres seed parameter values for recommendations asynchronously.
533+
/// </summary>
534+
/// <returns></returns>
535+
/// <remarks>AUTH NEEDED</remarks>
536+
public async Task<RecommendationSeedGenres> GetRecommendationSeedsGenresAsync()
537+
{
538+
return await DownloadDataAsync<RecommendationSeedGenres>(_builder.GetRecommendationSeedsGenres());
539+
}
540+
464541
#endregion Browse
465542

466543
#region Follow

‎SpotifyAPI/Web/SpotifyWebBuilder.cs‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,61 @@ public string GetCategoryPlaylists(string categoryId, string country = "", int l
284284
return builder.ToString();
285285
}
286286

287+
/// <summary>
288+
/// Create a playlist-style listening experience based on seed artists, tracks and genres.
289+
/// </summary>
290+
/// <param name="artistSeed">A comma separated list of Spotify IDs for seed artists.
291+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
292+
/// </param>
293+
/// <param name="genreSeed">A comma separated list of any genres in the set of available genre seeds.
294+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
295+
/// </param>
296+
/// <param name="trackSeed">A comma separated list of Spotify IDs for a seed track.
297+
/// Up to 5 seed values may be provided in any combination of seed_artists, seed_tracks and seed_genres.
298+
/// </param>
299+
/// <param name="target">Tracks with the attribute values nearest to the target values will be preferred.</param>
300+
/// <param name="min">For each tunable track attribute, a hard floor on the selected track attribute’s value can be provided</param>
301+
/// <param name="max">For each tunable track attribute, a hard ceiling on the selected track attribute’s value can be provided</param>
302+
/// <param name="limit">The target size of the list of recommended tracks. Default: 20. Minimum: 1. Maximum: 100.
303+
/// 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.
304+
/// </param>
305+
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.
306+
/// Because min_*, max_* and target_* are applied to pools before relinking, the generated results may not precisely match the filters applied.</param>
307+
/// <returns></returns>
308+
/// <remarks>AUTH NEEDED</remarks>
309+
public string GetRecommendations(List<string> artistSeed = null, List<string> genreSeed = null, List<string> trackSeed = null,
310+
TuneableTrack target = null, TuneableTrack min = null, TuneableTrack max = null, int limit = 20, string market = "")
311+
{
312+
limit = Math.Min(100, limit);
313+
StringBuilder builder = new StringBuilder($"{APIBase}/recommendations");
314+
builder.Append("?limit=" + limit);
315+
if (artistSeed?.Count > 0)
316+
builder.Append("&seed_artists=" + string.Join(",", artistSeed));
317+
if (genreSeed?.Count > 0)
318+
builder.Append("&seed_genres=" + string.Join(",", genreSeed));
319+
if (trackSeed?.Count > 0)
320+
builder.Append("&seed_tracks=" + string.Join(",", trackSeed));
321+
if (target != null)
322+
builder.Append(target.BuildUrlParams("target"));
323+
if (min != null)
324+
builder.Append(min.BuildUrlParams("min"));
325+
if (max != null)
326+
builder.Append(max.BuildUrlParams("max"));
327+
if (!string.IsNullOrEmpty(market))
328+
builder.Append("&market=" + market);
329+
return builder.ToString();
330+
}
331+
332+
/// <summary>
333+
/// Retrieve a list of available genres seed parameter values for recommendations.
334+
/// </summary>
335+
/// <returns></returns>
336+
/// <remarks>AUTH NEEDED</remarks>
337+
public string GetRecommendationSeedsGenres()
338+
{
339+
return $"{APIBase}/recommendations/available-genre-seeds";
340+
}
341+
287342
#endregion Browse
288343

289344
#region Follow

0 commit comments

Comments
 (0)