示例#1
0
    def update_ride_basic(self, strava_activity: Activity, ride: Ride):
        """
        Set basic ride properties from the Strava Activity object.

        :param strava_activity: The Strava Activity
        :param ride: The ride model object.
        """
        # Should apply to both new and preexisting rides ...
        # If there are multiple instagram photos, then request syncing of non-primary photos too.

        if strava_activity.photo_count > 1 and ride.photos_fetched is None:
            self.logger.debug(
                "Scheduling non-primary photos sync for {!r}".format(ride))
            ride.photos_fetched = False

        ride.private = bool(strava_activity.private)
        ride.name = strava_activity.name
        ride.start_date = strava_activity.start_date_local

        # We need to round so that "1.0" miles in data is "1.0" miles when we convert back from meters.
        ride.distance = round(
            float(unithelper.miles(strava_activity.distance)), 3)

        ride.average_speed = float(
            unithelper.mph(strava_activity.average_speed))
        ride.maximum_speed = float(unithelper.mph(strava_activity.max_speed))
        ride.elapsed_time = timedelta_to_seconds(strava_activity.elapsed_time)
        ride.moving_time = timedelta_to_seconds(strava_activity.moving_time)

        location_parts = []
        if strava_activity.location_city:
            location_parts.append(strava_activity.location_city)
        if strava_activity.location_state:
            location_parts.append(strava_activity.location_state)
        location_str = ', '.join(location_parts)

        ride.location = location_str

        ride.commute = strava_activity.commute
        ride.trainer = strava_activity.trainer
        ride.manual = strava_activity.manual
        ride.elevation_gain = float(
            unithelper.feet(strava_activity.total_elevation_gain))
        ride.timezone = str(strava_activity.timezone)

        # # Short-circuit things that might result in more obscure db errors later.
        if ride.elapsed_time is None:
            raise DataEntryError("Activities cannot have null elapsed time.")

        if ride.moving_time is None:
            raise DataEntryError("Activities cannot have null moving time.")

        if ride.distance is None:
            raise DataEntryError("Activities cannot have null distance.")

        self.logger.debug(
            "Writing ride for {athlete!r}: \"{ride!r}\" on {date}".format(
                athlete=ride.athlete.name,
                ride=ride.name,
                date=ride.start_date.strftime('%m/%d/%y')))
示例#2
0
def update_ride_from_activity(strava_activity, ride):
    """
    Refactoring to just set ride properties from the Strava Activity object.

    :param strava_activity: The Strava Activyt
    :type strava_activity: stravalib.model.Activity
    :param ride: The ride model object.
    :type ride: Ride
    """
     # Should apply to both new and preexisting rides ...
    # If there are multiple instagram photos, then request syncing of non-primary photos too.

    if strava_activity.photo_count > 1 and ride.photos_fetched is None:


        log.debug("Scheduling non-primary photos sync for {!r}".format(ride))
        ride.photos_fetched = False

    ride.private = bool(strava_activity.private)
    ride.name = strava_activity.name
    ride.start_date = strava_activity.start_date_local

    # We need to round so that "1.0" miles in strava is "1.0" miles when we convert back from meters.
    ride.distance = round(float(unithelper.miles(strava_activity.distance)), 3)

    ride.average_speed = float(unithelper.mph(strava_activity.average_speed))
    ride.maximum_speed = float(unithelper.mph(strava_activity.max_speed))
    ride.elapsed_time = timedelta_to_seconds(strava_activity.elapsed_time)
    ride.moving_time = timedelta_to_seconds(strava_activity.moving_time)

    location_parts = []
    if strava_activity.location_city:
        location_parts.append(strava_activity.location_city)
    if strava_activity.location_state:
        location_parts.append(strava_activity.location_state)
    location_str = ', '.join(location_parts)

    ride.location = location_str

    ride.commute = strava_activity.commute
    ride.trainer = strava_activity.trainer
    ride.manual = strava_activity.manual
    ride.elevation_gain = float(unithelper.feet(strava_activity.total_elevation_gain))
    ride.timezone = str(strava_activity.timezone)

    # # Short-circuit things that might result in more obscure db errors later.
    if ride.elapsed_time is None:
        raise DataEntryError("Activities cannot have null elapsed time.")

    if ride.moving_time is None:
        raise DataEntryError("Activities cannot have null moving time.")

    if ride.distance is None:
        raise DataEntryError("Activities cannot have null distance.")

    log.debug("Writing ride for {athlete!r}: \"{ride!r}\" on {date}".format(athlete=ride.athlete.name,
                                                                        ride=ride.name,
                                                                        date=ride.start_date.strftime('%m/%d/%y')))
示例#3
0
def get_activity_summary(activity):
    """Pulls activity metrics and returns a dict with name, id, distance,
       elevation, type, and date.
    """
    vals = { "id": activity.id, "name": activity.name, "type": activity.type,
             "distance": unithelper.miles(activity.distance),
             "elevation": unithelper.feet(activity.total_elevation_gain), 
             "date": activity.start_date.replace(tzinfo=TZ_LOCAL).strftime("%m/%d") }
    return vals
示例#4
0
    def build_df_summary(self):
        self.df_summary = pd.DataFrame()
        self.df_summary['activity_id'] = [self.id]

        if self.start_latlng is not None:
            self.df_summary['start_lat'] = [self.start_latlng[0]]
            self.df_summary['start_lon'] = [self.start_latlng[1]]
        else:
            self.df_summary['start_lat'] = None
            self.df_summary['start_lon'] = None
        if self.end_latlng is not None:
            self.df_summary['end_lat'] = [self.end_latlng[0]]
            self.df_summary['end_lon'] = [self.end_latlng[1]]
        else:
            self.df_summary['end_lat'] = None
            self.df_summary['end_lon'] = None

        self.df_summary['achievement_count'] = [self.achievement_count]
        self.df_summary['activity_id'] = [self.id]
        self.df_summary['average_heartrate'] = [self.average_heartrate]
        self.df_summary['average_speed'] = [
            unithelper.mph(self.average_speed).num
        ]
        self.df_summary['average_watts'] = [self.average_watts]
        self.df_summary['calories'] = [self.calories]
        self.df_summary['commute'] = [self.commute]
        self.df_summary['description'] = [self.description]
        self.df_summary['device_name'] = [self.device_name]
        self.df_summary['distance'] = [unithelper.miles(self.distance).num]
        self.df_summary['elapsed_time'] = [self.elapsed_time.seconds]
        self.df_summary['gear_id'] = [self.gear_id]
        self.df_summary['kilojoules'] = [self.kilojoules]
        self.df_summary['location_city'] = [self.location_city]
        self.df_summary['location_country'] = [self.location_country]
        self.df_summary['location_state'] = [self.location_state]
        self.df_summary['max_heartrate'] = [self.max_heartrate]
        self.df_summary['max_speed'] = [unithelper.mph(self.max_speed).num]
        self.df_summary['max_watts'] = [self.max_watts]
        self.df_summary['moving_time'] = [self.moving_time.seconds]
        self.df_summary['name'] = [self.name]
        self.df_summary['pr_count'] = [self.pr_count]
        self.df_summary['start_date_local'] = [self.start_date_local]
        self.df_summary['start_date_utc'] = [self.start_date]
        self.df_summary['start_day_local'] = [self.start_date_local.date()]
        self.df_summary['timezone'] = [str(self.timezone)]
        self.df_summary['total_elevation_gain'] = [
            unithelper.feet(self.total_elevation_gain).num
        ]
        self.df_summary['trainer'] = [self.trainer]
        self.df_summary['type'] = [self.type]
        self.df_summary.set_index(['start_date_utc'], inplace=True)
示例#5
0
	def __init__(self, act):
		self.actId=act.id
		self.athId=act.athlete.id
		self.dist=float(unithelper.miles(act.distance))
		self.time=act.moving_time.seconds
		self.date=act.start_date
		print "start_date type",type(act.start_date)
		try:
			self.pace=ru.minPerMile(act.average_speed)
			self.maxPace=ru.minPerMile(act.max_speed)
		except:
			self.pace=0.
			self.maxPace=0.
		self.el=unithelper.feet(act.total_elevation_gain)
		self.name=act.name
def add_activity(conn, athlete_id, Activity):
    """Adds an metrics from a DETAILED Activity object activity to the database
    """
    table     = TABLES["activities"]
    distance  = float( unithelper.miles(Activity.distance) )
    elevation = float( unithelper.feet(Activity.total_elevation_gain) )
    date_time  = Activity.start_date.strftime('%Y-%m-%d %H:%M:%S')

    statement = "INSERT INTO %s VALUES (%i, %i, '%s', '%s', %.2f, %.2f, '%s');" % \
                (table, athlete_id, Activity.id, Activity.type, Activity.name, \
		 distance, elevation, Activity.start_date)
    try:
        cur = conn.cursor()
        cur.execute(statement)
        logger.info("Activity %i added for athlete %i" % (Activity.id, athlete_id))

    except Exception, e:
        logger.critical("Error with activity %i for %i, error:\n%s" % (Activity.id, athlete_id, e))
示例#7
0
hikeelev = []
snowshoe = []
snowdis = []
snowelev = []

for a in activities:
    atype.append(a.type)

types = set(atype)
print types

for a in activities:
    if a.type == 'Run':
        run.append(a)
        rundis.append(float(unithelper.miles(a.distance)))
        runelev.append(float(unithelper.feet(a.total_elevation_gain)))
    elif a.type == 'Walk':
        walk.append(a)
        walkdis.append(float(unithelper.miles(a.distance)))
        walkelev.append(float(unithelper.feet(a.total_elevation_gain)))
    elif a.type == 'Ride':
        ride.append(a)
        ridedis.append(float(unithelper.miles(a.distance)))
        rideelev.append(float(unithelper.feet(a.total_elevation_gain)))
    elif a.type == 'Hike':
        hike.append(a)
        hikedis.append(float(unithelper.miles(a.distance)))
        hikeelev.append(float(unithelper.feet(a.total_elevation_gain)))
    elif a.type == 'Snowshoe':
        snowshoe.append(a)
        snowdis.append(float(unithelper.miles(a.distance)))
示例#8
0
    def build_df_samples(self):
        seconds = 1
        streams = get_strava_client().get_activity_streams(self.id,
                                                           types=types)
        self.df_samples = pd.DataFrame(columns=types)
        # Write each row to a dataframe
        for item in types:
            if item in streams.keys():
                self.df_samples[item] = pd.Series(streams[item].data,
                                                  index=None)
        self.df_samples['start_date_local'] = self.start_date_local
        self.df_samples['timestamp_local'] = pd.Series(
            map(calctime, self.df_samples['time'],
                self.df_samples['start_date_local']))
        self.df_samples.set_index('timestamp_local', inplace=True)

        # Parse latlngs into seperate columns
        try:
            self.df_samples['latitude'] = self.df_samples['latlng'].apply(
                lambda x: x[0] if isinstance(x, list) else None).apply(
                    pd.to_numeric, errors='coerce')
            self.df_samples['longitude'] = self.df_samples['latlng'].apply(
                lambda x: x[1] if isinstance(x, list) else None).apply(
                    pd.to_numeric, errors='coerce')
        except KeyError:
            self.df_samples['latitude'] = None
            self.df_samples['longitude'] = None

        # Interpolate samples - each workout in samples data should already be at 1s intervals, calling resample fills in gaps so mean() does not matter
        self.df_samples = self.df_samples.resample(str(seconds) + 'S').mean()
        self.df_samples = self.df_samples.interpolate(
            limit_direction='both'
        )  # TODO: Consider if interpolating of nans is skuing data too much

        try:  # Indoor activity samples wont have altitudes
            self.df_samples['altitude'] = self.df_samples['altitude'] * 3.28084
        except KeyError:
            self.df_samples['altitude'] = None

        try:
            # Convert celcius to farenheit
            self.df_samples['temp'] = unithelper.c2f(self.df_samples['temp'])
        except:
            pass

        try:
            # Convert meter per second to mph
            self.df_samples['velocity_smooth'] = unithelper.mph(
                self.df_samples['velocity_smooth']).num
        except:
            pass
        try:
            # Convert meters to feet
            self.df_samples['distance'] = unithelper.feet(
                self.df_samples['distance']).num
        except:
            pass

        # Add Time Interval
        epoch = pd.to_datetime('1970-01-01')
        self.df_samples['time_interval'] = self.df_samples['time'].astype(
            'int').apply(lambda x: epoch + timedelta(seconds=x))

        # Add date column
        self.df_samples['date'] = self.df_samples.index.date
        # Add activity id and name back in
        self.df_samples['activity_id'] = self.id
        self.df_samples['act_name'] = self.name
示例#9
0
def activity_dict(athlete, a):
    elapsed_time = unithelper.seconds(a.elapsed_time.total_seconds())
    if athlete.measurement_preference == 'feet':
        distance = str(unithelper.miles(a.distance))
        gain = str(unithelper.feet(a.total_elevation_gain))
        if a.type == 'Ride':
            speed = str(unithelper.mph(a.average_speed))
            elapsed_speed = str(unithelper.mph(a.distance / elapsed_time))
        else:
            try:
                speed = "{0:.2f} /mi".format(
                    60 / (unithelper.mph(a.average_speed).num))
                elapsed_speed = "{0:.2f} /mi".format(
                    60 / unithelper.mph(a.distance / elapsed_time).num)
            except ZeroDivisionError:
                speed = 'NaN'
                elapsed_speed = 'NaN'
    else:
        distance = str(unithelper.kilometers(a.distance))
        gain = str(unithelper.meters(a.total_elevation_gain))
        if a.type == 'Ride':
            speed = str(unithelper.kph(a.average_speed))
            elapsed_speed = str(unithelper.kph(a.distance / elapsed_time))
        else:
            try:
                speed = "{0:.2f} /km".format(
                    60 / (unithelper.kph(a.average_speed).num))
                elapsed_speed = "{0:.2f} /km".format(
                    60 / unithelper.kph(a.distance / elapsed_time).num)
            except ZeroDivisionError:
                speed = 'NaN'
                elapsed_speed = 'NaN'

    date = a.start_date_local.strftime(athlete.date_preference
                                       or "%a, %d %b %Y")
    weekday = calendar.day_name[a.start_date_local.weekday()]

    workout_type = ''
    if a.type == 'Run':
        workout_type = ['', 'Race', 'Long Run', 'Workout'][int(a.workout_type
                                                               or 0)]

    garmin_link = ''
    if a.external_id:
        if a.external_id.startswith('garmin_push_'):
            garmin_id = a.external_id.split('_')[2]
            garmin_link = 'https://connect.garmin.com/modern/activity/{}'.format(
                garmin_id)

    return {
        'id': a.id,
        'link': url_for('query.show_activity', id=a.id),
        'strava_link': 'https://www.strava.com/activities/{}'.format(a.id),
        'garmin_link': garmin_link,
        'name': a.name,
        'type': a.type,
        'workout_type': workout_type,
        'date': date,
        'weekday': weekday,
        'distance': distance,
        'gain': gain,
        'elapsed_time': str(a.elapsed_time),
        'moving_time': str(a.moving_time),
        'speed': speed,
        'elapsed_speed': elapsed_speed,
        'start_latlng': [a.start_latitude, a.start_longitude],
        'polyline': a.map.polyline or a.map.summary_polyline
    }
示例#10
0
runs = 0
print 'Writing activities...'
for x in range(total_activities-1,-1,-1):
	curr_activity = activity_list[x]
	if curr_activity.type == 'Run':
		print("Writing activity {i} (Run): {act_id}".format(i=x, act_id=curr_activity.id))
		curr_activity_full = client.get_activity(curr_activity.id)
		record = ''
		record = record + '"' + xstr(curr_activity_full.id) + '",'
		record = record + '"' + xstr(curr_activity_full.name) + '",'

		record = record + '"' + xstr(unithelper.miles(curr_activity_full.distance).num) + '",'
		record = record + '"' + xstr(curr_activity_full.moving_time.seconds) + '",'
		record = record + '"' + xstr(curr_activity_full.elapsed_time.seconds) + '",'
		record = record + '"' + xstr(unithelper.feet(curr_activity_full.total_elevation_gain).num) + '",'
		record = record + '"' + xstr(unithelper.miles_per_hour(curr_activity_full.average_speed).num) + '",'
		record = record + '"' + xstr(unithelper.miles_per_hour(curr_activity_full.max_speed).num) + '",'
		record = record + '"' + xstr(curr_activity_full.average_cadence) + '",'
		record = record + '"' + xstr(curr_activity_full.average_temp) + '",'
		record = record + '"' + xstr(curr_activity_full.average_heartrate) + '",'
		record = record + '"' + xstr(curr_activity_full.max_heartrate) + '",'
		record = record + '"' + xstr(curr_activity_full.calories) + '",'

		record = record + '"' + xstr(curr_activity_full.gear.name) + '",'
		record = record + '"' + xstr(createTimestamp(curr_activity_full.start_date_local)) + '",'

		start_lat = ''
		start_lng = ''
		end_lat = ''
		end_lng = ''