using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MoreLinq; using Nancy; using Sony.Filtr.AdminAPI.ViewModels.AppleMusic.Chart; using Sony.Filtr.AppleMusic; using Sony.Filtr.AppleMusic.Data; using Sony.Filtr.Contracts.Abstractions; using Sony.Filtr.Utility; using Sony.Filtr.Utility.Extensions; namespace Sony.Filtr.AdminAPI.Modules.AppleMusic { public class AppleMusicChartsModule : BaseModule { private readonly AppleMusicChartManager _chartManager; private readonly AppleMusicSongManager _songManager; public AppleMusicChartsModule(IApplicationInstanceManager applicationInstanceManager, AppleMusicChartManager chartManager, AppleMusicSongManager songManager) : base(applicationInstanceManager) { _chartManager = chartManager; _songManager = songManager; Get["AppleMusicChartsForTrack", "/AppleMusic/Charts/TrackSummary", true] = async (parameters, cx) => { string isrc = (string)Request.Query.isrc; var marketSummaries = await GetChartSummaryForTrackAsync(isrc); FixPositionIndexing(marketSummaries); FixDateShift(marketSummaries); return Response.AsJson(marketSummaries); }; Get["AppleMusicAvailableCharts", "/AppleMusic/Charts/AvailableCharts", true] = async (parameters, cx) => { ChartsFilter chartsFilter = new ChartsFilter { Storefront = ReadStorefrontFromRequest(), Date = Maybe.ToDateTimeOrDefault((string)Request.Query.date), ChartType = Maybe.ToEnumOrDefault((string)Request.Query.chartType), ChartName = (string)Request.Query.chartname }; var genreId = (string)Request.Query.genreId; chartsFilter.GenreIsNull = string.Equals(genreId, "null", StringComparison.InvariantCultureIgnoreCase); chartsFilter.GenreId = Maybe.ToIntOrDefault(genreId); var charts = chartManager.GetCharts(chartsFilter); var chartsViewModel = charts.Select(p => AutoMapper.Mapper.Map(p)); return Response.AsJson(chartsViewModel); }; Get["AppleMusicChartGenres", "/AppleMusic/Charts/Genres", true] = async (parameters, cx) => { var storefront = ReadStorefrontFromRequest(); var genres = chartManager.GetChartGenres(storefront); return Response.AsJson(genres); }; Get["AppleMusicChartEntriesById", "/AppleMusic/Charts/{chartId}", true] = async (parameters, cx) => { var chartId = (int?)parameters.chartId; if (!chartId.HasValue) return HttpStatusCode.BadRequest; var chart = chartManager.GetChart(chartId.Value); if (chart == null) return HttpStatusCode.NotFound; IEnumerable chartEntries = new List(); if (chart.ChartType == ChartType.Albums) { chartEntries = GetAlbumChartEntries(chart); } else if (chart.ChartType == ChartType.MusicVideos) { chartEntries = GetMusicVideoChart(chart); } else if (chart.ChartType == ChartType.Songs) { chartEntries = await GetSongChartEntriesAsync(chart); } else if (chart.ChartType == ChartType.PlaylistBased) { chartEntries = await GetSongChartEntriesAsync(chart); } var viewModel = new AppleMusicChartDataViewModel() { GenreId = chart.GenreId, Date = chart.Date, Chartname = chart.Chartname, Charttype = chart.ChartType, Country = chart.Storefront, Id = chart.Id, Timestamp = chart.Timestamp, ChartPositions = chartEntries, }; return Response.AsJson(viewModel); }; Get["AppleMusicLatestMostPlayedSongChart", "/AppleMusic/Charts/LatestMostPlayedSongChart", true] = async (parameters, cx) => { var storefront = ReadStorefrontFromRequest(); var mostPlayedSongChartEntries = chartManager.GetMostPlayedSongChartEntries(storefront); var songIds = mostPlayedSongChartEntries.Select(s => s.SongId).Distinct().ToList(); var isrcs = await songManager.GetISRCAsync(storefront, songIds); var songViewModels = mostPlayedSongChartEntries.Select(s => new AppleMusicChartSongMostPlayedSongEntryViewModel() { TrackName = s.Name, Position = s.Position + 1, Isrc = isrcs.GetValueOrDefault(s.SongId), SongId = s.SongId, ArtistName = s.ArtistName, Date = s.Date, Country = s.Storefront }); return Response.AsJson(songViewModels); }; } private List GetAlbumChartEntries(AppleMusicChart chart) { var chartEntries = _chartManager.GetAlbumChartEntries(chart.Id); chartEntries.ForEach(p => p.Position++); return chartEntries; } private List GetMusicVideoChart(AppleMusicChart chart) { var chartEntries = _chartManager.GetMusicVideoChartEntries(chart.Id); chartEntries.ForEach(p => p.Position++); return chartEntries; } private async Task> GetSongChartEntriesAsync(AppleMusicChart chart) { var songEntries = _chartManager.GetSongChartEntries(chart.Id); var songIds = songEntries.Select(p => p.SongId).ToList(); var fullSongs = await _songManager.GetSongsAsync(chart.Storefront, songIds); var fullSongDic = fullSongs.ToDictionary(k => k.Id, v => v); var comparisonChart = _chartManager.GetChart(chart.Storefront, chart.ChartType, chart.Chartname, chart.GenreId, chart.Date.AddDays(-7)); List comparisonSongEntries = new List(); if (comparisonChart != null) { comparisonSongEntries = _chartManager.GetSongChartEntries(comparisonChart.Id); } var chartEntries = songEntries.Select(s => BuildAppleMusicChartSongEntryViewModel(s, fullSongDic.GetValueOrDefault(s.SongId), comparisonSongEntries)).ToList(); return chartEntries; } private AppleMusicChartSongEntryViewModel BuildAppleMusicChartSongEntryViewModel(AppleMusicChartSongEntry songEntry, AppleMusicFullSong fullSong, List comparisonTrackChartPosition) { var comparison = comparisonTrackChartPosition.FirstOrDefault(c => c.SongId == songEntry.SongId || c.ISRC == songEntry.ISRC); return new AppleMusicChartSongEntryViewModel() { SongId = songEntry.SongId, TrackName = songEntry.Name, ArtistName = songEntry.ArtistName, Isrc = songEntry.ISRC, Artists = fullSong?.Artists, ArtworkUrl = fullSong?.ArtworkUrl, Position = songEntry.Position + 1, ComparisonPosition = comparison?.Position + 1, }; } private string ReadStorefrontFromRequest() { var storefront = (string)Request.Query.storefront ?? (string)Request.Query.country ?? (string)Request.Query.countryCode ?? (string)Request.Query.market; return storefront; } private async Task>> GetChartSummaryForTrackAsync(string isrc) { var availableCharts = await _chartManager.GetAvailableChartsOverviewAsync(ChartType.PlaylistBased, "track_chart_playlist"); var availableOldCharts = await _chartManager.GetAvailableChartsOverviewAsync(ChartType.Songs, "most-played"); var trackSummary = await _chartManager.GetTrackChartSummaryAsync(isrc); var charts = availableCharts.Union(availableOldCharts.ExceptBy(availableCharts, chart => new { chart.Storefront })); return charts.OrderBy(p => p.Storefront) .Join(trackSummary, overview => overview.Storefront, summary => summary.Storefront, (overview, summary) => new { Key = overview.Storefront, Value = summary }) .ToDictionary(k => k.Key, v => BuildAppleMusicTrackChartSummaryViewModels(v.Value)); } private static List BuildAppleMusicTrackChartSummaryViewModels(AppleMusicTrackChartSummary trackChartSummary) { var value = AutoMapper.Mapper.Map(trackChartSummary); value.LatestUpdateTimestamp = DateTime.SpecifyKind(value.LatestUpdateTimestamp, DateTimeKind.Utc); return new List() { value }; } private static Dictionary> FixPositionIndexing(Dictionary> marketSummaries) { foreach (var marketSummary in marketSummaries) { foreach (var appleMusicTrackChartSummary in marketSummary.Value) { appleMusicTrackChartSummary.CurrentPosition += 1; appleMusicTrackChartSummary.EntryPosition += 1; appleMusicTrackChartSummary.LatestPosition += 1; appleMusicTrackChartSummary.PeakPosition += 1; appleMusicTrackChartSummary.PreviousPosition += 1; } } return marketSummaries; } private static Dictionary> FixDateShift(Dictionary> marketSummaries) { foreach (var marketSummary in marketSummaries) { foreach (var appleMusicTrackChartSummary in marketSummary.Value) { if (appleMusicTrackChartSummary.EntryDate.HasValue) { appleMusicTrackChartSummary.EntryDate = appleMusicTrackChartSummary.EntryDate.Value.AddDays(-1); } if (appleMusicTrackChartSummary.LatestDate.HasValue) { appleMusicTrackChartSummary.LatestDate = appleMusicTrackChartSummary.LatestDate.Value.AddDays(-1); } if (appleMusicTrackChartSummary.PeakDate.HasValue) { appleMusicTrackChartSummary.PeakDate = appleMusicTrackChartSummary.PeakDate.Value.AddDays(-1); } if (appleMusicTrackChartSummary.PeakLatestDate.HasValue) { appleMusicTrackChartSummary.PeakLatestDate = appleMusicTrackChartSummary.PeakLatestDate.Value.AddDays(-1); } if (appleMusicTrackChartSummary.LatestUpdateDate.HasValue) { appleMusicTrackChartSummary.LatestUpdateDate = appleMusicTrackChartSummary.LatestUpdateDate.Value.AddDays(-1); } appleMusicTrackChartSummary.LatestUpdateTimestamp = appleMusicTrackChartSummary.LatestUpdateTimestamp.AddDays(-1); } } return marketSummaries; } } public class AppleMusicChartSongEntryViewModel : IAppleMusicChartEntry { public int Position { get; set; } public long SongId { get; set; } public string TrackName { get; set; } public string ArtistName { get; set; } public string Isrc { get; set; } public int? ComparisonPosition { get; set; } public List Artists { get; set; } public string ArtworkUrl { get; set; } } public class AppleMusicChartSongMostPlayedSongEntryViewModel { public string Isrc { get; set; } public int Position { get; set; } public long SongId { get; set; } public string ArtistName { get; set; } public string TrackName { get; set; } public DateTime Date { get; set; } public string Country { get; set; } } }