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')))
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')))
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
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)
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))
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)))
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
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 }
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 = ''