using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AutoMapper; using Sony.Filtr.AdminAPI.ViewModels.PlaylistCuration; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Core.EditorialPlaylists; using Sony.Filtr.SpotifyAnalytics; using Sony.Filtr.Utility.Extensions; namespace Sony.Filtr.AdminAPI.ViewModels { public class EditorialPlaylistViewModelHelper { private readonly EditorialPlaylistManager _editorialPlaylistManager; private readonly SpotifyAnalyticsManager _spotifyAnalyticsManager; public EditorialPlaylistViewModelHelper(EditorialPlaylistManager editorialPlaylistManager, SpotifyAnalyticsManager spotifyAnalyticsManager) { _editorialPlaylistManager = editorialPlaylistManager; _spotifyAnalyticsManager = spotifyAnalyticsManager; } private EditorialPlaylistViewModel SetPlaylistViewModelAttributes(EditorialPlaylistViewModel viewModel, EditorialPlaylistAttributes attributes) { //TODO: Mapping, or expose entire attribute object? if (attributes != null) { if (attributes.Followers.HasValue) viewModel.Subscribers = (uint)attributes.Followers; if (attributes.LastFollowers.HasValue) viewModel.PreviousSubscribers = (uint)attributes.LastFollowers; if (attributes.TrackDuration.HasValue) viewModel.TrackDuration = (int)attributes.TrackDuration; if (attributes.TrackCount.HasValue) viewModel.TracksCount = (int)attributes.TrackCount.Value; if (attributes.TracksAddedThisWeek.HasValue) viewModel.TracksAddedInWeek = (int)attributes.TracksAddedThisWeek.Value; if (attributes.TracksAddedToday.HasValue) viewModel.TracksAddedToday = (int)attributes.TracksAddedToday.Value; if (attributes.Changed.HasValue) viewModel.TracksLastAdded = attributes.Changed.Value.ToString("O"); if (attributes.FollowerChange7.HasValue) viewModel.FollowerChange7 = attributes.FollowerChange7; if (attributes.FollowerChange15.HasValue) viewModel.FollowerChange15 = attributes.FollowerChange15; if (attributes.FollowerChange30.HasValue) viewModel.FollowerChange30 = attributes.FollowerChange30; if (attributes.SonyPercentage.HasValue) viewModel.SonyPercentage = attributes.SonyPercentage; if (attributes.Energy.HasValue) viewModel.Energy = attributes.Energy; if (attributes.Hotness.HasValue) viewModel.Hotness = attributes.Hotness; if (attributes.Tempo.HasValue) viewModel.Tempo = attributes.Tempo; } return viewModel; } private EditorialPlaylistViewModel BuildPlaylistViewModel(EditorialPlaylist playlist) { var viewModel = Mapper.Map(playlist); if (playlist.Genres != null) viewModel.Tags = playlist.Genres.Select(g => g.Genre).Take(3); if (playlist.Artists != null) viewModel.Artists = playlist.Artists.Where(a => Math.Abs(a.Match - 1) < 0.1).Select(a => a.Artist.Name).Take(5); return viewModel; } public async Task GetExtendedPlaylistInfoAsync(EditorialPlaylist playlist) { var viewModels = await GetExtendedPlaylistInfoAsync(playlist.AsEnumerable().ToList()); return viewModels.First(); } public async Task> GetExtendedPlaylistInfoAsync(IEnumerable playlists, bool loadAttributes = true) { var viewModels = playlists.Select(p => BuildPlaylistViewModel(p)).ToList(); if (loadAttributes) { await FillAttributeValuesAsync(viewModels); } return viewModels; } private async Task FillAttributeValuesAsync(List viewModels) { if (!viewModels.Any()) return; var playlistUris = GetPlaylistUris(viewModels); var playlistAttributes = await _editorialPlaylistManager.GetPlaylistAttributesAsync(playlistUris.Select(p=> p.Uri)); var playlistAttributesDic = playlistAttributes.ToDictionary(k => k.Key, v => v.Value); foreach(var viewModel in viewModels) { var attributes = playlistAttributesDic.GetValueOrDefault(viewModel.SpotifyLink); if (attributes != null) { SetPlaylistViewModelAttributes(viewModel, attributes); } } } private List GetPlaylistUris(List viewModels) { return viewModels.Select(p => new SpotifyLink(p.SpotifyLink)).Distinct().ToList(); } private List GetPlaylistIds(List viewModels) { return viewModels.Select(p => new SpotifyLink(p.SpotifyLink).ExtractPlaylistID()).Distinct().ToList(); } public async Task FillStreamsAsync(List viewModels, string localStreamsCountryCode) { if (!viewModels.Any()) return; var playlistIds = GetPlaylistIds(viewModels); var analyticsData = await _spotifyAnalyticsManager.GetPlaylistsStreamSummaryAsync(playlistIds); var analyticsDic = analyticsData.GroupBy(p => p.PlaylistId).ToDictionary(k => k.Key, v => v); foreach(var viewModel in viewModels) { var playlistId = new SpotifyLink(viewModel.SpotifyLink).ExtractPlaylistID(); var anlyticsDataForPlaylist = analyticsDic.GetValueOrDefault(playlistId); if (anlyticsDataForPlaylist != null) { viewModel.GlobalUsers28days = anlyticsDataForPlaylist.Sum(p => p.Listeners28days); viewModel.GlobalUsers7days = anlyticsDataForPlaylist.Sum(p => p.Listeners7days); viewModel.GlobalUsersLatest = anlyticsDataForPlaylist.Sum(p => p.ListenersLatest); viewModel.GlobalStreams28days = anlyticsDataForPlaylist.Sum(p => p.Streams28days); viewModel.GlobalStreams7days = anlyticsDataForPlaylist.Sum(p => p.Streams7days); viewModel.GlobalStreamsLatest = anlyticsDataForPlaylist.Sum(p => p.StreamsLatest); viewModel.LatestStreamsDate = anlyticsDataForPlaylist.Max(p => p.LatestDate); if (!string.IsNullOrWhiteSpace(localStreamsCountryCode)) { var localAnalytics = anlyticsDataForPlaylist.FirstOrDefault(p => p.Market == localStreamsCountryCode); if (localAnalytics != null) { viewModel.LocalUsers28days = localAnalytics.Listeners28days; viewModel.LocalUsers7days = localAnalytics.Listeners7days; viewModel.LocalUsersLatest = localAnalytics.ListenersLatest; viewModel.LocalStreams28days = localAnalytics.Streams28days; viewModel.LocalStreams7days = localAnalytics.Streams7days; viewModel.LocalStreamsLatest = localAnalytics.StreamsLatest; } } } } } } }