def handle_json(self, user, file): for line in file: try: obj = json.loads(line) self.stdout.write(str(obj) + '\n') if obj[u'workout_type'] == u'Running': run = Run() run.user = user date = datetime.strptime(obj[u'date'], "%m/%d/%y") self.stdout.write("Date: " + str(date) + ', ') run.date = date distance = float(obj[u'distance']) self.stdout.write("Distance: " + str(distance) + ', ') run.distance = distance duration_in_secs = int(obj[u'duration']) duration = run.set_duration(0,0,duration_in_secs) self.stdout.write("Duration: " + str(duration) + ', ') if not obj[u'hr_avg'] == None: heart_rate = int(obj[u'hr_avg']) run.average_heart_rate = heart_rate self.stdout.write("HR: " + str(heart_rate) + ', ') self.stdout.write('\n') run.save() except: print "Skipping line: " + line
def handle_csv(self, user, file): reader = csv.reader(file, dialect=csv.excel) for row in reader: if row[1] == "Running": try: run = Run() run.user = user date = datetime.strptime(row[0], "%m/%d/%Y") run.date = date self.stdout.write("Date: " + str(date) + ', ') distance = float(row[2]) / m_in_mi run.distance = distance self.stdout.write("Dist: " + str(distance) + ', ') duration = int(row[3]) d = run.set_duration(0,0,duration) self.stdout.write("Dur: " + str(d) + '\n') run.save() except ValueError: self.stdout.write("Skipping: " + ', '.join(row) + '\n')
def obj_to_run(obj): _date = u'date' _duration = u'duration' _average_heart_rate = u'average_heart_rate' _calories = u'calories' _distance = u'distance' run = Run() # try to parse date field run.date = datetime.datetime.strptime(obj[_date], "%Y-%m-%d").date() # try to parse the duration and distance fields run.duration = hms_to_time(0,0,int(obj[_duration])) run.distance = float(obj[_distance]) / 1609.344 # try to parse the HR and calories fields, which may be null if obj[_average_heart_rate]: run.average_heart_rate = int(obj[_average_heart_rate]) if obj[_calories]: run.calories = int(obj[_calories]) return run
def handle_csv(self, user, file): reader = csv.reader(file, dialect=csv.excel) for row in reader: try: run = Run() run.user = user date = datetime.strptime(row[0], "%b %d, %Y") run.date = date self.stdout.write("Date: " + str(date) + ', ') minutes = int(row[1]) seconds = int(row[2]) d = run.set_duration(0,minutes,seconds) self.stdout.write("Dur: " + str(d) + ', ') distance = Decimal(float(row[3])) run.distance = distance self.stdout.write("Dist: " + str(distance) + ', ') if (row[5]): hr = int(row[5]) run.average_heart_rate = hr self.stdout.write("HR: " + str(hr) + ', ') if (row[6]): calories = int(row[6]) run.calories = calories self.stdout.write("Cal: " + str(calories) + ', ') else: run.set_calories() self.stdout.write("Cal': " + str(run.calories) + ', ') run.set_zone() self.stdout.write("Zone: " + str(run.zone) + '\n') run.save() except ValueError: self.stdout.write("Skipping: " + ', '.join(row) + '\n')
def parse_run(debug, fitfiles): for fitfile_in in fitfiles: if debug: print('#' * 80) print('Debug mode active') print('#' * 80) ########################################## # Parse the fit file ########################################### try: fitfile_processor = StandardUnitsDataProcessor() fitfile = FitFile(fitfile_in, data_processor=fitfile_processor, check_crc=False) fitfile.parse() except FitParseError as err: print('Error while parsing {}: {}'.format(fitfile_in.relpath(), err)) sys.exit(1) # Build our api instances geocoder = OpenMapQuest(api_key=run_app.config['OPEN_MAPQUEST_KEY'], scheme='http', timeout=100) tf = TimezoneFinder() #ureg = UnitRegistry() # Pull manufacturer data for record in fitfile.get_messages('file_id', with_definitions=False): manufacturer = record.get_value('manufacturer') product = record.get_value('garmin_product') for record in fitfile.get_messages('file_creator', with_definitions=False): pass if debug: print(f"device: {manufacturer} -- {product}") print() # Parse all events for record in fitfile.get_messages('event', with_definitions=False): event_group = record.get_value('event_group') timestamp = record.get_value('timestamp') if debug: print(f"event: {event_group} -- {timestamp}") for record_data in record: print(f" * {record_data.name}: {record_data.value}") print() initial = True for record in fitfile.get_messages('record', with_definitions=False): # Parse all fields lat = record.get_value('position_lat') lng = record.get_value('position_long') if lat and lng: timezone = find_timezone(tf, lat, lng) location = geocoder.reverse([lat, lng]).raw else: print('skipping record w/o lat or long\n') continue utc_time = pendulum.instance(record.get_value('timestamp')) local_tz = pendulum.timezone(timezone) local_time = local_tz.convert(utc_time) distance = record.get_value('distance') * ureg.km elevation = record.get_value('enhanced_altitude') * ureg.meter speed = record.get_value( 'enhanced_speed') * ureg.kilometer_per_hour if speed.magnitude > 0: pace = 60 / speed.to(ureg.mile_per_hour).magnitude else: print('too fast for me!') continue if not debug: # Add to the database if initial: print('Setting up initial city/state/country') try: cur_country = db.session.query(Country).filter( Country.name == location['address'] ['country_code']).one() except: cur_country = Country( name=location['address']['country_code']) try: cur_state = db.session.query(State).filter( State.name == location['address']['state']).one() except: cur_state = State(name=location['address']['state'], country=cur_country) try: cur_city = db.session.query(City).filter( City.name == location['address']['city']).one() except: cur_city = City(name=location['address']['city'], state=cur_state) cur_run = Run(cur_city) cur_leg = Leg(cur_run) db.session.add_all( [cur_country, cur_state, cur_city, cur_run, cur_leg]) initial = False point = Point(local_time, elevation.magnitude, lat, lng, distance.to(ureg.meter).magnitude, speed.magnitude, cur_leg, cur_run) print(point) print('Adding prev. point') db.session.add(point) output_str = [] output_str.append( f" * datetime: {local_time.strftime('%Y-%m-%d %H:%M:%S')}") output_str.append(f" * timezone: {timezone}") output_str.append(f" * location: {lat},{lng}") if 'city' in location['address']: output_str.append(f" * city: {location['address']['city']}") else: output_str.append(f" * city: {None}") if 'state' in location['address']: output_str.append(f" * state: {location['address']['state']}") else: output_str.append(f" * state: {None}") if 'country_code' in location['address']: output_str.append( f" * country: {location['address']['country_code']}") else: output_str.append(f" * country: {None}") output_str.append(f" * distance: {distance.to(ureg.mile):02.2~}") output_str.append(f" * elevation: {elevation.to(ureg.foot):.5~}") output_str.append( f" * speed: {speed.to(ureg.mile / ureg.hour):.3~}") output_str.append( f" * pace: {round(pace):02}:{round((pace % 1) * 60):02} min / mi" ) print(f"record: {local_time.strftime('%Y-%m-%d %H:%M:%S')}") print('\n'.join(output_str)) print() if not debug: print('DB session committing') db.session.commit() print('DB session committed')
def aggregate_runs(user, first_day, last_day): MAX_CONST = 1000000 # ought to be enough for anyone duration = 0 distance = 0 total_distance_in_meters = 0 hr_distance_in_meters = 0 hr_duration_in_seconds = 0 heartbeats = 0 calories = 0 minimum = MAX_CONST maximum = 0 if user: runs = (Run.objects.filter(user=user.id) .filter(date__gte=first_day).filter(date__lte=last_day)) else: # user == None means aggregate all users runs = (Run.objects.all() .filter(date__gte=first_day).filter(date__lte=last_day)) for run in runs: duration += run.duration_in_seconds() distance += run.distance total_distance_in_meters += run.distance_in_meters() calories += run.calories if run.average_heart_rate: hr_distance_in_meters += run.distance_in_meters() hr_duration_in_seconds += run.duration_in_seconds() heartbeats += run.heartbeats() if run.distance < minimum: minimum = run.distance if run.distance > maximum: maximum = run.distance if minimum == MAX_CONST: minimum = 0 if duration > 0: speed = total_distance_in_meters / duration else: speed = None if len(runs) > 0: average = distance / len(runs) else: average = 0 if hr_duration_in_seconds > 0: beats_per_second = (heartbeats / hr_duration_in_seconds) heart_rate = beats_per_second * 60 else: heart_rate = None beats_per_second = None efficiency = Run.compute_efficiency(hr_distance_in_meters, heartbeats) if not efficiency > 0: efficiency = None ag = Aggregate() ag.user = user ag.distance = distance ag.minimum = minimum ag.maximum = maximum ag.average = average ag.pace = Run.compute_pace(duration, distance) ag.efficiency = efficiency ag.speed = speed ag.calories = calories ag.first_date = first_day ag.last_date = last_day ag.heart_rate = heart_rate ag.beats_per_second = beats_per_second ag.save() return ag