Example #1
0
def segments_by_chunk():
    global segment_ids_todo
    global athlete_names
    global segment_rivals

    print('starting another chunk!')
    # segment_rivals = request.args.get('rivals')
    # athlete_names = request.args.get('names')
    chunk_size = 10
    client = Client(access_token=session['access_token'])
    # loop over chunks of segments
    j = 0

    if len(segment_ids_todo) < chunk_size:
        chunk_size = len(segment_ids_todo)
    for segment_id in segment_ids_todo[0:chunk_size]:
        try:
            leaderboard = client.get_segment_leaderboard(
                segment_id=segment_id,
                top_results_limit=1,
                context_entries=session['context_entries'])
            print('on segment {}; {} to go'.format(segment_id,
                                                   len(segment_ids_todo)))
        except:
            # janky error handling, should specify http error -- probably need urllib2
            print('whoops, error on {}; {} to go'.format(
                segment_id, len(segment_ids_todo)))
        j = j + 1

        segment_ids_todo.remove(segment_id)  # remove from to do list
        segment_athletes = dict()
        for i, entry in enumerate(leaderboard):
            # remove first entry
            # this should not be done if athlete is within context_entries of 1st
            if i == 0:
                continue
            else:
                segment_athletes[entry.athlete_id] = entry.athlete_name
                athlete_names[entry.athlete_id] = entry.athlete_name

        segment_rivals[segment_id] = segment_athletes
        time.sleep(0.5)  # avoid time out?

    # json.dump(segment_rivals, open(str(session['athlete_id'])+'segment_rivals.json','w'))
    # json.dump(athlete_names, open(str(session['athlete_id'])+'athlete_names.json','w'))

    if (len(segment_ids_todo) > 0):
        return redirect(url_for('segments_by_chunk'))
    else:
        return redirect(url_for('results_table'))
def massive_test(access_token, athlete_id):
    client = Client(access_token=access_token)

    mysegments = {}  # all segments a user has ridden

    # get athlete activities
    athlete_from_db = Athlete.objects.get(strava_id=athlete_id)
    activities = client.get_activities(limit=5, before=athlete_from_db.oldest_activity_date)  # API call

    # per activity, get segment efforts
    for activity in activities:
        if activity.type not in ['Ride', 'ride']:
            continue

        try:
            # if activity already exists in db, skip it
            Activity.objects.get(strava_id=activity.id)
            continue
        except Activity.DoesNotExist:
            new_activity = Activity()
            new_activity.strava_id = activity.id
            new_activity.start_lat = activity.start_latitude
            new_activity.start_long = activity.start_longitude
            new_activity.start_date = activity.start_date
            new_activity.save()

            # update newest / oldest activity dates
            if athlete_from_db.newest_activity_date is None:
                athlete_from_db.newest_activity_date = activity.start_date
                athlete_from_db.oldest_activity_date = activity.start_date
            else:
                if activity.start_date > athlete_from_db.newest_activity_date:
                    athlete_from_db.newest_activity_date = activity.start_date
                elif activity.start_date < athlete_from_db.oldest_activity_date:
                    athlete_from_db.oldest_activity_date = activity.start_date
            athlete_from_db.save()

        segment_efforts = client.get_activity(activity.id).segment_efforts   # API call

        # per segment effort
        for segment in segment_efforts:
            mysegments[segment.segment.id] = segment.segment  # save to db

    # check if segment leaderboard contains any friends
    for key, segment in mysegments.iteritems():
        leaderboard = client.get_segment_leaderboard(key, following=True).entries   # API call (possibly lots, depends on number of segments)

        # get friend with time < athlete time
        for i, entry in enumerate(leaderboard):
            if entry.athlete_id == athlete_id:
                me = entry

                if i == 0:
                    # I'm already the winner!
                    break

                j = 1
                while j <= i and leaderboard[i - j].elapsed_time == me.elapsed_time:
                    # check for ties, compare each entry from i to zero (possibly)
                    j += 1
                if leaderboard[i - j].elapsed_time == me.elapsed_time:
                    # if they're still tied at the end of the loop, I don't want to see it
                    break

                other = leaderboard[i - j]

                try:
                    new_segment = ChallengedSegment.objects.get(my_id=athlete_id, segment_id=segment.id)
                except ChallengedSegment.DoesNotExist:
                    new_segment = ChallengedSegment()

                new_segment.my_id = athlete_id
                new_segment.their_id = other.athlete_id
                new_segment.their_name = other.athlete_name

                new_segment.my_pr = me.activity_id
                new_segment.their_pr = other.activity_id

                new_segment.my_time = str(me.elapsed_time)
                new_segment.their_time = str(other.elapsed_time)
                new_segment.difference = str(me.elapsed_time - other.elapsed_time)

                new_segment.segment_id = segment.id
                new_segment.segment_name = segment.name
                new_segment.segment_distance = str(unithelper.miles(segment.distance))
                new_segment.save()

                break  # we already found my entry, why keep looking through the list?
def main():
    assert len(args.athlete_ids) == len(args.access_tokens)

    logger.info("app id: %i, fetching activities for ids %s" % \
                (args.id_strava_app, str(args.athlete_ids)))
    
    for i in range( len(args.access_tokens) ): # for each athlete
        client              = Client()
        client.access_token = args.access_tokens[i]
        athlete_id          = args.athlete_ids[i]
        
        # get summary activities first (filterd before detailed activity call)
        time.sleep(TIME_PAUSE)
        activity_ids = get_user_activities(client) 

        # now fetch detailed versions, add to db
        detailed_activites = []
        activity_to_segments = {} # { act_id: 
                                  #    { seg_id : 
                                  #       { "distance" : x, "grade" : y }, }, }

        segment_ranks = {}        # { seg_id : { "auth_athlete_rank" : auth_rank,
                                  #              "other_athletes"    : { other_id : other_rank, } } }
        for act_id in activity_ids:
	    try:
                 activity_to_segments[act_id] = {}

                 time.sleep(TIME_PAUSE)
            
                 detailed_activity = client.get_activity( act_id )
                 detailed_activites.append( detailed_activity )
		 
                 for seg_effort in detailed_activity.segment_efforts:
                     segment   = seg_effort.segment
                     seg_id    = int(segment.id)
                     seg_dist  = float( unithelper.miles(segment.distance) )
                     seg_grade = segment.average_grade
                     seg_dct   = { "distance" : seg_dist, "grade" : seg_grade }

                     activity_to_segments[act_id][seg_id] = seg_dct

                     if segment_ranks.has_key(seg_id): # already have ranks
                         continue                      # might be overlap between activities
                     else:
                         try: # some = hazardous = error
                             time.sleep(TIME_PAUSE) # now get ranks for this segment
                             leaderboard_entries = \
                                 client.get_segment_leaderboard(seg_id, 
                                                                top_results_limit=1).entries
                             segment_ranks[seg_id] = { "auth_athlete_rank" : -1,
                                                       "other_athletes" : {} }

                             for entry in leaderboard_entries:
                                 if entry.athlete_id == athlete_id: 
                                     segment_ranks[seg_id]["auth_athlete_rank"] = entry.rank
                                     continue
                            
                                 other_id   = entry.athlete_id
                                 other_rank = entry.rank
                                 segment_ranks[seg_id]["other_athletes"][other_id] = other_rank

                         except Exception, e:
                             logger.warning("Error with segment_id %i, removing from activity,"\
                                            " trace:\n %s" % (seg_id, traceback.print_exc()))
                             activity_to_segments[act_id].pop(seg_id)
                             continue
		 if len(activity_to_segments[act_id]) > 0:
                     add_activity(conn, athlete_id, detailed_activity) # if made it here, okay
		 else:
		     logger.info("No segments for activity %i, skipping" % act_id)

	    except Exception, e: # occurs with wrong privaleges, eg private activity
	        logger.warning("Error with activity %i for athlete %i, popping. tracebac:\n%s" % \
				(act_id, athlete_id, traceback.print_exc()))
		activity_to_segments.pop(act_id)