def setup_client(self): self.client = Client() if os.path.exists(self.token_file): f = open(self.token_file, "r") token = f.readline() f.close() else: token = input('Enter access token: ') self.client = Client(access_token=token) self.client.get_athlete() # Get current athlete details
def get_client_or_authorize_url(): """Get strava client, or authorization URL if not authenticated""" client = Client() authorize_url = None if "strava_refresh_token" in session.keys(): client.refresh_token = session["strava_refresh_token"] LOGGER.debug("{} / {} / {}".format( session["strava_access_token"], session["strava_refresh_token"], session["strava_expires_at"], )) if ("strava_access_token" in session.keys() and int(session["strava_expires_at"]) > datetime.datetime.now().timestamp()): client.access_token = session["strava_access_token"] client.refresh_token = session["strava_refresh_token"] client.token_expires_at = session["strava_expires_at"] else: authorize_url = get_authorization_url() LOGGER.debug("Authorize URL: {}".format(authorize_url)) return client, authorize_url
def collect_ride_data(self, challenge): """ Pull the latest ride data from Strava via the API """ client = Client() client.access_token = self.strava_config['access-token'] #activities = client.get_club_activities(165009) activities = client.get_club_activities(challenge.get_group_id()) act_list = [] for activity in activities: if not activity.type == 'Ride' and not activity.type == 'VirtualRide': print 'Non-ride activity: %s, type: %s' % (activity.name, activity.type) continue act = Activity(activity.id) act.set_athlete(activity.athlete.id) act.set_name(activity.name) act.set_gmt_date(activity.start_date) # GMT Start date act.set_elapsed_time(activity.elapsed_time) act.set_distance(round(unithelper.kilometers(activity.distance).num, 2)) act.set_elevation(unithelper.meters(activity.total_elevation_gain).num) act.set_ride_type(activity.type) act.set_trainer_ride(activity.trainer) act_list.append(act) db_store = GTDataStore(challenge.get_db_path(), self.verbose) db_store.store_if_new(act_list)
def __fetch_token(self): host = '127.0.0.1' port = 5000 client = Client() url = client.authorization_url( client_id=self.__client_id, redirect_uri='http://127.0.0.1:5000/authorization') print("follow this link (ctrl-c to cancel): {}".format(url)) client_id = self.__client_id secret = self.__secret class Handler(http.server.BaseHTTPRequestHandler): def do_GET(self): code = urllib.parse.parse_qs( urllib.parse.urlparse(self.path).query).get('code', None)[0] token = client.exchange_code_for_token(client_id=client_id, client_secret=secret, code=code) keyring.set_password('bike2cern', 'strava', token) s = http.server.HTTPServer((host, port), Handler) try: s.handle_request() except KeyboardInterrupt: pass s.server_close()
def parse_input_to_map(access_token): client = Client(access_token) all_activities = client.get_activities() date_activities_map = {} for activity in all_activities: date = str(activity.start_date)[0:10] date_formated = datetime.datetime.strptime(str(date), "%Y-%m-%d").date() # group activities by weeks with monday date as a key monday = date_formated - datetime.timedelta(date_formated.weekday()) if monday in date_activities_map: date_found = False for day_activity in date_activities_map[monday]: if date_formated in day_activity: day_activity[date_formated].append(activity) date_found = True break if not date_found: date_activities_map[monday].append({date_formated: [activity]}) else: date_activities_map[monday] = [{ date_formated: [activity] }] # [{"2020-03-03": [Activity]}] print("Success! Activities from strava retrieved, start building table") print("Total number of weeks with at least 1 training:" + str(len(date_activities_map))) return date_activities_map
def map(): #return to index if user has no session cookie if not session: return redirect(request.url_root+'authenticate', code=302) #redirect to reauthenticate if token has expired if time.time() > session['expires_at']: return redirect(request.url_root+'authenticate', code=302) # create strava client and pull activities client = Client(session['access_token']) activities=list(client.get_activities()) # add polylines gmap = gmplot.GoogleMapPlotter(0,0, 12,config.google_api_key) for i in reversed(range(len(activities))): try: pl=polyline.decode(activities[i].to_dict()['map']['summary_polyline']) lats,longs=zip(*pl) gmap.plot(lats,longs, 'cornflowerblue', edge_width=4)#,edge_alpha=0.3) except: print('no polyline for '+activities[i].to_dict()['name']) gmap.center = (mean(lats),mean(longs)) #output maps html file and load back in as string form(kinda hacky since the draw() function only outputs files) file_name=str(session['athlete_id'])+'.html' os.chdir('/tmp') gmap.draw(file_name) with open(file_name, 'r') as map_file: html_string = map_file.read() os.remove(file_name) return html_string
def create_context(): token_struct = session.get('token_struct') if token_struct == None: raise NoToken try: access_token = token_struct['access_token'] except KeyError: raise NoToken client = Client(access_token=access_token) try: refresh_token(client) athlete = client.get_athlete() except AccessUnauthorized: raise athlete_dir = os.path.join(current_app.instance_path, 'athletes', str(athlete.id)) if not os.path.isdir(athlete_dir): make_dirs(athlete_dir) with open(os.path.join(athlete_dir, 'athlete.json'), 'w') as f: json.dump(athlete.to_dict(), f) return client, athlete
def strava_upload(tcxfiles, login=None): logging.basicConfig(level=logging.DEBUG) client = Client() creds = read_strava_auth_file() if login == None: if len(creds) > 0: print("found strava credentials for: " ) n = 0 for email in creds.keys(): print(str(n) + " " + email) n += 1 index_input = raw_input("enter the number corresponding to your email address. Or just press enter to use your default browser to login\n") if re.match("\A\d+\Z", index_input): index = int(index_input) if index < len(creds): login = creds.keys()[index] if login and creds.has_key(login): client.access_token = creds[login] else: strava_authorize(client) for tcxfile in tcxfiles: r = post_file_to_strava(client, tcxfile) if(r.status_code == 401): print("invalid auth token, rerequesting authorization") strava_authorize(client) r = post_file_to_strava(client, tcxfile) if(r.status_code not in [200,201]): print("error uploading file. HTTP response code: " + str(r.status_code)) print(str(r.text))
def test_retrieve_segments_one_region(mock_stravalib, segments_db, regions_db): mock_stravalib.patch( "stravalib.client.Client.explore_segments", return_value=[SegmentExplorerResult(id=id) for id in range(5)], ) client = Client() bounds = [(0, 0), (2, 2)] crawler = SegmentCrawler(client, segments_db, regions_db, max_zoom=1) is_explored = crawler.retrieve_segments_recursively(bounds) assert is_explored assert len(segments_db.data) == 5 LOGGER.info(segments_db.display_segments()) displayed = segments_db.display_segments() assert len(displayed) == 5 displayed[0].pop("fastest_pace") # can't compare this as it's nan assert displayed[0] == { 'id': 0, 'name': 'Segment name', 'distance': 1000.0, 'avg_grade': 1.0, 'climb': 10.0, 'effort_count': 0, 'start_latlng': LatLon(lat=0.0, lon=0.0), 'end_latlng': LatLon(lat=1.0, lon=0.0), 'polyline': 'abc', 'url': 'https://www.strava.com/segments/0', 'colour': '#000000' }
def handle(self, *args, **options): settings_obj = Site.objects.get_current().settings self.stdout.write("Updating the Strava cache...") if settings.STRAVA_ACCESS_TOKEN == None: self.stdout.write("You must set STRAVA_ACCESS_TOKEN") return client = Client() client.access_token = settings.STRAVA_ACCESS_TOKEN if settings.STRAVA_CYCLING_CLUB != 0: cycling_club = client.get_club(settings.STRAVA_CYCLING_CLUB) self.stdout.write("Got this many cyclists = " + str(cycling_club.member_count)) settings_obj.cyclists = cycling_club.member_count # self.stdout.write("Getting cycling activities") # cycling_activities = client.get_club_activities(settings.STRAVA_CYCLING_CLUB) # Just get all of them, database can dedupe # self.insert_into_db(cycling_activities, ActivityCache.RIDE) if settings.STRAVA_RUNNING_CLUB != 0: running_club = client.get_club(settings.STRAVA_RUNNING_CLUB) self.stdout.write("Got this many runners = " + str(running_club.member_count)) settings_obj.runners = running_club.member_count # self.stdout.write("Getting running activities") # running_activities = client.get_club_activities(settings.STRAVA_RUNNING_CLUB) # self.insert_into_db(running_activities, ActivityCache.RUN) settings_obj.save()
def test_not_explored(mock_stravalib, segments_db, regions_db): def segments_for_region(bounds, activity_type): segments_range = None if bounds == [(0, 0), (2, 2)]: segments_range = range(10) elif bounds == [(0, 0), (1.0, 1.0)]: segments_range = range(5) elif bounds == [(0, 1.0), (1.0, 2)]: segments_range = range(5, 10) elif bounds == [(1.0, 1.0), (2, 2)]: segments_range = range(10, 15) elif bounds == [(1.0, 0), (2, 1.0)]: segments_range = range(15, 25) return [SegmentExplorerResult(id=id) for id in segments_range] mock_stravalib.patch("stravalib.client.Client.explore_segments", side_effect=segments_for_region) client = Client() bounds = [(0, 0), (2, 2)] crawler = SegmentCrawler(client, segments_db, regions_db, max_zoom=1) is_explored = crawler.retrieve_segments_recursively(bounds) assert not is_explored assert len(segments_db.data) == 25
def create_client(self): self.s3_file_manager.download_file('strava_auth.json', '/tmp/strava_auth.json') with open('/tmp/strava_auth.json') as auth_json: data = json.load(auth_json) access_token = data['access_token'] refresh_token = data['refresh_token'] expires_at = data['expires_at'] client = Client() client.access_token = access_token client.refresh_token = refresh_token client.token_expires_at = expires_at if time.time() > client.token_expires_at: print('Token has expired - refreshing...') refresh_response = client.refresh_access_token( client_id=int(os.getenv('STRAVA_CLIENT_ID', None)), client_secret=os.getenv('STRAVA_CLIENT_SECRET', None), refresh_token=client.refresh_token) with open('/tmp/strava_auth.json', 'w') as outfile: json.dump(refresh_response, outfile) self.s3_file_manager.upload_file('/tmp/strava_auth.json', 'strava_auth.json') return client
def make_authorization_url(): client = Client() authorize_url = client.authorization_url(client_id=CLIENT_ID, redirect_uri=REDIRECT_URI, scope='view_private,write') print(authorize_url) return authorize_url
def login(): client = Client() authorize_url = client.authorization_url( client_id=CONSTANTS.CLIENT_ID, redirect_uri=CONSTANTS.CALLBACK_URL) # Have the user click the authorization URL, # a 'code' param will be added to the redirect_uris return jsonify({"status": "success", "url": authorize_url})
def __init__(self): self.client = Client() self.API_CALL_PAUSE_SECONDS = 1.5 # 40 requests per minute # the self-authorization is NOT working right now -- using hard-coded URL / ACCESS_CODE right now #url = self.client.authorization_url(client_id=CLIENT_ID, # redirect_uri='http://localhost:5000/authorization') #code = request.args.get('code') # or whatever flask does #url = 'http://www.strava.com/oauth/authorize?client_id=16424&response_type=code&redirect_uri=http://localhost/5001&approval_prompt=force&scope=write' #print(url) access_token = self.client.exchange_code_for_token( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, code=ACCESS_CODE) # Now store that access token somewhere (a database?) self.client.access_token = access_token # retrieve the athlete self.athlete = self.client.get_athlete() print("For {}, I now have an access token".format(self.athlete.id)) # name of tables in model self.user_TBL = 'users' self.activity_TBL = 'activities' self.streams_TBL = 'streams' self.gear_TBL = 'gear' # streams to extract from strava self.streams = [ 'time', 'latlng', 'distance', 'altitude', 'velocity_smooth', 'heartrate', 'cadence', 'temp', 'moving', 'grade_smooth' ]
def handle(self, *args, **options): self.stdout.write("Updating the Acacia event miles") client = Client() rides_after = datetime(2018, 9, 1) rides_before = datetime(2018, 9, 3) participants = BigBulletRider.objects.exclude( access_token__isnull=True) for particpant in participants: self.stdout.write("Looking up activities for " + str(particpant.name)) client.access_token = particpant.access_token activities = client.get_activities(before=rides_before, after=rides_after) for activity in activities: km = unithelper.kilometers(activity.distance).num self.stdout.write("Got activity " + str(activity.id) + " distance = " + str(km) + " = " + str(activity)) ride, created = BigBulletRide.objects.get_or_create( activity_id=activity.id, bullet=particpant, distance=km, start_date=activity.start_date) self.stdout.write("Created = " + str(created))
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 strava_authorize_url(page=None): client = Client() url = url_for('query.authorized', _external=True, page=page) return client.authorization_url( scope=['profile:read_all', 'activity:read_all'], client_id=CLIENT_ID, redirect_uri=url)
def rides(request): if (not request.user.is_authenticated): return JsonResponse({"user_auth": False}) client = Client() user = AuthUser.objects.get(user_id=request.user.id) client.access_token = user.auth_code _before = datetime.now() _after = datetime(2018, 4, 1) batched_activities = client.get_activities(before=_before, after=_after) list_activities = list(batched_activities) rtn_activity_list = [] for a in list_activities: detailed_activity = client.get_activity(a.id) _new_activity = JsonActivity(detailed_activity.id, detailed_activity.map.polyline, a.distance, a.start_date) rtn_activity_list.append(_new_activity.toJson()) rtn = { "user_auth": True, "activities": rtn_activity_list } return JsonResponse(rtn)
def index(): #if the user has already used the app(and has a cookie saved) if session: #if user is already authenticated and not expired if (time.time() < session['expires_at']): return render_template('index.html',auth_link=request.url_root+'map') #if the user's token is expired, refresh the oken else: token = refresh_token(session['refresh_token']) #if a code is being returned if request.args.get('code'): #take code and convert to token code = request.args.get('code') token = token_exchange(code) # if this is the user's first visit, load page for authentication else: return render_template('index.html',auth_link=request.url_root+'authenticate') #store token and athlete_id in flask session session.clear() client = Client(token['access_token']) athlete_id = client.get_athlete().id session['athlete_id'] = athlete_id session['expires_at'] = token['expires_at'] session['access_token'] = token['access_token'] session['refresh_token'] = token['refresh_token'] session['code'] = code #send to map page return redirect(request.url_root+'map', code=302)
def __init__(self, api_key=None, csv_path=None, df=None): self.api_key = api_key self.csv_path = csv_path self.df = df if self.api_key: self.client = Client(access_token=self.api_key)
def get_strava_api(secret, ID): all_act = [] client = Client(access_token=secret) tot = total_num(client) me = client.get_athlete(ID) activities = client.get_activities() for i in trange(tot): df = pd.DataFrame() _a = activities.next() _streams = client.get_activity_streams(_a.id, types=types) for item in types: if item in _streams.keys(): df[item] = pd.Series(_streams[item].data, index=None) df['act_id'] = _a.id df['act_name'] = _a.name df['act_type'] = _a.type df['lat'] = map(split_lat, (df['latlng'])) df['lon'] = map(split_long, (df['latlng'])) df['time'] = df['distance'] / (df['velocity_smooth']) df.fillna(0) all_act.append(df) del df with open(save_file + '.pkl', 'wb') as fp: pickle.dump(all_act, fp) pd.concat(all_act, ignore_index=True).to_csv(save_file + '.csv') return all_act
def get_authorization_url(): client = Client() return client.authorization_url( client_id=STRAVA_CLIENT_ID, redirect_uri=url_for("authenticate", _external=True), scope=["activity:write", "activity:read_all"], )
def authenticate(): ## Strava API uses OAuth2, which requires users to manually allow permission, which generates ## a token only valid for a number of hours. ## get API client id and secret from config file config = configparser.ConfigParser() config.read("credentials.cfg") client_id = config.get('credentials', 'client_id') client_secret = config.get('credentials', 'client_secret') client = Client(rate_limiter=limiter.DefaultRateLimiter()) authorize_url = client.authorization_url( client_id=client_id, redirect_uri='http://localhost:8282/authorized') ## getting token -- pretty manual process for now webbrowser.open_new_tab(authorize_url) code = input('Enter Temporary Code: ') code = str(code) ## authenticate using API credntials + token token_response = client.exchange_code_for_token( client_id=client_id, client_secret=client_secret, code=code) return client
def api_profiles_activities_id(player_id, activity_id): if not request.stream: return '', 400 activity_id = int(activity_id) & 0xffffffffffffffff activity = activity_pb2.Activity() activity.ParseFromString(request.stream.read()) update_protobuf_in_db('activity', activity, activity_id) response = '{"id":%s}' % activity_id if request.args.get('upload-to-strava') != 'true': return response, 200 try: from stravalib.client import Client except ImportError: logger.warn( "stravalib is not installed. Skipping Strava upload attempt.") return response, 200 strava = Client() try: with open('%s/strava_token.txt' % STORAGE_DIR, 'r') as f: strava.access_token = f.read().rstrip('\r\n') except: logger.warn( "Failed to read %s/strava_token.txt. Skipping Strava upload attempt." ) return response, 200 try: # See if there's internet to upload to Strava strava.upload_activity(BytesIO(activity.fit), data_type='fit', name=activity.name) # XXX: assume the upload succeeds on strava's end. not checking on it. except: logger.warn("Strava upload failed. No internet?") return response, 200
class ClientUtilsTest(TestBase): client = Client() def test_utc_datetime_to_epoch_utc_datetime_given_correct_epoch_returned( self): dt = pytz.utc.localize(datetime.datetime(2014, 1, 1, 0, 0, 0)) self.assertEquals(1388534400, self.client._utc_datetime_to_epoch(dt))
class ClientAuthorizationUrlTest(TestBase): client = Client() def get_url_param(self, url, key): """ >>> get_url_param("http://www.example.com/?key=1", "key") 1 """ return urlparse.parse_qs(urlparse.urlparse(url).query)[key][0] def test_incorrect_scope_raises(self): self.assertRaises(Exception, self.client.authorization_url, 1, "www.example.com", scope="wrong") self.assertRaises(Exception, self.client.authorization_url, 1, "www.example.com", scope=["wrong"]) def test_correct_scope(self): url = self.client.authorization_url(1, "www.example.com", scope="write") self.assertEqual(self.get_url_param(url, "scope"), "write") # Check also with two params url = self.client.authorization_url(1, "www.example.com", scope="write,view_private") self.assertEqual(self.get_url_param(url, "scope"), "write,view_private") def test_scope_may_be_list(self): url = self.client.authorization_url(1, "www.example.com", scope=["write", "view_private"]) self.assertEqual(self.get_url_param(url, "scope"), "write,view_private") def test_incorrect_approval_prompt_raises(self): self.assertRaises(Exception, self.client.authorization_url, 1, "www.example.com", approval_prompt="wrong") def test_state_param(self): url = self.client.authorization_url(1, "www.example.com", state="my_state") self.assertEqual(self.get_url_param(url, "state"), "my_state") def test_params(self): url = self.client.authorization_url(1, "www.example.com") self.assertEqual(self.get_url_param(url, "client_id"), "1") self.assertEqual(self.get_url_param(url, "redirect_uri"), "www.example.com") self.assertEqual(self.get_url_param(url, "approval_prompt"), "auto")
def home(request): if 'access_token' not in request.session: return redirect('auth') # Retrieving athlete's data from API client = Client(access_token=request.session.get('access_token')) athlete = client.get_athlete() # Checking if the athlete has already visited the site before try: db_athlete = Athlete.objects.get(id=athlete.id) except Athlete.DoesNotExist: db_athlete = Athlete.create(athlete) db_athlete.save() # Getting the latest activity from the current athlete try: latest_activity = Activity.objects.filter(athlete=db_athlete).latest('date') activities = client.get_activities(after=latest_activity.date) except Activity.DoesNotExist: activities = client.get_activities() # Adding new activities to the database for activity in activities: if not activity.manual: stream = client.get_activity_streams(activity.id, types=['latlng'], resolution='medium').get('latlng') db_activity = Activity.create(activity, db_athlete, stream.data) db_activity.save() return render(request, 'home.html', {'athlete': athlete, 'activities': activities, 'act_length': len(list(activities))})
def make_client(client_id, client_secret, refresh_token): client = Client() refresh_response = client.refresh_access_token( client_id=client_id, client_secret=client_secret, refresh_token=refresh_token ) client.access_token = refresh_response["access_token"] return client
def auth_done(request): code = request.GET.get('code') client = Client() access_token = client.exchange_code_for_token(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, code=code) request.session['access_token'] = access_token return redirect('home')