public async Task <SyncResult> SyncAsync(int numWorkouts) { using var timer = SyncHistogram.NewTimer(); using var activity = Tracing.Trace($"{nameof(SyncService)}.{nameof(SyncAsync)}") .WithTag("numWorkouts", numWorkouts.ToString()); ICollection <RecentWorkout> recentWorkouts; var syncTime = await _db.GetSyncStatusAsync(); syncTime.LastSyncTime = DateTime.Now; try { recentWorkouts = await _pelotonService.GetRecentWorkoutsAsync(numWorkouts); } catch (Exception ex) { _logger.Error(ex, "Failed to fetch recent workouts from Peleoton."); activity?.AddTag("exception.message", ex.Message); activity?.AddTag("exception.stacktrace", ex.StackTrace); await _db.UpsertSyncStatusAsync(syncTime); var response = new SyncResult(); response.SyncSuccess = false; response.PelotonDownloadSuccess = false; response.Errors.Add(new ErrorResponse() { Message = "Failed to fetch recent workouts from Peloton. Check logs for more details." }); return(response); } var completedWorkouts = recentWorkouts .Where(w => { var shouldKeep = w.Status == "COMPLETE"; if (shouldKeep) { return(true); } _logger.Debug("Skipping in progress workout. {@WorkoutId} {@WorkoutStatus} {@WorkoutType} {@WorkoutTitle}", w.Id, w.Status, w.Fitness_Discipline, w.Title); return(false); }) .Select(r => r.Id) .ToList(); _logger.Debug("Total workouts found after filtering out InProgress: {@FoundWorkouts}", completedWorkouts.Count()); activity?.AddTag("workouts.completed", completedWorkouts.Count()); var result = await SyncAsync(completedWorkouts, _config.Peloton.ExcludeWorkoutTypes); if (result.SyncSuccess) { syncTime.LastSuccessfulSyncTime = DateTime.Now; } await _db.UpsertSyncStatusAsync(syncTime); return(result); }
public async Task <SyncResult> SyncAsync(ICollection <string> workoutIds, ICollection <WorkoutType>?exclude = null) { using var timer = SyncHistogram.NewTimer(); using var activity = Tracing.Trace($"{nameof(SyncService)}.{nameof(SyncAsync)}.ByWorkoutIds"); var response = new SyncResult(); var recentWorkouts = workoutIds.Select(w => new RecentWorkout() { Id = w }).ToList(); P2GWorkout[] workouts = { }; try { workouts = await _pelotonService.GetWorkoutDetailsAsync(recentWorkouts); response.PelotonDownloadSuccess = true; } catch (Exception e) { _logger.Error(e, "Failed to download workouts from Peleoton."); response.SyncSuccess = false; response.PelotonDownloadSuccess = false; response.Errors.Add(new ErrorResponse() { Message = "Failed to download workouts from Peloton. Check logs for more details." }); return(response); } var filteredWorkouts = workouts.Where(w => { if (exclude is null || exclude.Count == 0) { return(true); } if (exclude.Contains(w.WorkoutType)) { _logger.Debug("Skipping excluded workout type. {@WorkoutId} {@WorkoutType}", w.Workout.Id, w.WorkoutType); return(false); } return(true); }); activity?.AddTag("workouts.filtered", filteredWorkouts.Count()); _logger.Debug("Number of workouts to convert after filtering InProgress: {@NumWorkouts}", filteredWorkouts.Count()); try { Parallel.ForEach(filteredWorkouts, (workout) => { Parallel.ForEach(_converters, (converter) => { converter.Convert(workout); }); }); response.ConversionSuccess = true; } catch (Exception e) { _logger.Error(e, "Failed to convert workouts to FIT format."); response.SyncSuccess = false; response.ConversionSuccess = false; response.Errors.Add(new ErrorResponse() { Message = "Failed to convert workouts to FIT format. Check logs for more details." }); return(response); } try { await _garminUploader.UploadToGarminAsync(); response.UploadToGarminSuccess = true; } catch (Exception e) { _logger.Error(e, "GUpload returned an error code. Failed to upload workouts."); _logger.Warning("GUpload failed to upload files. You can find the converted files at {@Path} \n You can manually upload your files to Garmin Connect, or wait for P2G to try again on the next sync job.", _config.App.OutputDirectory); response.SyncSuccess = false; response.UploadToGarminSuccess = false; response.Errors.Add(new ErrorResponse() { Message = "Failed to upload to Garmin Connect. Check logs for more details." }); return(response); } finally { _fileHandler.Cleanup(_config.App.DownloadDirectory); _fileHandler.Cleanup(_config.App.UploadDirectory); _fileHandler.Cleanup(_config.App.WorkingDirectory); } response.SyncSuccess = true; return(response); }