def test_add_workout(self): number_of_workouts = self.db.session.query(Workout.id).count() workout = Workout(name="TEST_WORKOUT") workout.add(self.db) self.assertEqual(number_of_workouts + 1, self.db.session.query(Workout.id).count()) self.assertEqual("TEST_WORKOUT", self.db.session.query( Workout.name).filter(Workout.id == workout.id).first()[0])
def test_add_sportstype(self): number_of_sportstypes = self.db.session.query(SportsType.id).count() sportstype = SportsType(name="TEST_SPORTSTYPE") workout = Workout() sportstype.add(workout, self.db) self.assertEqual(number_of_sportstypes + 1, self.db.session.query(SportsType.id).count()) self.assertEqual("TEST_SPORTSTYPE", self.db.session.query( SportsType.name).filter(SportsType.id == sportstype.id).first()[0])
def test_workout_as_dict(self): workout = Workout(name = "TEST_WORKOUT") sportstype = SportsType(name="TEST_SPORTSTYPE") workout = Workout() sportstype.add(workout, self.db) workout.sportstype_id = sportstype.id workout.sport_id = sportstype.sport_id workout.add(self.db) as_dict = workout.as_dict(self.db) self.assertTrue(isinstance(as_dict, dict)) self.assertIn('id', as_dict) self.assertNotIn('external_id', as_dict) self.assertIn('name', as_dict) self.assertNotIn('sportstype_id', as_dict) self.assertIn('sportstype', as_dict)
def import_workouts(self, db): """ Imports workouts into a database from a list of csv records """ logger.info("fetching workouts ...") total_fetched_workouts = 0 total_imported_workouts = 0 keys = Workout.header() workouts = csv.DictReader(self.csv) # TODO check if header is correct if self.csv: for record in workouts: logger.debug('CSV record: {}'.format(record)) workout = Workout() total_fetched_workouts += 1 for key in keys: if key == "start_time": record[key] = datetime.strptime(record[key], "%Y-%m-%d %H:%M:%S") elif key == "id": workout.external_id = record[key] continue elif key == "sportstype": sportstype = SportsType(name = record[key]) if record["name"]: workout.name = record["name"] # necessary for sportstype association sportstype.add(workout, db) workout.sportstype_id = sportstype.id workout.sport_id = sportstype.sport_id continue setattr(workout, key, record[key]) if getattr(workout, key) == '': setattr(workout, key, None) if 'source' not in keys or record['source'] == '' or record['source'] == None: workout.source = "CSV import" logger.debug('WORKOUT: {}'.format(workout)) if workout.add(db): total_imported_workouts += 1 logger.info("{} workouts fetched and {} workouts imported".format( total_fetched_workouts, total_imported_workouts)) return(total_fetched_workouts, total_imported_workouts)
def test_workout_as_list(self): workout = Workout(name="TEST_WORKOUT", start_time=datetime.strptime("2020-05-05 20:00:00", "%Y-%m-%d %H:%M:%S")) sportstype = SportsType(name="TEST_SPORTSTYPE") sportstype.add(workout, self.db) workout.sportstype_id = sportstype.id workout.sport_id = sportstype.sport_id workout.add(self.db) as_list = workout.as_list(self.db) self.assertTrue(isinstance(as_list, list)) self.assertIn('TEST_WORKOUT', as_list) self.assertIn('TEST_SPORTSTYPE', as_list)
def export_workouts(self, db): logger.info("exporting workouts ...") exported_workouts = 0 workouts = db.session.query(Workout).all() csv_data = [] # header line header = Workout.header() csv_data.append(header) # record lines for workout in workouts: csv_data.append(workout.as_list(db)) exported_workouts += 1 writer = csv.writer(self.csv) writer.writerows(csv_data) logger.info("{} workouts exported".format(exported_workouts))
def test_duplicate_workouts(self): # this workout |-----------------| # 1st potential duplicate in db |-----------------| # 2nd potential duplicate in db |------------------------| # 3rd potential duplicate in db |----------------| # 4th potential duplicate in db |---------| number_of_workouts_before = self.db.session.query(Workout.id).count() id_counter = 0 workout = Workout(external_id=id_counter, sportstype_id=1, sport_id=1, start_time=datetime.strptime("2020-05-21 20:00:00", "%Y-%m-%d %H:%M:%S"), duration_sec=600) workout.add(self.db) number_of_workouts_after = self.db.session.query(Workout.id).count() self.assertTrue(number_of_workouts_after == number_of_workouts_before + 1) # time is overlapping, same sport -> is_duplicate number_of_workouts_before = self.db.session.query(Workout.id).count() id_counter += 1 workout = Workout(external_id=id_counter, sportstype_id=1, sport_id=1, start_time=datetime.strptime("2020-05-21 19:58:00", "%Y-%m-%d %H:%M:%S"), duration_sec=600) workout.add(self.db) number_of_workouts_after = self.db.session.query(Workout.id).count() self.assertEqual(number_of_workouts_after, number_of_workouts_before + 2) # this workout added plus a merged one self.assertIsNotNone(workout.is_duplicate_with) # time is overlapping, same sport -> is_duplicate number_of_workouts_before = self.db.session.query(Workout.id).count() id_counter += 1 workout = Workout(external_id=id_counter, sportstype_id=1, sport_id=1, start_time=datetime.strptime("2020-05-21 20:02:00", "%Y-%m-%d %H:%M:%S"), duration_sec=600) workout.add(self.db) number_of_workouts_after = self.db.session.query(Workout.id).count() self.assertEqual(number_of_workouts_after, number_of_workouts_before + 1) # this workout added, no add. merged workout created because already existing self.assertIsNotNone(workout.is_duplicate_with) # time is overlapping, different sport -> manual_check_required_with number_of_workouts_before = self.db.session.query(Workout.id).count() id_counter += 1 workout = Workout(external_id=id_counter, sportstype_id=2, sport_id=2, start_time=datetime.strptime("2020-05-21 20:01:00", "%Y-%m-%d %H:%M:%S"), duration_sec=600) workout.add(self.db) number_of_workouts_after = self.db.session.query(Workout.id).count() self.assertEqual(number_of_workouts_after, number_of_workouts_before + 1) self.assertIsNotNone(workout.manual_check_required_with) # time not overlapping, no duplicate number_of_workouts_before = self.db.session.query(Workout.id).count() id_counter += 1 workout = Workout(external_id=id_counter, sportstype_id=1, sport_id=1, start_time=datetime.strptime("2020-05-22 20:11:00", "%Y-%m-%d %H:%M:%S"), duration_sec=600) workout.add(self.db) number_of_workouts_after = self.db.session.query(Workout.id).count() self.assertEqual(number_of_workouts_after, number_of_workouts_before + 1) # this workout added, no merged one self.assertIsNone(workout.is_duplicate_with)
def _create_workout(self, record, db): workout = Workout() workout.source = "Garmin" workout.external_id = record['activityId'] workout.name = record['activityName'] workout.description = record['description'] sportstype = SportsType(name=record['activityType']['typeKey']) sportstype.add(workout, db) workout.sportstype_id = sportstype.id workout.sport_id = sportstype.sport_id if record['minTemperature']: workout.min_temperature = int(record['minTemperature']) if record['maxTemperature']: workout.max_temperature = int(record['maxTemperature']) workout.start_time = datetime.strptime( record['startTimeLocal'], "%Y-%m-%d %H:%M:%S") # 2020-03-28 16:25:47 if record['duration']: workout.duration_sec = int(record['duration']) if record['movingDuration']: workout.moving_duration_sec = int(record['movingDuration']) if record['distance']: workout.distance_m = int(record['distance']) if record['averageSpeed']: workout.average_speed_m_per_sec = round(record['averageSpeed'], 3) if record['maxSpeed']: workout.max_speed_m_per_sec = round(record['maxSpeed'], 3) workout.elevation_gain_m = record['elevationGain'] workout.elevation_loss_m = record['elevationLoss'] if record['calories']: workout.calories = int(record['calories']) workout.average_hr = record['averageHR'] workout.max_hr = record['maxHR'] workout.avg_power = record['avgPower'] workout.max_power = record['maxPower'] if record['normPower']: workout.norm_power = int(record['normPower']) if record['aerobicTrainingEffect']: workout.aerobic_training_effect = round( record['aerobicTrainingEffect'], 1) if record['anaerobicTrainingEffect']: workout.anaerobic_training_effect = round( record['anaerobicTrainingEffect'], 1) if record['trainingStressScore']: workout.training_stress_score = round( record['trainingStressScore'], 1) if record['intensityFactor']: workout.intensity_factor = round(record['intensityFactor'], 3) if record['averageRunningCadenceInStepsPerMinute']: workout.average_running_cadence_steps_per_min = int( record['averageRunningCadenceInStepsPerMinute']) if record['maxRunningCadenceInStepsPerMinute']: workout.max_running_cadence_steps_per_min = int( record['maxRunningCadenceInStepsPerMinute']) workout.average_biking_cadence_rev_per_min = record[ 'averageBikingCadenceInRevPerMinute'] workout.max_biking_cadence_rev_per_min = record[ 'maxBikingCadenceInRevPerMinute'] workout.average_swim_cadence_strokes_per_min = record[ 'averageSwimCadenceInStrokesPerMinute'] workout.max_swim_cadence_strokes_per_min = record[ 'maxSwimCadenceInStrokesPerMinute'] workout.average_swolf = record['averageSwolf'] workout.active_lengths = record['activeLengths'] workout.pool_length = record['poolLength'] if record['unitOfPoolLength']: if record['unitOfPoolLength']['unitKey']: workout.unit_of_pool_length = str( record['unitOfPoolLength']['unitKey']) if record['unitOfPoolLength']: if record['unitOfPoolLength']['factor']: workout.pool_length_factor = int( record['unitOfPoolLength']['factor']) workout.strokes = record['strokes'] if record['avgStrokeDistance']: workout.avg_stroke_distance = int(record['avgStrokeDistance']) workout.avg_stroke_cadence = record['avgStrokeCadence'] workout.max_stroke_cadence = record['maxStrokeCadence'] if record['avgStrokes']: workout.avg_strokes = round(record['avgStrokes'], 1) if record['minStrokes']: workout.min_strokes = round(record['minStrokes'], 1) workout.left_balance = record['leftBalance'] workout.right_balance = record['rightBalance'] workout.avg_left_balance = record['avgLeftBalance'] if record['avgVerticalOscillation']: workout.avg_vertical_oscillation = round( record['avgVerticalOscillation'], 1) if record['avgGroundContactTime']: workout.avg_ground_contact_time = int( record['avgGroundContactTime']) if record['avgStrideLength']: workout.avg_stride_length = int(record['avgStrideLength']) workout.avg_fractional_cadence = record['avgFractionalCadence'] workout.max_fractional_cadence = record['maxFractionalCadence'] if record['avgVerticalRatio']: workout.avg_vertical_ratio = round(record['avgVerticalRatio'], 2) if record['avgGroundContactBalance']: workout.avg_ground_contact_balance = round( record['avgGroundContactBalance'], 2) workout.vo2_max_value = record['vO2MaxValue'] workout.lactate_threshold_bpm = record['lactateThresholdBpm'] workout.lactate_threshold_speed = record['lactateThresholdSpeed'] workout.max_ftp = record['maxFtp'] if record['max20MinPower']: workout.max_20_min_power = int(record['max20MinPower']) workout.max_avg_power_1 = record['maxAvgPower_1'] workout.max_avg_power_2 = record['maxAvgPower_2'] workout.max_avg_power_5 = record['maxAvgPower_5'] workout.max_avg_power_10 = record['maxAvgPower_10'] workout.max_avg_power_20 = record['maxAvgPower_20'] workout.max_avg_power_30 = record['maxAvgPower_30'] workout.max_avg_power_60 = record['maxAvgPower_60'] workout.max_avg_power_120 = record['maxAvgPower_120'] workout.max_avg_power_300 = record['maxAvgPower_300'] workout.max_avg_power_600 = record['maxAvgPower_600'] workout.max_avg_power_1200 = record['maxAvgPower_1200'] workout.max_avg_power_1800 = record['maxAvgPower_1800'] workout.max_avg_power_3600 = record['maxAvgPower_3600'] workout.max_avg_power_7200 = record['maxAvgPower_7200'] workout.max_avg_power_18000 = record['maxAvgPower_18000'] return workout.add(db)
def test_cleanup_sportstype(self): sportstype = SportsType(name="RuNnInG") workout = Workout() sportstype.cleanup_sportstype(workout) self.assertEqual(sportstype.name, "Running")