using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; using MoreLinq; using NLog; using Sony.Filtr.Buzz; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Core.EditorialPlaylists; using Sony.Filtr.DeezerAPI; using Sony.Filtr.ErrorLogging; using Sony.Filtr.Playlists.Deezer; using Sony.Filtr.Utility; using Sony.Filtr.Utility.Extensions; namespace Sony.Filtr.Tasks.Tasks.Deezer { public class DeezerFanLogTask : IScheduledTask { private readonly DeezerPlaylistManager _deezerPlaylistManager; private readonly DeezerApi _deezerApi; private readonly DeezerFanLogManager _deezerFanLogManager; private readonly BuzzAccountManager _buzzAccountManager; private readonly EditorialPlaylistImportManager _editorialPlaylistImportManager; private Logger _logger; public DeezerFanLogTask(DeezerPlaylistManager deezerPlaylistManager, DeezerApi deezerApi, DeezerFanLogManager deezerFanLogManager, BuzzAccountManager buzzAccountManager, EditorialPlaylistImportManager editorialPlaylistImportManager) { _deezerPlaylistManager = deezerPlaylistManager; _deezerApi = deezerApi; _deezerFanLogManager = deezerFanLogManager; _buzzAccountManager = buzzAccountManager; _editorialPlaylistImportManager = editorialPlaylistImportManager; _logger = NLog.LogManager.GetLogger("DeezerFanLogTask"); } public async Task ExecuteAsync(Guid scheduledTaskLogId) { ServicePointManager.DefaultConnectionLimit = 100; await FetchDeezerUserFans(); await FetchPlaylistFans(); _logger.Info("All done!"); return null; } private async Task> FetchDeezerUserFans() { ConcurrentBag deezerUserFanStats = new ConcurrentBag(); var deezerImportUsers = _editorialPlaylistImportManager.GetDeezerImportUsers(); _logger.Info("Found {0} deezer editorial playlist import users in database", deezerImportUsers.Count); var deezerBuzzUsers = await _buzzAccountManager.GetBuzzUsersAsync(musicServiceId: (int)MusicService.Deezer); var deezerBuzzUsersId = deezerBuzzUsers.Select(u => Maybe.ToLongOrDefault(u.Username)).FilterNull().ToList(); _logger.Info("Found {0} deezer buzz users in database", deezerBuzzUsers.Count()); var deezerBuzzUsersLookup = deezerBuzzUsers.ToDictionary(k => k.Username, v => v); var deezerUsers = deezerBuzzUsersId.Union(deezerImportUsers.Select(u => u.UserId)).Distinct().ToList(); //Don't get stats for users where we already have existing values for today. var existingFanStats = await _deezerFanLogManager.GetDeezerUserFansStatsAsync(DateTime.Today); var existingFanStatsUsers = existingFanStats.Where(p=> p.Fans != 0).Select(p => p.DeezerEntityId).Distinct().ToHashSet(); deezerUsers = deezerUsers.Where(u => !existingFanStatsUsers.Contains(u)).ToList(); await deezerUsers.ForEachAsync(10, async userId => { _logger.Debug("Fetching followers (fans) for user {0}", userId); try { var deezerUserFollowers = await _deezerApi.GetUserFollowersAsync(userId); deezerUserFanStats.Add(new DeezerFanStat { Date = DateTime.Today, DeezerEntityId = userId, Fans = deezerUserFollowers.total }); if (deezerBuzzUsersLookup.ContainsKey(userId.ToString())) { var user = await _deezerApi.GetUserAsync(userId); var buzzUser = deezerBuzzUsersLookup[userId.ToString()]; buzzUser.DisplayName = user.name; buzzUser.Subscribers = deezerUserFollowers?.total; buzzUser.Error = false; await _buzzAccountManager.UpdateBuzzUserAsync(buzzUser, new List() {"DisplayName", "Subscribers", "Error"}); } } catch (Exception ex) { _logger.Error(ex, "Could not get fans for user: {0}", userId); ErrorLoggingManager.Instance.LogError(ex); if (deezerBuzzUsersLookup.ContainsKey(userId.ToString())) { var buzzUser = deezerBuzzUsersLookup[userId.ToString()]; buzzUser.Error = true; await _buzzAccountManager.UpdateBuzzUserAsync(buzzUser, new List() { "Error" }); } } }); if (deezerUserFanStats.Any()) { _logger.Info("Saving stats for deezer users."); await _deezerFanLogManager.AddDeezerUserFansStatsAsync(deezerUserFanStats.ToList()); _logger.Info("Done saving stats for deezer users."); } else { _logger.Debug("No stats to save for deezer users."); } return deezerUserFanStats; } private async Task> FetchPlaylistFans() { var playlists = _deezerPlaylistManager.GetPlaylists(); _logger.Info("Found {0} deezer playlists in database", playlists.Count); //Don't get stats for playlists where we already have existing values for today. var existingFanStats = await _deezerFanLogManager.GetDeezerPlaylistFansStatsAsync(DateTime.Today); var existingFanStatsPlaylists = existingFanStats.Where(p => p.Fans != 0).Select(p => p.DeezerEntityId).Distinct().ToHashSet(); playlists = playlists.Where(u => !existingFanStatsPlaylists.Contains(u.DeezerId)).ToList(); ConcurrentBag deezerPlaylistFanStats = new ConcurrentBag(); await playlists.ForEachAsync(10, async playlist => { _logger.Debug("Fetching fans for playlist {0}", playlist.DeezerId); try { var deezerPlaylist = await _deezerApi.GetPlaylistAsync(playlist.DeezerId); if (deezerPlaylist != null) { deezerPlaylistFanStats.Add(new DeezerFanStat { Date = DateTime.Today, DeezerEntityId = playlist.DeezerId, Fans = deezerPlaylist.fans }); } } catch (Exception ex) { _logger.Error(ex, "Could not get fans for playlist: {0}", playlist.Title); ErrorLoggingManager.Instance.LogError(ex); } }); if (deezerPlaylistFanStats.Any()) { _logger.Info("Saving stats for deezer playlists."); await _deezerFanLogManager.AddDeezerPlaylistFansStatsAsync(deezerPlaylistFanStats.ToList()); _logger.Info("Done saving stats for deezer playlists."); } else { _logger.Debug("No stats to save for deezer playlists."); } return deezerPlaylistFanStats; } } }