Exemple #1
0
def get_athlete(username, activity_id=0):
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')

    # Load athlete info and set environ vars
    athlete = db.SELECT('athletes',
                        where=f"username = '******'",
                        conn=conn)

    if activity_id:
        activity = db.SELECT('activities',
                             where=f"activity_id = {activity_id}",
                             conn=conn)
        if activity['a_id'] != athlete['a_id']:
            raise LookupError

    # If subscription has a date field, change tier status if past date
    try:
        expiration = datetime.datetime.strptime(athlete['subscription'],
                                                '%Y-%m-%d')
        if expiration <= datetime.datetime.today():
            db.UPDATE('athletes',
                      where=f"username = '******'",
                      numCols=2,
                      cols="tier, subscription",
                      vals="'free', NULL",
                      conn=conn)
            athlete['tier'] = 'free'
    except:
        pass

    conn.close()

    return athlete
Exemple #2
0
def upgrade(request, success=1):
    athlete = db.SELECT('athletes', where=f"username = '******'")

    return render(request, 'upgrade.html', {
        'athlete': athlete,
        'success': bool(success)
    })
Exemple #3
0
def charge(request):
    athlete = db.SELECT('athletes', where=f"username = '******'")
    amount = int(request.POST['amount'])
    stripe_config = {'publicKey': STRIPE_PUBLISHABLE_KEY}

    if request.method == "POST":
        print('Data:', request.POST)

    if athlete['customer'] != None:
        try:
            customer = stripe.Customer.retrieve(athlete['customer'])
        except:
            customer = stripe.Customer.create(
                name=request.POST['user'], source=request.POST['stripeToken'])
    else:
        customer = stripe.Customer.create(name=request.POST['user'],
                                          source=request.POST['stripeToken'])

    try:
        charge = stripe.Charge.create(customer=customer,
                                      amount=amount * 100,
                                      currency='usd',
                                      description='Donation')
    except:
        return redirect(reverse('success', args=('False', 'None')))

    return redirect(reverse('success', args=(amount, customer['id'])))
Exemple #4
0
def heatmap(athlete):
    from scripts import polyline
    import zlib
    import time
    RAW_MAP = {8:r'\b', 7:r'\a', 12:r'\f', 10:r'\n', 13:r'\r', 9:r'\t', 11:r'\v'}
    t0 = time.time()

    # Get athlete info from DB
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    a_id = athlete['a_id']

    # Get runs/streams
    raw = db.SELECT('polylines', where=f'a_id = {a_id}', conn=conn)
    print('FETCHED:', time.time()-t0)
    latlng = raw['polyline'].split(',')
    lat = []
    lng = []
    print('SPLIT:', time.time()-t0)

    # Decode
    for line in latlng:
        raw = r''.join(i if ord(i) > 32 else RAW_MAP.get(ord(i), i) for i in line)
        decoded = polyline.decode(raw, precision=5)
        if not decoded: continue
        lat += list(map(lambda x : x[0], decoded))
        lng += list(map(lambda x: x[1], decoded))
    print('DECODED:', time.time()-t0)

    # Get map
    heatmap = map_charts.global_heatmap(lat, lng)
    print('MAP:', time.time()-t0)

    return heatmap
Exemple #5
0
def subscribed(request, email, subscription_id):
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    athlete = db.SELECT('athletes',
                        where=f"username = '******'",
                        conn=conn)

    if email == 'False':
        return redirect(reverse('upgrade', args=(0)))

    db.UPDATE('auth_user',
              where=f"username = '******'",
              numCols=1,
              cols='email',
              vals=f"'{email}'",
              conn=conn)
    db.UPDATE('athletes',
              where=f"username = '******'",
              numCols=2,
              cols="tier, subscription",
              vals=f"'pro', '{subscription_id}'",
              conn=conn)

    conn.close()

    return render(request, 'subscribed.html', {
        'email': email,
        'athlete': athlete
    })
Exemple #6
0
def shareable(request, activity_id, key):

    activity = db.SELECT(
        'activities',
        where=f"activity_id = {activity_id} AND shareable_key = '{key}'")
    if not activity:
        return redirect('/')

    athlete = db.SELECT('athletes', where=f"a_id = {activity['a_id']}")
    athlete = driver.get_athlete(athlete['username'])
    athlete['profile_pic'] = None

    if athlete['unit'] == 'imperial':
        units = {'dist': 'mi', 'elev': 'ft'}
    else:
        units = {'dist': 'km', 'elev': 'ft'}

    context = {'athlete': athlete, 'units': units, 'shareable_key': 'PUBLIC'}

    run_info, weather, streams, streams_laps, map_stream = driver.activity_details(
        athlete, activity_id)

    graph_dict = dict.fromkeys([f'g{i}' for i in range(9)], '')

    try:
        graphs, tables = asyncio.run(
            driver.graphs(athlete, run_info, streams, streams_laps,
                          map_stream))
        for k, v in graph_dict.items():
            if k in graphs:
                graph_dict[k] = graphs[k]
    except:
        tables = ['', '']

    context.update(graph_dict)
    context.update({
        'auto_table': tables[0],
        'device_table': tables[1],
        'run_info': run_info,
        'weather': weather,
        'id': activity_id
    })

    return render(request, 'activity_dashboard/activity_detail.html', context)

    return render(request)
Exemple #7
0
def trends(athlete, metric):
    import pandas as pd
    import math
    import datetime

    # Select runs
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    cur_year = datetime.datetime.today().year
    all_runs = db.SELECT('activities',
                         where=f"a_id = {athlete['a_id']}",
                         conn=conn)
    conn.close()

    try:
        # Create and group DataFrame
        if metric == 'pace':
            df = pd.DataFrame(all_runs, columns=['date', 'dist', 'time'])
            pace = list(
                map(lambda t, d: d / t
                    if t > 0 else math.nan, df['time'], df['dist']))
            df.insert(loc=0, column='pace', value=pace)
        else:
            df = pd.DataFrame(all_runs, columns=['date', metric])

        df.dropna(axis=0)
        df['date'] = pd.to_datetime(df['date'])
        cr_year = min(df['date']).year

        if metric in ['dist', 'time', 'elev']:
            monthly = df.groupby([df['date'].dt.year,
                                  df['date'].dt.month]).sum()
            weekly = df.groupby(
                [df['date'].dt.year, df['date'].dt.strftime('%W')]).sum()
        else:
            monthly = df.groupby([df['date'].dt.year,
                                  df['date'].dt.month]).mean()
            weekly = df.groupby(
                [df['date'].dt.year, df['date'].dt.strftime('%W')]).mean()

        monthly_trends, monthly_table = trend_graphs.trend(
            monthly, 12, range(cr_year, cur_year + 1), athlete['unit'])

        weekly_trends, weekly_table = trend_graphs.trend(
            weekly, 52, range(cr_year, cur_year + 1), athlete['unit'])

        mega_h = trend_graphs.mega_hist(df, metric, athlete['unit'])
        mega_b = trend_graphs.mega_box(df, metric, athlete['unit'])
    except:
        return (None, ) * 4 + ('', '')

    return (monthly_trends, weekly_trends, mega_h, mega_b, monthly_table,
            weekly_table)
Exemple #8
0
def cancelled(request, expiration):
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    athlete = db.SELECT('athletes',
                        where=f"username = '******'",
                        conn=conn)

    stripe.Subscription.delete(athlete['subscription'])
    db.UPDATE('athletes',
              where=f"username = '******'",
              numCols=1,
              cols='subscription',
              vals=f"'{expiration}'")

    return render(request, 'cancelled.html', {'athlete': athlete})
Exemple #9
0
def activity_details(athlete, activity_id):
    # Get athlete info from DB
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    unit = athlete['unit']
    weather, streams, streams_laps, map_stream = None, None, None, None

    # Authenticate athlete
    client = authenticate(athlete)

    # Get run stats
    try:
        run = client.get_activity(activity_id).to_dict()
    except:
        try:  # hit rate limit, try getting data from DB
            run = db.SELECT('activities', where=f"activity_id = {activity_id}")
            stats = last7.last7([run], unit)
            stats['name'] = run['name']
            stats['date'] = run['date']
            try:
                weather = helper.weather(run['datetime'], run['start_lat'],
                                         run['start_lng'])
            except:
                weather = ''
            return (stats, weather) + (None, ) * 3
        except:
            return (None, ) * 5

    dt = datetime.datetime.strptime(run['start_date_local'].replace(
        'T', ' '), '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d %H:%M:%S')
    try:
        weather = helper.weather(dt, run['start_latitude'],
                                 run['start_longitude'], unit)
    except:
        weather = ''

    # Collect streams and udpate DB
    try:
        streams_laps, streams, map_stream = helper.get_run_streams(
            client, activity_id)
        stats = helper.run_stats(run, athlete, streams=streams)
        conn.close()
    except:
        conn.close()
        stats = helper.run_stats(run, athlete, streams=None)

    return stats, weather, streams, streams_laps, map_stream
Exemple #10
0
def deauthorize(a_id):
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')

    # Get username
    user = db.SELECT('athletes', where=f'a_id = {a_id}', conn=conn)['username']

    # Delete auth_user
    try:
        db.DELETE('auth_user', where=f"username = '******'")
    except:  # All Auth user
        cur = conn.cursor()
        cur.execute(f"SELECT id FROM auth_user WHERE username = '******'")
        user_id = cur.fetchone()[0]
        cur.close()
        db.DELETE('socialaccount_socialaccount', where=f"user_id = {user_id}")
        db.DELETE('auth_user', where=f"username = '******'")

    conn.close()
    return
Exemple #11
0
def new_activity(a_id, activity_id):
    # Retrieve info from DB
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    athlete = db.SELECT('athletes', where=f"a_id = {a_id}", conn=conn)

    # Get run details
    client = authenticate(athlete)
    run = client.get_activity(activity_id=activity_id)

    # skip if activity is not a run
    if run.type not in [
            'Run', 'Ride', 'Walk', 'Hike', 'Apline Ski', 'Nordic Ski'
    ]:
        return

    # Parse run info
    run_info = parse_run(run, athlete)

    # Parse polyline
    polyline = run.map.summary_polyline
    if polyline != None:
        raw = r''.join(i if ord(i) > 32 else RAW_MAP.get(ord(i), i)
                       for i in polyline)
        cur = conn.cursor()
        sql = f"UPDATE polylines SET polyline = polyline || '" + raw + f",' WHERE a_id = {athlete['a_id']}"

        try:
            cur.execute(sql)
            print(sql)
            conn.commit()
        except:
            print('FAILED:', sql)
            conn.close()
            conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')

    db.INSERT('activities', run_info, conn=conn)
    conn.close()

    return
Exemple #12
0
def cancel(request):
    import datetime

    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    athlete = db.SELECT('athletes',
                        where=f"username = '******'",
                        conn=conn)

    # Find out how long user has left
    try:
        subscription = stripe.Subscription.retrieve(athlete['subscription'])
        expiration = datetime.datetime.fromtimestamp(
            subscription['current_period_end']).strftime('%Y-%m-%d')
        cancelled = False
    except:
        expiration = athlete['subscription']
        cancelled = True

    return render(request, 'cancel.html', {
        'athlete': athlete,
        'expiration': expiration,
        'cancelled': cancelled
    })
Exemple #13
0
def subscribe(request):
    athlete = db.SELECT('athletes', where=f"username = '******'")
    email = request.POST.get('email')
    user = request.POST['user']
    price = {
        '$1.99 /month': 'price_1GuLgxB1V92AxtqIa3AtO3ov',
        '$19.99 /year': 'price_1GuLgxB1V92AxtqIxlGRjaqg'
    }
    stripe_config = {'publicKey': STRIPE_PUBLISHABLE_KEY}

    if request.method == 'POST':
        print('Data:', request.POST)

    if athlete['customer'] != None:
        try:
            customer = stripe.Customer.retrieve(athlete['customer'])
            customer = stripe.Customer.modify(athlete['customer'],
                                              metadata={'email': email})
        except:
            customer = stripe.Customer.create(
                name=user, email=email, source=request.POST['stripeToken'])
    else:
        customer = stripe.Customer.create(name=user,
                                          email=email,
                                          source=request.POST['stripeToken'])

    try:
        subscription = stripe.Subscription.create(
            customer=customer,
            items=[{
                "price": price[request.POST['plan']]
            }],
            payment_behavior='error_if_incomplete')
    except:
        return redirect(reverse('subscribed', args=('False', 'None')))

    return redirect(reverse('subscribed', args=(email, subscription['id'])))
Exemple #14
0
def success(request, amount, customer_id):
    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    athlete = db.SELECT('athletes',
                        where=f"username = '******'",
                        conn=conn)

    if amount == 'False':
        conn.close()
        return render(request, 'success.html', {
            'amount': amount,
            'athlete': athlete
        })

    db.UPDATE('athletes',
              where=f"username = '******'",
              numCols=1,
              cols='customer',
              vals=f"'{customer_id}'")
    conn.close()

    return render(request, 'success.html', {
        'amount': amount,
        'athlete': athlete
    })
Exemple #15
0
def account(request):
    from . import forms

    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    context = {}

    try:
        # Load athlete info
        athlete = db.SELECT('athletes',
                            where=f"username = '******'",
                            conn=conn)
        unit = athlete['unit']

        # Best Effort
        be_time = tm.strftime('%H:%M:%S', tm.gmtime(athlete['pr_time']))
        be_dist = '{:,}'.format(athlete['pr_dist'])
        be_km = round(athlete['pr_dist'] / 1000, 2)
        be_mi = round(athlete['pr_dist'] * 0.000621371, 2)

        # Get all runs
        all_runs = db.SELECT('activities',
                             where=f"a_id = {athlete['a_id']}",
                             conn=conn)
        if type(all_runs) is not list:
            all_runs = [all_runs]
        all_runs = pd.DataFrame(all_runs)
        try:
            totals = scripts.account_totals(all_runs, athlete, unit)
            print('TOTALS:\n', totals)

            for k, v in totals.items():
                context[k] = v
        except:
            totals = None
    except:
        athlete = ''
        be_time = '06:30'
        be_dist = 1609
        be_km = 1.609
        be_mi = 1
        return render(request, 'home/connect_to_strava.html',
                      {'strava_client_id': os.environ['STRAVA_CLIENT_ID']})

    # PR form
    pr_form = forms.PersonalRecord(request.POST)
    unit_preference = forms.UnitPreference(request.POST)
    import_form = forms.ImportRuns(request.POST)
    email_form = forms.EmailForm(request.POST)

    if request.method == 'POST':
        if 'pr_sub' in request.POST:
            if pr_form.is_valid():
                pr_info = pr_form.cleaned_data
                time = (int(pr_info['h']) * 3600) + (int(pr_info['m']) *
                                                     60) + int(pr_info['s'])
                if pr_info['unit'] == 'mi':
                    dist = int(pr_info['distance'] * 1609.34 + 0.5)
                elif pr_info['unit'] == 'km':
                    dist = int(pr_info['distance'] * 1000 + 0.5)
                else:
                    dist = pr_info['distance']

                db.UPDATE('athletes',
                          where=f"username = '******'",
                          numCols=2,
                          cols='pr_time, pr_distance',
                          vals=f"{time}, {dist}",
                          conn=conn)
                conn.close()
                return redirect('/account')
            else:
                pr_form = forms.PersonalRecord()
        elif 'unit_sub' in request.POST:
            if unit_preference.is_valid():
                unit_pref = unit_preference.cleaned_data['metric']

                db.UPDATE('athletes',
                          where=f"username = '******'",
                          numCols=1,
                          cols='unit',
                          vals=f"'{unit_pref}'",
                          conn=conn)
                conn.close()
                return redirect('/account')
            else:
                unit_preference = forms.UnitPreference()
        elif 'import_runs' in request.POST:
            #try:
            importer.import_runs(athlete)
            db.UPDATE('athletes',
                      where=f"username = '******'",
                      numCols=1,
                      cols='imported',
                      vals="'Y'",
                      conn=conn)
            return redirect('/dashboard')
            #except:
            #    context.update({'error': True})
        elif 'email_sub' in request.POST:
            if email_form.is_valid():
                email = email_form.cleaned_data['email']
                db.UPDATE('auth_user',
                          where=f"username = '******'",
                          numCols=1,
                          cols='email',
                          vals=f"'{email}'",
                          conn=conn)
            else:
                email_form = forms.EmailForm()

    context.update({
        'pr_form': pr_form,
        'unit_preference': unit_preference,
        'import_form': import_form,
        'email_form': email_form,
        'athlete': athlete,
        'be_time': be_time,
        'be_dist': be_dist,
        'be_km': be_km,
        'be_mi': be_mi,
    })

    try:
        conn.close()
    except:
        pass

    return render(request, 'home/account.html', context)
Exemple #16
0
def activity_dashboard(athlete, after, before):
    import datetime

    conn = psy.connect(os.environ['DATABASE_URL'], sslmode='prefer')
    a_id = athlete['a_id']
    unit = athlete['unit']

    delta = (before - after).days
    runs = db.SELECT('activities',
                 where=f"a_id = {a_id} AND date BETWEEN '{after}' AND '{before}'", conn=conn)
    runs_dict = helper.organize_dict(runs, 'date')

    # Barcharts
    if runs: # runs != []
        graphs_dict = asyncio.run(dashboard_charts(runs, runs_dict, before, delta, unit))
    else:
        graphs_dict = {}

    graphs = (
            graphs_dict.get('dist', ''),
            graphs_dict.get('time', ''),
            graphs_dict.get('elev', ''),
            graphs_dict.get('velocity', ''),
            graphs_dict.get('avg_hr', ''),
            graphs_dict.get('intensity', ''),
            graphs_dict.get('achievement_count', ''),
            graphs_dict.get('kudos_count', ''),
            graphs_dict.get('tod', ''),
            graphs_dict.get('table', '')
            )

    # Last7
    last7_runs = db.SELECT('activities', where=f"a_id = {a_id} AND date BETWEEN '{datetime.datetime.today()-datetime.timedelta(days=6)}' AND '{datetime.datetime.today()}'", conn=conn)
    last7_stats = last7.last7(last7_runs, unit)

    # Month stats
    import calendar
    today = datetime.datetime.today()
    mo_range = calendar.monthrange(today.year, today.month)
    mo_start = datetime.datetime.strftime(datetime.date(today.year, today.month, 1), '%Y-%m-%d')
    mo_end = datetime.datetime.strftime(datetime.date(today.year, today.month, mo_range[1]), '%Y-%m-%d')
    month_runs = db.SELECT('activities', where=f"a_id = {a_id} AND date BETWEEN '{mo_start}' AND '{mo_end}'", conn=conn)
    month_stats = last7.last7(month_runs, unit)

    yr_runs = db.SELECT('activities', where=f"a_id = {a_id} AND date BETWEEN '{today.year}-01-01' AND '{today}'", conn=conn)
    yr_stats = last7.last7(yr_runs, unit)

    # View stats
    view_stats = last7.last7(runs, unit)

    conn.close()

    # Display info
    info = {
            'date_end': before.strftime('%a, %b %d, %Y'),
            'date_start': after.strftime('%a, %b %d, %Y'),
            'date_end_abv': before.strftime('%m/%d/%y'),
            'date_start_abv': after.strftime('%m/%d/%y')
            }

    return graphs + (info, last7_stats, view_stats, month_stats, yr_stats)
Exemple #17
0
def support(request):
    athlete = db.SELECT('athletes', where=f"username = '******'")

    return render(request, 'support.html', {'athlete': athlete})