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
def upgrade(request, success=1): athlete = db.SELECT('athletes', where=f"username = '******'") return render(request, 'upgrade.html', { 'athlete': athlete, 'success': bool(success) })
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'])))
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
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 })
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)
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)
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})
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
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
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
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 })
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'])))
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 })
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)
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)
def support(request): athlete = db.SELECT('athletes', where=f"username = '******'") return render(request, 'support.html', {'athlete': athlete})