Beispiel #1
0
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)
Beispiel #3
0
    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=''))
Beispiel #4
0
    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=''))
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #7
0
    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 
Beispiel #8
0
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
Beispiel #9
0
 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))
Beispiel #10
0
 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
Beispiel #11
0
    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
Beispiel #12
0
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
Beispiel #13
0
 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()
Beispiel #14
0
    def __init__(self, db_path):
        self.client = stravalib.Client()
        self.session = init_db(db_path)

        self.client_id = ""
        self.client_secret = ""
        self.refresh_token = ""
Beispiel #15
0
 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)
Beispiel #16
0
 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)
Beispiel #17
0
 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)
Beispiel #18
0
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")
Beispiel #19
0
 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'))
Beispiel #20
0
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
Beispiel #21
0
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
Beispiel #22
0
 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,
     }
Beispiel #23
0
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)
Beispiel #24
0
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]
Beispiel #25
0
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
Beispiel #26
0
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)
Beispiel #27
0
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
Beispiel #28
0
 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"))
Beispiel #29
0
    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()
Beispiel #30
0
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