class ActivitiesView(generic.ListView): global _loginId print('ActivitiesView') template_name = 'strava2/activity_list.html' context_object_name = 'activities_list' def get_queryset(self): #swagger_client.configuration.access_token = self.request.session.get('access_token') #api_instance = swagger_client.ActivitiesApi() #print ('api_instance=',api_instance) #before = 56 # Integer | An epoch timestamp to use for filtering activities that have taken place before a certain time. (optional) #after = 56 # Integer | An epoch timestamp to use for filtering activities that have taken place after a certain time. (optional) #page = 56 # Integer | Page number. (optional) #per_page = 56 #api_response = api_instance.get_logged_in_athlete_activities(before=before, after=after, page=page, per_page=per_page) #pprint(api_response) self.client = Client(self.request.session.get('access_token')) return Activity.objects.filter( uid=self.client.get_athlete().id).order_by('-strTime') def get_context_data(self, **kwargs): context = super(ActivitiesView, self).get_context_data(**kwargs) login = get_object_or_404(Login, pk=_loginId) user = self.client.get_athlete() print("lastname=", user.lastname) print('firstname=', user.firstname) print('mail=', user.email) print('id=', user.id) login.userName = user.lastname login.firstName = user.firstname context['login'] = login return context
def check_if_access_token_valid(): print("Checking Access token valid") access_token = get_string_from_file('access_token') strava = Client() try: strava.access_token = access_token strava.get_athlete() except AccessUnauthorized: print("Access Token not valid") return False print("Access Token valid. Exiting...") sys.exit(0)
def get_activity_map(): # just to see if i can plot my own activity map! f = open('secrets.txt', 'r') MY_STRAVA_CLIENT_ID = f.readline().strip() MY_STRAVA_CLIENT_SECRET = f.readline().strip() STORED_ACCESS_TOKEN = f.readline().strip() f.close() from stravalib import Client client = Client(access_token=STORED_ACCESS_TOKEN) client.get_athlete(7656735) # Get current athlete details #now get most recent activity for this athlete... a=client.get_activities(before = "2016-08-11T00:00:00Z", limit=1) session['map']=a.map session['name']=a.name
async def strava_callback(background_task: BackgroundTasks, code: str, scope: str, state: str = None): client = Client() token_response = client.exchange_code_for_token( client_id=STRAVA_CLIENT_ID, client_secret=STRAVA_CLIENT_SECRET, code=code) client = Client(access_token=token_response['access_token']) athlete = client.get_athlete() try: strava_athlete = await StravaAthlete.objects.get(id=athlete.id) except orm_exceptions.NoMatch: strava_athlete = await StravaAthlete.objects.create( id=athlete.id, access_token=token_response['access_token'], refresh_token=token_response['refresh_token'], token_expiration_datetime=datetime.utcfromtimestamp(token_response['expires_at']).isoformat()) background_task.add_task(new_athlete, strava_athlete) response = RedirectResponse('/reports') jwt_token = create_jwt_token(sub=strava_athlete.id) response.set_cookie( key="jwt_token", value=jwt_token, httponly=True) return response
def main(): access_token = getToken() if access_token == None: return redirectAuth() client = Client(access_token=access_token) athlete = client.get_athlete() # Get current athlete details #if you want a simple output of first name, last name, just use this line: #return athlete.firstname + ' ' + athlete.lastname #now get most recent activity for this athlete... names = [] maps = [] for a in client.get_activities(before = "2016-08-12T00:00:00Z", limit=1): names.append(a.name) maps.append(a.map) # another simple output for this bit is to return the name of the route #return names[0] # but a sightly more complicated output is this matplotlib figure -- m = maps[0] summary_lat_lon = polyline.decode(m.summary_polyline) lats = [i[0] for i in summary_lat_lon] lons = [i[1] for i in summary_lat_lon] session['name']=names[0] session['lats']=lats session['lons']=lons return redirect('/simple.png')
def logged_in(): error = request.args.get('error') state = request.args.get('state') try: if error: return render_template('login_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token( client_id=current_app.config['STRAVA_CLIENT_ID'], client_secret=current_app.config['STRAVA_CLIENT_SECRET'], code=code) strava_athlete = client.get_athlete() session.parmanent = True session['access_token'] = access_token return render_template('login_results.html', athlete=strava_athlete, access_token=access_token) except Exception as e: return render_template('login_error.html', error=str(e))
def authorization(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('authorization_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token(client_id=app.config['STRAVA_CLIENT_ID'], client_secret=app.config['STRAVA_CLIENT_SECRET'], code=code) # Use the now-authenticated client to get the current athlete strava_athlete = client.get_athlete() athlete_model = data.register_athlete(strava_athlete, access_token) multiple_teams = None no_teams = False team = None try: team = data.register_athlete_team(strava_athlete=strava_athlete, athlete_model=athlete_model) except bafs.exc.MultipleTeamsError as multx: multiple_teams = multx.teams except bafs.exc.NoTeamsError: no_teams = True return render_template('authorization_success.html', athlete=strava_athlete, team=team, multiple_teams=multiple_teams, no_teams=no_teams)
def authenticate(self, code): logger.info('StravaV3Backend.authenticate begging') client_id = settings.CLIENT_ID client_secret = settings.CLIENT_SECRET # Make the request to the API client = Client() access_token = client.exchange_code_for_token(client_id=client_id, client_secret=client_secret, code=code) athlete = client.get_athlete() # username must be unique hence use id username = "******" % (athlete.id , athlete.firstname, athlete.lastname) # Get or create the user (returns tuple) try: user = User.objects.get(id=athlete.id) except: logger.error('User.objects.get failed') user = User(id=athlete.id) # Update username logger.info('Update username: '******'Update token: '+access_token) token_model.token = access_token token_model.code = code token_model.save() logger.info(user) # Return the user return user
def authorization(): code = request.args.get('code') client = Client() token_response = client.exchange_code_for_token( client_id=os.environ.get('CLIENT_ID'), client_secret=os.environ.get('CLIENT_SECRET'), code=code) access_token = token_response['access_token'] client = Client(access_token=access_token) athlete = client.get_athlete() r_out = requests.get(API_BASE_URL + '/segments/' + LEGENDS_OUT + '/all_efforts' + '?access_token=' + access_token) legends_out_data = r_out.json() r_back = requests.get(API_BASE_URL + '/segments/' + LEGENDS_BACK + '/all_efforts' + '?access_token=' + access_token) legends_back_data = r_back.json() if (len(legends_out_data) == 0 or len(legends_back_data) == 0) and \ (int(athlete.id) != 13260725 and int(athlete.id) != 18685549): return redirect(url_for('not_legend')) # user is authorized at this point response = redirect(url_for('chat')) response.set_cookie('name', athlete.firstname + ' ' + athlete.lastname) response.set_cookie('authcookie', os.environ.get('VERIFICATION_KEY')) return response
def getActivitiesView(request): global _loginId #print (' >>>> getActivitiesView, get_queryset') client = Client(request.session.get('access_token')) print(' >>>> getActivitiesView, client=', client) act = Activity.objects.filter( uid=client.get_athlete().id).order_by('-strTime') #print (' >>>> getActivitiesView, acts=',act) tid = request.session.get('task_id') result = AsyncResult(tid) print(' >>>> getActivitiesView, state=', result.state) print(' >>>> getActivitiesView, meta_data=', result.info) actList = [] for actItem in act: #print (actItem) serializer = ActivityItemSerializer(actItem) #print ('serializer.data: ',serializer.data) actList.append(serializer.data) if (result.info['total'] is None): result.info['total'] = 0 if (result.info['current'] is None): result.info['current'] = 0 data = { 'nbAct': result.info['total'], 'currentAct': result.info['current'], 'activities': actList } #print ('data=',data) return JsonResponse(data)
def process(): token = session.get('access_token', None) if token is None: return redirect(url_for('login')) client = Client(token) athlete = client.get_athlete() activities = client.get_activities() points = [pnt for a in activities for pnt in (a.end_latlng, a.start_latlng) if pnt] #temp = [pnt for ints in point_intercepts(points) for pnt in ints] #temp = filter_close_points(points) seg = [] for grps in group_points(points): out = [] for pnt in grps: out.append("<trkpt lat=\"{0.lat}\" lon=\"{0.lon}\"></trkpt>".format(pnt)) seg.append("<trkseg>{}</trkseg>".format("".join(out))) return """<?xml version="1.0" encoding="UTF-8"?> <gpx version="1.0"> <name>TEST</name> <trk>{}</trk> </gpx>""".format("".join(seg)) return "<html><body><img src='{}'/>{} {}</body></html>".format(athlete.profile, athlete.firstname, athlete.lastname)
def get(self, request, athlete_id): if request.user.is_authenticated(): template = loader.get_template('athlete.html') try: token = StravaToken.objects.get(user=request.user.id) except ObjectDoesNotExist: logger.error("Either the entry or blog doesn't exist.") client_id = settings.CLIENT_ID client_secret = settings.CLIENT_SECRET client = Client(access_token=token.token) logger.info(token.user) logger.info(token.token) athlete = client.get_athlete() logger.info(athlete.city) activities = client.get_activities(limit=10) for activity in activities: logger.info( u"{0.name} {0.moving_time} {0.suffer_score}".format( activity)) context = { # 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request)) else: raise Http404("user is not login.")
def get_activity_data(access_token): client = Client(access_token) athlete = client.get_athlete() activity_stats = client.get_athlete_stats() run_count = activity_stats.all_run_totals.count bike_count = activity_stats.all_ride_totals.count swim_count = activity_stats.all_swim_totals.count total_count = run_count + bike_count + swim_count all_activities = client.get_activities() run_activities = [] swim_activities = [] bike_activities = [] calorie_count = 0.0 for activity in all_activities: if (activity.type == "Run"): run_activities.append(activity) calorie_count += (float(activity.distance) / 1000) * float(athlete.weight) * 1.036 if (activity.type == "Swim"): swim_activities.append(activity) if (activity.type == "Ride"): bike_activities.append(activity) return ({"Runs": run_activities, "Swims" : swim_activities, "Rides": bike_activities, "Calorie_Count" : calorie_count})
def main(): with open('secrets.txt') as f: MY_STRAVA_CLIENT_ID = f.readline().strip() MY_STRAVA_CLIENT_SECRET = f.readline().strip() with open('maps.txt') as f: gid = f.readline().strip() session['gid']=gid #google map api key access_token = getToken(MY_STRAVA_CLIENT_ID, MY_STRAVA_CLIENT_SECRET) if access_token == None: return redirectAuth(MY_STRAVA_CLIENT_ID) #session['access_token'] = access_token client = Client(access_token=session['access_token']) athlete = client.get_athlete() # Get current athlete details clubs = athlete.clubs session['num_clubs']=len(clubs) cnames = [] cids = [] for i in range(len(clubs)): cnames.append(clubs[i].name) cids.append(clubs[i].id) session['cids']=cids session['cnames']=cnames session['athlete_name'] = athlete.firstname + ' ' + athlete.lastname return redirect('/cluboptions')
def details(id): racer = Racer.query.get_or_404(id) teams = (Team.query.join(Participant) .join(Racer) .filter_by(id=id) .join(Race) .order_by(Race.date.desc()) .all()) current_team = racer.current_team if current_team in teams: teams.remove(current_team) current_year = datetime.date.today().year current_membership = ( AcaMembership.query.with_entities( AcaMembership.paid, AcaMembership.season_pass) .filter(AcaMembership.year == current_year) .filter(AcaMembership.racer_id == racer.id) ).first() strava_client = Client() strava_client_id = current_app.config['STRAVA_CLIENT_ID'] strava_url = ( strava_client.authorization_url( client_id=strava_client_id, redirect_uri=url_for('racer.authorize_strava', _external=True), state=racer.id, approval_prompt='force')) if racer.strava_access_token: access_token = racer.strava_access_token try: strava_client = Client(access_token) strava_client.get_athlete() except Exception: racer.strava_access_token = None racer.strava_id = None racer.strava_email = None racer.strava_profile_url = None racer.strava_profile_last_fetch = None current_app.logger.info('forced strava deauth %s[%d]', racer.name, racer.id) db.session.commit() return render_template('racer/details.html', racer=racer, current_membership=current_membership, current_team=current_team, teams=teams, strava_url=strava_url)
def give_kudos(activity_id): client = Client(access_token=os.environ.get('STRAVA_ACCESS_TOKEN')) activity = client.get_activity(activity_id) logger.info('activity = {}'.format(activity)) athlete = client.get_athlete(activity.athlete.id) logger.info('Giving kudos to {}'.format(athlete.username)) logger.info('Email: {}'.format(athlete.email)) send_email(athlete, activity)
def logged_in(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('login_error.html', error=error, competition_title=config.COMPETITION_TITLE) else: code = request.args.get('code') client = Client() token_dict = client.exchange_code_for_token(client_id=config.STRAVA_CLIENT_ID, client_secret=config.STRAVA_CLIENT_SECRET, code=code) # Use the now-authenticated client to get the current athlete strava_athlete = client.get_athlete() athlete_model = data.update_athlete_auth(strava_athlete, token_dict) if not athlete_model: return render_template('login_error.html', error="ATHLETE_NOT_FOUND", competition_title=config.COMPETITION_TITLE) multiple_teams = None no_teams = False team = None message = None try: team = data.register_athlete_team( strava_athlete=strava_athlete, athlete_model=athlete_model, ) except MultipleTeamsError as multx: multiple_teams = multx.teams message = multx except NoTeamsError as noteamsx: no_teams = True message = noteamsx if not no_teams: auth.login_athlete(strava_athlete) return redirect(url_for('user.rides')) else: return render_template( 'login_results.html', athlete=strava_athlete, team=team, multiple_teams=multiple_teams, no_teams=no_teams, message=message, competition_title=config.COMPETITION_TITLE, )
def main(): # Creating a log file and a logging function log = open("log.txt","a+") now = str(datetime.now()) def logger (message): log.write(now + " | " + message + "\n") print(message) # Opening the connection to Strava logger("Connecting to Strava") client = Client() # You need to run the strava_local_client.py script - with your application's ID and secret - to generate the access token. access_token = "442a2a9e4db1f7008fc96789e18c16e05875305d" # replace this with your token client.access_token = access_token athlete = client.get_athlete() logger("Now authenticated for " + athlete.firstname + " " + athlete.lastname) # We open the cardioactivities CSV file and start reading through it with open('logarun.csv') as csvfile: activities = csv.reader(csvfile) activity_counter = 0 for row in activities: if row[2] == 'time': continue if activity_counter >= 500: logger("Upload count at 500 - pausing uploads for 15 minutes to avoid rate-limit") time.sleep(900) activity_counter = 0 if row[0] not in log: logger("Manually uploading " + row[0]) duration = int(float(row[2])) # time in seconds dist = float(row[1])*1609.344 # convert miles to meters starttime = row[0] strava_activity_type = "Run" try: upload = client.create_activity( name = "logarun Run", start_date_local = starttime, elapsed_time = duration, distance = dist, description = "Shoe used: " + row[3], activity_type = strava_activity_type ) logger("Manually created " + row[0]) activity_counter += 1 except ConnectionError as err: logger("No Internet connection: {}".format(err)) exit(1) logger("Complete! Logged " + str(activity_counter) + " activities.")
def add_user(code: str): """ Takes a temporary access code returned from Strava and retrieves the associated user and access token. Then it checks for the user in the database. If they're not found, then the new user is recorded. If they are found, then just the access token is recorded in case it has changed. """ client = Client() if not Config.TESTING: response = client.exchange_code_for_token( client_id=Config.CLIENT_ID, client_secret=Config.CLIENT_SECRET, code=code, ) current_app.logger.debug("Response: " + str(response)) client.access_token = response["access_token"] access_token = response["access_token"] refresh_token = response["refresh_token"] access_expr = datetime.fromtimestamp(response["expires_at"]) athlete = client.get_athlete() user_id = athlete.id first_name = athlete.firstname else: access_token = "access" refresh_token = "refresh" access_expr = datetime.now() - timedelta(hours=5) user_id = 1 first_name = "joe" # noinspection PyArgumentList # Check if the user is already in the db if User.query.get(user_id) is None: u = User( id=user_id, first_name=first_name, access_token=access_token, refresh_token=refresh_token, access_expr=access_expr, ) db.session.add(u) db.session.commit() current_app.logger.info(f"New user added: {user_id}") else: u = User.query.get(user_id) u.access_token = access_token u.refresh_token = refresh_token u.access_expr = access_expr db.session.commit() current_app.logger.info( f"User {user_id} already found; updating token, logging in," " and redirecting to dashboard" ) return u
class StravaData: """Implementation of the Strava data retriever.""" def __init__(self, hass, accesstoken, devices): self.hass = hass from stravalib import Client from stravalib.util import limiter self._strava_client = Client(access_token=accesstoken, rate_limiter=limiter.DefaultRateLimiter()) self._athlete = self._strava_client.get_athlete() self._accesstoken = accesstoken self._devices = devices self._athlete_stats = None @asyncio.coroutine def fetch_data(self, *_): """Get the athlete stats.""" stats_fetched_ok = False from requests.exceptions import ConnectionError try: athlete_stats = self._strava_client.get_athlete_stats( athlete_id=self._athlete.id) stats_fetched_ok = True except: _LOGGER.warn("Failed to get athlete stats, re-initiating client") from stravalib import Client from stravalib.util import limiter self._strava_client = Client( access_token=self._accesstoken, rate_limiter=limiter.DefaultRateLimiter()) if stats_fetched_ok: self._athlete_stats = athlete_stats.to_dict() yield from self.update_devices() async_call_later(self.hass, 2 * 60, self.fetch_data) @asyncio.coroutine def update_devices(self, *_): if not self._athlete_stats: return tasks = [] for sensor_type in self._athlete_stats: for device in self._devices: if device.type == sensor_type: device.set_state(self._athlete_stats[sensor_type]) tasks.append(device.async_update_ha_state()) if tasks: yield from asyncio.wait(tasks, loop=self.hass.loop)
def welcome_user(strava_auth): if not 'access_token' in strava_auth: raise PreventUpdate client = Client(access_token=strava_auth['access_token']) athlete = client.get_athlete() # print(activity, ) # print("{0.name} {0.moving_time}".format(activity)) return [ athlete.profile, f'{athlete.firstname} {athlete.lastname}', ]
def main(): with open('secrets.txt') as f: MY_STRAVA_CLIENT_ID = f.readline().strip() MY_STRAVA_CLIENT_SECRET = f.readline().strip() access_token = auth.getToken(MY_STRAVA_CLIENT_ID, MY_STRAVA_CLIENT_SECRET) if access_token == None: return auth.redirectAuth(MY_STRAVA_CLIENT_ID) #session['access_token'] = access_token client = Client(access_token=session['access_token']) athlete = client.get_athlete() # Get current athlete details session['athlete_name'] = athlete.firstname + ' ' + athlete.lastname # segment_ids_from_activities(client, max_activities = 5) # sets segment_ids_unique return redirect('/options')
def strava_email(self): if self.strava_access_token is None: return None if self.strava_profile_last_fetch is None or\ (datetime.now(pytz.timezone('UTC')) -\ self.strava_profile_last_fetch)\ > timedelta(minutes=5): self.strava_profile_last_fetch = datetime.now(pytz.timezone('UTC')) strava_client = Client(self.strava_access_token) strava_athlete = strava_client.get_athlete() self.strava_email = strava_athlete.email return self._strava_email
def process(): token = session.get('access_token', None) if token is None: return redirect(url_for('login')) client = Client(token) athlete = client.get_athlete() activities = client.get_activities() for a in activities: if not a.commute and "commute" in a.name.lower(): print(a) client.update_activity(a.id, commute=True) return "<html><body>processed</body></html>"
def get_workout(self, token, pk): client = Client(token) user = client.get_athlete() strUser = StravaUser.objects.filter(uid=user.id) workout = Workout.objects.get(pk=pk) data = "" if workout.jsonData == '': build_workout(self, token, pk, True) print('workout.jsonData=', workout.jsonData) else: sendProgress(strUser[0].channel_name, 60, None) print('Read Json data ...') data = {'progress': 75, 'workout': json.loads(workout.jsonData)} sendMessage('workout', data, strUser[0].channel_name)
def authorization(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') if error: return render_template('authorization_error.html', error=error, competition_title=config.COMPETITION_TITLE) else: code = request.args.get('code') client = Client() token_dict = client.exchange_code_for_token( client_id=config.STRAVA_CLIENT_ID, client_secret=config.STRAVA_CLIENT_SECRET, code=code, ) # Use the now-authenticated client to get the current athlete strava_athlete = client.get_athlete() athlete_model = data.register_athlete(strava_athlete, token_dict) multiple_teams = None no_teams = False team = None message = None try: team = data.register_athlete_team( strava_athlete=strava_athlete, athlete_model=athlete_model, ) except MultipleTeamsError as multx: multiple_teams = multx.teams message = multx except NoTeamsError as noteamx: no_teams = True message = noteamx return render_template( 'authorization_success.html', athlete=strava_athlete, team=team, multiple_teams=multiple_teams, no_teams=no_teams, message=message, competition_title=config.COMPETITION_TITLE, )
def logged_in(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('login_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token( client_id=app.config['STRAVA_CLIENT_ID'], client_secret=app.config['STRAVA_CLIENT_SECRET'], code=code) # Use the now-authenticated client to get the current athlete strava_athlete = client.get_athlete() athlete_model = meta.session_factory().query(Athlete).get( strava_athlete.id) if not athlete_model: return render_template('login_error.html', error="ATHLETE_NOT_FOUND") multiple_teams = None no_teams = False team = None try: team = data.register_athlete_team(strava_athlete=strava_athlete, athlete_model=athlete_model) except MultipleTeamsError as multx: multiple_teams = multx.teams except NoTeamsError: no_teams = True if not no_teams: auth.login_athlete(strava_athlete) return redirect(url_for('user.rides')) else: return render_template('login_results.html', athlete=strava_athlete, team=team, multiple_teams=multiple_teams, no_teams=no_teams)
def get_activity(event: dict, context=None): """ Retrieve the given activity, and its streams, and save the data as one json file to Cloud Storage. Args: event (dict): Dict in Pub/Sub format context: Not used """ # Initialise Google Cloud Storage. Doing this first because to save an # API call if there is a problem loading the bucket. storage_client = storage.Client() bucket = storage_client.bucket(os.getenv('STORAGE_BUCKET_NAME')) # Parse the Pub/Sub message data. data = json.loads(base64.b64decode(event['data']).decode('utf-8')) logging.info(data) # Check if a fresh token is required. if sm.expires_at < datetime.now().timestamp(): refresh_access_token() client = Client(access_token=sm.access_token) # Check we're logged in correctly. logger.info('Logged in as athlete %s', client.get_athlete()) # Download the activity data. activity = client.get_activity(data['object_id']) activity_dict = activity.to_dict() logger.debug('Activity %s: %s', activity.id, activity_dict) # Download the streams data. streams = client.get_activity_streams(activity.id, STREAM_TYPES) logger.debug(streams) # Append the streams data to the activity data. This is the only # manipulation in this workflow; everything else should be manipulated # when you read this file from Cloud Storage. activity_dict['streams'] = {k: v.to_dict() for k, v in streams.items()} logger.debug(activity_dict) # Save to Cloud Storage. blob = bucket.blob(f'{activity.id}.json') blob.upload_from_string(json.dumps(activity_dict), content_type="application/json") return 0
def strava_profile_url(self): if self.strava_access_token is None: return None if self.strava_profile_last_fetch is None or\ (datetime.now(pytz.timezone('UTC')) -\ self.strava_profile_last_fetch)\ > timedelta(minutes=5): self.strava_profile_last_fetch = datetime.now(pytz.timezone('UTC')) strava_client = Client(self.strava_access_token) strava_athlete = strava_client.get_athlete() if strava_athlete.profile == 'avatar/athlete/large.png': self.strava_profile_url = None else: self.strava_profile_url = strava_athlete.profile return self._strava_profile_url
def token(request): # Get temporary code after the request code = request.GET.get("code") # exchange the code for an access token. client = Client() access_token = client.exchange_code_for_token(client_id=STRAVA_CLIENT_ID, client_secret=STRAVA_CLIENT_SECRET, code=code) # Get Athlete athlete = client.get_athlete() # See if the athlete exists in our DB # current_athlete = get_object_or_404(Athlete, id_strava = athlete.id) # current_athlete = "" try: current_athlete = Athlete.objects.get(id_strava = athlete.id) except (KeyError, Athlete.DoesNotExist): current_athlete = Athlete(first_name=athlete.firstname, last_name=athlete.lastname, access_token=access_token, id_strava = athlete.id ) current_athlete.save() # ************************** # Prep content for the HTML page. # Get Activities. activities = client.get_activities() # Make a list of activities to send to the html page. These are all the activities for this athlete. activity_list = [] name_list = [] for a in activities: temp = [a.id, a.name, a.distance, a.moving_time, a.elapsed_time, a.start_date_local] activity_list.append(temp) # information to send to the html page context = { 'activity_list': activity_list, 'current_athlete': current_athlete } template = loader.get_template('shred/activities.html') return HttpResponse(template.render(context))
def authorize_strava(): if request.args.get('state') and request.args.get('code'): id = request.args.get('state') strava_code = request.args.get('code') strava_client_id = current_app.config['STRAVA_CLIENT_ID'] strava_client_secret = current_app.config['STRAVA_CLIENT_SECRET'] strava_client = Client() try: access_token = ( strava_client.exchange_code_for_token( client_id=strava_client_id, client_secret=strava_client_secret, code=strava_code)) except Exception: return redirect(url_for('racer.index')) else: racer = Racer.query.get_or_404(id) strava_client = Client(access_token) strava_athlete = strava_client.get_athlete() existing_racer = Racer.query\ .filter_by(strava_id=strava_athlete.id)\ .first() if existing_racer: flash('Racer ' + existing_racer.name + ' already linked with Strava account for ' + strava_athlete.firstname + ' ' + strava_athlete.lastname + '!') current_app.logger.info('%s[%d] failed against %s[%d]', racer.name, racer.id, existing_racer.name, existing_racer.id) return redirect(url_for('racer.details', id=id)) else: racer.strava_access_token = access_token racer.strava_id = strava_athlete.id racer.strava_email = strava_athlete.email racer.profile_url = strava_athlete.profile db.session.commit() current_app.logger.info('%s[%d]', racer.name, racer.id) flash('Racer ' + racer.name + ' linked with Strava!') return redirect(url_for('racer.details', id=id)) return redirect(url_for('racer.index'))
def getCourseInfo(): STORED_ACCESS_TOKEN = "903910abaf69b186957a22c1227d6f19237cd233" client = Client(access_token=STORED_ACCESS_TOKEN) athlete_data = client.get_athlete() activity_id = 887327831 activity = client.get_activity(887327831) types = ['time', 'altitude', 'velocity_smooth', 'distance', 'grade_smooth', 'watts','latlng'] streams = client.get_activity_streams(activity_id, types = types, resolution='medium') # for i in range(0, len(streams['time'].data)): # print "{} {}".format(streams['distance'].data[i], streams['watts'].data[i]) x = streams['distance'].data y = streams['altitude'].data inclin = streams['grade_smooth'].data latlng = streams['latlng'].data return {'x':x,'y': y, 'inclin':inclin, 'latlng': latlng}
def logged_in(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('login_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token(client_id=app.config['STRAVA_CLIENT_ID'], client_secret=app.config['STRAVA_CLIENT_SECRET'], code=code) # Use the now-authenticated client to get the current athlete strava_athlete = client.get_athlete() athlete_model = db.session.query(Athlete).get(strava_athlete.id) if not athlete_model: return render_template('login_error.html', error="ATHLETE_NOT_FOUND") multiple_teams = None no_teams = False team = None try: team = data.register_athlete_team(strava_athlete=strava_athlete, athlete_model=athlete_model) except bafs.exc.MultipleTeamsError as multx: multiple_teams = multx.teams except bafs.exc.NoTeamsError: no_teams = True if not no_teams: auth.login_athlete(strava_athlete) return redirect(url_for('user.rides')) else: return render_template('login_results.html', athlete=strava_athlete, team=team, multiple_teams=multiple_teams, no_teams=no_teams)
def logged_in(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('login_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token(client_id=app.config['STRAVA_CLIENT_ID'], client_secret=app.config['STRAVA_CLIENT_SECRET'], code=code) # Probably here you'd want to store this somewhere -- e.g. in a database. strava_athlete = client.get_athlete() return render_template('login_results.html', athlete=strava_athlete, access_token=access_token)
def token(request): code = request.GET.get("code", None) if not code: return HttpResponse('<a href=' + reverse('index') + '>Failed, try again.</a>') else: client = Client() access_token = client.exchange_code_for_token( client_id=os.environ['SMOOTHIFY_ID'], client_secret=os.environ['SMOOTHIFY_SECRET'], code=code) request.session['SMOOTHIFY_TOKEN'] = access_token athlete = client.get_athlete() request.session['ATHLETE_FIRSTNAME'] = athlete.firstname request.session['ACTIVITY_ERROR'] = None return HttpResponseRedirect('/activity/')
def dave(): config = configparser.ConfigParser() config.read(BEE42_INI) ini_beeminder = config[BEE42_INI_BEEMINDER] username = ini_beeminder[BEE42_INI_USERNAME] token = ini_beeminder[BEE42_INI_TOKEN] strava_token = ini_beeminder[BEE42_INI_STRAVA_TOKEN] user = User(username, token) print("Username:"******"tz:", user.timezone, "update:", user.updated_at, "goals", user.goalslugs, "db:", user.deadbeat) strava_client = Client(access_token=strava_token) strava_athlete = strava_client.get_athlete() print(strava_athlete.firstname) strava_activities = strava_client.get_activities(limit=15) for a in strava_activities: if (a.type == "Run"): print(add_run(user, a)) elif (a.type == "Ride"): print(add_ride(user, a))
def index(request): access_token = request.session.get('access_token', None) if access_token is None: # if access_token is NOT in session, kickoff the oauth exchange client = Client() url = client.authorization_url( client_id=os.environ.get('STRAVA_CLIENT_ID', None), redirect_uri='http://' + settings.ALLOWED_HOSTS[0] + '/authorization' # redirect_uri='http://127.0.0.1:8000/authorization' ) context = {'auth_url': url} return render(request, 'index.html', context) # otherwise, load authorized user client = Client(access_token=access_token) athlete_id = request.session.get('athlete_id', None) if athlete_id is None: # if athlete is NOT already in session, get athlete # (attempting to reduce calls to the API) athlete = client.get_athlete() request.session['athlete_id'] = athlete.id request.session['firstname'] = athlete.firstname try: Athlete.objects.get(strava_id=athlete.id) except Athlete.DoesNotExist: new_athlete = Athlete() new_athlete.strava_id = athlete.id new_athlete.first_name = athlete.firstname new_athlete.last_name = athlete.lastname new_athlete.city = athlete.city new_athlete.state = athlete.state new_athlete.country = athlete.country new_athlete.save() return render(request, 'welcome_landing.html')
def auth(request): global _loginId print("Auth") code = request.GET.get('code') print("code=", code) scope = request.GET.get('scope') print("scope=", scope) login = get_object_or_404(Login, pk=_loginId) client = Client() access_token = client.exchange_code_for_token( client_id=login.clientID, client_secret=login.clientSecret, code=code) print("access_token=", access_token) user = client.get_athlete() strUser = StravaUser.objects.filter(uid=user.id) if not strUser.exists(): print('create user', ) strUser = StravaUser(uid=user.id, lastname=user.lastname, firstname=user.firstname, \ lastUpdate=(datetime.now()-timedelta(days=30)), token=access_token) strUser.save() else: strUser.update(token=access_token) request.session['access_token'] = access_token #request.session['access_token'] = 'ff4f273a775a57ce1c7dcc837e18a059370d338c' return redirect('/strava2/activities')
def logged_in(): """ Method called by Strava (redirect) that includes parameters. - state - code - error """ error = request.args.get('error') state = request.args.get('state') if error: return render_template('login_error.html', error=error) else: code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token( client_id=app.config['STRAVA_CLIENT_ID'], client_secret=app.config['STRAVA_CLIENT_SECRET'], code=code) # Probably here you'd want to store this somewhere -- e.g. in a database. strava_athlete = client.get_athlete() return render_template('login_results.html', athlete=strava_athlete, access_token=access_token)
global gpsd #bring it in scope gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info self.current_value = None self.running = True #setting the thread running to true def run(self): global gpsd while gpsp.running: gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer #client = Client() client = Client(access_token=STORED_ACCESS_TOKEN) gmaps = googlemaps.Client(key='AIzaSyAWAcpS14bsm6zgzOG2hnMBwRILtdwYEFY') athlete = client.get_athlete(77138) print("Hello, {}".format(athlete.firstname)) print("Hello, {}. I know your email is {}".format(athlete.firstname, athlete.email)) url = "https://www.strava.com/api/v3/segments/starred" header = {'Authorization': 'Bearer 59415871d89656eaf18fb8bee6a999c0a332489e'} response = r.get(url, headers=header).json() #print(response) for i in range(0,1): #len(response)): print(response[i]['name']) start_latitude = response[i]['start_latitude']
# Creating a log file and a logging function log = open("log.txt","a+") now = str(datetime.now()) def logger (message): log.write(now + " | " + message + "\n") print message # Opening the connection to Strava logger("Connecting to Strava") client = Client() # You need to run the strava_local_client.py script - with your application's ID and secret - to generate the access token. access_token = "your_token" # replace this with your token client.access_token = access_token athlete = client.get_athlete() logger("Now authenticated for " + athlete.firstname + " " + athlete.lastname) # Creating an archive folder to put uploaded .gpx files archive = "../archive" # Function to convert the HH:MM:SS in the Runkeeper CSV to seconds def duration_calc(duration): # Splits the duration on the :, so we wind up with a 3-part array split_duration = str(duration).split(":") # If the array only has 2 elements, we know the activity was less than an hour if len(split_duration) == 2: hours = 0 minutes = int(split_duration[0])
def authorization(request): client = Client() code = request.GET['code'] access_token = client.exchange_code_for_token(client_id=MY_STRAVA_CLIENT_ID, client_secret=MY_STRAVA_CLIENT_SECRET, code=code) # making a global variable to be used across views. don't know how this will work in practice client = Client(access_token=access_token) athlete = client.get_athlete() # Get current athlete details global athleteId athleteId = athlete.id # if athlete doesn't exist, add them if len(Athlete.objects.filter(athleteId=athleteId)) == 0: ath = Athlete.objects.create(name=str(athlete.firstname+' '+athlete.lastname), athleteId=athleteId, profilePic=athlete.profile, city=athlete.city, country=athlete.country, sex=athlete.sex, premium=athlete.premium, created_at=athlete.created_at, updated_at=athlete.updated_at, followers=athlete.follower_count, friends=athlete.friend_count, email=athlete.email, weight=athlete.weight, meas_pref=athlete.measurement_preference, runsSummary = DataFrame({}).to_json(orient='records'), fitLines = DataFrame({}).to_json(orient='records'), masterList = DataFrame({}).to_json(orient='records')) ath.profilePic.name = "rudyzPic" ath.save(update_fields=['profilePic']) # if athlete already exists, draw their file elif len(Athlete.objects.filter(athleteId=athleteId)) == 1: ath = Athlete.objects.get(athleteId=athleteId) ############################################ ##### compiling new runs, updating summary # athlete's existing runs summary existingSummary = DataFrame(pd.read_json(ath.runsSummary)) existingFitlines = DataFrame(pd.read_json(ath.fitLines)) masterList = DataFrame(pd.read_json(ath.masterList)) activities = list(client.get_activities()) # activity IDs of runs already in the system try: ids = existingSummary.activityId except AttributeError: ids = [] for i in range(len(activities)): #for i in range(30,37): # Ignoring activities already in the system if (len(ids) == 0) or (float(activities[i].id) not in list(ids)): try: # compiling df for raw json-ization activityId = activities[i].id run = client.get_activity_streams(activityId, types=['time','latlng','distance','heartrate','altitude','cadence']) latlng = run['latlng'].data time = run['time'].data distance = run['distance'].data heartrate = run['heartrate'].data altitude = run['altitude'].data cadence = run['cadence'].data date = activities[i].start_date_local activity = activityId dfi = thresher.assemble(date, activityId, heartrate, distance, time, altitude, latlng, cadence) # basic cleanup, only removing totally unreasonable values dfi = thresher.basicClean(dfi) # if we ever want to try our hand at improving strava's speed data (ie by predicting speed when GPS blanks), intervene here: #dfi = thresher.addDistDeltas(dfi) try: fitline = thresher.getFitlineLws(dfi) # this adds speed-shifted columns except: fitline = pd.DataFrame({}) try: mafScore = fitline[fitline.hr == 140.0].avgSpeed.iloc[0] print "MAF " print mafScore except: mafScore = np.nan fitline_json = fitline.to_json(orient='records') # getting summary info for run (as one-entry dict) runSummary = thresher.getSingleSummaryDf(dfi) # adding mafScore to summary runSummary['mafScore'] = mafScore print runSummary # adding predicted hr and speed values #dfi = thresher.getPred(dfi) # saving entry to database Activity.objects.create(act_id = activityId, name=str(activities[i].name), description=activities[i].description, act_type=activities[i].type, date=activities[i].start_date_local, timezone=activities[i].timezone, df=dfi.to_json(orient='records'), avgHr=runSummary['avgHr'], hrVar=runSummary['variation'], realMiles=runSummary['realMiles'], recovery=runSummary['recovery'], easy=runSummary['easy'], stamina=runSummary['stamina'], impulse=runSummary['impulse'], totalTime=runSummary['totalTime'], totalDist=runSummary['totalDist'], climb=runSummary['climb'], fitline=fitline_json, mafScore=mafScore, athlete=ath) # updating runs summary existingSummary = existingSummary.append(runSummary, ignore_index=True) existingFitlines = existingFitlines.append(fitline, ignore_index=True) masterList = masterList.append(dfi, ignore_index=True) except: continue # saving updated runs summary to athlete profile ath.runsSummary = existingSummary.to_json(orient='records') ath.save(update_fields=['runsSummary']) existingSummary.to_pickle("runsSummary.txt") # saving updated runs summary to athlete profile ath.fitLines = existingFitlines.to_json(orient='records') ath.save(update_fields=['fitLines']) ath.masterList = masterList.to_json(orient='records') ath.save(update_fields=['masterList']) # testing... existingSummary = pd.read_json(ath.runsSummary) #print(existingSummary) existingFitlines = pd.read_json(ath.fitLines) #print(existingFitlines) global path path = os.path.dirname(__file__) # updating dataframe, pickling for use in other views #global df #df = thresher.masterAssemble(client) masterDf = pd.read_json(ath.masterList) #print(masterDf) masterDf.to_pickle(str(path)+"/"+str(athlete.id)+"masterDf.txt") return render(request, 'stravaChimp/authorization.html', {'code':code, 'access_token':access_token, 'athleteId':athleteId})
""" import json, os, io from datetime import datetime from stravalib import Client from instance import hidden_conf # Import secret token STORED_ACCESS_TOKEN = hidden_conf.get_access_token() client = Client(access_token=STORED_ACCESS_TOKEN) CYCLING_JSON = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data", "cycling_coll.json") SWIMMING_JSON = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data", "swimming_coll.json") # My data my_data = client.get_athlete() # athlete details me = {} me["id"] = my_data.id me["name"] = my_data.firstname + " " + my_data.lastname me["city"] = my_data.city my_bikes = my_data.bikes bikes = {} for b in my_bikes: bike = {} bike[b.id] = b.name bikes.update(bike) me["bikes"] = bikes # Fetch activities this year my_activities = client.get_activities(after=datetime(2015, 1, 1)) #(limit=5) act = []
from requests.exceptions import ConnectionError, HTTPError from datetime import datetime, timedelta # First, load settings from file print("Loading settings...") with open("settings.json", "r") as f: settings = json.load(f) # Then, connect to user Strava account. try: print("Connecting to Strava...") StravaClient = Client() StravaClient.access_token = settings.get('strava_token') # You're logged in ! StravaAthlete = StravaClient.get_athlete() print("Hello, {} {}.\nYou are now connected to Strava.".format( StravaAthlete.firstname, StravaAthlete.lastname)) except HTTPError as err: print("Connecting problem: {}".format(err)) exit(1) # Now we'll try to find activity(ies) to upload. tcxStorageDir = settings.get('archives_dir') # Where TCX files are stored Debug = False # If we need to have some more informations... #Debug = True Year = datetime.now().strftime( "%Y" ) # This exists because TCX files are like : 2015-06-06T15-23-01.000Z_Walking.tcx Exclude = ('UploadedToStrava', 'Endomondo', 'runtastic2strava' ) # List directories we don't want do search into
from stravalib import Client from stravalib import unithelper client = Client(access_token='YourAccessToken') athlete = client.get_athlete() activities = client.get_activities(limit=9000) print athlete.firstname print athlete.lastname print athlete.state print athlete.email atype = [] run = [] rundis = [] runelev = [] walk = [] walkdis = [] walkelev = [] ride = [] ridedis = [] rideelev = [] hike = [] hikedis = [] hikeelev = [] snowshoe = [] snowdis = [] snowelev = [] for a in activities:
def main(): # Creating a log file and a logging function log = open("log.txt", "a+") now = str(datetime.now()) def logger(message): log.write(now + " | " + message + "\n") print(message) # Opening the connection to Strava logger("Connecting to Strava") client = Client() # You need to run the strava_local_client.py script - with your application's ID and secret - to generate the access token. access_token = "your_token" # replace this with your token client.access_token = access_token athlete = client.get_athlete() logger("Now authenticated for " + athlete.firstname + " " + athlete.lastname) # Creating an archive folder to put uploaded .gpx files archive = "../archive" # Function to convert the HH:MM:SS in the Runkeeper CSV to seconds def duration_calc(duration): # Splits the duration on the :, so we wind up with a 3-part array split_duration = str(duration).split(":") # If the array only has 2 elements, we know the activity was less than an hour if len(split_duration) == 2: hours = 0 minutes = int(split_duration[0]) seconds = int(split_duration[1]) else: hours = int(split_duration[0]) minutes = int(split_duration[1]) seconds = int(split_duration[2]) total_seconds = seconds + (minutes * 60) + (hours * 60 * 60) return total_seconds # Translate RunKeeper's activity codes to Strava's, could probably be cleverer def activity_translator(rk_type): if rk_type == "Running": return "Run" elif rk_type == "Cycling": return "Ride" elif rk_type == "Hiking": return "Hike" elif rk_type == "Walking": return "Walk" elif rk_type == "Swimming": return "Swim" elif rk_type == "Elliptical": return "Elliptical" else: return "None" # feel free to extend if you have other activities in your repertoire; Strava activity codes can be found in their API docs # We open the cardioactivities CSV file and start reading through it with open('cardioActivities.csv') as csvfile: activities = csv.DictReader(csvfile) activity_counter = 0 for row in activities: if activity_counter >= 599: logger( "Upload count at 599 - pausing uploads for 15 minutes to avoid rate-limit" ) time.sleep(900) activity_counter = 0 else: # used to have to check if we were trying to process the header row # no longer necessary when we process as a dictionary # if there is a gpx file listed, find it and upload it if ".gpx" in row['GPX File']: gpxfile = row['GPX File'] strava_activity_type = activity_translator(str( row['Type'])) if gpxfile in os.listdir('.'): logger("Uploading " + gpxfile) try: upload = client.upload_activity( activity_file=open(gpxfile, 'r'), data_type='gpx', private=False, description=row['Notes'], activity_type=strava_activity_type) except exc.ActivityUploadFailed as err: logger("Uploading problem raised: {}".format(err)) errStr = str(err) # deal with duplicate type of error, if duplicate then continue with next file, else stop if errStr.find('duplicate of activity'): logger( "Moving duplicate activity file {}".format( gpxfile)) shutil.move(gpxfile, archive) isDuplicate = True logger("Duplicate File " + gpxfile) else: exit(1) except ConnectionError as err: logger("No Internet connection: {}".format(err)) exit(1) logger("Upload succeeded.\nWaiting for response...") try: upResult = upload.wait() except HTTPError as err: logger( "Problem raised: {}\nExiting...".format(err)) exit(1) except: logger("Another problem occured, sorry...") exit(1) logger("Uploaded " + gpxfile + " - Activity id: " + str(upResult.id)) activity_counter += 1 shutil.move(gpxfile, archive) else: logger("No file found for " + gpxfile + "!") #if no gpx file, upload the data from the CSV else: if row['Activity Id'] not in log: logger("Manually uploading " + row['Activity Id']) # convert to total time in seconds dur = duration_calc(row['Duration']) # convert to meters dist = float(row['Distance (mi)']) * 1609.344 starttime = datetime.strptime(str(row['Date']), "%Y-%m-%d %H:%M:%S") strava_activity_type = activity_translator( str(row['Type'])) # designates part of day for name assignment above, matching Strava convention for GPS activities if 3 <= starttime.hour <= 11: part = "Morning " elif 12 <= starttime.hour <= 4: part = "Afternoon " elif 5 <= starttime.hour <= 7: part = "Evening " else: part = "Night " try: upload = client.create_activity( name=part + strava_activity_type + " (Manual)", start_date_local=starttime, elapsed_time=dur, distance=dist, description=row['Notes'], activity_type=strava_activity_type) logger("Manually created " + row['Activity Id']) activity_counter += 1 except ConnectionError as err: logger("No Internet connection: {}".format(err)) exit(1) logger("Complete! Logged " + str(activity_counter) + " activities.")
from requests.exceptions import ConnectionError, HTTPError from datetime import datetime, timedelta # First, load settings from file print("Loading settings...") with open("settings.json", "r") as f: settings = json.load(f) # Then, connect to user Strava account. try: print("Connecting to Strava...") StravaClient = Client() StravaClient.access_token = settings.get('strava_token') # You're logged in ! StravaAthlete = StravaClient.get_athlete() print("Hello, {} {}.\nYou are now connected to Strava.".format(StravaAthlete.firstname, StravaAthlete.lastname)) except HTTPError as err: print("Connecting problem: {}".format(err)) exit(1) # Now we'll try to find activity(ies) to upload. tcxStorageDir = settings.get('archives_dir') # Where TCX files are stored Debug = False # If we need to have some more informations... #Debug = True Year = datetime.now().strftime("%Y") # This exists because TCX files are like : 2015-06-06T15-23-01.000Z_Walking.tcx Exclude = ('UploadedToStrava', 'Endomondo', 'runtastic2strava') # List directories we don't want do search into print("List files to upload...") # Check if directory exists before go ahead.
from config import * from stravalib import Client import sys client = Client() if len( sys.argv ) == 1: url = client.authorization_url(client_id=STRAVA_CLIENT_ID, redirect_uri='http://localhost', scope='view_private,write' ) print "Paste this URL in your browser:" print print url print print "And then re-run this script like so: " print "\t" + sys.argv[0] + " <code>" elif sys.argv[1] == 'test': client = Client( access_token=STRAVA_ACCESS_TOKEN) print client.get_athlete() else: code = sys.argv[1] access_token = client.exchange_code_for_token(client_id=STRAVA_CLIENT_ID, client_secret=STRAVA_CLIENT_SECRET, code=code) print "Your Strava access token is: " + access_token
def main(): # Creating a log file and a logging function log = open("log.txt","a+") now = str(datetime.now()) def logger (message): log.write(now + " | " + message + "\n") print message # Opening the connection to Strava logger("Connecting to Strava") client = Client() # You need to run the strava_local_client.py script - with your application's ID and secret - to generate the access token. access_token = "your_token" # replace this with your token client.access_token = access_token athlete = client.get_athlete() logger("Now authenticated for " + athlete.firstname + " " + athlete.lastname) # Creating an archive folder to put uploaded .gpx files archive = "../archive" # Function to convert the HH:MM:SS in the Runkeeper CSV to seconds def duration_calc(duration): # Splits the duration on the :, so we wind up with a 3-part array split_duration = str(duration).split(":") # If the array only has 2 elements, we know the activity was less than an hour if len(split_duration) == 2: hours = 0 minutes = int(split_duration[0]) seconds = int(split_duration[1]) else: hours = int(split_duration[0]) minutes = int(split_duration[1]) seconds = int(split_duration[2]) total_seconds = seconds + (minutes*60) + (hours*60*60) return total_seconds # Translate RunKeeper's activity codes to Strava's, could probably be cleverer def activity_translator(rk_type): if rk_type == "Running": return "Run" elif rk_type == "Cycling": return "Ride" elif rk_type == "Hiking": return "Hike" elif rk_type == "Walking": return "Walk" elif rk_type == "Swimming": return "Swim" elif rk_type == "Elliptical": return "Elliptical" else: return "None" # feel free to extend if you have other activities in your repertoire; Strava activity codes can be found in their API docs # We open the cardioactivities CSV file and start reading through it with open('cardioActivities.csv', 'rb') as csvfile: activities = csv.reader(csvfile) activity_counter = 0 for row in activities: if activity_counter >= 599: logger("Upload count at 599 - pausing uploads for 15 minutes to avoid rate-limit") time.sleep(900) activity_counter = 0 else: pass if row[0] == "Date": pass else: # if there is a gpx file listed, find it and upload it if ".gpx" in row[11]: gpxfile = row[11] strava_activity_type = activity_translator(str(row[1])) if gpxfile in os.listdir('.'): logger("Uploading " + gpxfile) try: upload = client.upload_activity( activity_file = open(gpxfile,'r'), data_type = 'gpx', private = False, description = row[10], activity_type = strava_activity_type ) except exc.ActivityUploadFailed as err: logger("Uploading problem raised: {}".format(err)) errStr = str(err) # deal with duplicate type of error, if duplicate then continue with next file, else stop if errStr.find('duplicate of activity'): logger("Moving dulicate activity file {}".format(gpxfile)) shutil.move(gpxfile,archive) isDuplicate = True logger("Duplicate File " + gpxfile) else: exit(1) except ConnectionError as err: logger("No Internet connection: {}".format(err)) exit(1) logger("Upload succeeded.\nWaiting for response...") try: upResult = upload.wait() except HTTPError as err: logger("Problem raised: {}\nExiting...".format(err)) exit(1) except: logger("Another problem occured, sorry...") exit(1) logger("Uploaded " + gpxfile + " - Activity id: " + str(upResult.id)) activity_counter += 1 shutil.move(gpxfile, archive) else: logger("No file found for " + gpxfile + "!") #if no gpx file, upload the data from the CSV else: if row[0] not in log: logger("Manually uploading " + row[0]) dur = duration_calc(row[4]) dist = float(row[3])*1609.344 starttime = datetime.strptime(str(row[0]),"%Y-%m-%d %H:%M:%S") strava_activity_type = activity_translator(str(row[1])) # designates part of day for name assignment above, matching Strava convention for GPS activities if 3 <= starttime.hour <= 11: part = "Morning " elif 12 <= starttime.hour <= 4: part = "Afternoon " elif 5 <= starttime.hour <=7: part = "Evening " else: part = "Night " try: upload = client.create_activity( name = part + strava_activity_type + " (Manual)", start_date_local = starttime, elapsed_time = dur, distance = dist, description = row[10], activity_type = strava_activity_type ) logger("Manually created " + row[0]) activity_counter += 1 except ConnectionError as err: logger("No Internet connection: {}".format(err)) exit(1) logger("Complete! Logged " + str(activity_counter) + " activities.")