예제 #1
0
def join():
    c = Client()
    public_url = c.authorization_url(client_id=app.config['STRAVA_CLIENT_ID'],
                                     redirect_uri=url_for('.authorization', _external=True),
                                     approval_prompt='auto')
    private_url = c.authorization_url(client_id=app.config['STRAVA_CLIENT_ID'],
                                      redirect_uri=url_for('.authorization', _external=True),
                                      approval_prompt='auto',
                                      scope='view_private')
    return render_template('authorize.html', public_authorize_url=public_url, private_authorize_url=private_url)
예제 #2
0
def join():
    c = Client()
    public_url = c.authorization_url(client_id=app.config['STRAVA_CLIENT_ID'],
                                     redirect_uri=url_for('.authorization', _external=True),
                                     approval_prompt='auto')
    private_url = c.authorization_url(client_id=app.config['STRAVA_CLIENT_ID'],
                                      redirect_uri=url_for('.authorization', _external=True),
                                      approval_prompt='auto',
                                      scope='view_private')
    return render_template('authorize.html', public_authorize_url=public_url, private_authorize_url=private_url)
예제 #3
0
    def connect_to_strava(self):
        strava_client = Client(access_token=CONFIG['ACCESS_TOKEN'])

        if os.getenv('DEPLOYMENT_STAGE', 'dev'):
            redirect_url = 'http://127.0.0.1:5000/authorization'
        else:
            redirect_url = CONFIG['WEBSITE']

        strava_client.authorization_url(client_id=CONFIG['CLIENT_ID'],
                                        redirect_uri=redirect_url)
        return strava_client
예제 #4
0
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"]
예제 #5
0
class Strava():

    def __init__(self):
        self.client = Client()
        self.url = self.client.authorization_url(client_id=41952,
                                                 redirect_uri='https://strava2toggl.herokuapp.com/authorization')

    def get_access_token(self, code):
        self.code = code
        s3 = S3Connection(os.environ['client_id'], os.environ['client_secret'])
        self.access_token = self.client.exchange_code_for_token(client_id=os.environ['client_id'],
                                                                client_secret=os.environ['client_secret'],
                                                                code=self.code)
        self.access_token = self.access_token['access_token']
        self.client = Client(access_token=self.access_token)
        return self.access_token

    def get_activities(self, days, code):
        dt1 = datetime.now()
        dt2 = timedelta(days=days)
        dt3 = dt1 - dt2
        dt3 = dt3.strftime("%Y-%m-%dT%H:%M:%SZ")
        client = Client(access_token=code)
        activities = client.get_activities(after=dt3)
        return activities
예제 #6
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)
예제 #7
0
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
예제 #8
0
    def do_GET(self):

        request_path = self.path

        parsed_path = urlparse.urlparse(request_path)

        client = Client()

        if request_path.startswith('/authorization'):
            self.send_response(200)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.end_headers()

            self.wfile.write(six.b("Authorization Handler\n\n"))
            code = urlparse.parse_qs(parsed_path.query).get('code')
            if code:
                code = code[0]
                token_response = client.exchange_code_for_token(client_id=self.server.client_id,
                                                              client_secret=self.server.client_secret,
                                                              code=code)
                access_token = token_response['access_token']
                self.server.logger.info("Exchanged code {} for access token {}".format(code, access_token))
                self.wfile.write(six.b("Access Token: {}\n".format(access_token)))
            else:
                self.server.logger.error("No code param received.")
                self.wfile.write(six.b("ERROR: No code param recevied.\n"))
        else:
            url = client.authorization_url(client_id=self.server.client_id,
                                           redirect_uri='http://localhost:{}/authorization'.format(self.server.server_port))

            self.send_response(302)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.send_header(six.b('Location'), six.b(url))
            self.end_headers()
            self.wfile.write(six.b("Redirect to URL: {}\n".format(url)))
예제 #9
0
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
예제 #10
0
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)
예제 #11
0
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()
예제 #12
0
def login():
    c = Client()
    url = c.authorization_url(client_id='30922',
                              redirect_uri=url_for('.logged_in', _external=True),
                              approval_prompt='auto')
    
    #Showing the login page
    return render_template('login.html', authorize_url=url)
예제 #13
0
def join():
    c = Client()
    public_url = c.authorization_url(
        client_id=config.STRAVA_CLIENT_ID,
        redirect_uri=url_for('.authorization', _external=True),
        approval_prompt='auto',
        scope=['read', 'activity:read', 'profile:read_all'],
    )
    private_url = c.authorization_url(
        client_id=config.STRAVA_CLIENT_ID,
        redirect_uri=url_for('.authorization', _external=True),
        approval_prompt='auto',
        scope=['read_all', 'activity:read_all', 'profile:read_all'],
    )
    return render_template('authorize.html',
                           public_authorize_url=public_url,
                           private_authorize_url=private_url,
                           competition_title=config.COMPETITION_TITLE)
예제 #14
0
    def test_index(self):
        self.client.get('/')
        self.assertTemplateUsed('index.html')

        from stravalib import Client
        client = Client()
        client_id = self.app.config['STRAVA_CLIENT_ID']
        redirect = 'http://127.0.0.1:5000/strava_auth'
        url = client.authorization_url(client_id=client_id, redirect_uri=redirect)
        self.assertContext("strava_auth_url", url)
        self.assertContext("runs", None)
예제 #15
0
def login():
    c = Client()
    url = c.authorization_url(
        client_id=config.STRAVA_CLIENT_ID,
        redirect_uri=url_for('.logged_in', _external=True),
        approval_prompt='auto',
        scope=['read_all', 'activity:read_all', 'profile:read_all'],
    )
    return render_template('login.html',
                           authorize_url=url,
                           competition_title=config.COMPETITION_TITLE)
예제 #16
0
    def do_GET(self):

        request_path = self.path

        parsed_path = urlparse.urlparse(request_path)

        client = Client()

        if request_path.startswith('/authorization'):
            self.send_response(200)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.end_headers()

            self.wfile.write(six.b("Authorization Handler\n\n"))
            code = urlparse.parse_qs(parsed_path.query).get('code')
            if code:
                code = code[0]
                token_response = client.exchange_code_for_token(
                    client_id=self.server.client_id,
                    client_secret=self.server.client_secret,
                    code=code)
                access_token = token_response['access_token']
                refresh_token = token_response['refresh_token']
                expires_at = token_response['expires_at']
                self.server.logger.info(
                    "Exchanged code {} for access token {}".format(
                        code, access_token))
                self.wfile.write(
                    six.b("Access Token: {}\n".format(access_token)))
                self.wfile.write(
                    six.b("Refresh Token: {}\n".format(refresh_token)))
                self.wfile.write(six.b("Expires at: {}\n".format(expires_at)))
                with open('strava_token.txt', 'w') as f:
                    f.write(self.server.client_id + '\n')
                    f.write(self.server.client_secret + '\n')
                    f.write(access_token + '\n')
                    f.write(refresh_token + '\n')
                    f.write(str(expires_at) + '\n')
            else:
                self.server.logger.error("No code param received.")
                self.wfile.write(six.b("ERROR: No code param recevied.\n"))
        else:
            url = client.authorization_url(
                client_id=self.server.client_id,
                redirect_uri='http://localhost:{}/authorization'.format(
                    self.server.server_port),
                scope='activity:write')

            self.send_response(302)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.send_header(six.b('Location'), six.b(url))
            self.end_headers()
            self.wfile.write(six.b("Redirect to URL: {}\n".format(url)))
예제 #17
0
def index(request):

    client_id = os.environ['SMOOTHIFY_ID']

    client = Client()

    redirect_uri = request.build_absolute_uri('/token/')
    url = client.authorization_url(client_id=client_id,
                                   redirect_uri=redirect_uri,
                                   scope='view_private,write')

    #print '(index) Memory usage: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

    return render(request, 'index.html', {'url': url})
예제 #18
0
def get_activities_from_strava():
    last_activity = None
    if not os.path.exists(STRAVA_ACCESS_TOKEN_STRING_FNAME):

        print '* Obtain a request token ...'
        strava_client = Client()
        auth_url = strava_client.authorization_url(client_id='601', redirect_uri='http://127.0.0.1:5000/authorisation')
        print auth_url

        auth_token = strava_client.exchange_code_for_token(client_id='601', client_secret='600580e02b4814c75c93d3a60e15077147895776', code = '74cc257e6bc370d9da44cabc8852f3667ad95515')

        print auth_token

        # write the access token to file; next time we just read it from file
        if DEBUG:
            print 'Writing file', STRAVA_ACCESS_TOKEN_STRING_FNAME


        fobj = open(STRAVA_ACCESS_TOKEN_STRING_FNAME, 'w')
        fobj.write(auth_token)
        fobj.close()

    else:
        if DEBUG:
            print 'Reading file', STRAVA_ACCESS_TOKEN_STRING_FNAME
        fobj = open(STRAVA_ACCESS_TOKEN_STRING_FNAME)
        access_token_string = fobj.read()

        print access_token_string
        #access_token = oauth.OAuthToken.from_string(access_token_string)

        strava_client = Client(access_token=access_token_string)
        activities = strava_client.get_activities(limit=10)

        # for activity in activities:
        #     details = strava_client.get_activity(activity_id=activity.id)
        #     print details.name
        #     print unithelper.kilometers(details.distance)
        #     print details.start_date_local
        #     print details.elapsed_time
        #     print details.calories
        #     print details.type
        #     print "------"
        # fobj.close()
        for activity in activities:
            last_activity = activity

    return strava_client.get_activity(activity_id=activity.id)
예제 #19
0
파일: views.py 프로젝트: jyundt/oval
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)
예제 #20
0
파일: views.py 프로젝트: jyundt/oval
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)
예제 #21
0
def start_strava_auth_flow():
    print('---------------------------------------------')
    print('| Starting Strava OAuth authentication flow |')
    print('---------------------------------------------\n')

    httpd = HTTPServer(('127.0.0.1', 0), AuthRequestHandler)

    client = Client()
    url = client.authorization_url(
        client_id=CLIENT_ID,
        redirect_uri='http://{}:{}'.format('localhost', httpd.server_port),
        scope='activity:write',
    )
    print('Open the following page to authorize drpexe-uploader to '
          'upload files to your Strava account\n')
    print(url)

    httpd.handle_request()
예제 #22
0
def start_strava_auth_flow():
    print('---------------------------------------------')
    print('| Starting Strava OAuth authentication flow |')
    print('---------------------------------------------\n')

    client = Client()
    url = client.authorization_url(
        client_id=DRPEXE_CLIENT_ID,
        redirect_uri=DRPEXE_UPLOADER_API,
        scope='write',
        state='REDIRECT-%s' % LOCAL_SERVER_PORT,
    )
    print('Open the following page to authorize drpexe-uploader to '
          'upload files to your Strava account\n')
    print(url)

    httpd = HTTPServer(('127.0.0.1', LOCAL_SERVER_PORT), AuthRequestHandler)
    httpd.handle_request()
예제 #23
0
def start_strava_auth_flow():
    print("---------------------------------------------")
    print("| Starting Strava OAuth authentication flow |")
    print("---------------------------------------------\n")

    httpd = HTTPServer(("127.0.0.1", 0), AuthRequestHandler)

    client = Client()
    url = client.authorization_url(
        client_id=CLIENT_ID,
        redirect_uri="http://{}:{}".format("localhost", httpd.server_port),
        scope="activity:write",
    )
    print("Open the following page to authorize drpexe-uploader to "
          "upload files to your Strava account\n")
    print(url)

    httpd.handle_request()
예제 #24
0
    def auth_strava(self):

        if self.account_dict.get('uid', None) is None:
            notify = QMessageBox()
            notify.setText('请先获取Zwift数据!')
            notify.exec_()
            logger.warning('请先获取Zwift数据!')
            return
        strava_oauth_server.bridge.token_got.connect(self.format_strava_token)
        t = Thread(target=strava_oauth_server.app.run, args=('0.0.0.0', 6734))
        t.daemon = True
        t.start()
        client = Client()
        url = client.authorization_url(
            client_id=STRAVA_CLIENT_ID,
            approval_prompt="force",
            scope="activity:write",
            redirect_uri='http://127.0.0.1:6734/authorization')
        QDesktopServices.openUrl(QUrl(url))
예제 #25
0
def authenticate():
    client = Client()
    url = client.authorization_url(client_id=sm.client_id,
                                   redirect_uri='http://localhost')
    logger.info(
        'Open this URL, then paste in the code provided in the URL: '
        '%s', url)
    code = input('Paste code here: ')

    auth_dict = client.exchange_code_for_token(client_id=sm.client_id,
                                               client_secret=sm.client_secret,
                                               code=code)
    logger.debug('Auth Dict: %s', auth_dict)

    # Save the dict back to Secret manager
    try:
        sm.set_auth_dict(auth_dict)
    except PermissionDenied:
        logger.error(f'Looks like your token could not be saved. Try manually '
                     f'adding this value to your STRAVA_ACCESS_TOKEN secret:\n'
                     f'  {json.dumps(auth_dict)}')
예제 #26
0
    def do_GET(self):

        request_path = self.path

        parsed_path = urlparse.urlparse(request_path)

        client = Client()

        if request_path.startswith('/authorization'):
            self.send_response(200)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.end_headers()

            self.wfile.write(six.b("Authorization Handler\n\n"))
            code = urlparse.parse_qs(parsed_path.query).get('code')
            if code:
                code = code[0]
                access_token = client.exchange_code_for_token(
                    client_id=self.server.client_id,
                    client_secret=self.server.client_secret,
                    code=code)
                self.server.logger.info(
                    "Exchanged code {} for access token {}".format(
                        code, access_token))
                self.wfile.write(
                    six.b("Access Token: {}\n".format(access_token)))
            else:
                self.server.logger.error("No code param received.")
                self.wfile.write(six.b("ERROR: No code param recevied.\n"))
        else:
            url = client.authorization_url(
                client_id=self.server.client_id,
                redirect_uri='http://localhost:{}/authorization'.format(
                    self.server.server_port))

            self.send_response(302)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.send_header(six.b('Location'), six.b(url))
            self.end_headers()
            self.wfile.write(six.b("Redirect to URL: {}\n".format(url)))
예제 #27
0
def index(request):
    access_token = request.session.get('access_token', None)
    if access_token is None:
        # if access_token is NOT in session, kickoff the oauth exchange
        client = Client()
        url = client.authorization_url(
            client_id=os.environ.get('STRAVA_CLIENT_ID', None),
            redirect_uri='http://' + settings.ALLOWED_HOSTS[0] + '/authorization'
            # redirect_uri='http://127.0.0.1:8000/authorization'
        )
        context = {'auth_url': url}
        return render(request, 'index.html', context)

    # otherwise, load authorized user
    client = Client(access_token=access_token)

    athlete_id = request.session.get('athlete_id', None)
    if athlete_id is None:
        # if athlete is NOT already in session, get athlete
        # (attempting to reduce calls to the API)
        athlete = client.get_athlete()
        request.session['athlete_id'] = athlete.id
        request.session['firstname'] = athlete.firstname

        try:
            Athlete.objects.get(strava_id=athlete.id)
        except Athlete.DoesNotExist:
            new_athlete = Athlete()
            new_athlete.strava_id = athlete.id
            new_athlete.first_name = athlete.firstname
            new_athlete.last_name = athlete.lastname
            new_athlete.city = athlete.city
            new_athlete.state = athlete.state
            new_athlete.country = athlete.country
            new_athlete.save()

    return render(request, 'welcome_landing.html')
예제 #28
0
파일: home.py 프로젝트: toirl/trainable
def trainable_index_view(request):
    values = index_view(request)
    if request.user:
        client = Client()
        client_id = request.user.profile[0].strava_client_id
        redirect_uri = request.route_url("authstrava")
        url = client.authorization_url(client_id=client_id,
                                       redirect_uri=redirect_uri,
                                       scope="view_private")
        _ = request.translate
        config = Config(load(get_path_to_form_config('strava.xml')))
        form_config = config.get_form('syncform')
        form = Form(form_config, csrf_token=request.session.get_csrf_token(),
                    translate=_, locale="de", eval_url=get_eval_url())

        if request.POST and form.validate(request.params):
            sync(request, form.data.get("sport"),
                 form.data.get("start"), form.data.get("end"),
                 form.data.get("commute"))

        values["fitness"] = get_fitness(0, 0, get_activities_for_user(request))
        values["strava_auth_url"] = url
        values["strava_syncform"] = form.render()
    return values
예제 #29
0
import dash_core_components as dcc
import dash_html_components as html
import activity_selector
from stravalib import Client
import style
import settings
from appserver import app
import datetime
now = datetime.datetime.now()

client = Client()
strava_authorization_url = client.authorization_url(
    client_id=settings.STRAVA_CLIENT_ID,
    redirect_uri=settings.APP_URL,
    state='strava-dash-app')

app.layout = html.Div(
    className="container",
    children=[
        html.Link(rel='stylesheet', href='/static/style.css'),
        dcc.Store(id='strava-auth', storage_type='session'),
        dcc.Store(id='strava-activity_list', storage_type='session'),
        dcc.Store(id='strava-activity-data', storage_type='local'),
        html.Div(id='strava-config',
                 **{
                     "data-debug-mode": False,
                     "data-year": 2021,
                     "data-activities-limit": 500,
                 }),
        dcc.Location(id='url', refresh=False),
        html.Div(
예제 #30
0
from flask import Flask, request, redirect, render_template, url_for
import sqlite3 as sql
from stravalib import Client, unithelper
import pandas as pd
import numpy as np
from bokeh.plotting import figure, output_file, show
from bokeh.embed import components
import math
from datetime import date, datetime
import time
import model
from app import app, model, controller

client = Client()
url = client.authorization_url(client_id = strava_client_id, \
	redirect_uri = 'http://127.0.0.1:5000/authorization')

# ==================- Database functions -==================

# This assumes that segment contains an id, name, hill_score and var_score
def insert_segment(segment, cur, con):
	cur.execute('INSERT INTO segments (segment_id, segment_name, hill_score, \
		var_score) VALUES (?,?,?,?)', (segment.id, segment.name, segment.hill_score, \
		segment.var_score))
	con.commit()
	return segment.id
				
# A sqlite row_factory, which gives the results as a dict 
def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
예제 #31
0
from stravalib import Client
client = Client()

CLIENT_ID = "CLIENT ID"
CLIENT_SECRET = "CLIENT SECRET"

url = client.authorization_url(client_id=CLIENT_ID,
                               scope="write",
                               redirect_uri='http://localhost')
# Go to that URL and retrieve the code
print(url)

CODE = "PUT THE CODE HERE"

access_token = client.exchange_code_for_token(client_id=CLIENT_ID,
                                              client_secret=CLIENT_SECRET,
                                              code=CODE)

print(access_token)
예제 #32
0
    cp.read(os.path.expanduser('~/.stravacli'))
    cat = None
    if cp.has_section('API'):
        cat = cp.get('API', 'ACCESS_TOKEN') if 'access_token' in cp.options('API') else None

while True:
    client = Client(cat)
    try:
        athlete = client.get_athlete()
    except requests.exceptions.ConnectionError:
        p.error("Could not connect to Strava API")
    except Exception as e:
        print("NOT AUTHORIZED", file=stderr)
        print("Need Strava API access token. Launching web browser to obtain one.", file=stderr)
        client = Client()
        authorize_url = client.authorization_url(client_id=cid, redirect_uri='http://stravacli-dlenski.rhcloud.com/auth', scope='view_private,write')
        webbrowser.open_new_tab(authorize_url)
        client.access_token = cat = raw_input("Enter access token: ")
    else:
        if not cp.has_section('API'):
            cp.add_section('API')
        if not 'ACCESS_TOKEN' in cp.options('API') or cp.get('API', 'ACCESS_TOKEN', None)!=cat:
            cp.set('API', 'ACCESS_TOKEN', cat)
            cp.write(open(os.path.expanduser('~/.stravacli'),"w"))
        break

print("Authorized to access account of {} {} (id {:d}).".format(athlete.firstname, athlete.lastname, athlete.id))

#####

for ii,f in enumerate(args.activities):
예제 #33
0
#import urllib3.contrib.pyopenssl
#urllib3.contrib.pyopenssl.inject_into_urllib3()
import thresher, os
from models import Activity, Athlete

client = Client()

# Got from Strava after registering on website
MY_STRAVA_CLIENT_ID = "9558"
MY_STRAVA_CLIENT_SECRET = "734e394ff653703abaef7c7c061cc8d685241a10"

# a url sending visitor to strava's website for authentication
# THIS MUST BE UPDATED FOR WEB USE, strava website must be updated as well
#stravaURL = client.authorization_url(client_id=MY_STRAVA_CLIENT_ID, redirect_uri='http://reddlee.pythonanywhere.com/authorization')
stravaURL = client.authorization_url(
    client_id=MY_STRAVA_CLIENT_ID,
    redirect_uri='http://127.0.0.1:8000/authorization')


def index(request):
    return render(request, 'stravaChimp/index.html', {'c': stravaURL})


#
# visitors sent to this page after agreeing to allow our site to use their strava
def authorization(request):
    client = Client()
    code = request.GET['code']
    access_token = client.exchange_code_for_token(
        client_id=MY_STRAVA_CLIENT_ID,
        client_secret=MY_STRAVA_CLIENT_SECRET,
예제 #34
0
class Strava:
    def __init__(self, client_id, client_secret):
        self.client = Client()
        self.client_id = client_id
        self.client_secret = client_secret

    def _check_and_refresh_token(self, member=None):

        if not member:
            member = Member.objects.filter(
                refresh_token__gte="").order_by('refresh_token').limit(1)
            member = list(member)[0]

        logger.info("Using access token for: {}".format(member))

        self.client.access_token = member.access_token
        self.client.refresh_token = member.refresh_token
        self.client.token_expires_at = member.access_token_expiry

        # 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() > member.access_token_expiry:
            logger.info("Renewing token")
            refresh_response = self.client.refresh_access_token(
                client_id=self.client_id,
                client_secret=self.client_secret,
                refresh_token=member.refresh_token)
            member.access_token = refresh_response['access_token']
            member.refresh_token = refresh_response['refresh_token']
            member.access_token_expiry = refresh_response['expires_at']
            member.save()

    def register_new_member(self, code):
        token_response = self.client.exchange_code_for_token(
            client_id=self.client_id,
            client_secret=self.client_secret,
            code=code)
        access_token = token_response['access_token']
        refresh_token = token_response['refresh_token']
        expires_at = token_response['expires_at']

        self.client.access_token = access_token
        self.client.refresh_token = refresh_token
        self.client.token_expires_at = expires_at

        athlete = self.client.get_athlete()
        logger.debug("Retrieved the authenticated athlete: {}".format(athlete))
        return athlete, access_token, refresh_token, expires_at

    def get_member_avatar(self, athlete_id, medium=False):
        logger.debug("Getting an avatar for member {} that is sized {}".format(
            athlete_id, medium))
        member = Member.objects.get(id=str(athlete_id))
        self._check_and_refresh_token(member)
        athlete = self.client.get_athlete()

        if medium:
            return athlete.profile_medium
        else:
            return athlete.profile

    def get_redirect_url(self, client_id, redirect_url, state):
        return self.client.authorization_url(client_id,
                                             redirect_url,
                                             state=state)
예제 #35
0
def redirectAuth():
    client = Client()
    url = client.authorization_url(client_id=MY_STRAVA_CLIENT_ID,
                                   redirect_uri=request.url)
    return redirect(url)
예제 #36
0
from stravalib import Client
#import urllib3.contrib.pyopenssl
#urllib3.contrib.pyopenssl.inject_into_urllib3()
import thresher, os
from models import Activity, Athlete

client = Client()

# Got from Strava after registering on website
MY_STRAVA_CLIENT_ID = "9558"
MY_STRAVA_CLIENT_SECRET = "734e394ff653703abaef7c7c061cc8d685241a10"

# a url sending visitor to strava's website for authentication
# THIS MUST BE UPDATED FOR WEB USE, strava website must be updated as well
#stravaURL = client.authorization_url(client_id=MY_STRAVA_CLIENT_ID, redirect_uri='http://reddlee.pythonanywhere.com/authorization')
stravaURL = client.authorization_url(client_id=MY_STRAVA_CLIENT_ID, redirect_uri='http://127.0.0.1:8000/authorization')

def index(request):
    return render(request, 'stravaChimp/index.html', {'c':stravaURL})
    
#
# visitors sent to this page after agreeing to allow our site to use their strava
def authorization(request):
    client = Client()
    code = request.GET['code']
    access_token = client.exchange_code_for_token(client_id=MY_STRAVA_CLIENT_ID, client_secret=MY_STRAVA_CLIENT_SECRET, code=code)   
    
    # making a global variable to be used across views. don't know how this will work in practice
    
    client = Client(access_token=access_token)
    athlete = client.get_athlete() # Get current athlete details
from config import *

from stravalib import Client
import sys

client = Client()

if len( sys.argv ) == 1:

  url = client.authorization_url(client_id=STRAVA_CLIENT_ID,
                                           redirect_uri='http://localhost', scope='view_private,write' )
  print "Paste this URL in your browser:"
  print
  print url
  print
  print "And then re-run this script like so: "
  print "\t" + sys.argv[0] + " <code>"

elif sys.argv[1] == 'test':
  client = Client( access_token=STRAVA_ACCESS_TOKEN)
  print client.get_athlete()

else:
  code = sys.argv[1]
  access_token = client.exchange_code_for_token(client_id=STRAVA_CLIENT_ID,
                                                client_secret=STRAVA_CLIENT_SECRET,
                                                code=code)
  print "Your Strava access token is: " + access_token
예제 #38
0
def connect():
	client = Client()
	url = client.authorization_url(client_id = app.vars['client_id'], \
		redirect_uri = 'http://127.0.0.1:5000/authorization')
	return render_template('connect.html', connect_url = url)
예제 #39
0
def strava_upload():
    """
        upload to strava, borrowed from https://github.com/dlenski/stravacli
    """
    allowed_exts = {
        '.tcx': lambda v: '<TrainingCenterDatabase' in v[:200],
        '.gpx': lambda v: '<gpx' in v[:200],
        '.fit': lambda v: v[8:12] == '.FIT'
    }

    par = argparse.ArgumentParser(description='Uploads activities to Strava.')
    par.add_argument(
        'activities',
        nargs='*',
        type=argparse.FileType("rb"),
        default=(stdin, ),
        help="Activity files to upload (plain or gzipped {})".format(', '.join(allowed_exts)))
    par.add_argument(
        '-P', '--no-popup', action='store_true', help="Don't browse to activities after upload.")
    par.add_argument(
        '-E',
        '--env',
        help='Look for ACCESS_TOKEN in environment variable '
        'rather than ~/.stravacli')
    grp = par.add_argument_group('Activity file details')
    grp.add_argument('-p', '--private', action='store_true', help='Make activities private')
    grp.add_argument(
        '-t',
        '--type',
        choices=allowed_exts,
        default=None,
        help='Force files to be interpreted as being of given '
        'type (default is to autodetect based on name, or '
        'contents for stdin)')
    grp.add_argument(
        '-x',
        '--xml-desc',
        action='store_true',
        help='Parse name/description fields from GPX and TCX '
        'files.')
    grp.add_argument('-T', '--title', help='Activity title')
    grp.add_argument('-D', '--desc', dest='description', help='Activity description')
    grp.add_argument(
        '-A',
        '--activity-type',
        default=None,
        help='Type of activity. If not specified, the default '
        'value is taken from user profile. '
        'Supported values: \n\t ride, run, swim, workout, '
        'hike, walk, nordicski, alpineski, backcountryski, '
        'iceskate, inlineskate, kitesurf, rollerski, '
        'windsurf, workout, snowboard, snowshoe')
    args = par.parse_args()

    if args.xml_desc:
        if args.title:
            print('argument -T/--title not allowed with argument ' '-x/--xml-desc', file=stderr)
        if args.description:
            print('argument -D/--desc not allowed with argument ' '-x/--xml-desc', file=stderr)

    # Authorize Strava
    cp_ = ConfigParser()
    cp_.read(os.path.expanduser('~/.stravacli'))
    cat = None
    if cp_.has_section('API'):
        if 'access_token' in cp_.options('API'):
            cat = cp_.get('API', 'ACCESS_TOKEN')
            cs = cp_.get('API', 'CLIENT_SECRET')
            cat = cp_.get('API', 'ACCESS_TOKEN')

    while True:
        client = Client(cat)
        try:
            athlete = client.get_athlete()
        except requests.exceptions.ConnectionError:
            print("Could not connect to Strava API", file=stderr)
        except Exception as e:
            print("NOT AUTHORIZED %s" % e, file=stderr)
            print(
                "Need Strava API access token. Launching web browser to "
                "obtain one.",
                file=stderr)
            client = Client()
            webserver = QueryGrabber(response='<title>Strava auth code received!</title>This window can be closed.')
            _scope = 'view_private,write'
            authorize_url = client.authorization_url(client_id=cid, redirect_uri=webserver.root_uri(), scope=_scope)
            webbrowser.open_new_tab(authorize_url)
            webserver.handle_request()
            client.access_token = cat = client.exchange_code_for_token(client_id=cid,client_secret=cs,code=webserver.received['code'])
            cp_.add_section('API')
            cp_.set('API','CLIENT_ID', cid)
            cp_.set('API','CLIENT_SECRET', cs)
            cp_.set('API','ACCESS_TOKEN', cat)
            cp_.write(open(os.path.expanduser('~/.stravacli'),"w"))
        else:
            if not cp_.has_section('API'):
                cp_.add_section('API')
            if 'ACCESS_TOKEN' not in cp_.options('API') or cp_.get('API', 'ACCESS_TOKEN',
                                                                   None) != cat:
                cp_.set('API', 'ACCESS_TOKEN', cat)
                cp_.write(open(os.path.expanduser('~/.stravacli'), "w"))
            break

    print("Authorized to access account of {} {} (id {:d}).".format(athlete.firstname,
                                                                    athlete.lastname, athlete.id))

    for act in args.activities:
        if act is stdin:
            contents = act.read()
            act = StringIO(contents)
            if args.type is None:
                # autodetect gzip and extension based on content
                if contents.startswith('\x1f\x8b'):
                    gz_, cf_, uf_ = '.gz', act, gzip.GzipFile(fileobj=act, mode='rb')
                    contents = uf_.read()
                else:
                    gz_, uf_, cf_ = '', act, NamedTemporaryFile(suffix='.gz')
                    gzip.GzipFile(fileobj=cf_, mode='w+b').writelines(act)
                for ext, checker in allowed_exts.items():
                    if checker(contents):
                        print("Uploading {} activity from stdin...".format(ext + gz_))
                        break
                else:
                    print("Could not determine file type of stdin", file=stderr)
            else:
                base, ext = 'activity', args.type
        else:
            base, ext = os.path.splitext(act.name if args.type is None else 'activity.' + args.type)
            # autodetect based on extensions
            if ext.lower() == '.gz':
                base, ext = os.path.splitext(base)
                # un-gzip it in order to parse it
                gz_, cf_, uf_ = '.gz', act, None if args.no_parse else \
                                gzip.GzipFile(fileobj=act, mode='rb')
            else:
                gz_, uf_, cf_ = '', act, NamedTemporaryFile(suffix='.gz')
                gzip.GzipFile(fileobj=cf_, mode='w+b').writelines(act)
            if ext.lower() not in allowed_exts:
                print(
                    "Don't know how to handle extension "
                    "{} (allowed are {}).".format(ext, ', '.join(allowed_exts)),
                    file=stderr)
            print("Uploading {} activity from {}...".format(ext + gz_, act.name))

        # try to parse activity name, description from file if requested
        if args.xml_desc:
            uf_.seek(0, 0)
            if ext.lower() == '.gpx':
                x = etree.parse(uf_)
                nametag, desctag = x.find("{*}name"), x.find("{*}desc")
                title = nametag and nametag.text
                desc = desctag and desctag.text
            elif ext.lower() == '.tcx':
                x = etree.parse(uf_)
                notestag = x.find("{*}Activities/{*}Activity/{*}Notes")
                if notestag is not None:
                    title, desc = (notestag.text.split('\n', 1) + [None])[:2]
        else:
            title = args.title
            desc = args.description

        # upload activity
        try:
            cf_.seek(0, 0)
            upstat = client.upload_activity(
                cf_,
                ext[1:] + '.gz',
                title,
                desc,
                private=args.private,
                activity_type=args.activity_type)
            activity = upstat.wait()
            duplicate = False
        except exc.ActivityUploadFailed as e:
            words = e.args[0].split()
            if words[-4:-1] == ['duplicate', 'of', 'activity']:
                activity = client.get_activity(words[-1])
                duplicate = True
            else:
                raise

        # show results
        uri = "http://strava.com/activities/{:d}".format(activity.id)
        print("  {}{}".format(uri, " (duplicate)" if duplicate else ''), file=stderr)
        if not args.no_popup:
            webbrowser.open_new_tab(uri)
예제 #40
0
def redirectAuth(MY_STRAVA_CLIENT_ID):
    client = Client()
    url = client.authorization_url(client_id=MY_STRAVA_CLIENT_ID,
                                   redirect_uri=request.url)
    return redirect(url)
예제 #41
0
from stravalib import Client
client = Client()

CLIENT_ID = "CLIENT ID"
CLIENT_SECRET = "CLIENT SECRET"

url = client.authorization_url(
    client_id=CLIENT_ID,
    scope="write",
    redirect_uri='http://localhost')
# Go to that URL and retrieve the code
print(url)

CODE = "PUT THE CODE HERE"

access_token = client.exchange_code_for_token(
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    code=CODE)

print(access_token)
예제 #42
0
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the Strava sensors."""
    from stravalib import Client
    client = Client()

    @asyncio.coroutine
    def _read_config():
        if not os.path.isfile(config_path):
            return None
        with open(config_path, 'r') as auth_file:
            config = json.load(auth_file)
            if config['client_id'] == client_id:
                return config['access_token']

    @asyncio.coroutine
    def _write_config(access_token):
        with open(config_path, 'w') as auth_file:
            json.dump({
                'client_id': client_id,
                'access_token': access_token,
            }, auth_file)

    @asyncio.coroutine
    def _add_devices(access_token):
        devices = []
        for resource in config.get(CONF_RESOURCES):
            sensor_type = resource[CONF_TYPE]
            is_simple_sensor = len(SENSOR_TYPES[sensor_type]) == 4
            if CONF_ARG not in resource:
                resource[CONF_ARG] = ATTR_TOTAL_DISTANCE

            name = SENSOR_TYPES[sensor_type][0]
            icon = SENSOR_TYPES[sensor_type][1]
            if is_simple_sensor:
                unit_of_measurement_lambda = SENSOR_TYPES[sensor_type][2]
                state_transformer_lambda = SENSOR_TYPES[sensor_type][3]
            else:
                total_type = resource[CONF_ARG]
                unit_of_measurement_lambda = TOTALS_TYPES[total_type][0]
                state_transformer_lambda = TOTALS_TYPES[total_type][1]

            devices.append(
                StravaSensor(
                    hass=hass,
                    sensor_type=sensor_type,
                    name=name,
                    icon=icon,
                    unit_of_measurement_lambda=unit_of_measurement_lambda,
                    state_transformer_lambda=state_transformer_lambda))

        strava_data = StravaData(hass, access_token, devices)
        yield from strava_data.fetch_data()
        return async_add_devices(devices)

    @asyncio.coroutine
    def initialize_callback(code):
        """Handle OAuth callback from Strava authorization flow."""
        access_token = client.exchange_code_for_token(
            client_id=client_id, client_secret=client_secret, code=code)
        yield from _write_config(access_token)
        yield from _add_devices(access_token)
        configurator.async_request_done(request_id)

    hass.http.register_view(StravaAuthCallbackView())

    client_id = config.get(CONF_CLIENT_ID)
    client_secret = config.get(CONF_CLIENT_SECRET)

    config_path = hass.config.path(STRAVA_CONFIG_PATH)

    access_token = yield from _read_config()
    if access_token is not None:
        yield from _add_devices(access_token)
    else:
        callback_url = '{}{}'.format(hass.config.api.base_url,
                                     StravaAuthCallbackView.url)
        authorize_url = client.authorization_url(client_id=client_id,
                                                 redirect_uri=callback_url)

        configurator = hass.components.configurator
        request_id = configurator.async_request_config(
            'Strava',
            description='Authorization required for Strava account.',
            link_name='Authorize Home Assistant',
            link_url=authorize_url,
            entity_picture='/local/icons/logo_strava.png')

    hass.data[DATA_CALLBACK] = initialize_callback
    return True
예제 #43
0
def index(request):
    client = Client()
    url = client.authorization_url(client_id=11103,
                                   redirect_uri='http://localhost:8000/authorization')
    ##TODO: Take out of code for version control
    return HttpResponse('Hello world, You are at the Strava Auth landing page. <a href="{0}">Click Here to authorize</a>'.format(url))
예제 #44
0
파일: server.py 프로젝트: hozn/stravalib
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)
예제 #45
0
    def do_GET(self):

        request_path = self.path

        parsed_path = urlparse.urlparse(request_path)

        client = Client()

        if request_path.startswith('/authorization'):
            self.send_response(200)
            self.send_header(six.b("Content-type"), six.b("text/html"))
            self.end_headers()

            code = urlparse.parse_qs(parsed_path.query).get('code')
            if code:
                code = code[0]
                token_response = client.exchange_code_for_token(
                    client_id=self.server.client_id,
                    client_secret=self.server.client_secret,
                    code=code)
                access_token = token_response['access_token']
                refresh_token = token_response['refresh_token']
                expires_at = token_response['expires_at']
                self.server.logger.info(
                    "Exchanged code {} for access token {}".format(
                        code, access_token))
                self.wfile.write(
                    six.b("<html><head><script>function download() {"))
                self.wfile.write(
                    six.b("var text = `{}\n".format(self.server.client_id)))
                self.wfile.write(
                    six.b("{}\n".format(self.server.client_secret)))
                self.wfile.write(six.b("{}\n".format(access_token)))
                self.wfile.write(six.b("{}\n".format(refresh_token)))
                self.wfile.write(six.b("{}\n`;".format(expires_at)))
                self.wfile.write(
                    six.b("var pom = document.createElement('a');"))
                self.wfile.write(
                    six.
                    b("pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));"
                      ))
                self.wfile.write(
                    six.b("pom.setAttribute('download', 'strava_token.txt');"))
                self.wfile.write(
                    six.
                    b("pom.style.display = 'none'; document.body.appendChild(pom);"
                      ))
                self.wfile.write(
                    six.b("pom.click(); document.body.removeChild(pom); }"))
                self.wfile.write(
                    six.
                    b("</script></head><body>Access token obtained successfully<br><br>"
                      ))
                self.wfile.write(
                    six.
                    b("<button onclick=\"download()\">Download</button></body></html>"
                      ))
                with open('%s/strava_token.txt' % SCRIPT_DIR, 'w') as f:
                    f.write(self.server.client_id + '\n')
                    f.write(self.server.client_secret + '\n')
                    f.write(access_token + '\n')
                    f.write(refresh_token + '\n')
                    f.write(str(expires_at) + '\n')
            else:
                self.server.logger.error("No code param received.")
                self.wfile.write(six.b("ERROR: No code param recevied.\n"))
        else:
            url = client.authorization_url(
                client_id=self.server.client_id,
                redirect_uri='http://localhost:{}/authorization'.format(
                    self.server.server_port),
                scope='activity:write')

            self.send_response(302)
            self.send_header(six.b("Content-type"), six.b("text/plain"))
            self.send_header('Location', url)
            self.end_headers()
            self.wfile.write(six.b("Redirect to URL: {}\n".format(url)))
예제 #46
0
def main(args=None):
    allowed_exts = {
        '.tcx': lambda v: '<TrainingCenterDatabase' in v[:200],
        '.gpx': lambda v: '<gpx' in v[:200],
        '.fit': lambda v: v[8:12] == '.FIT'
    }

    p = argparse.ArgumentParser(
        description='''Uploads activities to Strava.''')
    p.add_argument(
        'activities',
        nargs='*',
        type=argparse.FileType("rb"),
        default=(stdin, ),
        help="Activity files to upload (plain or gzipped {})".format(
            ', '.join(allowed_exts)))
    p.add_argument('-P',
                   '--no-popup',
                   action='store_true',
                   help="Don't browse to activities after upload.")
    p.add_argument(
        '-E',
        '--env',
        help=
        'Look for ACCESS_TOKEN in environment variable rather than ~/.stravacli'
    )
    g = p.add_argument_group('Activity file details')
    g.add_argument('-p',
                   '--private',
                   action='store_true',
                   help='Make activities private')
    g.add_argument(
        '-t',
        '--type',
        choices=allowed_exts,
        default=None,
        help=
        'Force files to be interpreted as being of given type (default is to autodetect based on name, or contents for stdin)'
    )
    g.add_argument(
        '-x',
        '--xml-desc',
        action='store_true',
        help="Parse name/description fields from GPX and TCX files.")
    g.add_argument('-T', '--title', help='Activity title')
    g.add_argument('-D',
                   '--desc',
                   dest='description',
                   help='Activity description')
    g.add_argument(
        '-A',
        '--activity-type',
        default=None,
        help='''Type of activity. If not specified, the default value is taken
                                                                  from user profile. Supported values:
                                                                  ride, run, swim, workout, hike, walk, nordicski, alpineski,
                                                                  backcountryski, iceskate, inlineskate, kitesurf, rollerski,
                                                                  windsurf, workout, snowboard, snowshoe'''
    )
    args = p.parse_args(args)

    if args.xml_desc:
        if args.title:
            p.error(
                'argument -T/--title not allowed with argument -x/--xml-desc')
        if args.description:
            p.error(
                'argument -D/--desc not allowed with argument -x/--xml-desc')

    #####

    # Authorize Strava

    cid = 3163  # CLIENT_ID
    if args.env:
        cat = os.environ.get('ACCESS_TOKEN')
    else:
        cp = ConfigParser.ConfigParser()
        cp.read(os.path.expanduser('~/.stravacli'))
        cat = None
        if cp.has_section('API'):
            cat = cp.get('API', 'ACCESS_TOKEN'
                         ) if 'access_token' in cp.options('API') else None

    while True:
        client = Client(cat)
        try:
            athlete = client.get_athlete()
        except requests.exceptions.ConnectionError:
            p.error("Could not connect to Strava API")
        except Exception as e:
            print("NOT AUTHORIZED", file=stderr)
            print(
                "Need Strava API access token. Launching web browser to obtain one.",
                file=stderr)
            client = Client()
            authorize_url = client.authorization_url(
                client_id=cid,
                redirect_uri='http://stravacli-dlenski.rhcloud.com/auth',
                scope='view_private,write')
            webbrowser.open_new_tab(authorize_url)
            client.access_token = cat = raw_input("Enter access token: ")
        else:
            if not cp.has_section('API'):
                cp.add_section('API')
            if not 'ACCESS_TOKEN' in cp.options('API') or cp.get(
                    'API', 'ACCESS_TOKEN', None) != cat:
                cp.set('API', 'ACCESS_TOKEN', cat)
                cp.write(open(os.path.expanduser('~/.stravacli'), "w"))
            break

    print(u"Authorized to access account of {} {} (id {:d}).".format(
        athlete.firstname, athlete.lastname, athlete.id))

    #####

    for ii, f in enumerate(args.activities):
        if f is stdin:
            fn = 'stdin'
            contents = f.read()
            f = StringIO(contents)
            if args.type is None:
                # autodetect gzip and extension based on content
                if contents.startswith('\x1f\x8b'):
                    gz, cf, uf = '.gz', f, gzip.GzipFile(fileobj=f, mode='rb')
                    contents = uf.read()
                else:
                    gz, uf, cf = '', f, NamedTemporaryFile(suffix='.gz')
                    gzip.GzipFile(fileobj=cf, mode='w+b').writelines(f)
                for ext, checker in allowed_exts.items():
                    if checker(contents):
                        print(
                            u"Uploading {} activity from stdin...".format(ext +
                                                                          gz))
                        break
                else:
                    p.error("Could not determine file type of stdin")
            else:
                base, ext = 'activity', args.type
        else:
            base, ext = os.path.splitext(
                f.name if args.type is None else 'activity.' + args.type)
            # autodetect based on extensions
            if ext.lower() == '.gz':
                base, ext = os.path.splitext(base)
                # un-gzip it in order to parse it
                gz, cf, uf = '.gz', f, None if args.no_parse else gzip.GzipFile(
                    fileobj=f, mode='rb')
            else:
                gz, uf, cf = '', f, NamedTemporaryFile(suffix='.gz')
                gzip.GzipFile(fileobj=cf, mode='w+b').writelines(f)
            if ext.lower() not in allowed_exts:
                p.error(
                    "Don't know how to handle extension {} (allowed are {}).".
                    format(ext, ', '.join(allowed_exts)))
            print(u"Uploading {} activity from {}...".format(ext + gz, f.name))

        # try to parse activity name, description from file if requested
        if args.xml_desc:
            uf.seek(0, 0)
            if ext.lower() == '.gpx':
                x = etree.parse(uf)
                nametag, desctag = x.find("{*}name"), x.find("{*}desc")
                title = nametag and nametag.text
                desc = desctag and desctag.text
            elif ext.lower() == '.tcx':
                x = etree.parse(uf)
                notestag = x.find("{*}Activities/{*}Activity/{*}Notes")
                if notestag is not None:
                    title, desc = (notestag.text.split('\n', 1) + [None])[:2]
        else:
            title = args.title
            desc = args.description

        # upload activity
        try:
            cf.seek(0, 0)
            upstat = client.upload_activity(cf,
                                            ext[1:] + '.gz',
                                            title,
                                            desc,
                                            private=args.private,
                                            activity_type=args.activity_type)
            activity = upstat.wait()
            duplicate = False
        except exc.ActivityUploadFailed as e:
            words = e.args[0].split()
            if words[-4:-1] == ['duplicate', 'of', 'activity']:
                activity = client.get_activity(words[-1])
                duplicate = True
            else:
                raise

        # show results
        uri = "http://strava.com/activities/{:d}".format(activity.id)
        print(u"  {}{}".format(uri, " (duplicate)" if duplicate else ''),
              file=stderr)
        if not args.no_popup:
            webbrowser.open_new_tab(uri)