Exemplo n.º 1
0
        public async Task <Stats> GetStatsAsync(string athleteId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Stats, athleteId)}?access_token={accessToken}";

                string json = await _stravaWebClient.GetAsync(new Uri(getUrl));

                Stats stats = Unmarshaller <Stats> .Unmarshal(json);

                StravaService.SetMetricUnits(stats, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RecentRunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.YearToDateRunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.YearToDateRideTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RideTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RecentRideTotals, defaultDistanceUnitType);

                return(stats);
            }
            catch (Exception ex)
            {
                string title = $"StravaAthleteService.GetStatsAsync - athleteId {athleteId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 2
0
        public async Task <IEnumerable <SegmentEffort> > GetKomsAsync(string athleteId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Koms, athleteId)}?access_token={accessToken}";

                string json = await _stravaWebClient.GetAsync(new Uri(getUrl));

                return(Unmarshaller <IEnumerable <SegmentEffort> > .Unmarshal(json).Select(segment =>
                {
                    StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                    return segment;
                }).ToList());
            }
            catch (Exception ex)
            {
                string title = $"StravaAthleteService.GetKomsAsync - athleteId {athleteId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 3
0
        private async Task <Leaderboard> GetLeaderBoardFromServiceAsync(string segmentId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Leaderboard, segmentId)}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var leaderboard = Unmarshaller <Leaderboard> .Unmarshal(json);

                if (leaderboard.Entries != null)
                {
                    foreach (LeaderboardEntry entry in leaderboard.Entries)
                    {
                        StravaService.SetMetricUnits(entry, defaultDistanceUnitType);
                    }
                }

                return(leaderboard);
            }
            catch (Exception ex)
            {
                string title = $"StravaSegmentService.GetLeaderBoardFromServiceAsync - segmentId {segmentId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets a single activity from Strava asynchronously.
        /// </summary>
        /// <param name="id">The Strava activity id.</param>
        /// <param name="includeEfforts">Used to include all segment efforts in the result.</param>
        /// <returns>The activity with the specified id.</returns>
        public async Task <Activity> GetActivityAsync(string id, bool includeEfforts)
        {
            try
            {
                _perflog.GetActivityAsync(false, id, includeEfforts);

                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Activity}/{id}?include_all_efforts={includeEfforts}&access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var activity = Unmarshaller <Activity> .Unmarshal(json);

                StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                if (activity.SegmentEfforts != null)
                {
                    foreach (SegmentEffort segment in activity.SegmentEfforts)
                    {
                        StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                    }
                }

                _perflog.GetActivityAsync(true, id, includeEfforts);
                return(activity);
            }
            catch (Exception ex)
            {
                //TODO: Glenn - Use logger to log errors ( Google )
            }

            return(null);
        }
Exemplo n.º 5
0
        public async Task <List <SegmentSummary> > GetStarredSegmentsAsync()
        {
            //TODO: Glenn - Caching?
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Starred}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var segments = Unmarshaller <List <SegmentSummary> > .Unmarshal(json);

                foreach (SegmentSummary segment in segments)
                {
                    StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                }

                return(segments);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaSegmentService.GetStarredSegmentsAsync");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
        private async Task <IList <ActivitySummary> > GetRelatedActivitiesFromServiceAsync(string activityId)
        {
            try
            {
                _perflog.GetRelatedActivitiesFromService(false, activityId);

                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Activity}/{activityId}/related?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var results = Unmarshaller <List <ActivitySummary> > .Unmarshal(json).Select(activity =>
                {
                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    return(activity);
                }).ToList();

                _perflog.GetRelatedActivitiesFromService(true, activityId);
                return(results);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaActivityService.GetRelatedActivitiesFromServiceAsync - activityId {activityId}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
Exemplo n.º 7
0
        public async Task <IEnumerable <SegmentEffort> > GetKomsAsync(string athleteId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Koms, athleteId)}?access_token={accessToken}";

                string json = await _stravaWebClient.GetAsync(new Uri(getUrl));

                return(Unmarshaller <IEnumerable <SegmentEffort> > .Unmarshal(json).Select(segment =>
                {
                    StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                    return segment;
                }).ToList());
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaAthleteService.GetKomsAsync - athleteId {athleteId}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
        /// <summary>
        /// Gets the latest activities of the currently authenticated athletes followers asynchronously.
        /// </summary>
        /// <param name="page">The page of activities.</param>
        /// <param name="perPage">The amount of activities per page.</param>
        /// <returns>A list of activities from your followers.</returns>
        public async Task <IList <ActivitySummary> > GetFollowersActivitiesAsync(int page, int perPage)
        {
            try
            {
                _perflog.GetFollowersActivitiesAsync(false, page, perPage);
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                //TODO: Glenn - Optional parameters should be treated as such!
                string getUrl = $"{Endpoints.ActivitiesFollowers}?page={page}&per_page={perPage}&access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var results = Unmarshaller <List <ActivitySummary> > .Unmarshal(json).Select(activity =>
                {
                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    return(activity);
                }).ToList();

                _perflog.GetFollowersActivitiesAsync(true, page, perPage);
                return(results);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaActivityService.GetFollowersActivitiesAsync - page {page} - perPage {perPage}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
        public async Task <List <ActivitySummary> > HydrateActivityData(string data)
        {
            var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

            List <ActivitySummary> results;

            if (data != null)
            {
                results = Unmarshaller <List <ActivitySummary> > .Unmarshal(data).Select(activity =>
                {
                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    if (!string.IsNullOrEmpty(activity.Map.SummaryPolyline))
                    {
                        activity.Map.GoogleImageApiUrl = $"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype={"roadmap"}&size={480}x{220}&scale=2&path=weight:4|color:0xff0000ff|enc:{activity.Map.SummaryPolyline}&key={StravaIdentityConstants.GOOGLE_MAP_API}";
                    }

                    return(activity);
                }).ToList();
            }
            else
            {
                results = new List <ActivitySummary>();
            }

            return(results);
        }
Exemplo n.º 10
0
        private async Task <Segment> GetSegmentFromServiceAsync(string segmentId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Segment}/{segmentId}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var segment = Unmarshaller <Segment> .Unmarshal(json);

                StravaService.SetMetricUnits(segment, defaultDistanceUnitType);

                return(segment);
            }
            catch (Exception ex)
            {
                string title = $"StravaSegmentService.GetSegmentFromServiceAsync - segmentId {segmentId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets all the starred segments of an Athlete.
        /// </summary>
        /// <returns>A list of segments that are starred by the athlete.</returns>
        private async Task <List <SegmentSummary> > GetStarredSegmentsFromServiceAsync(string athleteId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Athletes}/{athleteId}/segments/starred?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var segments = Unmarshaller <List <SegmentSummary> > .Unmarshal(json);

                foreach (SegmentSummary segment in segments)
                {
                    StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                }

                return(segments);
            }
            catch (Exception ex)
            {
                string title = $"StravaSegmentService.GetStarredSegmentsFromServiceAsync - athleteId {athleteId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 12
0
        public async Task <List <SegmentSummary> > GetStarredSegmentsAsync()
        {
            //TODO: Glenn - Caching?
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Starred}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var segments = Unmarshaller <List <SegmentSummary> > .Unmarshal(json);

                foreach (SegmentSummary segment in segments)
                {
                    StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                }

                return(segments);
            }
            catch (Exception ex)
            {
                string title = "StravaSegmentService.GetStarredSegmentsAsync";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 13
0
        private async Task <Segment> GetSegmentFromServiceAsync(string segmentId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Segment}/{segmentId}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var segment = Unmarshaller <Segment> .Unmarshal(json);

                StravaService.SetMetricUnits(segment, defaultDistanceUnitType);

                return(segment);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaSegmentService.GetSegmentFromServiceAsync - segmentId {segmentId}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
Exemplo n.º 14
0
        private async Task <Leaderboard> GetLeaderBoardFromServiceAsync(string segmentId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Leaderboard, segmentId)}?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var leaderboard = Unmarshaller <Leaderboard> .Unmarshal(json);

                if (leaderboard.Entries != null)
                {
                    foreach (LeaderboardEntry entry in leaderboard.Entries)
                    {
                        StravaService.SetMetricUnits(entry, defaultDistanceUnitType);
                    }
                }

                return(leaderboard);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaSegmentService.GetLeaderBoardFromServiceAsync - segmentId {segmentId}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
Exemplo n.º 15
0
        private async Task <IList <ActivitySummary> > GetRelatedActivitiesFromServiceAsync(string activityId)
        {
            try
            {
                _perflog.GetRelatedActivitiesFromService(false, activityId);

                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Activity}/{activityId}/related?access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var results = Unmarshaller <List <ActivitySummary> > .Unmarshal(json).Select(activity =>
                {
                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    return(activity);
                }).ToList();

                _perflog.GetRelatedActivitiesFromService(true, activityId);
                return(results);
            }
            catch (Exception ex)
            {
                string title = $"StravaActivityService.GetRelatedActivitiesFromServiceAsync - activityId {activityId}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Gets the latest activities of the currently authenticated athletes followers asynchronously.
        /// </summary>
        /// <param name="page">The page of activities.</param>
        /// <param name="perPage">The amount of activities per page.</param>
        /// <returns>A list of activities from your followers.</returns>
        public async Task <IList <ActivitySummary> > GetFollowersActivitiesAsync(int page, int perPage)
        {
            try
            {
                _perflog.GetFollowersActivitiesAsync(false, page, perPage);
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                //TODO: Glenn - Optional parameters should be treated as such!
                string getUrl = $"{Endpoints.ActivitiesFollowers}?page={page}&per_page={perPage}&access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var results = Unmarshaller <List <ActivitySummary> > .Unmarshal(json).Select(activity =>
                {
                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    return(activity);
                }).ToList();

                _perflog.GetFollowersActivitiesAsync(true, page, perPage);
                return(results);
            }
            catch (Exception ex)
            {
                string title = $"StravaActivityService.GetFollowersActivitiesAsync - page {page} - perPage {perPage}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Gets a single activity from Strava asynchronously.
        /// </summary>
        /// <param name="id">The Strava activity id.</param>
        /// <param name="includeEfforts">Used to include all segment efforts in the result.</param>
        /// <returns>The activity with the specified id.</returns>
        public async Task <Activity> GetActivityAsync(string id, bool includeEfforts)
        {
            try
            {
                _perflog.GetActivityAsync(false, id, includeEfforts);

                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Activity}/{id}?include_all_efforts={includeEfforts}&access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                if (!string.IsNullOrEmpty(json))
                {
                    var activity = Unmarshaller <Activity> .Unmarshal(json);

                    StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                    if (activity.SegmentEfforts != null)
                    {
                        foreach (SegmentEffort segment in activity.SegmentEfforts)
                        {
                            StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                        }
                    }

                    FillStatistics(activity);

                    _perflog.GetActivityAsync(true, id, includeEfforts);

                    string activityUri = $"{Endpoints.PublicActivity}/{id}";
                    _logService.Log("API", "GetActivityAsync", activityUri);

                    return(activity);
                }
                else
                {
                    throw new NullReferenceException("Strava returned no Json data for requested activity");
                }
            }
            catch (Exception ex)
            {
                string title = $"StravaActivityService.GetActivityAsync - id {id} - includeEfforts {includeEfforts}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Gets a single activity from Strava asynchronously.
        /// </summary>
        /// <param name="id">The Strava activity id.</param>
        /// <param name="includeEfforts">Used to include all segment efforts in the result.</param>
        /// <returns>The activity with the specified id.</returns>
        public async Task <Activity> GetActivityAsync(string id, bool includeEfforts)
        {
            try
            {
                _perflog.GetActivityAsync(false, id, includeEfforts);

                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{Endpoints.Activity}/{id}?include_all_efforts={includeEfforts}&access_token={accessToken}";
                string json   = await _stravaWebClient.GetAsync(new Uri(getUrl));

                var activity = Unmarshaller <Activity> .Unmarshal(json);

                StravaService.SetMetricUnits(activity, defaultDistanceUnitType);
                if (activity.SegmentEfforts != null)
                {
                    foreach (SegmentEffort segment in activity.SegmentEfforts)
                    {
                        StravaService.SetMetricUnits(segment, defaultDistanceUnitType);
                    }
                }

                FillStatistics(activity);

                _perflog.GetActivityAsync(true, id, includeEfforts);
                return(activity);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaActivityService.GetActivityAsync - id {id} - includeEfforts {includeEfforts}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }
Exemplo n.º 19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="following"></param>
        /// <returns></returns>
        /// <remarks>
        /// When Strava flags a segment as Hazardous : we will receive an empty JSON payload!
        /// </remarks>
        private async Task <Leaderboard> GetLeaderboardFromServiceAsync(string segmentId, bool following = false)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                //TODO: Glenn - Segment is needed to correctly calculate measurement values!
                Segment segment = await GetSegmentAsync(segmentId);

                string getUrl = $"{string.Format(Endpoints.Leaderboard, segmentId)}?access_token={accessToken}";
                if (following)
                {
                    getUrl += "&following=true";
                }
                string json = await _stravaWebClient.GetAsync(new Uri(getUrl));

                //TODO: Glenn - When we receive an empty JSON payload, this could mean the segment is marked as hazardous... do we notify user?

                var leaderboard = Unmarshaller <Leaderboard> .Unmarshal(json);

                if (leaderboard.Entries != null)
                {
                    foreach (LeaderboardEntry entry in leaderboard.Entries)
                    {
                        entry.Segment = segment;
                        StravaService.SetMetricUnits(entry, defaultDistanceUnitType);
                    }
                }

                return(leaderboard);
            }
            catch (Exception ex)
            {
                string title = $"StravaSegmentService.GetLeaderboardFromServiceAsync - segmentId {segmentId} - following {following}";
                _logService.LogException(title, ex);
            }

            return(null);
        }
Exemplo n.º 20
0
        public async Task <Stats> GetStatsAsync(string athleteId)
        {
            try
            {
                var accessToken = await _settingsService.GetStoredStravaAccessTokenAsync();

                var defaultDistanceUnitType = await _settingsService.GetStoredDistanceUnitTypeAsync();

                string getUrl = $"{string.Format(Endpoints.Stats, athleteId)}?access_token={accessToken}";

                string json = await _stravaWebClient.GetAsync(new Uri(getUrl));

                Stats stats = Unmarshaller <Stats> .Unmarshal(json);

                StravaService.SetMetricUnits(stats, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RecentRunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.YearToDateRunTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.YearToDateRideTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RideTotals, defaultDistanceUnitType);
                StravaService.SetMetricUnits(stats.RecentRideTotals, defaultDistanceUnitType);

                return(stats);
            }
            catch (Exception ex)
            {
#if !DEBUG
                _errorMessage.Clear();
                _errorMessage.AppendLine($"StravaAthleteService.GetStatsAsync - athleteId {athleteId}");
                _errorMessage.AppendLine(ex.Message);
                ServiceLocator.Current.GetInstance <IGoogleAnalyticsService>().Tracker.SendException(_errorMessage.ToString(), false);
#endif
            }

            return(null);
        }