def _populateActivityWaypoints(self, rawData, activity): ''' populate the Waypoints collection from pulsstory API data ''' lap = Lap(stats=activity.Stats, startTime=activity.StartTime, endTime=activity.EndTime) activity.Laps = [lap] streamData = {} self._convertList(streamData, "heart_rate", rawData, "HeartRate") self._convertList(streamData, "distance", rawData, "Distance") self._convertList(streamData, "speed", rawData, "Speed") self._convertList(streamData, "power", rawData, "Power") self._convertList(streamData, "cadence", rawData, "Cadence") self._convertPathList(streamData, "path", rawData) def _addWaypoint(timestamp, path=None, heart_rate=None, power=None, distance=None, speed=None, cadence=None): waypoint = Waypoint(activity.StartTime + timedelta(seconds=timestamp)) if path: if path["latitude"] != 0 and path["longitude"] != 0: waypoint.Location = Location(path["latitude"], path["longitude"], path["altitude"] if "altitude" in path and float(path["altitude"]) != 0 else None) # if you're running near sea level, well... waypoint.Type = WaypointType.Regular waypoint.HR = heart_rate waypoint.Distance = distance waypoint.Speed = speed waypoint.Cadence = cadence waypoint.Power = power lap.Waypoints.append(waypoint) StreamSampler.SampleWithCallback(_addWaypoint, streamData) activity.Stationary = len(lap.Waypoints) == 0 activity.GPS = any(wp.Location and wp.Location.Longitude is not None and wp.Location.Latitude is not None for wp in lap.Waypoints) if not activity.Stationary: lap.Waypoints[0].Type = WaypointType.Start lap.Waypoints[-1].Type = WaypointType.End
def _populateActivityWaypoints(self, rawData, activity): ''' populate the Waypoints collection from RK API data ''' lap = Lap(stats=activity.Stats, startTime=activity.StartTime, endTime=activity.EndTime) activity.Laps = [lap] streamData = {} for stream in ["path", "heart_rate", "calories", "distance"]: if stream in rawData and len(rawData[stream]): if stream == "path": # The path stream doesn't follow the same naming convention, so we cheat and put everything in. streamData[stream] = [(x["timestamp"], x) for x in rawData[stream]] else: streamData[stream] = [(x["timestamp"], x[stream]) for x in rawData[stream]] # Change up format for StreamSampler def _addWaypoint(timestamp, path=None, heart_rate=None, calories=None, distance=None): waypoint = Waypoint(activity.StartTime + timedelta(seconds=timestamp)) if path: waypoint.Location = Location(path["latitude"], path["longitude"], path["altitude"] if "altitude" in path and float(path["altitude"]) != 0 else None) # if you're running near sea level, well... waypoint.Type = self._wayptTypeMappings[path["type"]] if path["type"] in self._wayptTypeMappings else WaypointType.Regular waypoint.HR = heart_rate waypoint.Calories = calories waypoint.Distance = distance lap.Waypoints.append(waypoint) activity.Stationary = len(lap.Waypoints) == 0 if not activity.Stationary: lap.Waypoints[0].Type = WaypointType.Start lap.Waypoints[-1].Type = WaypointType.End StreamSampler.SampleWithCallback(_addWaypoint, streamData)
def DownloadActivity(self, serviceRecord, activity): session = self._get_session(serviceRecord) act_id = activity.ServiceData["ID"] activityDetails = session.get( "https://api.nike.com/me/sport/activities/%s" % act_id, params=self._with_auth(session)) activityDetails = activityDetails.json() streams = { metric["metricType"].lower(): self._nikeStream(metric) for metric in activityDetails["metrics"] } activity.GPS = activityDetails["isGpsActivity"] if activity.GPS: activityGps = session.get( "https://api.nike.com/me/sport/activities/%s/gps" % act_id, params=self._with_auth(session)) activityGps = activityGps.json() streams["gps"] = self._nikeStream(activityGps, "waypoints") activity.Stats.Elevation.update( ActivityStatistic(ActivityStatisticUnit.Meters, gain=float(activityGps["elevationGain"]), loss=float(activityGps["elevationLoss"]), max=float(activityGps["elevationMax"]), min=float(activityGps["elevationMin"]))) lap = Lap(startTime=activity.StartTime, endTime=activity.EndTime) lap.Stats = activity.Stats activity.Laps = [lap] # I thought I wrote StreamSampler to be generator-friendly - nope. streams = {k: list(v) for k, v in streams.items()} # The docs are unclear on which of these are actually stream metrics, oh well def stream_waypoint(offset, speed=None, distance=None, heartrate=None, calories=None, steps=None, watts=None, gps=None, **kwargs): wp = Waypoint() wp.Timestamp = activity.StartTime + timedelta(seconds=offset) wp.Speed = float(speed) if speed else None wp.Distance = float(distance) / 1000 if distance else None wp.HR = float(heartrate) if heartrate else None wp.Calories = float(calories) if calories else None wp.Power = float(watts) if watts else None if gps: wp.Location = Location(lat=float(gps["latitude"]), lon=float(gps["longitude"]), alt=float(gps["elevation"])) lap.Waypoints.append(wp) StreamSampler.SampleWithCallback(stream_waypoint, streams) activity.Stationary = len(lap.Waypoints) == 0 return activity