using NLog; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Contracts.Entities.Genre; using Sony.Filtr.Core.EditorialPlaylists; using Sony.Filtr.PlaylistGeneration; using Sony.Filtr.Playlists.Spotify; using Sony.Filtr.Playlists.Spotify.Model; using Sony.Filtr.Utility.Extensions; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Sony.Filtr.Tasks.Tasks.Spotify { public class SetEditorialPlaylistGenres : IScheduledTask { private readonly EditorialPlaylistManager _editorialPlaylistManager; private readonly SpotifyPlaylistManager _spotifyPlaylistManager; private readonly PlaylistGenerationManager _playlistGenerationManager; private readonly Logger _logger; public SetEditorialPlaylistGenres(EditorialPlaylistManager editorialPlaylistManager, SpotifyPlaylistManager spotifyPlaylistManager, PlaylistGenerationManager playlistGenerationManager) { _editorialPlaylistManager = editorialPlaylistManager; _spotifyPlaylistManager = spotifyPlaylistManager; _playlistGenerationManager = playlistGenerationManager; _logger = LogManager.GetLogger("IndexEditorialPlaylists"); } public async Task ExecuteAsync(Guid scheduledTaskLogId) { var editorialPlaylists = await _editorialPlaylistManager.GetEditorialPlaylistsAsync(null, onlyActive: false, lightWeight: true); var editorialPlaylistGroup = editorialPlaylists.GroupBy(p => p.SpotifyLink.ExtractPlaylistID()).ToList(); int totalCount = editorialPlaylistGroup.Count; await editorialPlaylistGroup.ItemIndex().ForEachAsync(2, async playlistGroup => { var index = playlistGroup.Index; _logger.Info("Getting playlist {0} of {1}", index, totalCount); var playlistId = playlistGroup.Item.Key; IEnumerable trackList = await _spotifyPlaylistManager.GetTrackListWithDataByIdAsync(playlistId); var artistList = GetArtistList(trackList); foreach(var editorialPlaylist in playlistGroup.Item) { var app = new Application() { ID = editorialPlaylist.ApplicationID }; List localGenres = null; if (artistList.Any()) { localGenres = await GetReweightedTagsAsync(app, artistList.Where(a => a.Match < 2.0).Select(a => a.Artist.Name).ToList()); } if (localGenres != null) { await _editorialPlaylistManager.SetEditorialPlaylistContentAsync(editorialPlaylist, localGenres); } } _logger.Info("Done with playlist {0} of {1}", index, totalCount); }); return null; } private async Task> GetReweightedTagsAsync(Application app, List artists) { var localArtists = artists.Distinct().Select(a => new Artist(a)).ToList(); var artistTags = await _playlistGenerationManager.GetArtistTagsAsync(app, localArtists); var genres = artists.Where(a => artistTags.ContainsKey(a)).SelectMany(a => artistTags[a]).Where(g => g.Weight > 0).GroupBy(g => g.Item.Name).Select(g => new GenreMatch(g.Key, (g.Sum(r => r.Weight) / artists.Count()))).Where(g => g.Score > 0).ToList(); return genres; } private static List GetArtistList(IEnumerable trackItems) { return trackItems.Where(t => t.Artists != null && t.Artists.Any()).SelectMany(t => t.Artists.ItemIndex()).Where(t => t?.Item != null).GroupBy(g => g.Item.Name) .Select(a => new SimilarArtistMatch(new Artist(a.Key), a.Min(ai => ai.Index) + 1)).ToList(); } } }