namespace Webzine.Entity.Fixtures; using System.Globalization; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text; using System.Text.Json.Serialization; using Microsoft.Extensions.Options; public class SpotifySeederOptions { public string ClientId { get; set; } = string.Empty; public string ClientSecret { get; set; } = string.Empty; public string Market { get; set; } = "FR"; public List Genres { get; set; } = [ "rock", "pop", "jazz", "hip hop", "electronic", "metal", ]; public int ArtistsPerGenre { get; set; } = 4; public int AlbumsPerArtist { get; set; } = 2; public int TracksPerAlbum { get; set; } = 4; public int MaxCommentsPerTrack { get; set; } = 3; } public class SeedDataSpotify { private readonly HttpClient httpClient; private readonly SpotifySeederOptions options; public SeedDataSpotify(HttpClient httpClient, IOptions optionsAccessor) { this.httpClient = httpClient; this.options = optionsAccessor.Value; } /// /// /// /// /// A representing the asynchronous operation. /// public async Task GenererJeuDeDonneesAsync(CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(this.options.ClientId) || string.IsNullOrWhiteSpace(this.options.ClientSecret)) { throw new InvalidOperationException("Renseignez SpotifySeeder:ClientId et SpotifySeeder:ClientSecret."); } var token = await this.GetTokenAsync(cancellationToken); var styles = new Dictionary(StringComparer.OrdinalIgnoreCase); var artistes = new List(); var titres = new List(); var commentaires = new List(); var artistIds = new HashSet(StringComparer.OrdinalIgnoreCase); int nextArtistId = 1; int nextStyleId = 1; int nextTitreId = 1; int nextCommentaireId = 1; foreach (var genre in this.options.Genres.Where(g => !string.IsNullOrWhiteSpace(g))) { var artistesSpotify = await this.GetAsync( $"https://api.spotify.com/v1/search?q={Uri.EscapeDataString($"genre:\"{genre}\"")}&type=artist&market={this.options.Market}&limit={Math.Clamp(this.options.ArtistsPerGenre, 1, 10)}", token, cancellationToken); foreach (var artisteSpotify in artistesSpotify?.Artists?.Items ??[]) { if (string.IsNullOrWhiteSpace(artisteSpotify.Id) || !artistIds.Add(artisteSpotify.Id)) { continue; } var stylesTitre = (artisteSpotify.Genres.Count > 0 ? artisteSpotify.Genres :[genre]) .Select(g => this.GetOrCreateStyle(styles, NormalizeGenre(g), ref nextStyleId)) .DistinctBy(s => s.IdStyle) .ToList(); var artiste = new Artiste { IdArtiste = nextArtistId++, Nom = Trim(artisteSpotify.Name, 50, "Artiste Spotify"), Biographie = Trim( $"{artisteSpotify.Name} est un artiste present sur Spotify, associe aux styles {string.Join(", ", stylesTitre.Select(s => s.Libelle))}.", 4000, "Artiste issu du catalogue Spotify."), Titres = new List(), }; artistes.Add(artiste); var albums = await this.GetAsync( $"https://api.spotify.com/v1/artists/{artisteSpotify.Id}/albums?include_groups=album,single&market={this.options.Market}", token, cancellationToken); foreach (var album in albums?.Items?.GroupBy(a => a.Name, StringComparer.OrdinalIgnoreCase).Select(g => g.First()) ??[]) { var tracks = await this.GetAsync( $"https://api.spotify.com/v1/albums/{album.Id}/tracks?market={this.options.Market}&limit={Math.Clamp(this.options.TracksPerAlbum, 1, 10)}", token, cancellationToken); foreach (var track in tracks?.Items ??[]) { var titre = new Titre { IdTitre = nextTitreId++, IdArtiste = artiste.IdArtiste, Artiste = artiste, Libelle = Trim(track.Name, 200, "Titre Spotify"), Chronique = Trim( $"{track.Name} est un titre de {artiste.Nom}, issu de l'album {album.Name}. Cette fiche a ete generee depuis Spotify.", 4000, "Titre importe depuis Spotify."), DateCreation = DateTime.UtcNow, DateSortie = ParseDate(album.ReleaseDate), Duree = Math.Max(1, track.DurationMs / 1000), UrlJaquette = Trim(album.Images.FirstOrDefault()?.Url, 250, "https://placehold.co/640x640"), UrlEcoute = Trim(track.ExternalUrls?.Spotify ?? $"https://open.spotify.com/track/{track.Id}", 250, string.Empty), NbLectures = Random.Shared.Next(500, 50000), NbLikes = Random.Shared.Next(50, 5000), Album = Trim(album.Name, 200, "Album Spotify"), Commentaires = new List(), Styles = new List