Beispiel #1
0
 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
Beispiel #2
0
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)
Beispiel #4
0
    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()
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #12
0
    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
Beispiel #13
0
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
Beispiel #14
0
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})
Beispiel #15
0
    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))
Beispiel #17
0
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)
Beispiel #18
0
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)
Beispiel #19
0
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)
Beispiel #20
0
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)
Beispiel #22
0
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
Beispiel #23
0
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
Beispiel #25
0
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
Beispiel #26
0
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))
Beispiel #27
0
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")
Beispiel #28
0
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))})
Beispiel #29
0
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
Beispiel #30
0
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')