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')
Exemple #3
0
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')
Exemple #5
0
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')
Exemple #6
0
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