Ejemplo n.º 1
0
        public async Task <List <DetailedActivity> > FetchActivitiesForParticipant(LeaderboardParticipant participant,
                                                                                   DateTime after)
        {
            StravaCredential credential = null;

            try
            {
                credential = await GetCredentialsForParticipant(participant);

                return(await _stravaApiService.FetchActivities(credential.AccessToken, after)
                       .ConfigureAwait(false));
            }
            catch (StravaException e) when(e.Error == StravaException.StravaErrorType.Unauthorized)
            {
                _logger.LogInformation($"Refresh token expired, refreshing");
                try
                {
                    credential = await RefreshCredentialsForParticipant(participant)
                                 .ConfigureAwait(false);

                    return(await _stravaApiService
                           .FetchActivities(credential.AccessToken, after)
                           .ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to refresh participant while fetching activies");
                    throw new StravaException(StravaException.StravaErrorType.RefreshFailed);
                }
            }
        }
        public Embed BuildParticipantStatsForCategoryEmbed(LeaderboardParticipant participant,
                                                           List <DetailedActivity> activities, string type, DateTime start,
                                                           DateTime end)
        {
            var categoryResult = _leaderboardResultService.GetTopResultsForCategory(
                new Dictionary <LeaderboardParticipant, List <DetailedActivity> > {
                { participant, activities }
            },
                type,
                x => x.Type == type);

            var embedBuilder = new EmbedBuilder()
                               .WithTitle(
                $"'{type}' stats for '{start:yyyy MMMM dd} - {end:yyyy MMMM dd}'")
                               .WithCurrentTimestamp()
                               .WithColor(Color.Gold);

            if (!categoryResult.ChallengeByChallengeResultDictionary.Any())
            {
                embedBuilder.WithDescription("Something went wrong");
                return(embedBuilder.Build());
            }

            foreach (var(categoryName, participantResults) in categoryResult.ChallengeByChallengeResultDictionary)
            {
                foreach (var participantResult in participantResults)
                {
                    embedBuilder.AddField(categoryName,
                                          OutputFormatters.ParticipantResultForChallenge(categoryName, participantResult.Value), true);
                }
            }

            return(embedBuilder.Build());
        }
Ejemplo n.º 3
0
        public IEnumerable <Embed> BuildDetailedAthleteEmbeds(LeaderboardParticipant participant,
                                                              DetailedAthlete athlete)
        {
            var results = new List <Embed>();

            var embedBuilder = new EmbedBuilder()
                               .WithCurrentTimestamp();

            if (participant == null)
            {
                results.Add(embedBuilder
                            .WithTitle("Participant Not Found")
                            .Build());
                return(results);
            }

            embedBuilder.WithTitle($"Leaderboard participant's profile");
            var embedFieldsAdded = 0;

            embedBuilder
            .AddField(efb => efb.WithName("Discord Id")
                      .WithValue(participant.DiscordUserId)
                      .WithIsInline(true));
            embedFieldsAdded++;
            foreach (var propertyInfo in athlete.GetType().GetProperties())
            {
                if (string.IsNullOrEmpty(propertyInfo.Name) || StravaPropertyBlacklist.Contains(propertyInfo.Name))
                {
                    continue;
                }

                var value = propertyInfo.GetValue(athlete)?.ToString();
                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }

                embedBuilder
                .AddField(efb => efb.WithName(propertyInfo.Name ?? "N/A")
                          .WithValue(value)
                          .WithIsInline(true));
                embedFieldsAdded++;
            }

            if (embedFieldsAdded >= 25)
            {
                results.Add(embedBuilder.Build());
                embedBuilder = new EmbedBuilder().WithCurrentTimestamp()
                               .WithTitle($"Detailed Info - {participant.DiscordUserId} - CONTINUED");
            }

            if (embedBuilder.Fields.Count > 0)
            {
                results.Add(embedBuilder.Build());
            }

            return(results);
        }
Ejemplo n.º 4
0
 public async Task Remove(LeaderboardParticipant participant, StravaCredential credentials = null)
 {
     _dbContext.Participants.Remove(participant);
     if (credentials != null)
     {
         _dbContext.Credentials.Remove(credentials);
     }
     await _dbContext.SaveChangesAsync();
 }
Ejemplo n.º 5
0
        public Task <StravaCredential> GetCredentialsForParticipant(LeaderboardParticipant participant)
        {
            if (participant == null)
            {
                throw new ArgumentNullException(nameof(participant));
            }

            return(_dbContext.Credentials.FirstOrDefaultAsync(x => x.StravaId == participant.StravaId));
        }
        public ParticipantResult CalculateParticipantsResults(LeaderboardParticipant participant, List <SummaryActivity> activities)
        {
            var result = 0d;

            if (activities?.Any() ?? false)
            {
                result = activities.Select(x => (x.Distance ?? 0d) / 1000)
                         .DefaultIfEmpty()
                         .Max();
            }

            return(new ParticipantResult(participant, result, string.Format("{0:0.##} km", result)));
        }
Ejemplo n.º 7
0
        public ParticipantResult CalculateParticipantsResults(LeaderboardParticipant participant, List <SummaryActivity> activities)
        {
            var result = 0d;

            if (activities?.Any() ?? false)
            {
                result = activities?.Where(x => (x.ElapsedTime ?? 0d) > 20 * 60)
                         .Select(x => x.WeightedAverageWatts ?? 0)
                         .DefaultIfEmpty()
                         .Max() ?? 0;
            }

            return(new ParticipantResult(participant, result, string.Format("{0:0} W", result)));
        }
        public Embed BuildAthleteInfoEmbed(LeaderboardParticipant participant, AthleteDetailed athlete)
        {
            var embedBuilder = new EmbedBuilder()
                               .WithCurrentTimestamp()
                               .AddField("Discord User Id", participant.DiscordUserId, true)
                               .AddField("Strava First Name", athlete?.Firstname ?? "Unknown", true)
                               .AddField("Strava Athlete Id", participant.StravaId, true)
                               .AddField("Strava Body Weight",
                                         (athlete.Weight ?? 0) == 0
                        ? "Not Specified"
                        : athlete.Weight.ToString(), true)
                               .AddField("Strava FTP", athlete?.Ftp?.ToString() ?? "Not Specified", true);

            return(embedBuilder.Build());
        }
Ejemplo n.º 9
0
        public async Task <AthleteDetailed> GetAthlete(LeaderboardParticipant participant)
        {
            try
            {
                var credentials = await GetCredentialsForParticipant(participant);

                return(await _stravaApiService.GetAthlete(credentials.AccessToken));
            }
            catch (StravaException e) when(e.Error == StravaException.StravaErrorType.Unauthorized)
            {
                var credentials = await RefreshCredentialsForParticipant(participant)
                                  .ConfigureAwait(false);

                return(await _stravaApiService.GetAthlete(credentials.AccessToken));
            }
        }
Ejemplo n.º 10
0
        public async Task CreateWithCredentials(LeaderboardParticipant participant, StravaOauthResponse oauthResponse)
        {
            _dbContext.Participants.Add(participant);

            var credentials = _dbContext.Credentials.FirstOrDefault(x => x.StravaId == participant.StravaId);

            if (credentials == null)
            {
                _dbContext.Credentials.Add(new StravaCredential(participant.StravaId, oauthResponse.AccessToken, oauthResponse.RefreshToken));
            }
            else
            {
                credentials.UpdateWithNewTokens(oauthResponse);
                _dbContext.Credentials.Update(credentials);
            }
            await _dbContext.SaveChangesAsync();
        }
Ejemplo n.º 11
0
        private async Task <IEnumerable <Embed> > BuildProfileEmbedsForStravaOrDiscordId(string id)
        {
            LeaderboardParticipant participant = null;


            participant = _participantService.GetParticipantOrDefault(Context.Guild.Id.ToString(), id) ??
                          _participantService.GetParticipantByStravaIdOrDefault(Context.Guild.Id.ToString(), id);

            if (participant == null)
            {
                throw new ArgumentException("Couldn't find participant");
            }

            var(policy, context) = _stravaAuthenticationService.GetUnauthorizedPolicy(participant.StravaId);
            var athlete = await policy.ExecuteAsync(x => _athleteService.Get(participant.StravaId), context);

            return(_embedBuilderService.BuildDetailedAthleteEmbeds(participant, athlete));
        }
Ejemplo n.º 12
0
        public async Task <StravaCredential> RefreshCredentialsForParticipant(LeaderboardParticipant participant)
        {
            StravaOauthResponse authResponse = null;
            StravaCredential    credential;

            try
            {
                credential = await GetCredentialsForParticipant(participant);

                authResponse = await _stravaApiService.RefreshAccessTokenAsync(credential.RefreshToken)
                               .ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Failed to refresh access token for {participant.DiscordUserId}");
                throw new StravaException(StravaException.StravaErrorType.RefreshFailed);
            }

            credential.UpdateWithNewTokens(authResponse);
            _dbContext.Credentials.Update(credential);
            await _dbContext.SaveChangesAsync();

            return(credential);
        }
Ejemplo n.º 13
0
        public ParticipantResult CalculateParticipantsResults(LeaderboardParticipant participant, List <SummaryActivity> activites)
        {
            var result = activites?.Sum(x => (x.Distance ?? 0d) / 1000) ?? 0;

            return(new ParticipantResult(participant, result, string.Format("{0:0.##} km", result)));
        }
 public ParticipantResult(LeaderboardParticipant participant, double value)
 {
     Participant = participant;
     Value       = value;
 }
        public ParticipantResult CalculateParticipantsResults(LeaderboardParticipant participant, List <SummaryActivity> activities)
        {
            var result = activities?.Sum(x => x.TotalElevationGain ?? 0d) ?? 0;

            return(new ParticipantResult(participant, result, string.Format("{0:0.#} m", result)));
        }
Ejemplo n.º 16
0
 public ParticipantResult(LeaderboardParticipant participant, double value, string displayValue)
 {
     Participant  = participant;
     Value        = value;
     DisplayValue = displayValue;
 }