public async Task ShowLeaderboard() { using (Context.Channel.EnterTypingState()) { try { _logger.LogInformation("Executing leaderboard command"); var start = DateTime.Now.AddDays(-7); var groupedActivitiesByParticipant = new Dictionary <LeaderboardParticipant, List <DetailedActivity> >(); var participants = await _participantService.GetAllParticipantsForServerAsync(Context.Guild.Id.ToString()); foreach (var participant in participants) { try { groupedActivitiesByParticipant.Add(participant, await _stravaService.FetchActivitiesForParticipant(participant, start)); } catch (StravaException e) when(e.Error == StravaException.StravaErrorType.RefreshFailed) { await AskToRelogin(participant.DiscordUserId); } } var realRideCategoryResult = _leaderboardResultService.GetTopResultsForCategory( groupedActivitiesByParticipant, Constants.LeaderboardRideType.RealRide, x => x.Type == Constants.LeaderboardRideType.RealRide); await ReplyAsync(embed : _embedBuilderService .BuildLeaderboardEmbed( realRideCategoryResult, start, DateTime.Now ) ); var virtualRideCategoryResult = _leaderboardResultService.GetTopResultsForCategory( groupedActivitiesByParticipant, Constants.LeaderboardRideType.VirtualRide, x => x.Type == Constants.LeaderboardRideType.VirtualRide); await ReplyAsync(embed : _embedBuilderService .BuildLeaderboardEmbed( virtualRideCategoryResult, start, DateTime.Now ) ); } catch (Exception e) { _logger.LogError(e, "leaderboard failed"); } } }
public async Task GenerateForServer(IMessageChannel replyChannel, string serverId, DateTime start, bool grantWinnerRole, params ICategory[] categories) { _logger.LogInformation("Executing leaderboard command"); if (grantWinnerRole) { await _roleService.RemoveRoleFromAllInServer(serverId, Constants.LeaderboardWinnerRoleName); } var participantsWithActivities = new List <ParticipantWithActivities>(); var participants = _participantService.GetAllParticipantsForServerAsync(serverId); foreach (var participant in participants) { var(policy, context) = _stravaAuthenticationService.GetUnauthorizedPolicy(participant.StravaId); try { var activities = await policy.ExecuteAsync(x => _activitiesService.GetForStravaUser(participant.StravaId, start), context); participantsWithActivities.Add(new ParticipantWithActivities { Participant = participant, Activities = activities }); } catch (Exception e) { _logger.LogWarning(e, $"Failed to fetch activities for {participant.DiscordUserId}, excluding participant from leaderboard"); } } var categoryResults = new List <CategoryResult>(); foreach (var category in categories) { var categoryResult = GetTopResultsForCategory(participantsWithActivities, category); await replyChannel.SendMessageAsync(embed : _embedBuilderService .BuildLeaderboardEmbed( categoryResult, start, DateTime.Now ) ); categoryResults.Add(categoryResult); } if (grantWinnerRole) { var winners = new List <ParticipantResult>(); foreach (var subCategoryResult in categoryResults.SelectMany(categoryResult => categoryResult.SubCategoryResults)) { winners.AddRange(subCategoryResult.OrderedParticipantResults.Take(3)); } await GrantWinnerRoles(serverId, winners); } }
public async Task RemoveRoleFromAllParticipantsInServer(string serverId, string roleName) { var server = _discordSocketClient.GetGuild(ulong.Parse(serverId)); var role = server?.Roles.FirstOrDefault(x => x.Name == roleName); if (role == null) { _logger.LogWarning($"Role '{roleName}' not found in server '{serverId}'"); return; } var participants = await _participantService.GetAllParticipantsForServerAsync(serverId); foreach (var participant in participants) { _logger.LogInformation($"Removing role from {participant?.DiscordUserId}"); try { var user = server.GetUser(ulong.Parse(participant?.DiscordUserId)); await user.RemoveRoleAsync(role); } catch (Exception e) { _logger.LogError(e, $"Failed to remove role from {participant?.DiscordUserId} in server {serverId}"); } } }
public async Task RemoveRoleFromAllInServer(string serverId, string roleName) { var server = _discordSocketClient.GetGuild(serverId); if (!server.TryGetRole(roleName, out var role)) { _logger.LogWarning($"Role '{roleName}' not found in server '{serverId}'"); return; } var participants = _participantService.GetAllParticipantsForServerAsync(serverId); foreach (var participant in participants) { _logger.LogInformation($"Removing role from {participant?.DiscordUserId}"); if (server.TryGetUser(participant?.DiscordUserId, out var user)) { await user.TryRemoveRoleAsync(role); } else { _logger.LogError($"Failed ot find {participant?.DiscordUserId} user"); } } }
public async Task UserCount() { using (Context.Channel.EnterTypingState()) { try { var users = _participantService.GetAllParticipantsForServerAsync(Context.Guild.Id.ToString()); await ReplyAsync($"Server has {users.Count} leaderboard participants"); } catch (Exception e) { _logger.LogError(e, $"Failed to prune users"); await ReplyAsync($"Failed - {e.Message}"); } } }
public async Task ListLeaderboardParticipants() { using (Context.Channel.EnterTypingState()) { try { _logger.LogInformation("Executing list"); var embeds = new List <Embed>(); var participants = _participantService.GetAllParticipantsForServerAsync(Context.Guild.Id.ToString()); foreach (var participant in participants) { var(policy, context) = _stravaAuthenticationService.GetUnauthorizedPolicy(participant.StravaId); try { var athlete = await policy.ExecuteAsync(x => _athleteService.Get(participant.StravaId), context); embeds.Add(_embedBuilderService.BuildAthleteInfoEmbed(participant, athlete)); } catch (ApiException e) { _logger.LogWarning(e, $"Failed to fetch athlete info for {participant.DiscordUserId}"); } } if (!embeds.Any()) { embeds.Add( new EmbedBuilder() .WithTitle("No participants found") .WithCurrentTimestamp() .Build() ); } foreach (var embed in embeds) { await ReplyAsync(embed : embed); } } catch (Exception e) { _logger.LogError(e, "list failed"); } } }
public override async Task DoWork(CancellationToken cancellationToken) { _logger.LogInformation("Executing leaderboard hosted service"); foreach (var leaderboard in await _leaderboardService.GetAllLeaderboards()) { try { _logger.LogInformation("Removing role from all users"); await _roleService.RemoveRoleFromAllParticipantsInServer(leaderboard.ServerId, Constants.LeaderboardWinnerRoleName); } catch (Exception e) { _logger.LogError(e, $"Failed to remove leaderboard role from all users in '{leaderboard.ServerId}'"); } var start = DateTime.Now.AddDays(-7); var groupedActivitiesByParticipant = new Dictionary <LeaderboardParticipant, List <DetailedActivity> >(); var participants = await _participantService.GetAllParticipantsForServerAsync(leaderboard.ServerId); foreach (var participant in participants) { try { groupedActivitiesByParticipant.Add(participant, await _stravaService.FetchActivitiesForParticipant(participant, start)); } catch (StravaException e) when(e.Error == StravaException.StravaErrorType.RefreshFailed) { await AskToRelogin(participant.DiscordUserId); } } var channel = _discordSocketClient.GetChannel(ulong.Parse(leaderboard.ChannelId)) as SocketTextChannel; var realRideCategoryResult = _leaderboardResultService.GetTopResultsForCategory( groupedActivitiesByParticipant, Constants.LeaderboardRideType.RealRide, x => x.Type == Constants.LeaderboardRideType.RealRide); await channel.SendMessageAsync(embed : _embedBuilderService .BuildLeaderboardEmbed(realRideCategoryResult, start, DateTime.Now)); var virtualRideCategoryResult = _leaderboardResultService.GetTopResultsForCategory( groupedActivitiesByParticipant, Constants.LeaderboardRideType.VirtualRide, x => x.Type == Constants.LeaderboardRideType.VirtualRide); await channel.SendMessageAsync(embed : _embedBuilderService .BuildLeaderboardEmbed( virtualRideCategoryResult, start, DateTime.Now ) ); var allParticipantResults = realRideCategoryResult.ChallengeByChallengeResultDictionary.SelectMany(x => x.Value).Union( virtualRideCategoryResult .ChallengeByChallengeResultDictionary.SelectMany(x => x.Value)); foreach (var participantResult in allParticipantResults) { try { await _roleService.GrantUserRoleIfExists(leaderboard.ServerId, participantResult.Participant.DiscordUserId, Constants.LeaderboardWinnerRoleName); } catch (Exception e) { _logger.LogError(e, $"Failed to grant leaderboard role for '{participantResult.Participant.DiscordUserId}'"); } } } }