def add_new_athlete(username, code): # Get API Auth info from DB conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer') # Authenticate athlete client = stravalib.Client() codes = client.exchange_code_for_token(int(os.environ['STRAVA_CLIENT_ID']), os.environ['STRAVA_CLIENT_SECRET'], code) # Get athlete info from Strava client = stravalib.Client(access_token=codes['access_token']) athlete = client.get_athlete() created_at = athlete.created_at if athlete.country == 'United States': unit = 'imperial' else: unit = 'metric' # Default PR value: 6:30 mile, insert athlete vals = f"{athlete.id}, '{codes['access_token']}', '{codes['refresh_token']}', {codes['expires_at']}, '{unit}', '{created_at}', 390, 1609, '{username}', '{athlete.profile}', 'pro', 'N', NULL, NULL" try: db.INSERT(table='athletes', vals=vals, conn=conn) except: conn.close() return False conn.close() return True
def initialize_client(url=None, web=None, scope='', CLIENT_ID=STRAVA_CLIENT_ID, CLIENT_SECRET=STRAVA_CLIENT_SECRET): _client = stravalib.Client() auth_url = _client.authorization_url(client_id=CLIENT_ID, redirect_uri='https://localhost:8000', approval_prompt='force', scope=scope) web.go_to(auth_url) web.click(id='authorize') print('Authorizing R2WImporter access...\n') time.sleep(4) auth_url = web.get_current_url() auth_code = auth_url[auth_url.find('code=') + 5:auth_url.find('&scope')] token = _client.exchange_code_for_token(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, code=auth_code).get('access_token') return stravalib.Client(access_token=token)
def authorized(self, scope=None, state=None, code=None): """ Echange code for a token and set token and athlete_id in the current session :param scope: the scope variable passed to Strava authentification url and returned here. We do not use it, so it is always None but we have to keep it in the argument list as it is part of the url. :param state: the state variable passed to Strava authentification url and returned here. We do not use it, so it is always None but we have to keep it in the argument list as it is part of the url. :param code: the code returned by Strava authentification to be further exchanged for a token. """ print(cherrypy.request.cookie['session_id']) print("authorization - {}".format(cherrypy.session.id)) # Keep session alive cherrypy.session[self.DUMMY] = 'MyStravaAuthorized' client = stravalib.Client() token = client.exchange_code_for_token( client_id=self.config['client_id'], client_secret=self.config['client_secret'], code=code) cherrypy.session[self.TOKEN] = token client = stravalib.Client(access_token=token) athlete = client.get_athlete() cherrypy.session[self.ATHLETE_ID] = athlete.id cherrypy.session[self.ATHLETE_IS_PREMIUM] = athlete.premium print("athlete: {}".format(cherrypy.session.get(self.ATHLETE_ID))) print("token: {}".format(cherrypy.session.get(self.TOKEN))) raise cherrypy.HTTPRedirect(cherrypy.url(path='/', script_name=''))
def authorized(self, scope=None, state=None, code=None): """ Exchange code for a token and set token and athlete_id in the current session :param scope: the scope variable passed to Strava authentification url and returned here. We do not use it, so it is always None but we have to keep it in the argument list as it is part of the url. :param state: the state variable passed to Strava authentification url and returned here. We do not use it, so it is always None but we have to keep it in the argument list as it is part of the url. :param code: the code returned by Strava authentification to be further exchanged for a token. """ print(cherrypy.request.cookie['session_id']) print("authorization - {}".format(cherrypy.session.id)) # Keep session alive cherrypy.session[self.DUMMY] = 'MyStravaAuthorized' client = stravalib.Client() auth_response = client.exchange_code_for_token( client_id=self.config['client_id'], client_secret=self.config['client_secret'], code=code) token = auth_response['access_token'] refresh_token = auth_response['refresh_token'] expires_at = auth_response['expires_at'] cherrypy.session[self.ACCESS_TOKEN] = token cherrypy.session[self.REFRESH_TOKEN] = refresh_token cherrypy.session[self.EXPIRES_AT] = expires_at client = stravalib.Client(access_token=token) athlete = client.get_athlete() cherrypy.session[self.ATHLETE_ID] = athlete.id cherrypy.session[self.ATHLETE_IS_PREMIUM] = athlete.premium print("-------") print("athlete: {}".format(cherrypy.session.get(self.ATHLETE_ID))) print("token: {}".format(cherrypy.session.get(self.ACCESS_TOKEN))) print("refresh token: {}".format( cherrypy.session.get(self.REFRESH_TOKEN))) print("expires at: {}".format( time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime(cherrypy.session.get(self.EXPIRES_AT))))) print("Session ID : {}".format(cherrypy.session.id)) print("Access code : {}".format(code)) print("-------") raise cherrypy.HTTPRedirect(cherrypy.url(path='/', script_name=''))
def upload(ctx): config = _load_config(ctx.obj['config_file']) token_config = _load_config(ctx.obj['token_file']) workout_dir = ctx.obj['workout_dir'] if token_config['access_token'] is None or token_config['expires_at'] is None or time.time( ) > token_config['expires_at']: logging.error("Access token missing or expired") sys.exit(1) strava = stravalib.Client() strava.access_token = token_config['access_token'] logging.debug(f"Using strava access token {strava.access_token}") athlete = strava.get_athlete() logging.debug(f"Strava athlete id {athlete.id}") ifit_workouts = _get_ifit_workouts(workout_dir) earliest_workout_start = ifit_workouts[0].started_at logging.debug(f"Earliest iFit workout started at {earliest_workout_start}") strava_activities = list(strava.get_activities(after=earliest_workout_start)) for workout in ifit_workouts: if _should_skip(workout, config['skip']): continue similar_activities = find_similar_activities(workout, strava_activities) if len(similar_activities) != 0: logging.debug(f"Skipping workout {workout} due to similar activities {similar_activities}") else: _strava_upload(workout, strava)
def sync(strava_account_id, manual_sync=True): """ Sync with a specific strava account. """ strava_account = StravaAccount.objects.get(id=strava_account_id) sclient = stravalib.Client() stats = { "new_trips": 0, "synced_trips": 0, "synced_activities": 0, "activities": [], # TODO "client": sclient, } try: if manual_sync: strava_account.user_sync_count += 1 else: strava_account.user_sync_count = 0 strava_account.errors = "" refresh_tokens(strava_account, sclient) earliest_start_date, latest_end_date = Phase.get_active_range( "entry_enabled") campaigns = [] for competition_phase in Phase.get_active().filter( phase_type="entry_enabled"): campaigns.append(competition_phase.campaign) hashtag_table = hashtags.HashtagTable(campaigns) activities = sclient.get_activities( after=datetime.combine(earliest_start_date, datetime.min.time()), before=datetime.combine(latest_end_date, datetime.max.time()), ) strava_account.last_sync_time = datetime.now() for activity in activities: try: sync_activity(activity, hashtag_table, strava_account, sclient, stats) except Exception as e: from raven.contrib.django.raven_compat.models import client client.captureException() strava_account.errors += ( "Error syncing activity {activity} \n{e}\n\n".format( activity=activity.name, e=str(e))) try: stats["activities"].append("{name}: {err}".format( name=activity.name, err=str(e))) except Exception: pass except (stravalib.exc.AccessUnauthorized, stravalib.exc.Fault): destroy_account_and_notify(strava_account, sclient) return stats # except Exception: # tb = traceback.format_exc() # strava_account.errors += tb # logger.error(tb) if stats["new_trips"] > 0: strava_account.user_sync_count = 0 strava_account.save() return stats
def __init__(self, db_path: str, client_id: str, client_secret: str, refresh_token: str): self.client = stravalib.Client() self.session = init_db(db_path) self.client_id = client_id self.client_secret = client_secret self.refresh_token = refresh_token
def sync(strava_account_id, manual_sync=True): """ Sync with a specific strava account. """ strava_account = StravaAccount.objects.get(id=strava_account_id) try: if manual_sync: strava_account.user_sync_count += 1 else: strava_account.user_sync_count = 0 sclient = stravalib.Client(access_token=strava_account.access_token) earliest_start_date, latest_end_date = Phase.get_active_range('entry_enabled') campaigns = [] for competition_phase in Phase.get_active().filter(phase_type='entry_enabled'): campaigns.append(competition_phase.campaign) hashtag_table = hashtags.HashtagTable(campaigns) activities = sclient.get_activities( after=datetime.combine(earliest_start_date, datetime.min.time()), before=datetime.combine(latest_end_date, datetime.max.time()), ) strava_account.last_sync_time = datetime.now() stats = { "new_trips": 0, "synced_trips": 0, "synced_activities": 0, "activities": [], } for activity in activities: sync_activity(activity, hashtag_table, strava_account, sclient, stats) strava_account.errors = "" except Exception as e: strava_account.errors = str(e) logger.error(e) strava_account.save() return stats
def get_public_activities(self, user, start_date, end_date): """Return detailed public activities for a given user beteen two dates""" token = self.get_user_access_token(user) client = stravalib.Client(token) activities = client.get_activities(after=start_date, before=end_date) return map(lambda activity: client.get_activity(activity.id, True), filter(lambda activity: not activity.private, activities))
def segment_leaderboard(self, segment_id, token, club_id, date_range): client = stravalib.Client(token) leaderboard = client.get_segment_leaderboard( segment_id, club_id=club_id, timeframe=date_range) leader_result = [self.get_leaderboard_entry_dict(entry) for entry in leaderboard] return leader_result
def __init__(self, strava_config_path: str, db_path: str, pois_data_path: str): self.client = stravalib.Client() self.session = init_db(db_path) # Load the strava account configuration with open(strava_config_path) as f: strava_config = json.load(f) if not {"client_id", "client_secret"} <= strava_config.keys(): raise KeyError("Missing keys from strava configuration.") self.client_id = strava_config["client_id"] self.client_secret = strava_config["client_secret"] # Load the POIs if pois_data_path: with open(pois_data_path) as f: self.pois = json.load(f) else: self.pois = None auth = self.session.query(Auth).first() if not auth: raise Exception("Missing auth data in DB.") self.authdata = auth self.authdata_changed = False
def authenticate(athlete): import time access_token = athlete['access_token'] if time.time() > athlete['expires_at'] - 100: try: codes = refresh_token(athlete['refresh_token']) except: pass db.UPDATE( 'athletes', where=f"a_id = {athlete['a_id']}", numCols=3, cols="access_token, refresh_token, expires_at", vals= f"'{codes['access_token']}', '{codes['refresh_token']}', {codes['expires_at']}" ) access_token = codes['access_token'] try: client = stravalib.Client(access_token=access_token) except: return None return client
def authorize(self, state=None, code=None): client = stravalib.Client() self.token = client.exchange_code_for_token(client_id=self.CLIENT_ID, client_secret=self.SECRET, code=code) print "Token : {} - Rights : {}".format(self.token, self.SCOPE) cherrypy.engine.exit()
def __init__(self, db_path): self.client = stravalib.Client() self.session = init_db(db_path) self.client_id = "" self.client_secret = "" self.refresh_token = ""
def refresh_access_token(self, refresh_token): """Request a new access_token using provided refresh_token""" client = stravalib.Client() resp = client.refresh_access_token( client_id=self.client_id, client_secret=self.secret, refresh_token=refresh_token) return SimpleNamespace(**resp)
def index(self): client = stravalib.Client() url = client.authorization_url( client_id=self.CLIENT_ID, scope=self.SCOPE, redirect_uri='http://localhost:{}/authorize'.format( cherrypy.server.socket_port)) raise cherrypy.HTTPRedirect(url)
def __init__(self): assert self.__class__.singleton is None super(Strava, self).__init__() if "strava" not in gripe.Config: gripe.Config.strava = {} self.config = gripe.Config.strava self.client = stravalib.Client(self.config.get("access_code", None)) self.codeReceived.connect(self.code_received)
def _authorize_app(): log("_authorize_app", "start") dameon = threading.Thread(name='herscript-server', target=_start_server) dameon.setDaemon(True) dameon.start() client = stravalib.Client() url = get_strava_authorization_url('http://{}:{}/authorize'.format( host_name, get_config(key_port))) # url = "https://www.strava.com/oauth/authorize?client_id={client_id}"\ # "&redirect_uri=http://{host_name}:{port}"\ # "&response_type=code"\ # "&approval_prompt=auto"\ # "&scope=activity:write,read".format(client_id="43527", host_name=host_name, port=port) # log("url", url) print( "Starting webbrowser, please authorize heroscript for STRAVA access.") # No glue, why this doesn't work with chromium (no redirection, but normal login) webbrowser.get('firefox').open_new(url) log("webbrowser", "called") i = 10 print(f"Waiting {i} sec for your authorization: {i:2}", end="", flush=True) while i >= 0 and threaded_authorize_code is None: i -= 1 print(f"\b\b{i:2}", end="", flush=True) # if authorize_code is None: if i == 0: exit_on_error("\nTimeout, authorization failed !") else: time.sleep(1) print("") if threaded_authorize_code is None: exit_on_error("Timeout, Authorization failed.") else: print("Done.") log("Go on now with code", threaded_authorize_code) if not key_strava_client_id in read_config(): exit_on_error( "STRAVA client ID not set. Set it with: heroscript config --strava_client_id ID-OF-YOUR-API" ) if not key_strava_client_secret in read_config(): exit_on_error( "STRAVA client secret not set. Set it with: heroscript config --strava_client_secret SECRET-OF-YOUR-API" ) obtain_new_token(threaded_authorize_code) log("_authorize_app", "end")
def post(self, request, *args, **kwargs): strava_account = request.user.stravaaccount sclient = stravalib.Client(access_token=strava_account.access_token) try: sclient.deauthorize() except AccessUnauthorized: pass strava_account.delete() return http.HttpResponseRedirect(reverse('about_strava'))
def get_athlete_info(): """ Returns a stravalib athlete object containing Strava info about the athlete The authentication token in athlete_codes identifies the right athlete to return """ access_token = refresh_token() client = stravalib.Client(access_token) athlete = client.get_athlete() return athlete
def auth_callback(): API_CLIENT = stravalib.Client() code = request.args.get('code') access_token = API_CLIENT.exchange_code_for_token( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, code=code ) return access_token
def __init__(self, year=2020, base_dir="GPX_DIR"): self.base_dir = base_dir self.client = stravalib.Client() self.year = year self.strava_access = False self.date_distance_dict = defaultdict(float) self.activities_get_dict = { "strava": self.__make_strava_activites, "gpx": self.__make_gpx_activites, }
def authorize(): state = request.args.get("state") redirect_uri = url_for('auth_callback', _external=True) client = stravalib.Client() auth_url = client.authorization_url( client_id=app.config["STRAVA_CLIENT_ID"], redirect_uri=redirect_uri, # approval_prompt="force", state=state) return redirect(auth_url)
def get_activities_as_rest_trips(strava_account): sclient = stravalib.Client() strava_account.errors = "" refresh_tokens(strava_account, sclient) earliest_start_date, latest_end_date = Phase.get_active_range( "entry_enabled") activities = sclient.get_activities( after=datetime.combine(earliest_start_date, datetime.min.time()), before=datetime.combine(latest_end_date, datetime.max.time()), ) return [get_activity_as_rest_trip(activity) for activity in activities]
def refresh_token(token): _client = stravalib.Client() refresh = _client.refresh_access_token(os.environ['STRAVA_CLIENT_ID'], os.environ['STRAVA_CLIENT_SECRET'], token) result = { 'access_token': refresh['access_token'], 'refresh_token': refresh['refresh_token'], 'expires_at': refresh['expires_at']} print(result) return result
def obtain_new_token(code): """ New token was obtained from Strava :param code: new code """ client = stravalib.Client() _obtain_new_token( lambda token: client.exchange_code_for_token( client_id=get_config(key_strava_client_id), client_secret=get_config(key_strava_client_secret), code=token), code)
def get_a_bunch_of_activities(): access_token = refresh_token() client = stravalib.Client(access_token) activities = client.get_activities( limit=100 ) #(after="2020-01-01") # this will get a list of non-detailed activity data. #for a in activities #activity_ids = [a.id] # extract all the activity IDs for example sample = list(activities)[0] sample.to_dict() return activities
def post(self, request, *args, **kwargs): try: strava_account = request.user.stravaaccount except models.StravaAccount.DoesNotExist: return http.HttpResponseRedirect(reverse("about_strava")) sclient = stravalib.Client(access_token=strava_account.access_token) try: sclient.deauthorize() except AccessUnauthorized: pass strava_account.delete() return http.HttpResponseRedirect(reverse("about_strava"))
def __init__(self): self.client_id = c.get_setting(c.SECTION_SETTINGS, c.CLIENT_ID) self.client_secret = c.get_setting(c.SECTION_SETTINGS, c.CLIENT_SECRET) self.access_token = c.get_setting(c.SECTION_SETTINGS, c.ACCESS_TOKEN) self.refresh_token = c.get_setting(c.SECTION_SETTINGS, c.REFRESH_TOKEN) self.expires_at = float(c.get_setting(c.SECTION_SETTINGS, c.EXPIRES_AT)) self.total_meters = 0 self.last_activity_date = None self.sc = stravalib.Client(self.access_token) self.start_time = time.time()
def refresh_token(token): _client = stravalib.Client() refresh = _client.refresh_access_token( client_id=os.environ['STRAVA_CLIENT_ID'], client_secret=os.environ['STRAVA_CLIENT_SECRET'], refresh_token=token) result = { 'access_token': refresh['access_token'], 'refresh_token': refresh['refresh_token'], 'expires_at': refresh['expires_at'] } return result