public TimerService(DiscordShardedClient client, Logger.Logger logger, ILastfmApi lastfmApi) { this._logger = logger; this._lastfmApi = lastfmApi; this._client = client; this._lastFMService = new LastFMService(this._lastfmApi); this._userService = new UserService(); this._guildService = new GuildService(); this._timer = new Timer(async _ => { var random = new Random(); var randomAvatarMode = random.Next(1, 4); var randomAvatarModeDesc = ""; switch (randomAvatarMode) { case 1: randomAvatarModeDesc = "Recent listens"; break; case 2: randomAvatarModeDesc = "Weekly albums"; break; case 3: randomAvatarModeDesc = "Monthly albums"; break; case 4: randomAvatarModeDesc = "Overall albums"; break; } Log.Information($"Featured: Picked mode {randomAvatarMode} - {randomAvatarModeDesc}"); try { var lastFMUserName = await this._userService.GetRandomLastFMUserAsync(); Log.Information($"Featured: Picked user {lastFMUserName}"); switch (randomAvatarMode) { // Recent listens case 1: var tracks = await this._lastFMService.GetRecentScrobblesAsync(lastFMUserName, 25); var trackList = tracks .Select(s => new CensoredAlbum(s.ArtistName, s.AlbumName)) .Where(w => !string.IsNullOrEmpty(w.AlbumName) && !GlobalVars.CensoredAlbums.Select(s => s.ArtistName).Contains(w.ArtistName) && !GlobalVars.CensoredAlbums.Select(s => s.AlbumName).Contains(w.AlbumName)); var currentTrack = trackList.First(); var albumImages = await this._lastFMService.GetAlbumImagesAsync(currentTrack.ArtistName, currentTrack.AlbumName); this._trackString = $"{currentTrack.AlbumName} \n" + $"by {currentTrack.ArtistName} \n \n" + $"{randomAvatarModeDesc} from {lastFMUserName}"; Log.Information("Featured: Changing avatar to: " + this._trackString); if (albumImages?.Large != null) { ChangeToNewAvatar(client, albumImages.Large.AbsoluteUri); } else { Log.Information("Featured: Album had no image, switching to alternative avatar mode"); goto case 3; } break; // Weekly albums case 2: case 3: case 4: var timespan = LastStatsTimeSpan.Week; switch (randomAvatarMode) { case 3: timespan = LastStatsTimeSpan.Month; break; case 4: timespan = LastStatsTimeSpan.Overall; break; } var albums = await this._lastFMService.GetTopAlbumsAsync(lastFMUserName, timespan, 10); if (!albums.Any()) { Log.Information($"Featured: User {lastFMUserName} had no albums, switching to different user."); lastFMUserName = await this._userService.GetRandomLastFMUserAsync(); albums = await this._lastFMService.GetTopAlbumsAsync(lastFMUserName, timespan, 10); } var albumList = albums .Select(s => new CensoredAlbum(s.ArtistName, s.Name)) .Where(w => !GlobalVars.CensoredAlbums.Select(s => s.ArtistName).Contains(w.ArtistName) && !GlobalVars.CensoredAlbums.Select(s => s.AlbumName).Contains(w.AlbumName)) .ToList(); var albumFound = false; var i = 0; while (!albumFound) { var currentAlbum = albumList[i]; var albumImage = await this._lastFMService.GetAlbumImagesAsync(currentAlbum.ArtistName, currentAlbum.AlbumName); this._trackString = $"{currentAlbum.AlbumName} \n" + $"by {currentAlbum.ArtistName} \n \n" + $"{randomAvatarModeDesc} from {lastFMUserName}"; if (albumImage?.Large != null) { Log.Information($"Featured: Album {i} success, changing avatar to: \n" + $"{this._trackString}"); ChangeToNewAvatar(client, albumImage.Large.AbsoluteUri); albumFound = true; } else { Log.Information($"Featured: Album {i} had no image, switching to alternative album"); i++; } } break; } } catch (Exception e) { Log.Error("ChangeFeaturedAvatar", e); } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + ConfigData.Data.Bot.FeaturedTimerStartupDelayInSeconds), // 4) Time that message should fire after the timer is created TimeSpan.FromMinutes(ConfigData.Data.Bot.FeaturedTimerRepeatInMinutes)); // 5) Time after which message should repeat (use `Timeout.Infinite` for no repeat) this._internalStatsTimer = new Timer(async _ => { Log.Information("Updating metrics"); Statistics.DiscordServerCount.Set(client.Guilds.Count); try { Statistics.RegisteredUsers.Set(await this._userService.GetTotalUserCountAsync()); Statistics.RegisteredGuilds.Set(await this._guildService.GetTotalGuildCountAsync()); } catch (Exception e) { Console.WriteLine(e); } if (string.IsNullOrEmpty(ConfigData.Data.Bot.Status)) { Log.Information("Updating status"); await client.SetGameAsync($"{ConfigData.Data.Bot.Prefix} | {client.Guilds.Count} servers | fmbot.xyz"); } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + 5), TimeSpan.FromMinutes(2)); this._externalStatsTimer = new Timer(async _ => { if (client.CurrentUser.Id.Equals(Constants.BotProductionId) && ConfigData.Data.BotLists != null && !string.IsNullOrEmpty(ConfigData.Data.BotLists.TopGgApiToken)) { Log.Information("Updating top.gg server count"); var dblApi = new AuthDiscordBotListApi(Constants.BotProductionId, ConfigData.Data.BotLists.TopGgApiToken); try { var me = await dblApi.GetMeAsync(); await me.UpdateStatsAsync(client.Guilds.Count); } catch (Exception e) { Log.Error("Exception while updating top.gg count!", e); } } else { Log.Information("Non-production bot found or top.gg token not entered, cancelling top.gg server count updater"); this._externalStatsTimer.Change(Timeout.Infinite, Timeout.Infinite); } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + 10), TimeSpan.FromMinutes(5)); this._timerEnabled = true; }
public TimerService(DiscordShardedClient client, LastFMService lastFmService, IUpdateService updateService, UserService userService, IIndexService indexService) { this._client = client; this._lastFMService = lastFmService; this._userService = userService; this._indexService = indexService; this._guildService = new GuildService(); this._updateService = updateService; this._timer = new Timer(async _ => { var random = new Random(); var randomAvatarMode = random.Next(1, 4); var randomAvatarModeDesc = ""; switch (randomAvatarMode) { case 1: randomAvatarModeDesc = "Recent listens"; break; case 2: randomAvatarModeDesc = "Weekly albums"; break; case 3: randomAvatarModeDesc = "Monthly albums"; break; case 4: randomAvatarModeDesc = "Overall albums"; break; } Log.Information($"Featured: Picked mode {randomAvatarMode} - {randomAvatarModeDesc}"); try { var lastFMUserName = await this._userService.GetRandomLastFMUserAsync(); Log.Information($"Featured: Picked user {lastFMUserName}"); switch (randomAvatarMode) { // Recent listens case 1: var tracks = await this._lastFMService.GetRecentScrobblesAsync(lastFMUserName, 25); var trackList = tracks .Select(s => new CensoredAlbum(s.ArtistName, s.AlbumName)) .Where(w => !string.IsNullOrEmpty(w.AlbumName) && !GlobalVars.CensoredAlbums.Select(s => s.ArtistName).Contains(w.ArtistName) && !GlobalVars.CensoredAlbums.Select(s => s.AlbumName).Contains(w.AlbumName)); var currentTrack = trackList.First(); var albumImages = await this._lastFMService.GetAlbumImagesAsync(currentTrack.ArtistName, currentTrack.AlbumName); this._trackString = $"{currentTrack.AlbumName} \n" + $"by {currentTrack.ArtistName} \n \n" + $"{randomAvatarModeDesc} from {lastFMUserName}"; Log.Information("Featured: Changing avatar to: " + this._trackString); if (albumImages?.Large != null) { ChangeToNewAvatar(client, albumImages.Large.AbsoluteUri); } else { Log.Information("Featured: Album had no image, switching to alternative avatar mode"); goto case 3; } break; // Weekly albums case 2: case 3: case 4: var timespan = LastStatsTimeSpan.Week; switch (randomAvatarMode) { case 3: timespan = LastStatsTimeSpan.Month; break; case 4: timespan = LastStatsTimeSpan.Overall; break; } var albums = await this._lastFMService.GetTopAlbumsAsync(lastFMUserName, timespan, 10); if (!albums.Any()) { Log.Information($"Featured: User {lastFMUserName} had no albums, switching to different user."); lastFMUserName = await this._userService.GetRandomLastFMUserAsync(); albums = await this._lastFMService.GetTopAlbumsAsync(lastFMUserName, timespan, 10); } var albumList = albums .Select(s => new CensoredAlbum(s.ArtistName, s.Name)) .Where(w => !GlobalVars.CensoredAlbums.Select(s => s.ArtistName).Contains(w.ArtistName) && !GlobalVars.CensoredAlbums.Select(s => s.AlbumName).Contains(w.AlbumName)) .ToList(); var albumFound = false; var i = 0; while (!albumFound) { var currentAlbum = albumList[i]; var albumImage = await this._lastFMService.GetAlbumImagesAsync(currentAlbum.ArtistName, currentAlbum.AlbumName); this._trackString = $"{currentAlbum.AlbumName} \n" + $"by {currentAlbum.ArtistName} \n \n" + $"{randomAvatarModeDesc} from {lastFMUserName}"; if (albumImage?.Large != null) { Log.Information($"Featured: Album {i} success, changing avatar to: \n" + $"{this._trackString}"); ChangeToNewAvatar(client, albumImage.Large.AbsoluteUri); albumFound = true; } else { Log.Information($"Featured: Album {i} had no image, switching to alternative album"); i++; } } break; default: break; } } catch (Exception e) { Log.Error("ChangeFeaturedAvatar", e); } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + ConfigData.Data.Bot.FeaturedTimerStartupDelayInSeconds), // 4) Time that message should fire after the timer is created TimeSpan.FromMinutes(ConfigData.Data.Bot.FeaturedTimerRepeatInMinutes)); // 5) Time after which message should repeat (use `Timeout.Infinite` for no repeat) this._internalStatsTimer = new Timer(async _ => { Log.Information("Updating metrics"); Statistics.DiscordServerCount.Set(client.Guilds.Count); try { Statistics.RegisteredUsers.Set(await this._userService.GetTotalUserCountAsync()); Statistics.RegisteredGuilds.Set(await this._guildService.GetTotalGuildCountAsync()); } catch (Exception e) { Console.WriteLine(e); } if (string.IsNullOrEmpty(ConfigData.Data.Bot.Status)) { Log.Information("Updating status"); if (!PublicProperties.IssuesAtLastFM) { await client.SetGameAsync($"{ConfigData.Data.Bot.Prefix} | {client.Guilds.Count} servers | fmbot.xyz"); } else { await client.SetGameAsync($"⚠️ Last.fm is currently experiencing issues -> twitter.com/lastfmstatus"); } } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + 5), TimeSpan.FromMinutes(2)); this._externalStatsTimer = new Timer(async _ => { if (client.CurrentUser.Id.Equals(Constants.BotProductionId) && ConfigData.Data.BotLists != null && !string.IsNullOrEmpty(ConfigData.Data.BotLists.TopGgApiToken)) { Log.Information("Updating top.gg server count"); var dblApi = new AuthDiscordBotListApi(Constants.BotProductionId, ConfigData.Data.BotLists.TopGgApiToken); try { var me = await dblApi.GetMeAsync(); await me.UpdateStatsAsync(client.Guilds.Count); } catch (Exception e) { Log.Error("Exception while updating top.gg count!", e); } } else { Log.Information("Non-production bot found or top.gg token not entered, cancelling top.gg server count updater"); this._externalStatsTimer.Change(Timeout.Infinite, Timeout.Infinite); } }, null, TimeSpan.FromSeconds(ConfigData.Data.Bot.BotWarmupTimeInSeconds + 10), TimeSpan.FromMinutes(30)); this._userUpdateTimer = new Timer(async _ => { if (ConfigData.Data.LastFm.UserUpdateFrequencyInHours == null || ConfigData.Data.LastFm.UserUpdateFrequencyInHours == 0) { Log.Warning("No user update frequency set, cancelling user update timer"); this._userUpdateTimer.Change(Timeout.Infinite, Timeout.Infinite); return; } Log.Information("Getting users to update"); var timeToUpdate = DateTime.UtcNow.AddHours(-ConfigData.Data.LastFm.UserUpdateFrequencyInHours.Value); var usersToUpdate = await this._updateService.GetOutdatedUsers(timeToUpdate); Log.Information($"Found {usersToUpdate.Count} outdated users, adding them to queue"); this._updateService.AddUsersToUpdateQueue(usersToUpdate); }, null, TimeSpan.FromMinutes(5), TimeSpan.FromHours(4)); this._userIndexTimer = new Timer(async _ => { if (ConfigData.Data.LastFm.UserIndexFrequencyInDays == null || ConfigData.Data.LastFm.UserIndexFrequencyInDays == 0) { Log.Warning("No user index frequency set, cancelling user index timer"); this._userUpdateTimer.Change(Timeout.Infinite, Timeout.Infinite); return; } if (DateTime.UtcNow.Hour <= 11 || DateTime.UtcNow.Hour >= 14) { Log.Information("Skipping index timer - peak hours detected"); return; } Log.Information("Getting users to index"); var timeToIndex = DateTime.UtcNow.AddDays(-ConfigData.Data.LastFm.UserIndexFrequencyInDays.Value); var usersToUpdate = (await this._indexService.GetOutdatedUsers(timeToIndex)) .Take(400) .ToList(); Log.Information($"Found {usersToUpdate.Count} outdated users, adding them to index queue"); this._indexService.AddUsersToIndexQueue(usersToUpdate); }, null, TimeSpan.FromMinutes(5), TimeSpan.FromHours(1)); this._timerEnabled = true; }