def get_strava_token(): """Return a valid strava token. This will initiate the OAUTH dance if needed (register or refresh), or just get the token from disk.""" if get_tokens_from_disk() == {}: client = Client() url = client.authorization_url(client_id=CLIENT_ID, redirect_uri='http://127.0.0.1:5000/authorization') print("Please open this in your browser:" + url) server_address = ('', 5000) httpd = PainfulHTTPServer(server_address, StravaOauthRequestHandler) httpd.serve_until_stopped() # Now the file really shouldn't be empty anymore. tokens = get_tokens_from_disk() # Is our token expired? now = datetime.datetime.now() if now.timestamp() >= (tokens["expires_at"] - 10000): # 10 seconds leeway client = Client() refresh_response = client.refresh_access_token( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, refresh_token=tokens["refresh_token"]) with open(".hurtlocker", "w") as thefile: thefile.write(json.dumps(refresh_response)) tokens = get_tokens_from_disk() return tokens["access_token"]
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
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 get_activity_data(date_start = last_activity_date(), date_end = pd.to_datetime('today', format = "%Y-%m-%d %H:%M:%S")): client = Client() access_token = _get_access_token(client, client_id, client_secret, refresh_token) client = Client(access_token=access_token) stream_list = [] activity_list, stream_list = _get_activity_data(client, date_start = date_start, date_end = date_end) return activity_list, stream_list
async def delete_strava_athletes(strava_athlete_id: int, admin: bool = Depends(is_admin)): strava_athlete = await StravaAthlete.objects.get(id=strava_athlete_id) client = Client(strava_athlete.access_token) try: client.deauthorize() except stravalib_exceptions.AccessUnauthorized: strava_athlete = await refresh_access_token(strava_athlete) client = Client(strava_athlete.access_token) client.deauthorize() await strava_athlete.delete() return strava_athlete
def resolve_webhook(self, object_id: int): """ Resolves a webhook event from Strava by retrieving the activity data and checking it against the user's existing rules. If a match is found, sends the request to Strava to rename it. """ self.refresh() client = Client(access_token=self.access_token) activity = client.get_activity(object_id) # The Strava API doesn't give enough precision in its start latitude and # longitude values, so we have to call the raw stream of points to get what we # need. points = client.get_activity_streams( activity.id, types=["latlng"], resolution="low" ) activity_start = points["latlng"].data[0] current_app.logger.info( f"Webhook event received: Activity {object_id}, User {self.id}, Starting" f"point {activity_start}, Starting time {activity.start_date_local}" ) for rule in self.rules.all(): current_app.logger.info(f"Checking {rule} against activity {object_id}") if rule.check_rule(activity_start, activity.start_date_local): # if not current_app.config.TESTING: client.update_activity(object_id, name=rule.activity_name) current_app.logger.info( f"Activity {activity.id} renamed to {rule.activity_name} for {self}" ) break # No need to check any more activities
def __init__(self): # Strava client to hold information for tracker. self.client = Client() # Time token expires at. self.token_expires_at_ = None # Client information. self.client_id = None self.client_secret = None # Time in seconds between refreshes. self.sleep_time_ = 300 # Number of target activities per week. self.target_ = 4 # Private display object. self.display_ = Display() # Activity tracking variables. self.start_date = datetime.datetime.utcnow().date() self.next_week = self.start_date + datetime.timedelta(weeks=1) self.week_streak = 0 self.num_activities = 0 # Filename of save file. self.save_file_ = 'streak.yaml'
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 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 get_strava_client(config: ConfigParser) -> Client: """ Checks the authentication token and generates the Strava client. Args: config (ConfigParser): app configuration. Returns: if exist, strava client configured with the authentication token. """ token_file_path = Path(check_folder(CONFIG_PATH), TOKEN_FILE_NAME) if token_file_path.is_file(): logger.debug('The token info file (`config/token.json`) was found.') with open(token_file_path, 'r') as file: token_data = json.load(file) token = token_data.get('access_token') # If the file exists but no access token found, check against the temporary auth if not token: logger.warning( 'The token info file (`config/token.json`) was found' ' but the access token could not be read.') token = get_strava_token_from_code_id(config) else: logger.info('The token info file (`config/token.json`) was NOT found. ' 'Retrieving from the temporal authentication code.') token = get_strava_token_from_code_id(config) client = Client(access_token=token) return client
def load_strava_tracks(self, strava_config: str) -> typing.List[Track]: tracks = [] tracks_names = [] if self.cache_dir: self.strava_cache_file = os.path.join(self.cache_dir, strava_config) if os.path.isfile(self.strava_cache_file): with open(self.strava_cache_file) as f: strava_cache_data = json.load(f) tracks = [self._strava_cache_to_track(i) for i in strava_cache_data] tracks_names = [track.file_names[0] for track in tracks] with open(strava_config) as f: strava_data = json.load(f) filter_type = strava_data.pop("activity_type", None) client = Client() response = client.refresh_access_token(**strava_data) client.access_token = response["access_token"] filter_dict = {"before": datetime.datetime.utcnow()} if tracks: max_time = max(track.start_time() for track in tracks) filter_dict = {"after": max_time - datetime.timedelta(days=2)} for activity in client.get_activities(**filter_dict): # tricky to pass the timezone if str(activity.id) in tracks_names: continue if filter_type and activity.type not in ( [filter_type] if isinstance(filter_type, str) else filter_type ): # pylint: disable=superfluous-parens continue t = Track() t.load_strava(activity) tracks.append(t) self._store_strava_tracks_to_cache(tracks) return self._filter_and_merge_tracks(tracks)
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 get_strava_client(): token = get_strava_access_token() rate_limiter = RateLimiter() rate_limiter.rules.append( XRateLimitRule({ 'short': { 'usageFieldIndex': 0, 'usage': 0, # 60s * 15 = 15 min 'limit': 100, 'time': (60 * 15), 'lastExceeded': None, }, 'long': { 'usageFieldIndex': 1, 'usage': 0, # 60s * 60m * 24 = 1 day 'limit': 1000, 'time': (60 * 60 * 24), 'lastExceeded': None } })) client = Client(rate_limiter=rate_limiter) client.access_token = token return client
def load_strava_tracks(self, strava_config: str) -> typing.List[Track]: tracks = [] tracks_names = [] if self.cache_dir: self.strava_cache_file = os.path.join(self.cache_dir, strava_config) if os.path.isfile(self.strava_cache_file): with open(self.strava_cache_file) as f: strava_cache_data = json.load(f) tracks = [ self._strava_cache_to_track(i) for i in strava_cache_data ] tracks_names = [track.file_names[0] for track in tracks] with open(strava_config) as f: strava_data = json.load(f) client = Client() response = client.refresh_access_token(**strava_data) client.access_token = response["access_token"] fliter_dict = {"before": datetime.datetime.utcnow()} if tracks: max_time = max(track.start_time for track in tracks) if max_time: fliter_dict = {"after": max_time - datetime.timedelta(days=2)} for activate in client.get_activities(**fliter_dict): # tricky to pass the timezone if str(activate.id) in tracks_names: continue t = Track() t.load_strava(activate) tracks.append(t) self._store_strava_tracks_to_cache(tracks) return self._filter_and_merge_tracks(tracks)
def process(request): client = Client(request.session['SMOOTHIFY_TOKEN']) activity_id = int(request.session['ACTIVITY_ID']) activity, client = functions.getactivity(activity_id, client) if activity == 0: request.session['ACTIVITY_ERROR'] = 0 return HttpResponseRedirect('/activity/') if activity == 1: request.session['ACTIVITY_ERROR'] = 1 return HttpResponseRedirect('/activity/') gpxfilename = extractgpx.extractgpx(activity, client) request.session['ACTIVITY_NAME'] = activity.name request.session['TIMESTAMP'] = str(activity.start_date) request.session['DISTANCE_STRAVA'] = float(activity.distance) request.session['ACTIVITY_TYPE'] = activity.type request.session['ACTIVITY_PRIVATE'] = activity.private request.session['ACTIVITY_ID'] = activity.id arg1 = smoothen.getgpxstring(gpxfilename) job = queue.enqueue(smoothenhelper, (arg1, )) request.session['SMOOTHENJOB_ID'] = job.id return HttpResponseRedirect('/waitprocess/')
def request_user_login(): print("Requesting user login") client_id = get_string_from_file('client_id') client_secret = get_string_from_file('client_secret') client=Client() LOGIN_URL = client.authorization_url(client_id=client_id, redirect_uri='http://localhost') print(LOGIN_URL) webbrowser.open(LOGIN_URL) try: auth_code = input("Enter the auth_code from the redirected URL: ") write_string_to_file("auth_code", auth_code) except EOFError: print("Unable to read code from stdin. Assuming `auth_code` file is manually populated") auth_code = get_string_from_file('auth_code') token_response = client.exchange_code_for_token(client_id=client_id, client_secret=client_secret, code=auth_code) write_string_to_file("access_token", token_response['access_token']) write_string_to_file("refresh_token", token_response['refresh_token']) print("Token expires at " + str(token_response['expires_at'])) check_if_access_token_valid()
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 main(action, filename): if action != "DOWNLOAD": return 0 try: with open(STRAVA_CREDENTIALS_FILE, 'r') as f: access_token = f.read().strip(' \t\n\r') except FileNotFoundError: print('No Strava credentials provided.') print('You first need to run the script to fetch the credentials') print('./40-upload_to_strava.py') return -1 try: client = Client(access_token=access_token) print('Uploading {}: '.format(os.path.basename(filename)), end='') with open(filename, 'rb') as f: upload = client.upload_activity( activity_file=f, data_type='fit', private=STRAVA_UPLOAD_PRIVATE, ) except (ActivityUploadFailed, FileNotFoundError) as err: print('FAILED') print('Reason:', err) return -1 print('SUCCESS') return 0
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: #Requesting the authorization code to STRAVA code = request.args.get('code') client = Client() access_token = client.exchange_code_for_token( client_id='30922', client_secret='2791ad32fb846e9f5b567f0a0deba5bb168fe533', code=code) logger.info(access_token) extractDataClub(client) return render_template('segment_results.html', segmentsPara=[], segmentsNort=[], segmentsCAM=[], segmentsCAS=[])
def strava_login(): client = Client() authorize_url = client.authorization_url( client_id=STRAVA_CLIENT_ID, redirect_uri=f'{APP_URL}/strava/callback') return RedirectResponse(authorize_url)
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 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 _strava_auth_url(config): client = Client() client_id = config['STRAVA_CLIENT_ID'] redirect = 'http://127.0.0.1:5000/strava_auth' url = client.authorization_url(client_id=client_id, redirect_uri=redirect) return url
def login(): if session.get('access_token', None) is None: return redirect(Client().authorization_url(client_id=STRAVA_CLIENT_ID, redirect_uri=STRAVA_CALLBACK_URL, scope="view_private")) else: token = session.get('access_token') return redirect('/whoami')
def main(): token = get_token() if not token: print("No API token available, can't continue") return client = Client(token) activities = client.get_activities() print("Looking for activites that have 'commute' in the title, but don't " "have the commute property set on them...") interactive = True for a in activities: if not a.commute and "commute" in a.name.lower(): print( "Found activity '{}' on {} - https://www.strava.com/activities/{}" "".format(a.name, a.start_date.astimezone(tz=None), a.id)) i = "" if not interactive: i = "y" while i not in ("y", "n", "a", "q"): i = input("Add the commute tag to this activity? [y/n/a/q]: " ).lower() if i == "y": client.update_activity(a.id, commute=True) print("Added commute tag") elif i == "q": break elif i == "a": interactive = False print("Done")
def pull_data(self, members, challenges): client = Client() for m in members: logger.debug("processing member: {}".format(m)) # Check if the access token needs renewing. Should last 6hrs, so only needs doing once regardless of how many calls we make. if time.time() > m.access_token_expiry: logger.info("Renewing token") refresh_response = client.refresh_access_token( client_id=config.strava_client_id, client_secret=config.strava_client_secret, refresh_token=m.refresh_token) m.access_token = refresh_response['access_token'] m.refresh_token = refresh_response['refresh_token'] m.access_token_expiry = refresh_response['expires_at'] m.save() client.access_token = m.access_token client.refresh_token = m.refresh_token client.token_expires_at = m.access_token_expiry for c in challenges: logger.debug("Processing challenge: {}".format(c)) efforts = client.get_segment_efforts( c.segment_id, start_date_local=c.date_from, end_date_local=c.date_to) for e in efforts: logger.debug("Processing effort: {}".format(e)) Attempt.add(e, m, c)
def get_auth_url(): """Get the Strava authorization URL.""" client = Client() auth_url = client.authorization_url( client_id=STRAVA_CLIENT_ID, redirect_uri= REDIRECT_URI) return auth_url
def login(): c = Client() url = c.authorization_url(client_id=app.config['STRAVA_CLIENT_ID'], redirect_uri=url_for('.logged_in', _external=True), approval_prompt='auto') return render_template('login.html', authorize_url=url)
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 get_activitys(LIMIT): TOKEN = retreve_token(c['client_id'], c['client_secret']) data = list() client = Client(access_token=TOKEN) activitys = client.get_activities(limit=LIMIT) for activ in activitys: data.append(activ.to_dict()) return data