using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MoreLinq; using NLog; using Sony.Filtr.Contracts.Abstractions; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Core.Releases; using Sony.Filtr.Core.Settings; using Sony.Filtr.DeezerAPI; using Sony.Filtr.DeezerAPI.Model; using Sony.Filtr.ErrorLogging; using Sony.Filtr.PlaylistGeneration.MusicInfoStore; using Sony.Filtr.Utility.Extensions; namespace Sony.Filtr.Tasks.Tasks.PublicApi { public class UpdateDeezerReleasesTask : IScheduledTask { private readonly IApplicationInstanceManager _applicationInstanceManager; private readonly DeezerApi _deezerApi; private readonly SettingsManager _settingsManager; private readonly DeezerReleaseManager _deezerReleaseManager; private readonly ISearchManager _searchManager; private readonly Logger _logger; public UpdateDeezerReleasesTask(IApplicationInstanceManager applicationInstanceManager, DeezerApi deezerApi, SettingsManager settingsManager, DeezerReleaseManager deezerReleaseManager, ISearchManager searchManager) { _applicationInstanceManager = applicationInstanceManager; _deezerApi = deezerApi; _settingsManager = settingsManager; _deezerReleaseManager = deezerReleaseManager; _searchManager = searchManager; _logger = LogManager.GetLogger("DeezerReleases"); } public async Task ExecuteAsync(Guid scheduledTaskLogId) { var applications = _applicationInstanceManager.GetApplications(); ConcurrentBag allDeezerReleases = new ConcurrentBag(); ConcurrentBag allRemovedReleases = new ConcurrentBag(); await applications.ForEachAsync(5, async application => { try { List releases = new List(); var albumPlaylistId = _settingsManager.GetIntSetting("DeezerReleaseAlbumPlaylistId", application); var singleId = _settingsManager.GetIntSetting("DeezerReleaseSinglePlaylistId", application); if (albumPlaylistId == default(int) && singleId == default(int)) { _logger.Debug("No playlists configured for {0}", application.Name); } _logger.Info("Getting releases for {0}", application.Name); if (albumPlaylistId != 0) { _logger.Info("Getting tracks from album playlist {0}", albumPlaylistId); var albumPlaylist = await _deezerApi.GetPlaylistAsync(albumPlaylistId); if (albumPlaylist != null && albumPlaylist.tracks != null) { var albumReleases = await BuildReleasesAsync(albumPlaylist, ReleaseType.Album, application.ID); _logger.Info("Found {0} single releases for {1}", albumReleases.Count, application.Name); releases.AddRange(albumReleases); } else { _logger.Warn("Could not get album playlist {0}", albumPlaylistId); } } if (singleId != 0) { _logger.Info("Getting tracks from single playlist {0}", singleId); var singlePlaylist = await _deezerApi.GetPlaylistAsync(singleId); if (singlePlaylist != null && singlePlaylist.tracks != null) { var singleReleases = await BuildReleasesAsync(singlePlaylist, ReleaseType.Single, application.ID); _logger.Info("Found {0} single releases for {1}", singleReleases.Count, application.Name); releases.AddRange(singleReleases); } else { _logger.Warn("Could not get single playlist {0}", albumPlaylistId); } } var existingReleases = _deezerReleaseManager.GetReleases(application); var removedReleases = existingReleases.ExceptBy(releases, release => release.ID); _logger.Info("Storing releases for {0}", application.Name); _deezerReleaseManager.SetReleases(application, releases); releases.ForEach(r=> allDeezerReleases.Add(r)); removedReleases.ForEach(r => allRemovedReleases.Add(r)); _logger.Info("Done getting releases for {0}", application.Name); } catch (Exception ex) { ErrorLoggingManager.Instance.LogError(ex); _logger.Error("Error getting releases for {0}: {1}", application.Name, ex.ToString()); } }); _logger.Info("Indexing deezer releases"); if (allRemovedReleases.Any()) await _searchManager.DeleteDeezerReleasesAsync(allRemovedReleases.ToList()); if (allDeezerReleases.Any()) await _searchManager.IndexDeezerReleasesAsync(allDeezerReleases.ToList()); _logger.Info("All done with deezer releases"); return null; } private async Task> BuildReleasesAsync(PlaylistResponse albumPlaylist, ReleaseType releaseType, int applicationId) { List releases = new List(); var tracks = albumPlaylist.tracks.data.DistinctBy(t => t.album.id).ToList(); if (!tracks.Any()) { return releases; } foreach (var track in tracks) { var release = new DeezerRelease() { ApplicationID = applicationId, ReleaseType = releaseType, AlbumID = track.album.id, AlbumName = track.album.title, TrackId = track.id.ToString(), //TODO: Change database type TrackName = track.title, ArtistName = track.artist.name, ArtistId = track.artist.id, ImageFilename = track.album.cover, }; releases.Add(release); } return releases; } } }