Private
Public Access
1
0

Merge branch 'feature/autopep' into develop

This commit is contained in:
Sander Roosendaal
2022-03-15 10:22:21 +01:00
59 changed files with 1136 additions and 1886 deletions
+1 -4
View File
@@ -2,9 +2,7 @@ from rowers.models import Alert, Condition, User, Rower, Workout
from rowers.teams import coach_getcoachees
from rowers.dataprep import getsmallrowdata_db, getrowdata_db
import datetime
# BASIC operations
# create alert
import numpy as np
def create_alert(manager, rower, measured, period=7, emailalert=True,
@@ -65,7 +63,6 @@ def alert_add_filters(alert, filters):
for f in filters:
metric = f['metric']
value1 = f['value1']
value2 = f['value2']
condition = f['condition']
if condition and metric and value1:
+14 -39
View File
@@ -72,8 +72,7 @@ def process_webhook(notification):
transactions = subscription.transactions
if transactions:
amount = int(transactions[0].amount)
eurocredits = credits.upgrade(amount, r)
eurocredits = credits.upgrade(amount, r)
_ = credits.upgrade(amount, r)
return send_invoice(notification.subscription)
if notification.kind == 'subscription_canceled':
subscription = notification.subscription
@@ -97,10 +96,7 @@ def process_webhook(notification):
def send_invoice(subscription):
with open('braintreewebhooks.log', 'a') as f:
t = time.localtime()
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
f.write('Subscription ID '+str(subscription.id)+'\n')
dologging('braintreewebhooks.log', 'Subscription ID '+str(subscription.id))
subscription_id = subscription.id
rs = Rower.objects.filter(subscription_id=subscription_id)
if rs.count() == 0: # pragma: no cover
@@ -176,20 +172,6 @@ def get_client_token(rower):
return client_token
def get_plans_costs(): # pragma: no cover
plans = gateway.plan.all()
localplans = PaidPlan.object.filter(paymentprocessor='braintree')
for plan in localplans:
for btplan in btplans:
if int(btplan.id) == plan.external_id:
plan.price = float(x)
plan.save()
return plans
def make_payment(rower, data):
nonce_from_the_client = data['payment_method_nonce']
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
@@ -226,17 +208,11 @@ def make_payment(rower, data):
fakturoid_contact_id = fakturoid.get_contacts(rower)
if not fakturoid_contact_id:
fakturoid_contact_id = fakturoid.create_contact(rower)
id = fakturoid.create_invoice(rower, amount, transaction.id, dosend=True, contact_id=fakturoid_contact_id,
_ = fakturoid.create_invoice(rower, amount, transaction.id, dosend=True, contact_id=fakturoid_contact_id,
name=additional_text)
try:
job = myqueue(queuehigh, handle_send_email_transaction,
_ = myqueue(queuehigh, handle_send_email_transaction,
name, rower.user.email, amount)
job = myqueue(queuehigh, handle_send_email_transation_notification,
name.rower.user.email, amount, additional_text)
except: # pragma: no cover
pass
return amount, True
else: # pragma: no cover
return 0, False
@@ -280,7 +256,7 @@ def update_subscription(rower, data, method='up'):
yesterday = (timezone.now()-datetime.timedelta(days=1)).date()
rower.paidplan = plan
amount_int = int(float(amount))
eurocredits = credits.upgrade(amount_int, rower)
_ = credits.upgrade(amount_int, rower)
rower.planexpires = result.subscription.billing_period_end_date
rower.teamplanexpires = result.subscription.billing_period_end_date
rower.clubsize = plan.clubsize
@@ -319,7 +295,7 @@ def update_subscription(rower, data, method='up'):
else: # pragma: no cover
amount = 0
job = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_send_email_subscription_update,
name, rower.user.email,
plan.name,
@@ -352,12 +328,12 @@ def create_subscription(rower, data):
nonce_from_the_client = data['payment_method_nonce']
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
info = nonce.three_d_secure_info
paymenttype = nonce.type
# paymenttype = nonce.type
if nonce.type != 'PayPalAccount': # pragma: no cover
if info is None or not info.liability_shifted:
return False, 0
amount = data['amount']
# amount = data['amount']
planid = data['plan']
plan = PaidPlan.objects.get(id=planid)
@@ -399,7 +375,7 @@ def create_subscription(rower, data):
recurring = plan.paymenttype
job = myqueue(
_ = myqueue(
queuehigh,
handle_send_email_subscription_create,
name, rower.user.email,
@@ -420,16 +396,17 @@ def cancel_subscription(rower, id):
themessages = []
errormessages = []
try:
result = gateway.subscription.cancel(id)
_ = gateway.subscription.cancel(id)
themessages.append("Subscription canceled")
except: # pragma: no cover
errormessages.append(
"We could not find the subscription record in our customer database. We have notified the site owner, who will contact you.")
"We could not find the subscription record in our customer database."
" We have notified the site owner, who will contact you.")
name = '{f} {l}'.format(f=rower.user.first_name,
l=rower.user.last_name)
job = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_send_email_failed_cancel,
name, rower.user.email, rower.user.username, id)
@@ -510,15 +487,13 @@ def get_transactions(start_date, end_date): # pragma: no cover
dates = []
currencies = []
statuses = []
ids = []
# ids = []
usernames = []
customerids = []
transactionids = []
subscriptionids = []
ownids = []
countlines = [1 for transaction in results]
for transaction in results:
r = None
rs = Rower.objects.filter(
+24 -58
View File
@@ -74,11 +74,12 @@ def getagegrouprecord(age, sex='male', weightcategory='hwt',
ages = df['age']
powers = df['power']
#poly_coefficients = np.polyfit(ages,powers,6)
def fitfunc(pars, x): return np.abs(pars[0])*(1-x/max(120, pars[1]))-np.abs(
def fitfunc(pars, x):
return np.abs(pars[0])*(1-x/max(120, pars[1]))-np.abs(
pars[2])*np.exp(-x/np.abs(pars[3]))+np.abs(pars[4])*(np.sin(np.pi*x/max(50, pars[5])))
def errfunc(pars, x, y): return fitfunc(pars, x)-y
def errfunc(pars, x, y):
return fitfunc(pars, x)-y
p0 = [700, 120, 700, 10, 100, 100]
@@ -92,8 +93,6 @@ def getagegrouprecord(age, sex='male', weightcategory='hwt',
if success:
power = fitfunc(p1, float(age))
#power = np.polyval(poly_coefficients,age)
power = 0.5*(np.abs(power)+power)
else: # pragma: no cover
power = 0
@@ -123,14 +122,13 @@ oauth_data = {
def c2_open(user):
r = Rower.objects.get(user=user)
if (r.c2token == '') or (r.c2token is None):
s = "Token doesn't exist. Need to authorize"
raise NoTokenError("User has no token")
else:
if (timezone.now() > r.tokenexpirydate):
res = rower_c2_token_refresh(user)
if res == None: # pragma: no cover
if res is None: # pragma: no cover
raise NoTokenError("User has no token")
if res[0] != None:
if res[0] is not None:
thetoken = res[0]
else: # pragma: no cover
raise NoTokenError("User has no token")
@@ -142,7 +140,7 @@ def c2_open(user):
def get_c2_workouts(rower, page=1, do_async=True):
try:
thetoken = c2_open(rower.user)
_ = c2_open(rower.user)
except NoTokenError: # pragma: no cover
return 0
@@ -175,7 +173,7 @@ def get_c2_workouts(rower, page=1, do_async=True):
knownc2ids = uniqify(knownc2ids+tombstones+parkedids)
newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
newids = [c2id for c2id in c2ids if c2id not in knownc2ids]
if settings.TESTING:
newids = c2ids
@@ -188,20 +186,18 @@ def get_c2_workouts(rower, page=1, do_async=True):
counter = 0
for c2id in newids:
if do_async: # pragma: no cover
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_c2_async_workout,
alldata,
rower.user.id,
rower.c2token,
c2id,
counter,
rower.defaulttimezone
)
#res = handle_c2_async_workout(alldata,rower.user.id,rower.c2token,c2id,counter)
rower.defaulttimezone)
counter = counter+1
else:
workoutid = create_async_workout(alldata,
rower.user, c2id)
_ = create_async_workout(alldata, rower.user, c2id)
return 1
@@ -212,12 +208,9 @@ def create_async_workout(alldata, user, c2id):
data = alldata[c2id]
splitdata = None
distance = data['distance']
c2id = data['id']
workouttype = data['type']
verified = data['verified']
startdatetime = iso8601.parse_date(data['date'])
weightclass = data['weight_class']
try:
title = data['name']
@@ -229,43 +222,16 @@ def create_async_workout(alldata, user, c2id):
except:
title = ''
weightcategory = 'hwt'
if weightclass == "L":
weightcategory = 'lwt'
# Create CSV file name and save data to CSV file
csvfilename = 'media/Import_'+str(c2id)+'.csv.gz'
totaltime = data['time']/10.
duration = dataprep.totaltime_sec_to_string(totaltime)
try:
timezone_str = data['timezone']
except: # pragma: no cover
timezone_str = 'UTC'
workoutdate = startdatetime.astimezone(
pytz.timezone(timezone_str)
).strftime('%Y-%m-%d')
starttime = startdatetime.astimezone(
pytz.timezone(timezone_str)
).strftime('%H:%M:%S')
try:
notes = data['comments']
name = notes[:40]
except (KeyError, TypeError):
notes = 'C2 Import Workout from {startdatetime}'.format(
startdatetime=startdatetime)
name = notes
r = Rower.objects.get(user=user)
authorizationstring = str('Bearer ' + r.c2token)
headers = {'Authorization': authorizationstring,
'user-agent': 'sanderroosendaal',
'Content-Type': 'application/json'}
url2 = "https://log.concept2.com/api/users/me/results"+str(c2id)
# url2 = "https://log.concept2.com/api/users/me/results"+str(c2id)
url = "https://log.concept2.com/api/users/me/results/"+str(c2id)+"/strokes"
try:
s = requests.get(url, headers=headers)
@@ -638,7 +604,7 @@ def createc2workoutdata(w):
spmav = int(row.df[' Cadence (stokes/min)'][mask].mean())
hrav = int(row.df[' HRCur (bpm)'][mask].mean())
except ValueError:
smpav = 0
spmav = 0
try:
hrav = int(row.df[' HRCur (bpm)'][mask].mean())
except ValuError:
@@ -729,7 +695,6 @@ def createc2workoutdata(w):
"time": int(10*makeseconds(durationstr)),
"weight_class": c2wc(w.weightcategory),
"comments": w.notes,
"stroke_count": int(row.stroke_count),
'stroke_rate': int(row.df[' Cadence (stokes/min)'].mean()),
'drag_factor': int(row.dragfactor),
"heart_rate": {
@@ -749,7 +714,7 @@ def createc2workoutdata(w):
def do_refresh_token(refreshtoken):
scope = "results:write,user:read"
client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
# client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
post_data = {"grant_type": "refresh_token",
"client_secret": C2_CLIENT_SECRET,
"client_id": C2_CLIENT_ID,
@@ -793,7 +758,7 @@ def do_refresh_token(refreshtoken):
def get_token(code):
messg = ''
scope = "user:read,results:write"
client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
# client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": C2_REDIRECT_URI,
@@ -840,7 +805,7 @@ def make_authorization_url(request): # pragma: no cover
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
# state = str(uuid4())
scope = "user:read,results:write"
params = {"client_id": C2_CLIENT_ID,
@@ -857,9 +822,9 @@ def make_authorization_url(request): # pragma: no cover
def get_workout(user, c2id, do_async=True):
r = Rower.objects.get(user=user)
thetoken = c2_open(user)
_ = c2_open(user)
job = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_c2_getworkout,
user.id,
r.c2token,
@@ -909,7 +874,7 @@ def get_username(access_token): # pragma: no cover
try:
res = me_json['data']['username']
id = me_json['data']['id']
_ = me_json['data']['id']
except KeyError:
res = None
@@ -974,7 +939,7 @@ def workout_c2_upload(user, w, asynchron=False):
except KeyError: # pragma: no cover
return "This workout type cannot be uploaded to Concept2", 0
thetoken = c2_open(user)
_ = c2_open(user)
r = Rower.objects.get(user=user)
@@ -1017,11 +982,12 @@ def workout_c2_upload(user, w, asynchron=False):
w.save()
message = "Upload to Concept2 was successful"
else: # pragma: no cover
message = "Something went wrong in workout_c2_upload_view. Response code 200/201 but C2 sync failed: "+response.text
message = "Something went wrong in workout_c2_upload_view." \
" Response code 200/201 but C2 sync failed: "+response.text
c2id = 0
else: # pragma: no cover
job = myqueue(queue,
_ = myqueue(queue,
handle_c2_sync,
w.id,
url,
+1 -9
View File
@@ -25,7 +25,7 @@ from django.conf import settings
import geocoder
from matplotlib import path
# from matplotlib import path
import xml.etree.ElementTree as et
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
@@ -42,10 +42,6 @@ def howfaris(lat_lon, course):
return distance
#whatisnear = 150
# get nearest races
def getnearestraces(lat_lon, races, whatisnear=150):
newlist = []
@@ -55,7 +51,6 @@ def getnearestraces(lat_lon, races, whatisnear=150):
newlist.append(race)
else:
c = race.course
coords = c.coord
distance = howfaris(lat_lon, c)
if distance < whatisnear:
newlist.append(race)
@@ -84,7 +79,6 @@ def getnearestcourses(lat_lon, courses, whatisnear=150, strict=False):
newlist = []
counter = 0
for c in courses:
coords = c.coord
distance = howfaris(lat_lon, c)
if distance < whatisnear:
@@ -199,8 +193,6 @@ def coursetokml(course):
polygons = GeoPolygon.objects.filter(
course=course).order_by("order_in_course")
polygonsxml = []
for polygon in polygons:
placemark = SubElement(folder2, 'Placemark')
polygonname = SubElement(placemark, 'name')
+2 -4
View File
@@ -20,10 +20,8 @@ def time_in_path(df, p, maxmin='max', getall=False, name='unknown', logfile=None
if df.empty: # pragma: no cover
return 0
latitude = df.latitude
longitude = df.longitude
def f(x): return coordinate_in_path(x['latitude'], x['longitude'], p)
def f(x):
return coordinate_in_path(x['latitude'], x['longitude'], p)
df['inpolygon'] = df.apply(f, axis=1)
+79 -96
View File
@@ -31,7 +31,6 @@ from zipfile import BadZipFile
import zipfile
import os
from rowers.models import strokedatafields
from rowingdata.csvparsers import HumonParser
from rowingdata import (
KinoMapParser,
@@ -56,8 +55,7 @@ from rowingdata import (
ETHParser,
NKLiNKLogbookParser,
HeroParser,
SmartRowParser,
)
SmartRowParser,)
# All the data preparation, data cleaning and data mangling should
# be defined here
@@ -111,13 +109,8 @@ import arrow
thetimezone = get_current_timezone()
#allowedcolumns = [item[0] for item in rowingmetrics]
allowedcolumns = [key for key, value in strokedatafields.items()]
#from async_messages import messages as a_messages
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('default')
@@ -169,8 +162,6 @@ def get_video_data(w, groups=['basic'], mode='water'):
p = nicepaceformat(p)
df2['pace'] = p
#mask = df2['time'] < delay
#df2 = df2.mask(mask).dropna()
df2['time'] = (df2['time']-df2['time'].min())
df2 = df2.round(decimals=2)
@@ -190,8 +181,6 @@ def get_video_data(w, groups=['basic'], mode='water'):
coordinates.set_index(pd.to_timedelta(
coordinates['time'], unit='s'), inplace=True)
coordinates = coordinates.resample('1s').mean().interpolate()
#mask = coordinates['time'] < delay
#coordinates = coordinates.mask(mask).dropna()
coordinates['time'] = coordinates['time']-coordinates['time'].min()
latitude = coordinates['latitude']
longitude = coordinates['longitude']
@@ -295,11 +284,11 @@ def get_latlon_time(id):
try:
try:
latitude = rowdata.df.loc[:, ' latitude']
longitude = rowdata.df.loc[:, ' longitude']
_ = rowdata.df.loc[:, ' latitude']
_ = rowdata.df.loc[:, ' longitude']
except KeyError: # pragma: no cover
latitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
longitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
rowdata.df['latitude'] = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
rowdata.df['longitude'] = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
except AttributeError: # pragma: no cover
return pd.DataFrame()
@@ -438,7 +427,7 @@ def get_workouts(ids, userid): # pragma: no cover
def filter_df(datadf, fieldname, value, largerthan=True):
try:
x = datadf[fieldname]
_ = datadf[fieldname]
except KeyError:
return datadf
@@ -486,9 +475,9 @@ def join_workouts(r, ids, title='Joined Workout',
makeprivate = False
startdatetime = timezone.now()
if setprivate == True and makeprivate == False: # pragma: no cover
if setprivate is True and makeprivate is False: # pragma: no cover
makeprivate = True
elif setprivate == False and makeprivate == True: # pragma: no cover
elif setprivate is False and makeprivate is True: # pragma: no cover
makeprivate = False
# reorder in chronological order
@@ -501,6 +490,11 @@ def join_workouts(r, ids, title='Joined Workout',
workouttype = parent.workouttype
notes = parent.notes
summary = parent.summary
if parent.privacy == 'hidden':
makeprivate = True
else:
makeprivate = False
startdatetime = parent.startdatetime
files = [w.csvfilename for w in ws]
@@ -524,7 +518,9 @@ def join_workouts(r, ids, title='Joined Workout',
notes=notes,
oarlength=oarlength,
inboard=inboard,
startdatetime=startdatetime,
makeprivate=makeprivate,
summary=summary,
dosmooth=False,
consistencychecks=False)
@@ -585,12 +581,12 @@ def resample(id, r, parent, overwrite='copy'):
row.write_csv(parent.csvfilename, gzip=True)
res = dataprep(row.df, id=parent.id, bands=True, barchart=True,
_ = dataprep(row.df, id=parent.id, bands=True, barchart=True,
otwpower=True, empower=True, inboard=parent.inboard)
isbreakthrough, ishard = checkbreakthrough(parent, r)
marker = check_marker(parent)
result = update_wps(r, mytypes.otwtypes)
result = update_wps(r, mytypes.otetypes)
_ = check_marker(parent)
_ = update_wps(r, mytypes.otwtypes)
_ = update_wps(r, mytypes.otetypes)
tss, normp = workout_rscore(parent)
goldmedalstandard, goldmedalseconds = workout_goldmedalstandard(parent)
@@ -607,7 +603,7 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
# clean data remove zeros and negative values
try:
workoutids = datadf['workoutid'].unique()
_ = datadf['workoutid'].unique()
except KeyError:
datadf['workoutid'] = 0
@@ -638,13 +634,13 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
# protect 0 spm values from being nulled
try:
datadf['spm'] = datadf['spm'] + 1.0
except (KeyError, TypeError) as e:
except (KeyError, TypeError):
pass
# protect 0 workoutstate values from being nulled
try:
datadf['workoutstate'] = datadf['workoutstate'] + 1
except (KeyError, TypeError) as e:
except (KeyError, TypeError):
pass
try:
@@ -676,13 +672,13 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
# bring spm back to real values
try:
datadf['spm'] = datadf['spm'] - 1
except (TypeError, KeyError) as e:
except (TypeError, KeyError):
pass
# bring workoutstate back to real values
try:
datadf['workoutstate'] = datadf['workoutstate'] - 1
except (TypeError, KeyError) as e:
except (TypeError, KeyError):
pass
# return from positive domain to negative
@@ -840,11 +836,11 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
except (KeyError, TypeError):
pass
workoutstateswork = [1, 4, 5, 8, 9, 6, 7]
# workoutstateswork = [1, 4, 5, 8, 9, 6, 7]
workoutstatesrest = [3]
workoutstatetransition = [0, 2, 10, 11, 12, 13]
# workoutstatetransition = [0, 2, 10, 11, 12, 13]
if workstrokesonly == 'True' or workstrokesonly == True:
if workstrokesonly == 'True' or workstrokesonly is True:
try:
datadf = datadf[~datadf['workoutstate'].isin(workoutstatesrest)]
except:
@@ -872,10 +868,10 @@ def getpartofday(row, r):
timezone_str = tf.timezone_at(lng=lonavg, lat=latavg)
except (ValueError, OverflowError): # pragma: no cover
timezone_str = 'UTC'
if timezone_str == None: # pragma: no cover
if timezone_str is None: # pragma: no cover
timezone_str = tf.closest_timezone_at(lng=lonavg,
lat=latavg)
if timezone_str == None:
if timezone_str is None:
timezone_str = r.defaulttimezone
try:
workoutstartdatetime = pytz.timezone(timezone_str).localize(
@@ -1008,7 +1004,7 @@ def update_c2id_sql(id, c2id):
table, c2id, id)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
_ = conn.execute(query)
conn.close()
engine.dispose()
@@ -1022,7 +1018,8 @@ def getcpdata_sql(rower_id, table='cpdata'):
rower_id=rower_id,
table=table,
))
connection = engine.raw_connection()
_ = engine.raw_connection()
df = pd.read_sql_query(query, engine)
return df
@@ -1036,7 +1033,7 @@ def deletecpdata_sql(rower_id, table='cpdata'): # pragma: no cover
))
with engine.connect() as conn, conn.begin():
try:
result = conn.execute(query)
_ = conn.execute(query)
except:
print("Database locked")
conn.close()
@@ -1064,11 +1061,10 @@ def updatecpdata_sql(rower_id, delta, cp, table='cpdata', distance=[]): # pragm
def fetchcperg(rower, theworkouts):
theids = [int(w.id) for w in theworkouts]
thefilenames = [w.csvfilename for w in theworkouts]
cpdf = getcpdata_sql(rower.id, table='ergcpdata')
job = myqueue(
_ = myqueue(
queuelow,
handle_updateergcp,
rower.id,
@@ -1138,7 +1134,7 @@ def check_marker(workout):
theid = df.loc[indexmax, 'id']
wmax = Workout.objects.get(id=theid)
gms_max = wmax.goldmedalstandard
# gms_max = wmax.goldmedalstandard
# check if equal, bigger, or smaller than previous
if not wmax.rankingpiece:
@@ -1210,16 +1206,17 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True):
)
)
jsondf = df2.to_json()
job = myqueue(queuelow, handle_getagegrouprecords,
_ = myqueue(queuelow, handle_getagegrouprecords,
jsondf, distances, durations, age, rower.sex, rower.weightcategory)
wcpower = pd.Series(wcpower, dtype='float')
wcdurations = pd.Series(wcdurations, dtype='float')
def fitfunc(pars, x): return pars[0] / \
(1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
def fitfunc(pars, x):
return pars[0] / (1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
def errfunc(pars, x, y): return fitfunc(pars, x)-y
def errfunc(pars, x, y):
return fitfunc(pars, x)-y
if len(wcdurations) >= 4: # pragma: no cover
p1wc, success = optimize.leastsq(
@@ -1227,7 +1224,7 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True):
else:
factor = fitfunc(p0, wcdurations.mean()/wcpower.mean())
p1wc = [p0[0]/factor, p0[1]/factor, p0[2], p0[3]]
success = 0
return 0, 0
times = df['delta']
@@ -1292,7 +1289,7 @@ def setcp(workout, background=False, recurrance=True):
return pd.DataFrame(), pd.Series(dtype='float'), pd.Series(dtype='float')
if background: # pragma: no cover
job = myqueue(queuelow, handle_setcp, strokesdf, filename, workout.id)
_ = myqueue(queuelow, handle_setcp, strokesdf, filename, workout.id)
return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float')
if not strokesdf.empty:
@@ -1339,7 +1336,7 @@ def update_wps(r, types, mode='water', asynchron=True):
ids = [w.id for w in workouts]
if asynchron:
job = myqueue(
_ = myqueue(
queue,
handle_update_wps,
r.id,
@@ -1441,7 +1438,7 @@ def fetchcp(rower, theworkouts, table='cpdata'): # pragma: no cover
if not cpdf.empty:
return cpdf['delta'], cpdf['cp'], avgpower2
else:
job = myqueue(queuelow,
_ = myqueue(queuelow,
handle_updatecp,
rower.id,
theids,
@@ -1489,11 +1486,11 @@ def create_row_df(r, distance, duration, startdatetime, workouttype='rower',
else:
spm = avgspm
step = totalseconds/float(nr_strokes)
# step = totalseconds/float(nr_strokes)
elapsed = np.arange(nr_strokes)*totalseconds/(float(nr_strokes-1))
dstep = distance/float(nr_strokes)
# dstep = distance/float(nr_strokes)
d = np.arange(nr_strokes)*distance/(float(nr_strokes-1))
@@ -1564,12 +1561,12 @@ def checkbreakthrough(w, r):
if workouttype in otwtypes:
res, btvalues, res2 = utils.isbreakthrough(
delta, cpvalues, r.p0, r.p1, r.p2, r.p3, r.cpratio)
success = update_rolling_cp(r, otwtypes, 'water')
_ = update_rolling_cp(r, otwtypes, 'water')
elif workouttype in otetypes:
res, btvalues, res2 = utils.isbreakthrough(
delta, cpvalues, r.ep0, r.ep1, r.ep2, r.ep3, r.ecpratio)
success = update_rolling_cp(r, otetypes, 'erg')
_ = update_rolling_cp(r, otetypes, 'erg')
else: # pragma: no cover
res = 0
res2 = 0
@@ -1584,7 +1581,7 @@ def checkbreakthrough(w, r):
w.rankingpiece = True
w.save()
if r.getemailnotifications and not r.emailbounced: # pragma: no cover
job = myqueue(queuehigh, handle_sendemail_breakthrough,
_ = myqueue(queuehigh, handle_sendemail_breakthrough,
w.id,
r.user.email,
r.user.first_name,
@@ -1597,7 +1594,7 @@ def checkbreakthrough(w, r):
w.rankingpiece = True
w.save()
if r.getemailnotifications and not r.emailbounced:
job = myqueue(queuehigh, handle_sendemail_hard,
_ = myqueue(queuehigh, handle_sendemail_hard,
w.id,
r.user.email,
r.user.first_name,
@@ -1624,7 +1621,6 @@ def checkduplicates(r, workoutdate, workoutstartdatetime, workoutenddatetime):
ws2.append(ww)
if (len(ws2) != 0):
message = "Warning: This workout overlaps with an existing one and was marked as a duplicate"
duplicate = True
return duplicate
@@ -1724,7 +1720,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
windowsize = 2 * (int(10. / (f))) + 1
else: # pragma: no cover
windowsize = 1
if not 'originalvelo' in row.df:
if 'originalvelo' not in row.df:
row.df['originalvelo'] = velo
if windowsize > 3 and windowsize < len(velo):
@@ -1861,15 +1857,15 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
w.team.add(t)
# put stroke data in database
res = dataprep(row.df, id=w.id, bands=True,
_ = dataprep(row.df, id=w.id, bands=True,
barchart=True, otwpower=True, empower=True, inboard=inboard)
isbreakthrough, ishard = checkbreakthrough(w, r)
marker = check_marker(w)
result = update_wps(r, mytypes.otwtypes)
result = update_wps(r, mytypes.otetypes)
_ = check_marker(w)
_ = update_wps(r, mytypes.otwtypes)
_ = update_wps(r, mytypes.otetypes)
job = myqueue(queuehigh, handle_calctrimp, w.id, f2,
_ = myqueue(queuehigh, handle_calctrimp, w.id, f2,
r.ftp, r.sex, r.hrftp, r.max, r.rest)
return (w.id, message)
@@ -1914,7 +1910,7 @@ def get_startdate_time_zone(r, row, startdatetime=None):
startdatetime = row.rowdatetime
try:
tz = startdatetime.tzinfo
_ = startdatetime.tzinfo
except AttributeError: # pragma: no cover
startdatetime = row.rowdatetime
@@ -1987,7 +1983,6 @@ def parsenonpainsled(fileformat, f2, summary, startdatetime='', empowerfirmware=
s = 'Parsenonpainsled, start date time = {startdatetime}'.format(
startdatetime=startdatetime,
#rowdatetime = row.rowdatetime
)
dologging('debuglog.log', s)
@@ -2158,11 +2153,10 @@ def new_workout_from_file(r, f2,
uploadoptions['file'] = datafile
url = settings.UPLOAD_SERVICE_URL
job = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions
)
uploadoptions)
except BadZipFile: # pragma: no cover
pass
@@ -2227,7 +2221,7 @@ def new_workout_from_file(r, f2,
extension = extension2
f4 = filename+'a'+extension
copyfile(f2, f4)
job = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_unrecognized,
f4,
r.user.email)
@@ -2377,7 +2371,7 @@ def split_workout(r, parent, splitsecond, splitmode):
messages.append(message)
ids.append(encoder.encode_hex(id))
if not 'keep original' in splitmode: # pragma: no cover
if 'keep original' not in splitmode: # pragma: no cover
if 'keep second' in splitmode or 'keep first' in splitmode:
parent.delete()
messages.append('Deleted Workout: ' + parent.name)
@@ -2448,7 +2442,6 @@ def new_workout_from_df(r, df,
df.rename(columns=columndict, inplace=True)
#starttimeunix = mktime(startdatetime.utctimetuple())
starttimeunix = arrow.get(startdatetime).timestamp()
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
@@ -2458,15 +2451,13 @@ def new_workout_from_df(r, df,
row.write_csv(csvfilename, gzip=True)
# res = df.to_csv(csvfilename+'.gz',index_label='index',
# compression='gzip')
id, message = save_workout_database(csvfilename, r,
workouttype=workouttype,
boattype=boattype,
title=title,
workoutsource=workoutsource,
notes=notes,
summary=summary,
oarlength=oarlength,
inboard=inboard,
makeprivate=makeprivate,
@@ -2474,7 +2465,7 @@ def new_workout_from_df(r, df,
rpe=rpe,
consistencychecks=False)
job = myqueue(queuehigh, handle_calctrimp, id, csvfilename,
_ = myqueue(queuehigh, handle_calctrimp, id, csvfilename,
r.ftp, r.sex, r.hrftp, r.max, r.rest)
return (id, message)
@@ -2520,7 +2511,7 @@ def delete_strokedata(id):
def update_strokedata(id, df):
delete_strokedata(id)
rowdata = dataprep(df, id=id, bands=True, barchart=True, otwpower=True)
_ = dataprep(df, id=id, bands=True, barchart=True, otwpower=True)
# Test that all data are of a numerical time
@@ -2555,7 +2546,7 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True,
else:
row = Workout.objects.get(id=id)
if checkefficiency == True and not data.empty:
if checkefficiency is True and not data.empty:
try:
if data['efficiency'].mean() == 0 and data['power'].mean() != 0: # pragma: no cover
data = add_efficiency(id=id)
@@ -2586,15 +2577,13 @@ def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True, comp
if len(ids) > 1:
for id, f in zip(ids, csvfilenames):
try:
#df = dd.read_parquet(f,columns=columns,engine='pyarrow')
df = pd.read_parquet(f, columns=columns)
data.append(df)
except (OSError, ArrowInvalid, IndexError): # pragma: no cover
rowdata, row = getrowdata(id=id)
if rowdata and len(rowdata.df):
datadf = dataprep(rowdata.df, id=id,
_ = dataprep(rowdata.df, id=id,
bands=True, otwpower=True, barchart=True)
# df = dd.read_parquet(f,columns=columns,engine='pyarrow')
df = pd.read_parquet(f, columns=columns)
data.append(df)
@@ -2649,7 +2638,6 @@ def getrowdata(id=0):
# get user
r = row.user
u = r.user
rr = rrower(hrmax=r.max, hrut2=r.ut2,
hrut1=r.ut1, hrat=r.at,
@@ -2677,7 +2665,7 @@ def prepmultipledata(ids, verbose=False): # pragma: no cover
if verbose:
print(id)
if rowdata and len(rowdata.df):
data = dataprep(rowdata.df, id=id, bands=True,
_ = dataprep(rowdata.df, id=id, bands=True,
barchart=True, otwpower=True)
return ids
@@ -2707,8 +2695,8 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
except OSError:
rowdata, row = getrowdata(id=ids[0])
if rowdata and len(rowdata.df):
datadf = dataprep(
rowdata.df, id=ids[0], bands=True, otwpower=True, barchart=True)
_ = dataprep(rowdata.df,
id=ids[0], bands=True, otwpower=True, barchart=True)
df = pd.read_parquet(filename, columns=columns)
else:
data = []
@@ -2721,7 +2709,7 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
except (OSError, IndexError, ArrowInvalid):
rowdata, row = getrowdata(id=id)
if rowdata and len(rowdata.df): # pragma: no cover
datadf = dataprep(rowdata.df, id=id,
_ = dataprep(rowdata.df, id=id,
bands=True, otwpower=True, barchart=True)
df = pd.read_parquet(f, columns=columns)
data.append(df)
@@ -2753,8 +2741,8 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
def initiate_cp(r):
success = update_rolling_cp(r, otwtypes, 'water')
success = update_rolling_cp(r, otetypes, 'erg')
_ = update_rolling_cp(r, otwtypes, 'water')
_ = update_rolling_cp(r, otetypes, 'erg')
# Read stroke data from the DB for a Workout ID. Returns a pandas dataframe
@@ -2784,9 +2772,6 @@ def read_df_sql(id):
def datafusion(id1, id2, columns, offset):
workout1 = Workout.objects.get(id=id1)
workout2 = Workout.objects.get(id=id2)
df1, w1 = getrowdata_db(id=id1)
df1 = df1.drop([ # 'cumdist',
'hr_ut2',
@@ -2821,7 +2806,7 @@ def datafusion(id1, id2, columns, offset):
keep1.pop(c)
for c in df1.columns:
if not c in keep1:
if c not in keep1:
df1 = df1.drop(c, 1, errors='ignore')
df = pd.concat([df1, df2], ignore_index=True)
@@ -2846,7 +2831,6 @@ def fix_newtons(id=0, limit=3000): # pragma: no cover
# rowdata,row = getrowdata_db(id=id,doclean=False,convertnewtons=False)
rowdata = getsmallrowdata_db(['peakforce'], ids=[id], doclean=False)
try:
#avgforce = rowdata['averageforce']
peakforce = rowdata['peakforce']
if peakforce.mean() > limit:
w = Workout.objects.get(id=id)
@@ -2860,7 +2844,7 @@ def fix_newtons(id=0, limit=3000): # pragma: no cover
def remove_invalid_columns(df): # pragma: no cover
for c in df.columns:
if not c in allowedcolumns:
if c not in allowedcolumns:
df.drop(labels=c, axis=1, inplace=True)
return df
@@ -2907,7 +2891,6 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
if rowdatadf.empty:
return 0
#rowdatadf.set_index([range(len(rowdatadf))], inplace=True)
t = rowdatadf.loc[:, 'TimeStamp (sec)']
t = pd.Series(t - rowdatadf.loc[:, 'TimeStamp (sec)'].iloc[0])
@@ -2981,7 +2964,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
if forceunit == 'lbs':
driveenergy = drivelength * averageforce * lbstoN
else:
drivenergy = drivelength * averageforce
driveenergy = drivelength * averageforce
if forceunit == 'lbs':
averageforce *= lbstoN
@@ -3034,7 +3017,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
data['hr_bottom'] = 0.0 * data['hr']
try:
tel = rowdatadf.loc[:, ' ElapsedTime (sec)']
_ = rowdatadf.loc[:, ' ElapsedTime (sec)']
except KeyError: # pragma: no cover
rowdatadf[' ElapsedTime (sec)'] = rowdatadf['TimeStamp (sec)']
@@ -3218,7 +3201,7 @@ def workout_trimp(w, reset=False):
w.maxhr = maxhr
w.save()
job = myqueue(
_ = myqueue(
queuehigh,
handle_calctrimp,
w.id,
@@ -3246,7 +3229,7 @@ def workout_rscore(w, reset=False):
r.hrftp = int(hrftp)
r.save()
job = myqueue(
_ = myqueue(
queuehigh,
handle_calctrimp,
w.id,
@@ -3274,7 +3257,7 @@ def workout_normv(w, pp=4.0):
r.hrftp = int(hrftp)
r.save()
job = myqueue(
_ = myqueue(
queuehigh,
handle_calctrimp,
w.id,
+17 -18
View File
@@ -2,6 +2,7 @@ from rowers.utils import totaltime_sec_to_string
from rowers.metrics import dtypes
import datetime
from scipy.signal import savgol_filter
import os
# This is Data prep used for testing purposes (no Django environment)
# Uses the debug SQLite database for stroke data
@@ -35,6 +36,12 @@ from rowers.utils import lbstoN
import pytz
from timezonefinder import TimezoneFinder
from rowingdata import (
RowProParser, TCXParser, MysteryParser, RowPerfectParser,
ErgDataParser, CoxMateParser, BoatCoachAdvancedParser, BoatCoachOTWParser,
BoatCoachParser, painsledDesktopParser, SpeedCoach2Parser, speedcoachParser,
ErgStickParser, FITParser, fitsummarydata
)
try:
user = DATABASES['default']['USER']
@@ -171,14 +178,12 @@ def create_c2_stroke_data_db(
spm = 20*np.zeros(nr_strokes)
try:
step = totalseconds/float(nr_strokes)
_ = totalseconds/float(nr_strokes)
except ZeroDivisionError:
return 0
elapsed = np.arange(nr_strokes)*totalseconds/(float(nr_strokes-1))
dstep = distance/float(nr_strokes)
d = np.arange(nr_strokes)*distance/(float(nr_strokes-1))
unixtime = starttimeunix + elapsed
@@ -215,12 +220,9 @@ def create_c2_stroke_data_db(
'cum_dist': d
})
timestr = strftime("%Y%m%d-%H%M%S")
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
res = df.to_csv(csvfilename, index_label='index',
compression='gzip')
_ = df.to_csv(csvfilename, index_label='index', compression='gzip')
data = dataprep(df, id=workoutid, bands=False, debug=debug)
@@ -300,8 +302,6 @@ def add_c2_stroke_data_db(strokedata, workoutid, starttimeunix, csvfilename,
df.sort_values(by='TimeStamp (sec)', ascending=True)
timestr = strftime("%Y%m%d-%H%M%S")
# Create CSV file name and save data to CSV file
res = df.to_csv(csvfilename, index_label='index',
@@ -447,8 +447,7 @@ def update_empower(id, inboard, oarlength, boattype, df, f1, debug=False): # pr
if debug: # pragma: no cover
print("not updated ", id)
rowdata = dataprep(df, id=id, bands=True, barchart=True, otwpower=True,
debug=debug)
_ = dataprep(df, id=id, bands=True, barchart=True, otwpower=True, debug=debug)
row = rrdata(df=df)
row.write_csv(f1, gzip=True)
@@ -511,7 +510,7 @@ def update_workout_field_sql(workoutid, fieldname, value, debug=False):
table, fieldname, value, workoutid)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
_ = conn.execute(query)
conn.close()
engine.dispose()
@@ -527,7 +526,7 @@ def update_c2id_sql(id, c2id): # pragma: no cover
table, c2id, id)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
_ = conn.execute(query)
conn.close()
engine.dispose()
@@ -588,7 +587,7 @@ def getcpdata_sql(rower_id, table='cpdata', debug=False): # pragma: no cover
rower_id=rower_id,
table=table,
))
connection = engine.raw_connection()
_ = engine.raw_connection()
df = pd.read_sql_query(query, engine)
return df
@@ -606,7 +605,7 @@ def deletecpdata_sql(rower_id, table='cpdata', debug=False): # pragma: no cover
))
with engine.connect() as conn, conn.begin():
try:
result = conn.execute(query)
_ = conn.execute(query)
except: # pragma: no cover
print("Database locked")
conn.close()
@@ -627,7 +626,7 @@ def delete_agegroup_db(age, sex, weightcategory, debug=False):
))
with engine.connect() as conn, conn.begin():
try:
result = conn.execute(query)
_ = conn.execute(query)
except: # pragma: no cover
print("Database locked")
conn.close()
@@ -818,7 +817,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
if forceunit == 'lbs':
driveenergy = drivelength*averageforce*lbstoN
else: # pragma: no cover
drivenergy = drivelength*averageforce
driveenergy = drivelength*averageforce
distance = rowdatadf.loc[:, 'cum_dist']
@@ -865,7 +864,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
data['hr_bottom'] = 0.0*data['hr']
try:
tel = rowdatadf.loc[:, ' ElapsedTime (sec)']
_ = rowdatadf.loc[:, ' ElapsedTime (sec)']
except KeyError: # pragma: no cover
rowdatadf[' ElapsedTime (sec)'] = rowdatadf['TimeStamp (sec)']
+11 -15
View File
@@ -6,7 +6,6 @@ from scipy import optimize
from rowers.mytypes import otwtypes, otetypes, rowtypes
#p0 = [500,350,10,8000]
p0 = [190, 200, 33, 16000]
# RPE to TSS
@@ -73,10 +72,12 @@ def updatecp(delta, cpvalues, r, workouttype='water'): # pragma: no cover
def cpfit(powerdf, fraclimit=0.0001, nmax=1000):
# Fit the data to thee parameter CP model
def fitfunc(pars, x): return abs(
def fitfunc(pars, x):
return abs(
pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
def errfunc(pars, x, y): return fitfunc(pars, x)-y
def errfunc(pars, x, y):
return fitfunc(pars, x)-y
p1 = p0
@@ -235,8 +236,6 @@ def getcp_new(dfgrouped, logarr): # pragma: no cover
restime = np.array(restime)
power = np.array(power)
#power[0] = power[1]
cpvalues = griddata(restime, power,
logarr, method='linear', fill_value=0)
@@ -264,7 +263,6 @@ def getcp(dfgrouped, logarr):
delta = []
cpvalue = []
avgpower = {}
#avgpower[0] = 0
for id, group in dfgrouped:
tt = group['time'].copy()
@@ -273,7 +271,7 @@ def getcp(dfgrouped, logarr):
# Remove data where PM is repeating final power value
# of an interval during the rest
rolling_std = ww.rolling(window=4).std()
deltas = tt.diff()
# deltas = tt.diff()
mask = rolling_std == 0
ww.loc[mask] = 0
@@ -281,7 +279,7 @@ def getcp(dfgrouped, logarr):
mask = ww > 2000
ww.loc[mask] = 0
tmax = tt.max()
# tmax = tt.max()
try:
avgpower[id] = int(ww.mean())
@@ -389,13 +387,13 @@ def getfastest(df, thevalue, mode='distance'):
dd = pd.Series(dd, dtype='float')
G = pd.concat([pd.Series([0]), dd])
T = pd.concat([pd.Series([0]), dd])
h = np.mgrid[0:len(tt)+1:1, 0:len(tt)+1:1]
distances = pd.DataFrame(h[1]-h[0])
# T = pd.concat([pd.Series([0]), dd])
# h = np.mgrid[0:len(tt)+1:1, 0:len(tt)+1:1]
# distances = pd.DataFrame(h[1]-h[0])
ones = 1+np.zeros(len(G))
Ghor = np.outer(ones, G)
Thor = np.outer(ones, T)
Tver = np.outer(T, ones)
# Thor = np.outer(ones, T)
# Tver = np.outer(T, ones)
Gver = np.outer(G, ones)
Gdif = Ghor-Gver
Gdif = np.tril(Gdif.T).T
@@ -428,8 +426,6 @@ def getfastest(df, thevalue, mode='distance'):
# if restime[i]<thevalue*60*1000:
# print(i,restime[i],distance[i],60*1000*thevalue)
d2 = 0
if mode == 'distance':
duration = griddata(distance, restime, [
thevalue], method='linear', rescale=True)
+1 -2
View File
@@ -1,5 +1,4 @@
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.http import HttpResponseRedirect
+2 -2
View File
@@ -20,7 +20,7 @@ import pytz
import iso8601
from matplotlib.backends.backend_agg import FigureCanvas
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
import matplotlib.pyplot as plt
from rowsandall_app.settings import SITE_URL
@@ -130,7 +130,7 @@ def send_confirm(user, name, link, options): # pragma: no cover
fullemail = user.email
subject = 'New Workout Added: '+name
res = send_template_email('Rowsandall <info@rowsandall.com>',
_ = send_template_email('Rowsandall <info@rowsandall.com>',
[fullemail],
subject, 'confirmemail.html',
d
+1 -1
View File
@@ -129,7 +129,7 @@ def create_invoice(rower, amount, braintreeid, dosend=True,
if res.status_code not in [200, 201]: # pragma: no cover
return 0
url = res.json()['url']
# url = res.json()['url']
id = res.json()['id']
urlpay = 'https://app.fakturoid.cz/api/v2/accounts/{slug}/invoices/{id}/fire.json?event=pay'.format(
+15 -26
View File
@@ -1,4 +1,3 @@
from rowers.models import VirtualRace, GeoCourse
from rowers.utils import rankingdistances, rankingdurations
from rowers.utils import (
workflowleftpanel, workflowmiddlepanel,
@@ -18,7 +17,7 @@ from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.admin.widgets import AdminDateWidget
from django.forms.widgets import SelectDateWidget, HiddenInput
#from django.forms.extras.widgets import SelectDateWidget
from django.utils import timezone, translation
from django.forms import ModelForm, Select
import rowers.dataprep as dataprep
@@ -573,11 +572,17 @@ class UploadOptionsForm(forms.Form):
choices3 = [(0, '---')]
noregistrations = []
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(), sessiontype='race'): # pragma: no cover
for ra in VirtualRace.objects.filter(
registration_closure__gt=timezone.now(),
sessiontype='race'
): # pragma: no cover
rs = VirtualRaceResult.objects.filter(race=ra, userid=r.id)
if rs.count() == 0:
noregistrations.append((-ra.id, ra.name))
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(), sessiontype='indoorrace'): # pragma: no cover
for ra in VirtualRace.objects.filter(
registration_closure__gt=timezone.now(),
sessiontype='indoorrace'
): # pragma: no cover
rs = IndoorVirtualRaceResult.objects.filter(race=ra, userid=r.id)
if rs.count() == 0:
noregistrations.append((-ra.id, ra.name))
@@ -1055,20 +1060,6 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
adaptiveclass = forms.ChoiceField(label='Adaptive Classification',
choices=adaptivecategories, initial='None', required=False)
# def __init__(self, *args, **kwargs):
# self.fields['sex'].initial = 'not specified'
# Time field supporting microseconds. Not used, I believe.
class MyTimeField(forms.TimeField):
def __init__(self, *args, **kwargs): # pragma: no cover
super(MyTimeField, self).__init__(*args, **kwargs)
supports_microseconds = True
# Form used to automatically define intervals by pace or power
class PowerIntervalUpdateForm(forms.Form):
selectorchoices = (
@@ -1847,14 +1838,13 @@ class StravaChartForm(forms.Form):
choices=yaxchoices2, label='Fourth Chart', required=True)
def __init__(self, request, *args, **kwargs):
extrametrics = kwargs.pop('extrametrics', [])
super(StravaChartForm, self).__init__(*args, **kwargs)
rower = Rower.objects.get(user=request.user)
axchoicespro = (
('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
)
# axchoicespro = (
# ('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
# )
axchoicesbasicx = []
axchoicesbasicy = []
@@ -1889,14 +1879,13 @@ class FlexAxesForm(forms.Form):
choices=yaxchoices2, label='Right Axis', required=True)
def __init__(self, request, *args, **kwargs):
extrametrics = kwargs.pop('extrametrics', [])
super(FlexAxesForm, self).__init__(*args, **kwargs)
rower = Rower.objects.get(user=request.user)
axchoicespro = (
('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
)
# axchoicespro = (
# ('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
# )
axchoicesbasicx = []
axchoicesbasicy = []
+21 -37
View File
@@ -11,7 +11,7 @@ import requests
from requests import Session, Request
from requests_oauthlib import OAuth1, OAuth1Session
from requests_oauthlib.oauth1_session import TokenRequestDenied
from requests import Request, Session
import rowers.mytypes as mytypes
from rowers.mytypes import otwtypes
from rowers.rower_rules import is_workout_user, ispromember
@@ -35,13 +35,6 @@ from rowsandall_app.settings import (
from pytz import timezone as tz, utc
# You must initialize logging, otherwise you'll not see debug output.
# logging.basicConfig()
# logging.getLogger().setLevel(logging.DEBUG)
#requests_log = logging.getLogger("requests.packages.urllib3")
# requests_log.setLevel(logging.DEBUG)
#requests_log.propagate = True
from rowers.tasks import handle_get_garmin_file
import django_rq
@@ -109,9 +102,6 @@ repeattypes = {
def garmin_authorize(): # pragma: no cover
redirect_uri = oauth_data['redirect_uri']
client_secret = oauth_data['client_secret']
client_id = oauth_data['client_id']
base_uri = oauth_data['base_url']
garmin = OAuth1Session(oauth_data['client_id'],
@@ -133,7 +123,7 @@ def garmin_processcallback(redirect_response, resource_owner_key, resource_owner
oauth_response = garmin.parse_authorization_response(redirect_response)
verifier = oauth_response.get('oauth_verifier')
token = oauth_response.get('oauth_token')
# token = oauth_response.get('oauth_token')
access_token_url = 'https://connectapi.garmin.com/oauth-service/oauth/access_token'
# Using OAuth1Session
@@ -155,7 +145,7 @@ def garmin_processcallback(redirect_response, resource_owner_key, resource_owner
def garmin_open(user): # pragma: no cover
r = Rower.objects.get(user=user)
token = Rower.garmintoken
token = r.garmintoken
if (token == '') or (token is None):
raise NoTokenError("User has no garmin token")
@@ -191,7 +181,8 @@ def get_garmin_workout_list(user): # pragma: no cover
resource_owner_secret=r.garminrefreshtoken,
)
url = 'https://healthapi.garmin.com/wellness-api/rest/activities?uploadStartTimeInSeconds=1593113760&uploadEndTimeInSeconds=1593279360'
url = 'https://healthapi.garmin.com/wellness-api/rest/' \
'activities?uploadStartTimeInSeconds=1593113760&uploadEndTimeInSeconds=1593279360'
result = garmin.get(url)
@@ -218,7 +209,7 @@ def step_to_garmin(step, order=0):
intensity = 'INTERVAL'
except KeyError:
intensity = None
#durationvaluetype = ''
# durationvaluetype = ''
if durationtype == 'Time':
durationtype = 'TIME'
durationvalue = int(durationvalue/1000.)
@@ -272,11 +263,11 @@ def step_to_garmin(step, order=0):
if targetType is not None and targetType.lower() == "power":
targetType = 'POWER'
if targetValue is not None and targetValue <= 1000:
targetValueType = 'PERCENT' # pragma: no cover
else:
targetValueType = None
targetValue -= 1000
# if targetValue is not None and targetValue <= 1000:
# targetValueType = 'PERCENT' # pragma: no cover
# else:
# # targetValueType = None
# targetValue -= 1000
try:
targetValueLow = step['dict']['targetValueLow']
@@ -285,8 +276,8 @@ def step_to_garmin(step, order=0):
targetValue = None
elif targetValueLow == 0: # pragma: no cover
targetValueLow = None
elif targetValueLow <= 1000 and targetType == 'POWER': # pragma: no cover
targetValueType = 'PERCENT'
# elif targetValueLow <= 1000 and targetType == 'POWER': # pragma: no cover
# targetValueType = 'PERCENT'
elif targetValueLow > 1000 and targetType == 'POWER': # pragma: no cover
targetValueLow -= 1000
except KeyError:
@@ -296,8 +287,8 @@ def step_to_garmin(step, order=0):
if targetValue is not None and targetValue > 0 and targetValueHigh == 0: # pragma: no cover
targetValueHigh = targetValue
targetValue = 0
elif targetValueHigh <= 1000 and targetType == 'POWER': # pragma: no cover
targetValueType = 'PERCENT'
# elif targetValueHigh <= 1000 and targetType == 'POWER': # pragma: no cover
# targetValueType = 'PERCENT'
elif targetValueHigh > 1000 and targetType == 'POWER': # pragma: no cover
targetValueHigh -= 1000
elif targetValueHigh == 0: # pragma: no cover
@@ -477,12 +468,6 @@ def garmin_getworkout(garminid, r, activity):
distance = activity['distanceInMeters']
except KeyError:
distance = 0
try:
averagehr = activity['averageHeartRateInBeatsPerMinute']
maxhr = activity['maxHeartRateInBeatsPerMinute']
except KeyError: # pragma: no cover
averagehr = 0
maxhr = 0
try:
w = Workout.objects.get(uploadedtogarmin=garminid)
except Workout.DoesNotExist:
@@ -494,8 +479,8 @@ def garmin_getworkout(garminid, r, activity):
utc_offset = datetime.timedelta(seconds=offset)
now = datetime.datetime.now(pytz.utc)
zones = [tz.zone for tz in map(pytz.timezone, pytz.all_timezones_set)
if now.astimezone(tz).utcoffset() == utc_offset]
zones = [ttz.zone for ttz in map(
pytz.timezone, pytz.all_timezones_set) if now.astimezone(ttz).utcoffset() == utc_offset]
if r.defaulttimezone in zones: # pragma: no cover
thetimezone = r.defaulttimezone
elif len(zones):
@@ -509,8 +494,7 @@ def garmin_getworkout(garminid, r, activity):
day=startdatetime.day,
hour=startdatetime.hour,
minute=startdatetime.minute,
second=startdatetime.second,
).astimezone(pytz.timezone(thetimezone))
second=startdatetime.second,).astimezone(pytz.timezone(thetimezone))
w.startdatetime = startdatetime
w.starttime = w.startdatetime.time()
@@ -557,12 +541,12 @@ def garmin_workouts_from_details(data):
df[' AverageBoatSpeed (m/s)'] = 0
df[' Stroke500mPace (sec/500m)'] = pace
try:
spm = df[' Cadence (stokes/min)']
_ = df[' Cadence (stokes/min)']
except KeyError:
df[' Cadence (stokes/min)'] = 0
df['cum_dist'] = df[' Horizontal (meters)']
try:
power = df[' Power (watts)']
_ = df[' Power (watts)']
except KeyError:
df[' Power (watts)'] = 0
df[' AverageDriveForce (lbs)'] = 0
@@ -591,7 +575,7 @@ def garmin_workouts_from_summaries(activities):
try:
r = Rower.objects.get(garmintoken=garmintoken)
id = activity['summaryId']
w = garmin_getworkout(id, r, activity)
_ = garmin_getworkout(id, r, activity)
except Rower.DoesNotExist: # pragma: no cover
pass
+7 -17
View File
@@ -70,10 +70,6 @@ def splitstdata(lijst):
def imports_open(user, oauth_data):
r = Rower.objects.get(user=user)
token = getattr(r, oauth_data['tokenname'])
try:
refreshtoken = getattr(r, oauth_data['refreshtokenname'])
except (TypeError, AttributeError, KeyError): # pragma: no cover
refreshtoken = None
try:
tokenexpirydate = getattr(r, oauth_data['expirydatename'])
@@ -81,7 +77,6 @@ def imports_open(user, oauth_data):
tokenexpirydate = None
if (token == '') or (token is None):
s = "Token doesn't exist. Need to authorize"
raise NoTokenError("User has no token")
else:
tokenname = oauth_data['tokenname']
@@ -109,10 +104,10 @@ def imports_open(user, oauth_data):
# Refresh token using refresh token
def imports_do_refresh_token(refreshtoken, oauth_data, access_token=''):
client_auth = requests.auth.HTTPBasicAuth(
oauth_data['client_id'],
oauth_data['client_secret']
)
# client_auth = requests.auth.HTTPBasicAuth(
# oauth_data['client_id'],
# oauth_data['client_secret']
# )
post_data = {"grant_type": "refresh_token",
"client_secret": oauth_data['client_secret'],
@@ -127,8 +122,6 @@ def imports_do_refresh_token(refreshtoken, oauth_data, access_token=''):
if 'grant_type' in oauth_data:
if oauth_data['grant_type']:
post_data['grant_type'] = oauth_data['grant_type']
else: # pragma: no cover
grant_type = post_data.pop('grant_type', None)
if oauth_data['bearer_auth']:
headers['authorization'] = 'Bearer %s' % access_token
@@ -192,9 +185,9 @@ def imports_get_token(
client_id = oauth_data['client_id']
base_uri = oauth_data['base_url']
client_auth = requests.auth.HTTPBasicAuth(
client_id, client_secret
)
# client_auth = requests.auth.HTTPBasicAuth(
# client_id, client_secret
# )
post_data = {"grant_type": "authorization_code",
"code": code,
@@ -216,8 +209,6 @@ def imports_get_token(
post_data['grant_type'] = oauth_data['grant_type']
if 'strava' in oauth_data['autorization_uri']:
post_data['grant_type'] = "authorization_code"
else: # pragma: no cover
grant_type = post_data.pop('grant_type', None)
if 'json' in oauth_data['content_type']:
response = requests.post(
@@ -268,7 +259,6 @@ def imports_make_authorization_url(oauth_data): # pragma: no cover
"scope": oauth_data['scope'],
"state": state}
import urllib
url = oauth_data['authorizaton_uri']+urllib.parse.urlencode(params)
return HttpResponseRedirect(url)
File diff suppressed because it is too large Load Diff
+2 -5
View File
@@ -14,7 +14,6 @@ redis_connection = StrictRedis()
def getvalue(data): # pragma: no cover
perc = 0
total = 1
done = 0
id = 0
@@ -43,8 +42,7 @@ def longtask(aantal, jobid=None, debug=False,
if counter > 10:
counter = 0
if debug:
progress = 100.*i/aantal
if jobid != None:
if jobid is not None:
redis_connection.publish(channel, json.dumps(
{
'done': i,
@@ -60,7 +58,6 @@ def longtask(aantal, jobid=None, debug=False,
def longtask2(aantal, jobid=None, debug=False, secret=''): # pragma: no cover
counter = 0
channel = 'tasks'
for i in range(aantal):
time.sleep(1)
counter += 1
@@ -69,7 +66,7 @@ def longtask2(aantal, jobid=None, debug=False, secret=''): # pragma: no cover
progress = int(100.*i/aantal)
if debug:
print(progress)
if jobid != None:
if jobid is not None:
if debug:
url = SITE_URL_DEV
else:
+6 -7
View File
@@ -7,20 +7,22 @@ import arrow
from django.utils import timezone
from django.core.management.base import BaseCommand
from rowers.models import Rower,Workout
from rowers.models import Rower, Workout
import re
from django.db.models import Q
from rowers.dataprep import join_workouts
def name_short(name):
expr = '(.*)\s.*\(\d+\)'
match = re.findall(expr,name)
match = re.findall(expr, name)
if match:
return match[0]
return name
def get_duplicates(a):
seen = {}
dupes = []
@@ -39,27 +41,24 @@ def get_duplicates(a):
class Command(BaseCommand):
def handle(self, *args, **options):
rs = (r for r in Rower.objects.all() if r.ispaid and r.autojoin)
now = timezone.now()
for r in rs:
workouts = Workout.objects.filter(user=r,
duplicate=False,
startdatetime__gte=timezone.now()-datetime.timedelta(days=2))
duplicates = get_duplicates(name_short(w.name) for w in workouts)
for name, count in duplicates.items():
if count > 1:
workouts2 = workouts.filter(
Q(name__contains=name)
)
Q(name__contains=name))
duplicates2 = get_duplicates(w.date for w in workouts)
for dd, count in duplicates2.items():
if count > 1:
workouts3 = workouts2.filter(date=dd)
ids = [w.id for w in workouts3]
id, message = join_workouts(r,ids,title=name,
id, message = join_workouts(r, ids, title=name,
parent=workouts3[0],
killparents=True)
+4 -8
View File
@@ -1,5 +1,3 @@
#!/srv/venv/bin/python
import sys
import os
@@ -10,11 +8,12 @@ import json
from simplejson.errors import JSONDecodeError
PY3K = sys.version_info >= (3,0)
from django.core.management.base import BaseCommand
from rowers.models import BlogPost
PY3K = sys.version_info >= (3, 0)
class Command(BaseCommand):
def handle(self, *args, **options):
blogs_json = []
@@ -35,16 +34,13 @@ class Command(BaseCommand):
pass
if blogs_json:
result = BlogPost.objects.all().delete()
_ = BlogPost.objects.all().delete()
for postdata in blogs_json[0:3]:
title = postdata['title']['rendered']
link = postdata['link']
datetime = postdata['date']
datetime = arrow.get(datetime).datetime
date = datetime.date()
blogpost = BlogPost(
link=link,
date=date,
+15 -16
View File
@@ -1,15 +1,9 @@
#!/srv/venv/bin/python
import sys
import os
# If you find a solution that does not need the two paths, please comment!
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError,EmailMessage
from django.core.mail import send_mail, BadHeaderError, EmailMessage
import datetime
from rowers.models import *
@@ -17,6 +11,12 @@ from rowsandall_app.settings import BASE_DIR
import pandas as pd
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
def getemails():
rs = Rower.objects.all()
firstnames = [r.user.first_name for r in rs]
@@ -24,20 +24,18 @@ def getemails():
emails = [r.user.email for r in rs]
is_actives = [r.user.is_active for r in rs]
df = pd.DataFrame({
'first_name':firstnames,
'last_name':lastnames,
'email':emails,
'is_active':is_actives
})
'first_name': firstnames,
'last_name': lastnames,
'email': emails,
'is_active': is_actives})
return df
class Command(BaseCommand):
def handle(self, *args, **options):
email_list = getemails()
email_list.to_csv('email_list.csv',encoding='utf-8')
email_list.to_csv('email_list.csv', encoding='utf-8')
fullemail = 'roosendaalsander@gmail.com'
subject = "Rowsandall users list"
@@ -45,7 +43,8 @@ class Command(BaseCommand):
message += "Best Regards, the Rowsandall Team"
message += "Users list attached \n\n"
email = EmailMessage(subject, message,
email = EmailMessage(
subject, message,
'Rowsandall <info@rowsandall.com>',
[fullemail])
@@ -53,4 +52,4 @@ class Command(BaseCommand):
os.remove('email_list.csv')
res = email.send()
_ = email.send()
+12 -13
View File
@@ -1,19 +1,19 @@
#!/srv/venv/bin/python
import sys
import os
# If you find a solution that does not need the two paths, please comment!
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError, EmailMessage
import datetime
from rowers.models import Rower
from rowsandall_app.settings import BASE_DIR
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError,EmailMessage
import datetime
from rowers.models import Rower
from rowsandall_app.settings import BASE_DIR
def getexpired():
rs = Rower.objects.all()
@@ -43,10 +43,9 @@ class Command(BaseCommand):
message += r.user.first_name+" "+r.user.last_name+" "+r.user.username
message += "\n"
email = EmailMessage(subject, message,
email = EmailMessage(
subject, message,
'Rowsandall <info@rowsandall.com>',
[fullemail])
res = email.send()
_ = email.send()
+10 -10
View File
@@ -3,8 +3,6 @@
import sys
import os
PY3K = sys.version_info >= (3,0)
from django.core.management.base import BaseCommand
from rowers.models import Alert, Condition, User
from rowers.tasks import handle_send_email_alert
@@ -13,15 +11,17 @@ from rowers import alerts
from rowers.utils import myqueue
import datetime
import django_rq
PY3K = sys.version_info >= (3, 0)
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
import datetime
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
@@ -29,8 +29,7 @@ class Command(BaseCommand):
action='store_true',
dest='testing',
default=False,
help="Run in testing mode, don't send emails",
)
help="Run in testing mode, don't send emails", )
def handle(self, *args, **options):
if 'testing' in options:
@@ -38,7 +37,8 @@ class Command(BaseCommand):
else:
testing = False
todaysalerts = Alert.objects.filter(next_run__lt = datetime.date.today(),emailalert=True)
todaysalerts = Alert.objects.filter(
next_run__lt=datetime.date.today(), emailalert=True)
for alert in todaysalerts:
stats = alerts.alert_get_stats(alert)
@@ -47,13 +47,13 @@ class Command(BaseCommand):
othertexts = [alert.description()]
# send email
job = myqueue(queue,handle_send_email_alert,
_ = myqueue(queue, handle_send_email_alert,
alert.manager.email,
alert.manager.first_name,
alert.manager.last_name,
alert.rower.user.first_name,
alert.name,
stats,debug=True,
stats, debug=True,
othertexts=othertexts)
# advance next_run
@@ -62,7 +62,7 @@ class Command(BaseCommand):
alert.save()
if testing:
print('{nr} alerts found'.format(nr = len(todaysalerts)))
print('{nr} alerts found'.format(nr=len(todaysalerts)))
self.stdout.write(self.style.SUCCESS(
'Successfully processed alerts'))
+17 -32
View File
@@ -1,9 +1,6 @@
#!/srv/venv/bin/python
""" Process emails """
import sys
import os
PY3K = sys.version_info >= (3, 0)
import zipfile
from zipfile import BadZipFile
@@ -18,12 +15,12 @@ import json
import io
from django.core.management.base import BaseCommand
#from django_mailbox.models import Message, MessageAttachment,Mailbox
from django.urls import reverse
from django.conf import settings
from django.utils import timezone
from rowers.models import Workout, Rower
from rowers.models import User, Workout, Rower
from rowingdata import rower as rrower
from rowingdata import rowingdata as rrdata
@@ -37,7 +34,6 @@ import rowers.stravastuff as stravastuff
import rowers.nkstuff as nkstuff
from rowers.opaque import encoder
from rowers.models import User,Workout
from rowers.rower_rules import user_is_not_basic
from rowers.utils import dologging
@@ -47,8 +43,12 @@ sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
PY3K = sys.version_info >= (3, 0)
if not getattr(__builtins__, "WindowsError", None):
class WindowsError(OSError): pass
class WindowsError(OSError):
pass
def rdata(file_obj, rower=rrower()): # pragma: no cover
""" Read rowing data file and return 0 if file doesn't exist"""
@@ -60,7 +60,6 @@ def rdata(file_obj, rower=rrower()): # pragma: no cover
return result
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
@@ -68,31 +67,24 @@ class Command(BaseCommand):
action='store_true',
dest='testing',
default=False,
help="Run in testing mode, don't send emails",
)
help="Run in testing mode, don't send emails", )
parser.add_argument(
'--mailbox',
action='store_true',
dest='mailbox',
default='workouts',
help="Changing mailbox name",
)
help="Changing mailbox name", )
"""Run the Email processing command """
def handle(self, *args, **options):
if 'testing' in options:
testing = options['testing']
else: # pragma: no cover
testing = False
# Polar
try:
polar_available = polarstuff.get_polar_notifications()
res = polarstuff.get_all_new_workouts(polar_available)
_ = polarstuff.get_all_new_workouts(polar_available)
except: # pragma: no cover
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
dologging('processemail.log',''.join('!! ' + line for line in lines))
dologging('processemail.log', ''.join('!! ' + line for line in lines))
# Concept2
try:
@@ -103,36 +95,29 @@ class Command(BaseCommand):
except: # pragma: no cover
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
dologging('processemail.log',''.join('!! ' + line for line in lines))
dologging('processemail.log', ''.join('!! ' + line for line in lines))
try:
rowers = Rower.objects.filter(rp3_auto_import=True)
for r in rowers: # pragma: no cover
if user_is_not_basic(r.user):
res = rp3stuff.get_rp3_workouts(r)
_ = rp3stuff.get_rp3_workouts(r)
except: # pragma: no cover
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
dologging('processemail.log',''.join('!! ' + line for line in lines))
dologging('processemail.log', ''.join('!! ' + line for line in lines))
try:
rowers = Rower.objects.filter(nk_auto_import=True)
for r in rowers: # pragma: no cover
if user_is_not_basic(r.user):
s = 'Starting NK Auto Import for user {id}'.format(id=r.user.id)
dologging('nklog.log',s)
res = nkstuff.get_nk_workouts(r)
dologging('nklog.log', s)
_ = nkstuff.get_nk_workouts(r)
except: # pragma: no cover
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
dologging('processemail.log',''.join('!! ' + line for line in lines))
# Strava
#rowers = Rower.objects.filter(strava_auto_import=True)
#for r in rowers:
# if user_is_not_basic(r.user): # pragma: no cover
# stravastuff.get_strava_workouts(r)
dologging('processemail.log', ''.join('!! ' + line for line in lines))
self.stdout.write(self.style.SUCCESS(
'Successfully processed email attachments'))
+12 -9
View File
@@ -1,24 +1,27 @@
#!/srv/venv/bin/python
import sys
import os
# If you find a solution that does not need the two paths, please comment!
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
#from rowers.mailprocessing import processattachments
import time
from django.conf import settings
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage,AdvancedWorkoutForm
from rowers.models import (
Workout, User, Rower, WorkoutForm,
RowerForm, GraphImage, AdvancedWorkoutForm)
from django.core.files.base import ContentFile
from rowsandall_app.settings import BASE_DIR
from rowers.dataprep import *
# If you find a solution that does not need the two paths, please comment!
sys.path.append('$path_to_root_of_project$')
sys.path.append('$path_to_root_of_project$/$project_name$')
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
class Command(BaseCommand):
def handle(self, *args, **options):
repair_data(verbose=True)
+1 -1
View File
@@ -99,7 +99,7 @@ class RowerPlanMiddleWare(object):
# remove from Free Coach groups
# send email
job = myqueue(queue,
_ = myqueue(queue,
handle_sendemail_expired,
r.user.email,
r.user.first_name,
+25 -46
View File
@@ -3,7 +3,7 @@ from rowers.metrics import rowingmetrics
from django.db.models.signals import m2m_changed
from rowers.courseutils import coordinate_in_path
from rowers.utils import (
workflowleftpanel, workflowmiddlepanel,
# workflowleftpanel, workflowmiddlepanel,
defaultleft, defaultmiddle, landingpages, landingpages2,
steps_read_fit, steps_write_fit, ps_dict_order
)
@@ -15,18 +15,15 @@ import uuid
from django.db import models, IntegrityError
from django.contrib.auth.models import User
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django import forms
from django.forms import ModelForm
from django.dispatch import receiver
from django.forms.widgets import SplitDateTimeWidget, SelectDateWidget
#from django.forms.extras.widgets import SelectDateWidget
from django.forms.formsets import BaseFormSet
#from datetimewidget.widgets import DateTimeWidget
from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime
from django.core.validators import validate_email
import os
import json
import twitter
@@ -55,8 +52,6 @@ import datetime
from taggit.managers import TaggableManager
#from rules.contrib.models import RulesModel
from rowers.rower_rules import *
from rowers.opaque import encoder
@@ -322,7 +317,6 @@ def update_records(url=c2url, verbose=True):
dfs = pd.read_html(url, attrs={'class': 'views-table'})
df = dfs[0]
df.columns = df.columns.str.strip()
success = 1
except: # pragma: no cover
df = pd.DataFrame()
@@ -574,29 +568,16 @@ def course_spline(coordinates):
latitudes = coordinates['latitude'].values
longitudes = coordinates['longitude'].values
# spline parameters
s = 1.0
k = min([5, len(latitudes)-1])
nest = -1
t = np.linspace(0, 1, len(latitudes))
tnew = np.linspace(0, 1, 100)
try:
#latnew = CubicSpline(t,latitudes,bc_type='not-a-knot')(tnew)
#lonnew = CubicSpline(t,longitudes,bc_type='not-a-knot')(tnew)
latnew = interp1d(t, latitudes)(tnew)
lonnew = interp1d(t, longitudes)(tnew)
except ValueError: # pragma: no cover
latnew = latitudes
lonnew = longitudes
# latnew = CubicSpline(t,latitudes,bc_type='natural')(tnew)
# lonnew = CubicSpline(t,longitudes,bc_type='natural')(tnew)
# tckp,u = splprep([t,latitudes,longitudes],s=s,k=k,nest=nest)
# tnew,latnew,lonnew = splev(np.linspace(0,1,100),tckp)
newcoordinates = pd.DataFrame({
'latitude': latnew,
'longitude': lonnew,
@@ -673,7 +654,8 @@ def get_delta(vector, polygon):
p = polygon_to_path(polygon)
def f(x): return coordinate_in_path(x['lat'], x['lon'], p)
def f(x):
return coordinate_in_path(x['lat'], x['lon'], p)
df = pd.DataFrame({'x': x,
'lat': lat,
@@ -795,7 +777,7 @@ class PaidPlan(models.Model):
shortname=self.shortname,
price=self.price,
paymenttype=self.paymenttype,
paymentprocessor=self.paymentprocessor,
# paymentprocessor=self.paymentprocessor,
)
@@ -1346,8 +1328,9 @@ class BaseFavoriteFormSet(BaseFormSet):
xparam = form.cleaned_data['xparam']
yparam1 = form.cleaned_data['yparam1']
yparam2 = form.cleaned_data['yparam2']
plottype = form.cleaned_data['plottype']
reststrokes = form.cleaned_data['reststrokes']
# plottype = form.cleaned_data['plottype']
# reststrokes = form.cleaned_data['reststrokes']
pass
if not xparam:
raise forms.ValidationError(
@@ -1402,10 +1385,11 @@ class BaseConditionFormSet(BaseFormSet):
for form in self.forms:
if form.cleaned_data:
metric = form.cleaned_data['metric']
condition = form.cleaned_data['condition']
value1 = form.cleaned_data['value1']
value2 = form.cleaned_data['value2']
# metric = form.cleaned_data['metric']
# condition = form.cleaned_data['condition']
# value1 = form.cleaned_data['value1']
# value2 = form.cleaned_data['value2']
pass
rowchoices = []
@@ -1475,7 +1459,7 @@ class Alert(models.Model):
return description
def shortdescription(self): # pragma: no cover
metricdict = {key: value for (key, value) in parchoicesy1}
# metricdict = {key: value for (key, value) in parchoicesy1}
if self.measured.condition == 'between':
description = '{value1} < {metric} < {value2}'.format(
@@ -1526,7 +1510,7 @@ class GeoCourse(models.Model):
def __str__(self):
name = self.name
country = self.country
# country = self.country
d = self.distance
if d == 0: # pragma: no cover
self.distance = course_length(self)
@@ -1535,7 +1519,7 @@ class GeoCourse(models.Model):
return u'{name} - {d}m'.format(
name=name,
country=country,
# country=country,
d=d,
)
@@ -2530,7 +2514,6 @@ class PlannedSession(models.Model):
can_be_shared = models.BooleanField(default=True)
fitfile = models.FileField(upload_to=get_file_path, blank=True, null=True)
#steps_json = models.TextField(max_length=10000,default=None,blank=True,null=True)
steps = PlannedSessionStepField(default={}, null=True, max_length=1000)
interval_string = models.TextField(max_length=1000, default=None, blank=True, null=True,
verbose_name='Interval String (optional)')
@@ -2565,7 +2548,7 @@ class PlannedSession(models.Model):
if self.sessionvalue <= 0: # pragma: no cover
self.sessionvalue = 1
manager = self.manager
# manager = self.manager
if self.sessiontype not in ['race', 'indoorrace']:
if not can_add_session(self.manager):
raise ValidationError(
@@ -2612,7 +2595,7 @@ class PlannedSession(models.Model):
self.sessionmode = 'distance'
self.sessionunit = 'm'
self.criterium = 'none'
if self.course == None: # pragma: no cover
if self.course is None: # pragma: no cover
self.course = GeoCourse.objects.all()[0]
self.sessionvalue = self.course.distance
elif self.sessiontype != 'coursetest' and self.sessiontype != 'race':
@@ -2626,7 +2609,6 @@ class PlannedSession(models.Model):
if self.preferreddate < self.startdate: # pragma: no cover
self.preferreddate = self.startdate
#super(PlannedSession,self).save(*args, **kwargs)
if self.steps:
steps = self.steps
elif self.fitfile: # pragma: no cover
@@ -2640,7 +2622,7 @@ class PlannedSession(models.Model):
steps = self.steps
steps['filename'] = os.path.join(settings.MEDIA_ROOT, filename)
fitfile = steps_write_fit(steps)
_ = steps_write_fit(steps)
self.fitfile.name = filename
self.steps = steps
@@ -2752,8 +2734,8 @@ class VirtualRace(PlannedSession):
def __str__(self):
name = self.name
startdate = self.startdate
enddate = self.enddate
# startdate = self.startdate
# enddate = self.enddate
stri = u'Virtual challenge {n}'.format(
n=name,
@@ -4031,9 +4013,6 @@ class WorkoutForm(ModelForm):
class AdvancedWorkoutForm(ModelForm):
#quick_calc = forms.BooleanField(initial=True,required=False)
#go_service = forms.BooleanField(initial=False,required=False,label='Experimental')
class Meta:
model = Workout
fields = ['boattype', 'weightvalue', 'boatbrand']
@@ -4332,8 +4311,8 @@ class RowerPowerZonesForm(ModelForm):
try:
ut3name = cleaned_data['ut3name']
except:
ut2name = 'UT3'
cleaned_data['ut3name'] = 'UT3'
ut3name = 'UT3'
cleaned_data['ut3name'] = ut3name
try:
ut2name = cleaned_data['ut2name']
except:
@@ -4717,10 +4696,10 @@ class SiteAnnouncement(models.Model):
self.modified = timezone.now()
if self.dotweet: # pragma: no cover
try:
status = tweetapi.PostUpdate(self.announcement)
_ = tweetapi.PostUpdate(self.announcement)
except:
try:
status = tweetapi.PostUpdate(self.announcement[:270])
_ = tweetapi.PostUpdate(self.announcement[:270])
except:
pass
return super(SiteAnnouncement, self).save(*args, **kwargs)
-1
View File
@@ -358,7 +358,6 @@ rowtypes = (
checktypes = [i[0] for i in workouttypes_ordered.items()]
#colors = Category10[9]
colors = list(set(Category10[9]))+list(set(Category20[19]+Category20c[19]))
color_map = {checktypes[i]: colors[i] for i in range(len(checktypes))}
+10 -9
View File
@@ -1,4 +1,5 @@
import pandas as pd
import numpy as np
import datetime
from datetime import timedelta
from uuid import uuid4
@@ -52,14 +53,14 @@ def add_workout_from_data(userid, nkid, data, strokedata, source='nk', splitdata
elapsedTime = data["elapsedTime"]
totalDistanceGps = data["totalDistanceGps"]
totalDistanceImp = data["totalDistanceImp"]
intervals = data["intervals"] # add intervals
# intervals = data["intervals"] # add intervals
oarlockSessions = data["oarlockSessions"]
deviceId = data["deviceId"] # you could get the firmware version
# deviceId = data["deviceId"] # you could get the firmware version
totalDistance = totalDistanceGps
useImpeller = False
if speedInput: # pragma: no cover
totdalDistance = totalDistanceImp
totalDistance = totalDistanceImp
useImpeller = True
summary = get_nk_allstats(data, strokedata)
@@ -69,19 +70,19 @@ def add_workout_from_data(userid, nkid, data, strokedata, source='nk', splitdata
# oarlock inboard, length, boat name
if oarlockSessions:
oarlocksession = oarlockSessions[0] # should take seatIndex
boatName = oarlocksession["boatName"]
# boatName = oarlocksession["boatName"]
oarLength = oarlocksession["oarLength"] # cm
oarInboardLength = oarlocksession["oarInboardLength"] # cm
seatNumber = oarlocksession["seatNumber"]
# seatNumber = oarlocksession["seatNumber"]
try:
oarlockfirmware = oarlocksession["firmwareVersion"]
except KeyError:
oarlockfirmware = ''
else: # pragma: no cover
boatName = ''
# boatName = ''
oarLength = 289
oarInboardLength = 88
seatNumber = 1
# seatNumber = 1
oarlockfirmware = ''
workouttype = "water"
@@ -139,7 +140,7 @@ def get_nk_intervalstats(workoutdata, strokedata):
i = 0
for interval in intervals:
id = interval['id']
# id = interval['id']
sdist = interval['totalDistanceGps']
avgpace = interval['avgPaceGps']/1000.
avgpacetd = timedelta(seconds=avgpace)
@@ -325,6 +326,6 @@ def readlogs_summaries(logfile, dosave=0): # pragma: no cover
json.dump(strokeData, f2)
with open(filename2, 'w') as f2:
json.dump(summaryData, f2)
except Exception as e:
except Exception:
print(traceback.format_exc())
print("error")
+5 -22
View File
@@ -31,13 +31,6 @@ queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
try:
from json.decoder import JSONDecodeError
except ImportError: # pragma: no cover
JSONDecodeError = ValueError
oauth_data = {
'client_id': NK_CLIENT_ID,
'client_secret': NK_CLIENT_SECRET,
@@ -56,12 +49,6 @@ oauth_data = {
def get_token(code): # pragma: no cover
url = oauth_data['base_url']
headers = {'Accept': 'application/json',
# 'Authorization': auth_header,
'Content-Type': 'application/x-www-form-urlencoded',
# 'user-agent': 'sanderroosendaal'
}
post_data = {"client_id": oauth_data['client_id'],
"grant_type": "authorization_code",
"redirect_uri": oauth_data['redirect_uri'],
@@ -88,13 +75,12 @@ def nk_open(user):
r = Rower.objects.get(user=user)
if (r.nktoken == '') or (r.nktoken is None): # pragma: no cover
s = "Token doesn't exist. Need to authorize"
raise NoTokenError("User has no token")
else:
if (timezone.now() > r.nktokenexpirydate):
thetoken = rower_nk_token_refresh(user)
if thetoken == None: # pragma: no cover
if thetoken is None: # pragma: no cover
raise NoTokenError("User has no token")
return thetoken
else:
@@ -105,7 +91,7 @@ def nk_open(user):
def get_nk_workouts(rower, do_async=True, before=0, after=0):
try:
thetoken = nk_open(rower.user)
_ = nk_open(rower.user)
except NoTokenError: # pragma: no cover
return 0
@@ -136,7 +122,7 @@ def get_nk_workouts(rower, do_async=True, before=0, after=0):
pass
knownnkids = uniqify(knownnkids+tombstones+parkedids)
newids = [nkid for nkid in nkids if not nkid in knownnkids]
newids = [nkid for nkid in nkids if nkid not in knownnkids]
s = 'New NK IDs {newids}'.format(newids=newids)
dologging('nklog.log', s)
@@ -211,7 +197,8 @@ def get_nk_workout_list(user, fake=False, after=0, before=0):
if (r.nktoken == '') or (r.nktoken is None): # pragma: no cover
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401, s)
elif (r.nktokenexpirydate is None or timezone.now()+timedelta(seconds=10) > r.nktokenexpirydate): # pragma: no cover
elif (r.nktokenexpirydate is None or
timezone.now()+timedelta(seconds=10) > r.nktokenexpirydate): # pragma: no cover
s = "Token expired. Needs to refresh."
return custom_exception_handler(401, s)
else:
@@ -251,10 +238,6 @@ def get_workout(user, nkid, do_async=True, startdate='', enddate=''):
s = "Token expired. Needs to refresh."
return custom_exception_handler(401, s), 0
params = {
'sessionIds': nkid,
}
before = 0
after = 0
if startdate: # pragma: no cover
+2 -2
View File
@@ -38,8 +38,8 @@ class OpaqueEncoder:
def transcode(self, i):
"""Reversibly transcode a 32-bit integer to a scrambled form, returning a new 32-bit integer."""
r = i & 0xffff
l = i >> 16 & 0xffff ^ self.transform(r)
return ((r ^ self.transform(l)) << 16) + l
lla = i >> 16 & 0xffff ^ self.transform(r)
return ((r ^ self.transform(lla)) << 16) + lla
def encode_hex(self, i):
"""Transcode an integer and return it as an 8-character hex string."""
+10 -8
View File
@@ -7,7 +7,7 @@ import requests
import requests.auth
import json
from django.utils import timezone
from datetime import datetime
from datetime import datetime, timedelta
import numpy as np
from dateutil import parser
import time
@@ -30,7 +30,10 @@ from rowingdata import rowingdata
import pandas as pd
from rowers.models import Rower, Workout
from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI
from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI)
TEST_CLIENT_ID = "1"
TEST_CLIENT_SECRET = "aapnootmies"
@@ -57,8 +60,8 @@ def custom_exception_handler(exc, message): # pragma: no cover
def do_refresh_token(refreshtoken): # pragma: no cover
client_auth = requests.auth.HTTPBasicAuth(
TEST_CLIENT_ID, TEST_CLIENT_SECRET)
# client_auth = requests.auth.HTTPBasicAuth(
# TEST_CLIENT_ID, TEST_CLIENT_SECRET)
post_data = {"grant_type": "refresh_token",
"client_secret": TEST_CLIENT_SECRET,
"client_id": TEST_CLIENT_ID,
@@ -86,8 +89,8 @@ def do_refresh_token(refreshtoken): # pragma: no cover
def get_token(code): # pragma: no cover
client_auth = requests.auth.HTTPBasicAuth(
TEST_CLIENT_ID, TEST_CLIENT_SECRET)
# client_auth = requests.auth.HTTPBasicAuth(
# TEST_CLIENT_ID, TEST_CLIENT_SECRET)
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://localhost:8000/rowers/test_callback",
@@ -123,7 +126,6 @@ def make_authorization_url(request): # pragma: no cover
"scope": "write",
"state": state}
import urllib
url = "http://localhost:8000/rowers/o/authorize" + \
urllib.parse.urlencode(params)
@@ -170,8 +172,8 @@ def get_ownapi_workout_list(user): # pragma: no cover
def get_ownapi_workout(user, ownapiid): # pragma: no cover
r = Rower.objects.get(user=user)
if (r.ownapitoken == '') or (r.ownapitoken is None):
return custom_exception_handler(401, s)
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401, s)
elif (timezone.now() > r.ownapitokenexpirydate):
s = "Token expired. Needs to refresh."
return custom_exception_handler(401, s)
+7 -24
View File
@@ -6,7 +6,6 @@ from rowers.models import (
get_course_timezone, IndoorVirtualRaceResult, VirtualRace, createmacrofillers,
createmesofillers, createmicrofillers, CourseStandard,
)
from rowers.utils import totaltime_sec_to_string
from rowers.tasks import (
handle_sendemail_raceregistration, handle_sendemail_racesubmission
)
@@ -372,8 +371,6 @@ def get_todays_micro(plan, thedate=timezone.now()):
if thismicro:
thismicro = thismicro[0]
else: # pragma: no cover
mms = TrainingMicroCycle.objects.all()
return None
return thismicro
@@ -421,7 +418,7 @@ def add_workouts_plannedsession(ws, ps, r):
coursecompleted=False,
)
record.save()
job = myqueue(queue, handle_check_race_course, w.csvfilename,
_ = myqueue(queue, handle_check_race_course, w.csvfilename,
w.id, ps.course.id, record.id,
w.user.user.email, w.user.user.first_name,
mode='coursetest')
@@ -429,9 +426,6 @@ def add_workouts_plannedsession(ws, ps, r):
records = CourseTestResult.objects.filter(
userid=w.user.id, plannedsession=ps)
for record in records:
#w1 = Workout.objects.get(id=record.workoutid)
#w1.plannedsession = None
# w1.save()
record.delete()
df = dataprep.getsmallrowdata_db(
@@ -463,9 +457,6 @@ def add_workouts_plannedsession(ws, ps, r):
records = CourseTestResult.objects.filter(
userid=w.user.id, plannedsession=ps)
for record in records:
#w1 = Workout.objects.get(id=record.workoutid)
#w1.plannedsession = None
# w1.save()
record.delete()
df = dataprep.getsmallrowdata_db(
@@ -638,7 +629,7 @@ def is_session_complete_ws(ws, ps):
value *= 1000.
cratiomin = 1
cratiomax = 1
# cratiomax = 1
cratios = {
'better than nothing': 0,
@@ -651,12 +642,12 @@ def is_session_complete_ws(ws, ps):
if ps.criterium == 'none':
if ps.sessiontype == 'session':
cratiomin = 0.8
cratiomax = 1.2
# cratiomax = 1.2
else:
cratios['on target'] = 0.9167
cratios['over target'] = 1.0833
cratiomin = 0.9167
cratiomax = 1.0833
# cratiomax = 1.0833
score = 0
completiondate = None
@@ -790,7 +781,7 @@ def is_session_complete_ws(ws, ps):
coursecompleted=False,
)
record.save()
job = myqueue(queue, handle_check_race_course, ws[0].csvfilename,
_ = myqueue(queue, handle_check_race_course, ws[0].csvfilename,
ws[0].id, ps.course.id, record.id,
ws[0].user.user.email, ws[0].user.user.first_name,
mode='coursetest')
@@ -804,8 +795,6 @@ def is_session_complete_ws(ws, ps):
def is_session_complete(r, ps):
verdict = 'not done'
if r not in ps.rower.all(): # pragma: no cover
return 0, 'not assigned', None
@@ -1290,7 +1279,7 @@ def race_can_submit(r, race):
if timezone.now() > startdatetime and timezone.now() < evaluation_closure:
is_complete, has_registered = race_rower_status(r, race)
if is_complete == False:
if is_complete is False:
return True
else:
return True
@@ -1311,7 +1300,7 @@ def race_can_editentry(r, race):
if timezone.now() < evaluation_closure:
is_complete, has_registered = race_rower_status(r, race)
if is_complete == False:
if is_complete is False:
return True
else: # pragma: no cover
return False
@@ -1594,7 +1583,6 @@ def add_workout_fastestrace(ws, race, r, recordid=0, doregister=False):
errors.append('For tests, you can only attach one workout')
return result, comments, errors, 0
username = r.user.first_name+' '+r.user.last_name
if r.birthdate:
age = calculate_age(r.birthdate)
else: # pragma: no cover
@@ -1634,7 +1622,6 @@ def add_workout_fastestrace(ws, race, r, recordid=0, doregister=False):
records = IndoorVirtualRaceResult.objects.filter(
userid=r.id,
race=race,
#workoutid = ws[0].id
)
if ws[0].workouttype != record.boatclass: # pragma: no cover
@@ -1767,7 +1754,6 @@ def add_workout_indoorrace(ws, race, r, recordid=0, doregister=False):
errors.append('For tests, you can only attach one workout')
return result, comments, errors, 0
username = r.user.first_name+' '+r.user.last_name
if r.birthdate:
age = calculate_age(r.birthdate)
else: # pragma: no cover
@@ -1915,7 +1901,6 @@ def add_workout_race(ws, race, r, splitsecond=0, recordid=0, doregister=False):
errors.append('For tests, you can only attach one workout')
return result, comments, errors, 0
username = r.user.first_name+' '+r.user.last_name
if r.birthdate:
age = calculate_age(r.birthdate)
else: # pragma: no cover
@@ -1971,8 +1956,6 @@ def add_workout_race(ws, race, r, splitsecond=0, recordid=0, doregister=False):
if ws[0].workouttype != record.boatclass: # pragma: no cover
ws[0].workouttype = record.boatclass
ws[0].save()
#errors.append('Your workout boat class is different than on your race registration')
# return 0,comments,errors,0
if ws[0].boattype != record.boattype: # pragma: no cover
errors.append(
+3 -3
View File
@@ -76,8 +76,8 @@ def mkplot(row, title):
ax1.set_title(title)
plt.grid(True)
majorFormatter = FuncFormatter(format_pace_tick)
majorLocator = (5)
timeTickFormatter = NullFormatter()
# majorLocator = (5)
# timeTickFormatter = NullFormatter()
ax1.yaxis.set_major_formatter(majorFormatter)
@@ -88,7 +88,7 @@ def mkplot(row, title):
ax2.plot(t, hr, 'r-')
ax2.set_ylabel('Heart Rate', color='r')
majorTimeFormatter = FuncFormatter(format_time_tick)
majorLocator = (15*60)
# majorLocator = (15*60)
ax2.xaxis.set_major_formatter(majorTimeFormatter)
ax2.patch.set_alpha(0.0)
for tl in ax2.get_yticklabels():
+7 -20
View File
@@ -57,8 +57,6 @@ queuehigh = django_rq.get_queue('high')
# Project
# from .models import Profile
#baseurl = 'https://polaraccesslink.com/v3-example'
baseurl = 'https://polaraccesslink.com/v3'
@@ -125,7 +123,7 @@ def get_token(code):
def make_authorization_url(): # pragma: no cover
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
state = str(uuid4())
# state = str(uuid4())
params = {"client_id": POLAR_CLIENT_ID,
"response_type": "code",
@@ -155,7 +153,7 @@ def revoke_access(user): # pragma: no cover
def get_polar_notifications():
url = baseurl+'/notifications'
state = str(uuid4())
# state = str(uuid4())
auth_string = '{id}:{secret}'.format(
id=POLAR_CLIENT_ID,
secret=POLAR_CLIENT_SECRET
@@ -302,16 +300,12 @@ def get_polar_workouts(user):
'title': '',
}
#session = requests.session()
#newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
# session.headers.update(newHeaders)
url = settings.UPLOAD_SERVICE_URL
dologging('polar.log', uploadoptions)
dologging('polar.log', url)
#response = session.post(url,json=uploadoptions)
job = myqueue(
_ = myqueue(
queuehigh,
handle_request_post,
url,
@@ -381,9 +375,6 @@ def register_user(user, token):
json=payload,
headers=headers
)
#url = baseurl+'/users'
#response = requests.post(url,params=params,headers=headers)
if response.status_code not in [200, 201]: # pragma: no cover
# dologging('polar.log',url)
@@ -419,10 +410,6 @@ def get_polar_user_info(user, physical=False): # pragma: no cover
'Accept': 'application/json'
}
params = {
'user-id': r.polaruserid
}
if not physical:
url = baseurl+'/users/{userid}'.format(
userid=r.polaruserid
@@ -478,11 +465,11 @@ def get_polar_workout(user, id, transactionid):
exercise_dict = response.json()
thisid = exercise_dict['id']
if thisid == id:
url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}/exercises/{exerciseid}/tcx'.format(
url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}' \
'/exercises/{exerciseid}/tcx'.format(
userid=r.polaruserid,
transactionid=transactionid,
exerciseid=id
)
exerciseid=id)
authorizationstring = str('Bearer ' + r.polartoken)
headers2 = {
'Authorization': authorizationstring,
+12 -1
View File
@@ -19,7 +19,18 @@ DESCRIPTOR = _descriptor.FileDescriptor(
package='rowing_workout_metrics',
syntax='proto3',
serialized_options=None,
serialized_pb=_b('\n\x1crowing-workout-metrics.proto\x12\x16rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03sex\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x32w\n\x07Metrics\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest\x1a..rowing_workout_metrics.WorkoutMetricsResponseb\x06proto3')
serialized_pb=_b('\n\x1crowing-workout-metrics.proto\x12\x16'
'rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest'
'\x12\x10\n\x08\x66ilename'
'\x18\x01 \x01(\t\x12\x0b\n\x03sex'
'\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01'
'(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax'
'\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse'
'\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp'
'\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv'
'\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x32w\n\x07Metrics'
'\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest'
'\x1a..rowing_workout_metrics.WorkoutMetricsResponseb\x06proto3')
)
+5 -7
View File
@@ -4,7 +4,7 @@ import gzip
import shutil
import hashlib
from math import isinf, isnan
import uuid
@@ -60,7 +60,7 @@ def validate_image_extension(value):
ext = os.path.splitext(value.name)[1].lower()
valid_extension = ['.jpg', '.jpeg', '.png', '.gif']
if not ext in valid_extension: # pragma: no cover
if ext not in valid_extension: # pragma: no cover
raise ValidationError(u'File not supported')
@@ -71,7 +71,7 @@ def validate_file_extension(value):
'.CSV', '.fit', '.FIT', '.zip', '.ZIP',
'.gz', '.GZ', '.xls',
'.jpg', '.jpeg', '.tiff', '.png', '.gif', '.bmp']
if not ext in valid_extensions: # pragma: no cover
if ext not in valid_extensions: # pragma: no cover
raise ValidationError(u'File not supported!')
@@ -79,7 +79,7 @@ def must_be_csv(value):
import os
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.csv', '.CSV']
if not ext in valid_extensions: # pragma: no cover
if ext not in valid_extensions: # pragma: no cover
raise ValidationError(u'File not supported!')
@@ -87,7 +87,7 @@ def validate_kml(value):
import os
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.kml', '.KML']
if not ext in valid_extensions: # pragma: no cover
if ext not in valid_extensions: # pragma: no cover
raise ValidationError(u'File not supported!')
@@ -144,8 +144,6 @@ def handle_uploaded_file(f):
fname = f.name
ext = fname.split('.')[-1]
fname = '%s.%s' % (uuid.uuid4(), ext)
#timestr = uuid.uuid4().hex[:10]+'-'+time.strftime("%Y%m%d-%H%M%S")
#fname = timestr+'-'+fname
fname2 = 'media/'+fname
with open(fname2, 'wb+') as destination:
for chunk in f.chunks():
+2 -15
View File
@@ -6,8 +6,6 @@ from rowers.tasks import handle_rp3_async_workout
from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
RP3_CLIENT_ID, RP3_CLIENT_SECRET,
RP3_REDIRECT_URI, RP3_CLIENT_KEY,
RP3_CLIENT_ID, RP3_CLIENT_KEY, RP3_REDIRECT_URI, RP3_CLIENT_SECRET,
UPLOAD_SERVICE_URL, UPLOAD_SERVICE_SECRET
)
@@ -29,8 +27,6 @@ queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('high')
#from async_messages import message_user,messages
oauth_data = {
'client_id': RP3_CLIENT_ID,
'client_secret': RP3_CLIENT_SECRET,
@@ -64,8 +60,6 @@ def do_refresh_token(refreshtoken): # pragma: no cover
def get_token(code): # pragma: no cover
client_auth = requests.auth.HTTPBasicAuth(
RP3_CLIENT_KEY, RP3_CLIENT_SECRET)
post_data = {
"client_id": RP3_CLIENT_KEY,
"grant_type": "authorization_code",
@@ -73,9 +67,6 @@ def get_token(code): # pragma: no cover
"redirect_uri": RP3_REDIRECT_URI,
"client_secret": RP3_CLIENT_SECRET,
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
response = requests.post(
"https://rp3rowing-app.com/oauth/token",
@@ -102,8 +93,6 @@ def make_authorization_url(request): # pragma: no cover
def get_rp3_workout_list(user):
r = Rower.objects.get(user=user)
auth_token = rp3_open(user)
headers = {'Authorization': 'Bearer ' + auth_token}
@@ -148,13 +137,13 @@ def get_rp3_workouts(rower, do_async=True): # pragma: no cover
w.uploadedtorp3 for w in Workout.objects.filter(user=rower)
])
newids = [rp3id for rp3id in rp3ids if not rp3id in knownrp3ids]
newids = [rp3id for rp3id in rp3ids if rp3id not in knownrp3ids]
for id in newids:
startdatetime = workouts_list.loc[id, 'executed_at']
dologging('rp3_import.log', startdatetime)
job = myqueue(
_ = myqueue(
queuehigh,
handle_rp3_async_workout,
rower.user.id,
@@ -221,7 +210,6 @@ def get_rp3_workout_token(workout_id, auth_token, waittime=3, max_attempts=20):
def get_rp3_workout_link(user, workout_id, waittime=3, max_attempts=20): # pragma: no cover
r = Rower.objects.get(user=user)
auth_token = rp3_open(user)
return get_rp3_workout_token(workout_id, auth_token, waittime=waittime, max_attempts=max_attempts)
@@ -231,7 +219,6 @@ def get_rp3_workout(user, workout_id, startdatetime=None): # pragma: no cover
url = get_rp3_workout_link(user, workout_id)
filename = 'media/RP3Import_'+str(workout_id)+'.csv'
r = Rower.objects.get(user=user)
auth_token = rp3_open(user)
if not startdatetime:
+1 -1
View File
@@ -6,7 +6,7 @@ from rest_framework import serializers
from rowers.models import (
Workout, Rower, FavoriteChart, VirtualRaceResult,
VirtualRace, GeoCourse, StandardCollection, CourseStandard,
GeoCourse, GeoPolygon, GeoPoint, PlannedSession,
GeoPolygon, GeoPoint, PlannedSession,
)
from django.core.exceptions import PermissionDenied
+4 -7
View File
@@ -164,7 +164,7 @@ def createsporttracksworkoutdata(w):
return 0
# adding diff, trying to see if this is valid
#t = row.df.loc[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
# t = row.df.loc[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
t = row.df.loc[:, 'TimeStamp (sec)'].values - \
row.df.loc[:, 'TimeStamp (sec)'].iloc[0]
try:
@@ -293,7 +293,6 @@ def workout_sporttracks_upload(user, w, asynchron=False): # pragma: no cover
message = "Uploading to SportTracks"
stid = 0
# ready to upload. Hurray
r = w.user
thetoken = sporttracks_open(user)
@@ -311,7 +310,7 @@ def workout_sporttracks_upload(user, w, asynchron=False): # pragma: no cover
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json"
if asynchron:
job = myqueue(queue, handle_sporttracks_sync,
_ = myqueue(queue, handle_sporttracks_sync,
w.id, url, headers, json.dumps(data, default=default))
return "Asynchronous sync", 0
@@ -398,9 +397,9 @@ def add_workout_from_data(user, importid, data, strokedata, source='sporttracks'
return (0, "No distance or heart rate data in the workout")
try:
l = data['location']
locs = data['location']
res = splitstdata(l)
res = splitstdata(locs)
times_location = res[0]
latlong = res[1]
latcoord = []
@@ -492,8 +491,6 @@ def add_workout_from_data(user, importid, data, strokedata, source='sporttracks'
df.sort_values(by='TimeStamp (sec)', ascending=True)
timestr = strftime("%Y%m%d-%H%M%S")
# csvfilename ='media/Import_'+str(importid)+'.csv'
csvfilename = 'media/{code}_{importid}.csv'.format(
importid=importid,
+10 -13
View File
@@ -82,7 +82,7 @@ def strava_open(user):
f.write('\n')
token = imports_open(user, oauth_data)
if user.rower.strava_owner_id == 0: # pragma: no cover
strava_owner_id = set_strava_athlete_id(user)
_ = set_strava_athlete_id(user)
return token
@@ -120,9 +120,6 @@ def strava_establish_push(): # pragma: no cover
'callback_url': webhooklink,
'verify_token': webhookverification,
}
headers = {'user-agent': 'sanderroosendaal',
'Accept': 'application/json',
'Content-Type': oauth_data['content_type']}
response = requests.post(url, data=post_data)
@@ -160,7 +157,7 @@ def set_strava_athlete_id(user):
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401, s)
elif (r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate):
token = imports_open(user, oauth_data)
_ = imports_open(user, oauth_data)
authorizationstring = str('Bearer ' + r.stravatoken)
headers = {'Authorization': authorizationstring,
@@ -185,7 +182,9 @@ def get_strava_workout_list(user, limit_n=0):
if (r.stravatoken == '') or (r.stravatoken is None): # pragma: no cover
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401, s)
elif (r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate): # pragma: no cover
elif (
r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate
): # pragma: no cover
s = "Token expired. Needs to refresh."
return custom_exception_handler(401, s)
else:
@@ -209,7 +208,7 @@ def get_strava_workout_list(user, limit_n=0):
def async_get_workout(user, stravaid):
try:
token = strava_open(user)
_ = strava_open(user)
except NoTokenError: # pragma: no cover
return 0
@@ -246,7 +245,7 @@ def createstravaworkoutdata(w, dozip=True):
if datalength != 0:
data.rename(columns=columndict, inplace=True)
res = data.to_csv(w.csvfilename+'.gz',
_ = data.to_csv(w.csvfilename+'.gz',
index_label='index',
compression='gzip')
try:
@@ -317,7 +316,7 @@ def handle_stravaexport(f2, workoutname, stravatoken, description='',
def workout_strava_upload(user, w, quick=False, asynchron=True):
try:
thetoken = strava_open(user)
_ = strava_open(user)
except NoTokenError: # pragma: no cover
return "Please connect to Strava first", 0
@@ -326,7 +325,6 @@ def workout_strava_upload(user, w, quick=False, asynchron=True):
r = Rower.objects.get(user=user)
res = -1
if (r.stravatoken == '') or (r.stravatoken is None): # pragma: no cover
s = "Token doesn't exist. Need to authorize"
raise NoTokenError("Your hovercraft is full of eels")
if (is_workout_user(user, w)):
@@ -340,13 +338,12 @@ def workout_strava_upload(user, w, quick=False, asynchron=True):
activity_type = mytypes.stravamapping[w.workouttype]
except KeyError: # pragma: no cover
activity_type = 'Rowing'
job = myqueue(queue,
_ = myqueue(queue,
handle_strava_sync,
r.stravatoken,
w.id,
tcxfile, w.name, activity_type,
w.notes
)
w.notes)
dologging('strava_export_log.log', 'Exporting as {t} from {w}'.format(
t=activity_type, w=w.workouttype))
return "Asynchronous sync", -1
+131 -286
View File
File diff suppressed because it is too large Load Diff
+2 -4
View File
@@ -7,6 +7,8 @@ import time
import os
import sys
import django
from django.contrib import messages
proj_path = "../"
sys.path.append(proj_path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rowsandall_app.settings")
@@ -15,11 +17,7 @@ django.setup()
@app.task
def addcomment2(userid, id, debug=False):
time.sleep(5)
# w = Workout.objects.get(id=id)
# w.notes += '\n the task has run'
# w.save()
u = User.objects.get(id=userid)
messages.info(u, ' The task has run')
messages.error(u, ' Het is veel te laat')
+22 -32
View File
@@ -88,7 +88,7 @@ def create_team(name, manager, private='open', notes='', viewing='allmembers'):
private=private, viewing=viewing)
t.save()
r = Rower.objects.get(user=manager)
res = add_member(t.id, r)
_ = add_member(t.id, r)
except IntegrityError:
return (0, 'Team name duplication')
return (t.id, 'Team created')
@@ -131,13 +131,13 @@ def add_member(id, rower):
# code to add all workouts
ws = Workout.objects.filter(user=rower)
res = handle_add_workouts_team(ws, t)
_ = handle_add_workouts_team(ws, t)
# code to add plannedsessions
plannedsessions = PlannedSession.objects.filter(
team=t, enddate__gte=timezone.now().date())
for ps in plannedsessions: # pragma: no cover
res = ps.rower.add(rower)
_ = ps.rower.add(rower)
# set_teamplanexpires(rower)
# code for Stuck At Home Team (temporary)
@@ -154,7 +154,7 @@ def remove_member(id, rower):
# remove the team from rower's workouts:
ws = Workout.objects.filter(user=rower, team=t)
res = handle_remove_workouts_team(ws, t)
_ = handle_remove_workouts_team(ws, t)
# set_teamplanexpires(rower)
return (id, 'Member removed')
@@ -270,7 +270,7 @@ def send_coachrequest_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coachrequest,
email, name, code, coachname)
@@ -283,14 +283,13 @@ def send_coacheerequest_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coacheerequest,
email, name, code, coachname)
def create_request(team, user):
r2 = Rower.objects.get(user=user)
r = Rower.objects.get(user=team.manager)
if r2 in Rower.objects.filter(team=team): # pragma: no cover
return (0, 'Already a member of that team')
@@ -323,8 +322,6 @@ def get_coach_club_size(coach):
# request by coach to coach user
def create_coaching_offer(coach, user):
r = user.rower
if coach in rower_get_coaches(user.rower): # pragma: no cover
return (0, 'You are already coaching this person.')
@@ -348,7 +345,6 @@ def create_coaching_offer(coach, user):
def create_invite(team, manager, user=None, email=''):
r = Rower.objects.get(user=manager)
if not is_team_manager(manager, team):
return (0, 'Not the team manager')
if user:
@@ -359,7 +355,7 @@ def create_invite(team, manager, user=None, email=''):
return (0, 'Rower does not exist')
if r2 in Rower.objects.filter(team=team):
return (0, 'Already member of that team')
elif email == None or email == '': # pragma: no cover
elif email is None or email == '': # pragma: no cover
return (0, 'Invalid request - missing email or user')
else:
try:
@@ -390,13 +386,11 @@ def revoke_request(user, id):
except TeamRequest.DoesNotExist: # pragma: no cover
return (0, 'The request is invalid')
t = rekwest.team
if rekwest.user == user:
rekwest.delete()
return (1, 'Request revoked')
else: # pragma: no cover
return (0, 'You are not the requestor')
return (0, 'You are not the requestor') # pragma: no cover
def reject_revoke_coach_offer(user, id):
@@ -493,7 +487,7 @@ def send_invite_email(id):
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_invite,
email, name, code, teamname, manager)
@@ -506,7 +500,7 @@ def send_team_delete_mail(t, rower):
email = u.email
name = u.first_name+' '+u.last_name
manager = t.manager.first_name+' '+t.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_team_removed,
email, name, teamname, manager)
@@ -521,19 +515,18 @@ def send_email_member_dropped(teamid, rower):
name = u.first_name+' '+u.last_name
manager = t.manager.first_name+' '+t.manager.last_name
res = myqueue(queuehigh, handle_sendemail_member_dropped,
_ = myqueue(queuehigh, handle_sendemail_member_dropped,
email, name, teamname, manager)
return (1, 'Member dropped email sent')
def send_request_accept_email(rekwest): # pragma: no cover
id = rekwest.id
email = rekwest.user.email
teamname = rekwest.team.name
name = rekwest.user.first_name+' '+rekwest.user.last_name
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_request_accept,
email, name, teamname, manager)
@@ -541,13 +534,12 @@ def send_request_accept_email(rekwest): # pragma: no cover
def send_request_reject_email(rekwest):
id = rekwest.id
teamname = rekwest.team.name
email = rekwest.user.email
name = rekwest.user.first_name+' '+rekwest.user.last_name
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_request_reject,
email, name, teamname, manager)
@@ -555,7 +547,6 @@ def send_request_reject_email(rekwest):
def send_invite_reject_email(invitation):
id = invitation.id
email = invitation.team.manager.email
if invitation.user:
name = invitation.user.first_name+' '+invitation.user.last_name
@@ -566,7 +557,7 @@ def send_invite_reject_email(invitation):
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_invite_reject,
email, name, teamname, manager)
@@ -574,7 +565,6 @@ def send_invite_reject_email(invitation):
def send_invite_accept_email(invitation): # pragma: no cover
id = invitation.id
email = invitation.team.manager.email
if invitation.user:
name = invitation.user.first_name+' '+invitation.user.last_name
@@ -585,7 +575,7 @@ def send_invite_accept_email(invitation): # pragma: no cover
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_invite_accept,
email, name, teamname, manager)
@@ -598,7 +588,7 @@ def send_team_message(team, message): # pragma: no cover
for rower in rowers:
rowername = rower.user.first_name + " " + rower.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_message,
rower.user.email, team.manager.email, rowername, message, team.name, managername)
@@ -613,7 +603,7 @@ def send_request_email(rekwest):
teamname = rekwest.team.name
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_request,
email, name, code, teamname, requestor, id)
@@ -729,7 +719,7 @@ def send_coachoffer_rejected_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coachoffer_rejected,
coachemail, coachname, name)
@@ -740,7 +730,7 @@ def send_coachrequest_rejected_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coachrequest_rejected,
email, coachname, name)
@@ -751,7 +741,7 @@ def send_coachrequest_accepted_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coachrequest_accepted,
email, coachname, name)
@@ -762,6 +752,6 @@ def send_coachoffer_accepted_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
res = myqueue(queuehigh,
_ = myqueue(queuehigh,
handle_sendemail_coachoffer_accepted,
coachemail, coachname, name)
+1 -6
View File
@@ -21,8 +21,6 @@ from rowsandall_app.settings import (
tpapilocation = "https://api.trainingpeaks.com"
#from async_messages import message_user,messages
oauth_data = {
'client_id': TP_CLIENT_ID,
'client_secret': TP_CLIENT_SECRET,
@@ -53,7 +51,7 @@ def do_refresh_token(refreshtoken):
def get_token(code):
client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
# client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
post_data = {
"client_id": TP_CLIENT_KEY,
"grant_type": "authorization_code",
@@ -61,9 +59,6 @@ def get_token(code):
"redirect_uri": TP_REDIRECT_URI,
"client_secret": TP_CLIENT_SECRET,
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
response = requests.post(
"https://oauth.trainingpeaks.com/oauth/token",
-2
View File
@@ -151,8 +151,6 @@ class TraverseLinksTest(TestCase):
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
text = soup.get_text()
for link in soup.find_all('a'):
new_link = link.get('href')
if VERBOSE:
+11 -12
View File
@@ -87,7 +87,7 @@ def make_plot(r, w, f1, f2, plottype, title, imagename='', plotnr=0):
}
axis = r.staticgrids
if axis == None: # pragma: no cover
if axis is None: # pragma: no cover
gridtrue = False
axis = 'both'
else:
@@ -133,14 +133,14 @@ def do_sync(w, options, quick=False):
do_strava_export = w.user.strava_auto_export
try:
upload_to_strava = options['upload_to_Strava'] or do_strava_export
do_strava_export = options['upload_to_Strava'] or do_strava_export
except KeyError:
upload_to_strava = False
pass
try:
if options['stravaid'] != 0 and options['stravaid'] != '': # pragma: no cover
w.uploadedtostrava = options['stravaid']
upload_to_strava = False
# upload_to_strava = False
do_strava_export = False
w.save()
except KeyError:
@@ -174,14 +174,14 @@ def do_sync(w, options, quick=False):
do_c2_export = w.user.c2_auto_export
try:
upload_to_c2 = options['upload_to_C2'] or do_c2_export
do_c2_export = options['upload_to_C2'] or do_c2_export
except KeyError:
upload_to_c2 = False
pass
try:
if options['c2id'] != 0 and options['c2id'] != '': # pragma: no cover
w.uploadedtoc2 = options['c2id']
upload_to_c2 = False
# upload_to_c2 = False
do_c2_export = False
w.save()
except KeyError:
@@ -250,16 +250,15 @@ def do_sync(w, options, quick=False):
with open('st_export.log', 'a') as logfile:
logfile.write(str(timezone.now())+': ')
logfile.write(str(w.user)+' NoTokenError\n')
message = "Please connect to SportTracks first"
id = 0
return 0
if ('upload_to_TrainingPeaks' in options and options['upload_to_TrainingPeaks']) or (w.user.trainingpeaks_auto_export): # pragma: no cover
try:
message, id = tpstuff.workout_tp_upload(
_, id = tpstuff.workout_tp_upload(
w.user.user, w
)
except NoTokenError:
message = "Please connect to TrainingPeaks first"
id = 0
return 0
return 1
+22 -16
View File
@@ -17,7 +17,6 @@ from rest_framework.permissions import *
from rowers import views
from django.contrib.auth import views as auth_views
from django.views.generic.base import TemplateView
from django.utils.decorators import method_decorator
from rowers.permissions import (
IsOwnerOrNot, IsOwnerOrReadOnly,
@@ -71,7 +70,7 @@ class PlannedSessionViewSet(viewsets.ModelViewSet):
class WorkoutViewSet(viewsets.ModelViewSet):
model = Workout
#queryset = Workout.objects.all().order_by("-date", "-starttime")
serializer_class = WorkoutSerializer
def get_queryset(self): # pragma: no cover
@@ -90,7 +89,6 @@ class WorkoutViewSet(viewsets.ModelViewSet):
class RowerViewSet(viewsets.ModelViewSet):
model = Rower
serializer_class = RowerSerializer
#queryset = Rower.objects.all()
def get_queryset(self): # pragma: no cover
try:
@@ -109,7 +107,6 @@ class RowerViewSet(viewsets.ModelViewSet):
class FavoriteChartViewSet(viewsets.ModelViewSet):
model = FavoriteChart
serializer_class = FavoriteChartSerializer
#queryset = FavoriteChart.objects.all()
def get_queryset(self): # pragma: no cover
try:
@@ -235,8 +232,6 @@ handler400 = views.error400_view
handler500 = views.error500_view
#app_name = "rowers"
urlpatterns = [
re_path(r'^o/authorize/$', base.AuthorizationView.as_view(), name="authorize"),
re_path(r'^o/token/$', base.TokenView.as_view(), name="token"),
@@ -352,17 +347,21 @@ urlpatterns = [
re_path(r'^workouts-join-select/user/(?P<userid>\d+)/$',
views.workouts_join_select, name='workouts_join_select'),
re_path(
r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
views.analysis_new, name='analysis_new'),
re_path(
r'^user-analysis-select/(?P<function>\w.*)/session/(?P<session>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
r'^user-analysis-select/(?P<function>\w.*)/session/(?P<session>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
views.analysis_new, name='analysis_new'),
re_path(
r'^user-analysis-select/(?P<function>\w.*)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
r'^user-analysis-select/(?P<function>\w.*)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
views.analysis_new, name='analysis_new'),
re_path(r'^user-analysis-select/(?P<function>\w.*)/user/(?P<userid>\d+)/$',
views.analysis_new, name='analysis_new'),
re_path(r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/$',
views.analysis_new, name='analysis_new'),
re_path(
r'^user-analysis-select/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
r'^user-analysis-select/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
views.analysis_new, name='analysis_new'),
re_path(r'^user-analysis-select/user/(?P<userid>\d+)/$',
views.analysis_new, name='analysis_new'),
re_path(r'^user-analysis-select/team/(?P<teamid>\d+)/$',
@@ -613,7 +612,8 @@ urlpatterns = [
views.workout_nkimport_view, name='workout_nkimport_view'),
re_path(r'^workout/nkimport/all/$', views.workout_getnkworkout_all,
name='workout_getnkworkout_all'),
re_path(r'^workout/nkimport/all/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$', views.workout_getnkworkout_all,
re_path(r'^workout/nkimport/all/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',
views.workout_getnkworkout_all,
name='workout_getnkworkout_all'),
re_path(r'^workout/rp3import/(?P<externalid>\d+)/$', views.workout_getrp3importview,
name='workout_getrp3importview'),
@@ -853,11 +853,15 @@ urlpatterns = [
name='workout_workflow_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/courses/$', views.workout_course_view,
name='workout_course_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
'(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',
views.workout_flexchart3_view, name='workout_flexchart3_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
'(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',
views.workout_flexchart3_view, name='workout_flexchart3_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',
re_path(
r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
'(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',
views.workout_flexchart3_view, name='workout_flexchart3_view'),
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/$',
views.workout_flexchart3_view, name='workout_flexchart3_view'),
@@ -1002,7 +1006,8 @@ urlpatterns = [
name='plannedsession_teamclone_view'),
re_path(r'^sessions/(?P<id>\d+)/clone/$', views.plannedsession_clone_view),
re_path(
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$', views.plannedsession_detach_view),
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$',
views.plannedsession_detach_view),
re_path(
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.plannedsession_detach_view),
re_path(r'^sessions/(?P<id>\d+)/$', views.plannedsession_view,
@@ -1043,7 +1048,8 @@ urlpatterns = [
name='plannedsessions_print_view'),
re_path(r'^sessions/(?P<id>\d+)/message/$', views.plannedsession_message_view,
name='plannedsession_message_view'),
re_path(r'^sessions/print/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$', views.plannedsessions_print_view,
re_path(r'^sessions/print/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',
views.plannedsessions_print_view,
name='plannedsessions_print_view'),
re_path(r'^sessions/sendcalendar/$', views.plannedsessions_icsemail_view,
name='plannedsessions_coach_icsemail_view'),
+24 -25
View File
@@ -16,14 +16,11 @@ import datetime
import json
import time
from fitparse import FitFile
from django.conf import settings
from django.http import HttpResponse
import requests
from django.http import HttpResponse
import humanize
from pytz.exceptions import UnknownTimeZoneError
import pytz
@@ -189,7 +186,6 @@ palettes = {
'gold_sunset': (47, -31, .26, -0.12, 0.94, -0.5),
'blue_red': (207, -200, .85, 0, .74, -.24),
'blue_green': (207, -120, .85, 0, .75, .25),
'cyan_green': (192, -50, .08, .65, .98, -.34),
'cyan_purple': trcolors(237, 248, 251, 136, 65, 157),
'green_blue': trcolors(240, 249, 232, 8, 104, 172),
'orange_red': trcolors(254, 240, 217, 179, 0, 0),
@@ -237,7 +233,8 @@ def str2bool(v): # pragma: no cover
def uniqify(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
def idfun(x):
return x
seen = {}
result = []
for item in seq:
@@ -465,14 +462,14 @@ def totaltime_sec_to_string(totaltime, shorten=False):
hours=hours,
minutes=minutes,
seconds=seconds,
tenths=tenths
# tenths=tenths
)
else:
duration = "{minutes}:{seconds:02d}".format(
hours=hours,
# hours=hours,
minutes=minutes,
seconds=seconds,
tenths=tenths
# tenths=tenths
)
return duration
@@ -559,12 +556,12 @@ def get_strava_stream(r, metric, stravaid, series_type='time', fetchresolution='
if metric == 'power': # pragma: no cover
metric = 'watts'
url = "https://www.strava.com/api/v3/activities/{stravaid}/streams/{metric}?resolution={fetchresolution}&series_type={series_type}".format(
url = "https://www.strava.com/api/v3/activities/{stravaid}" \
"/streams/{metric}?resolution={fetchresolution}&series_type={series_type}".format(
stravaid=stravaid,
fetchresolution=fetchresolution,
series_type=series_type,
metric=metric
)
metric=metric)
s = requests.get(url, headers=headers)
@@ -574,7 +571,6 @@ def get_strava_stream(r, metric, stravaid, series_type='time', fetchresolution='
try:
for data in s.json():
y = None
try:
if data['type'] == metric:
return np.array(data['data'])
@@ -790,14 +786,14 @@ def get_step_type(step): # pragma: no cover
return t
def peel(l):
if len(l) == 0: # pragma: no cover
def peel(listToPeel):
if len(listToPeel) == 0: # pragma: no cover
return None, None
if len(l) == 1:
return l[0], None
if len(listToPeel) == 1:
return listToPeel[0], None
first = l[0]
rest = l[1:]
first = listToPeel[0]
rest = listToPeel[1:]
if first['type'] == 'Step': # pragma: no cover
return first, rest
@@ -944,7 +940,7 @@ def step_to_string(step, short=False):
repeatValue = 1
nr = 0
name = ''
intensity = ''
duration = ''
unit = ''
@@ -954,7 +950,11 @@ def step_to_string(step, short=False):
durationtype = step['durationType']
if step['durationValue'] == 0:
if durationtype not in ['RepeatUntilStepsCmplt', 'RepeatUntilHrLessThan', 'RepeatUntilHrGreaterThan']: # pragma: no cover
if durationtype not in [
'RepeatUntilStepsCmplt',
'RepeatUntilHrLessThan',
'RepeatUntilHrGreaterThan'
]: # pragma: no cover
return '', type, -1, -1, 1
if durationtype == 'Time':
@@ -963,7 +963,6 @@ def step_to_string(step, short=False):
if value/1000. >= 3600: # pragma: no cover
unit = 'h'
dd = timedelta(seconds=value/1000.)
#duration = humanize.naturaldelta(dd, minimum_unit="seconds")
duration = '{v}'.format(v=str(dd))
elif durationtype == 'Distance':
unit = 'm'
@@ -1163,7 +1162,7 @@ def step_to_string(step, short=False):
nr = step['stepId']
name = step['wkt_step_name']
# name = step['wkt_step_name']
notes = ''
try:
@@ -1178,10 +1177,10 @@ def step_to_string(step, short=False):
intensity = 0
s = '{duration} {unit} {target} {repeat} {notes}'.format(
nr=nr,
name=name,
# nr=nr,
# name=name,
unit=unit,
intensity=intensity,
# intensity=intensity,
duration=duration,
target=target,
repeat=repeat,
+1 -2
View File
@@ -3736,8 +3736,7 @@ def workout_flexchart3_view(request, *args, **kwargs):
'yaxis1': yparam1,
'yaxis2': yparam2,
}
flexaxesform = FlexAxesForm(request, initial=initial,
extrametrics=extrametrics)
flexaxesform = FlexAxesForm(request, initial=initial)
initial = {
'includereststrokes': not workstrokesonly,
+2 -2
View File
@@ -70,7 +70,7 @@ def get_metar_data(airportcode, unixtime):
lengte = len(doc.xpath('data/METAR/station_id'))
idnr = int(lengte/2)
try:
id = doc.xpath('data/METAR/station_id')[idnr].text
_ = doc.xpath('data/METAR/station_id')[idnr].text
temp_c = doc.xpath('data/METAR/temp_c')[idnr].text
wind_dir = doc.xpath('data/METAR/wind_dir_degrees')[idnr].text
wind_speed = doc.xpath('data/METAR/wind_speed_kt')[idnr].text
@@ -138,7 +138,7 @@ def get_wind_data(lat, long, unixtime):
windbearing = 0
summary = 'unknown'
airports = ['unknown']
temparature = 'unknown'
temperature = 'unknown'
temperaturec = 'unknown'
message = 'Not able to get weather data'
-1
View File
@@ -1 +0,0 @@
-4
View File
@@ -1,5 +1 @@
from django import forms
-1
View File
@@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
from django.db import models
+54 -60
View File
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/
# -*- coding: utf-8 -*-
import os
from YamJam import yamjam
#from django.utils.translation import ugettext_lazy as _
# from django.utils.translation import ugettext_lazy as _
# Read configuration (passwords, keys, secrets) from YamJam configuration
# You have to create your own config.yaml in the project directory
@@ -20,8 +20,6 @@ CFG = yamjam()['rowsandallapp']
DEFAULT_CHARSET = 'UTF-8'
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -39,10 +37,10 @@ TESTING = False
ALLOWED_HOSTS = CFG['allowed_hosts']
#OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'oauth2_provider.AccessToken'
#OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
#OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = 'oauth2_provider.RefreshToken'
#OAUTH2_PROVIDER_ACCESS_TOKEN_EXPIRE_SECONDS = 3600
# OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'oauth2_provider.AccessToken'
# OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
# OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = 'oauth2_provider.RefreshToken'
# OAUTH2_PROVIDER_ACCESS_TOKEN_EXPIRE_SECONDS = 3600
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
@@ -51,20 +49,20 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
INSTALLED_APPS = [
'rowers',
'survey',
# 'cvkbrno',
# 'cvkbrno',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'suit',
# 'suit_rq',
# 'suit',
# 'suit_rq',
'leaflet',
'django_rq',
# 'django_rq_dashboard',
# 'translation_manager',
# 'django_mailbox',
# 'django_rq_dashboard',
# 'translation_manager',
# 'django_mailbox',
'rest_framework',
'datetimewidget',
'rest_framework_swagger',
@@ -91,12 +89,12 @@ MIDDLEWARE = [
'django.middleware.common.CommonMiddleware',
'django.middleware.common.BrokenLinkEmailsMiddleware',
'django.middleware.gzip.GZipMiddleware',
# 'htmlmin.middleware.HtmlMinifyMiddleware',
# 'htmlmin.middleware.MarkRequestMiddleware',
# 'htmlmin.middleware.HtmlMinifyMiddleware',
# 'htmlmin.middleware.MarkRequestMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# 'django.middleware.locale.LocaleMiddleware',
# 'django.middleware.locale.LocaleMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
@@ -106,14 +104,14 @@ MIDDLEWARE = [
'tz_detect.middleware.TimezoneMiddleware',
'rowers.middleware.SurveyMiddleWare',
'rowers.middleware.GDPRMiddleWare',
# 'rowers.middleware.PowerTimeFitnessMetricMiddleWare',
# 'rowers.middleware.PowerTimeFitnessMetricMiddleWare',
'rowers.middleware.RowerPlanMiddleWare',
]
ROOT_URLCONF = 'rowsandall_app.urls'
HTML_MINIFY = True
#EXCLUDE_FROM_MINIFYING = ('^rowers/flexall',
# EXCLUDE_FROM_MINIFYING = ('^rowers/flexall',
# '^rowers/list-workouts',
# '^rowers/list-graphs',
# '^admin/',
@@ -124,7 +122,7 @@ APPEND_SLASH = True
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
@@ -133,18 +131,17 @@ TEMPLATES = [
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
# 'context_processors.google_analytics',
# 'context_processors.google_analytics',
'context_processors.warning_message',
'rowers.context_processors.braintree_merchant',
],
'libraries' : {
'libraries': {
'staticfiles': 'django.templatetags.static',
}
# 'loaders': [
# 'django.template.loaders.app_directories.Loader',
# ],
# 'loaders': [
# 'django.template.loaders.app_directories.Loader',
# ],
},
},
]
@@ -229,12 +226,12 @@ DATE_FORMAT = 'Y-m-d'
USE_TZ = True
TIME_ZONE = 'UTC'
TZ_DETECT_COUNTRIES = ('US','DE','GB','CZ','FR','IT')
TZ_DETECT_COUNTRIES = ('US', 'DE', 'GB', 'CZ', 'FR', 'IT')
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
# os.path.join(BASE_DIR, 'cvkbrno/locale'),
)
# os.path.join(BASE_DIR, 'cvkbrno/locale'),
)
LANGUAGE_CODE = 'en-us'
@@ -244,19 +241,16 @@ LANGUAGE_COOKIE_NAME = 'wm_lang'
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'
#STATIC_ROOT = BASE_DIR
# STATIC_ROOT = BASE_DIR
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/plots'),]
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/plots'), ]
# os.path.join(BASE_DIR, 'static'),
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# user authentication
# user authentication
LOGIN_REDIRECT_URL = '/rowers/list-workouts/'
LOGIN_URL = '/login/'
@@ -279,7 +273,7 @@ except KeyError: # pragma: no cover
C2_CLIENT_ID = CFG['c2_client_id']
C2_CLIENT_SECRET = CFG['c2_client_secret']
C2_REDIRECT_URI = CFG['c2_callback']
#C2_REDIRECT_URI = "http://localhost:8000/call_back"
# C2_REDIRECT_URI = "http://localhost:8000/call_back"
# Strava
@@ -316,8 +310,8 @@ UNDERARMOUR_CLIENT_ID = CFG['underarmour_client_name']
UNDERARMOUR_CLIENT_SECRET = CFG['underarmour_client_secret']
UNDERARMOUR_CLIENT_KEY = CFG['underarmour_client_key']
UNDERARMOUR_REDIRECT_URI = CFG['underarmour_callback']
#UNDERARMOUR_REDIRECT_URI = "http://rowsandall.com/underarmour_callback"
#UNDERARMOUR_REDIRECT_URI = "http://localhost:8000/underarmour_callback"
# UNDERARMOUR_REDIRECT_URI = "http://rowsandall.com/underarmour_callback"
# UNDERARMOUR_REDIRECT_URI = "http://localhost:8000/underarmour_callback"
# TrainingPeaks
TP_CLIENT_ID = CFG["tp_client_id"]
@@ -349,35 +343,35 @@ RQ_QUEUES = {
'HOST': 'localhost',
'PORT': 6379,
'DB': 0,
# 'PASSWORD': 'some-password',
# 'PASSWORD': 'some-password',
'DEFAULT_TIMEOUT': 360,
},
'low': {
'HOST': 'localhost',
'PORT': 6379,
'DB': 0,
# 'PASSWORD': 'some-password',
# 'PASSWORD': 'some-password',
'DEFAULT_TIMEOUT': 360,
},
'high': {
'HOST': 'localhost',
'PORT': 6379,
'DB': 0,
# 'PASSWORD': 'some-password',
# 'PASSWORD': 'some-password',
'DEFAULT_TIMEOUT': 360,
},
}
#SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
#SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
# SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
# SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_SAVE_EVERY_REQUEST = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
# admin stuff for error reporting
SERVER_EMAIL='admin@rowsandall.com'
ADMINS = [('Sander','roosendaalsander@gmail.com')]
SERVER_EMAIL = 'admin@rowsandall.com'
ADMINS = [('Sander', 'roosendaalsander@gmail.com')]
CACHES = {
'default': {
@@ -385,20 +379,20 @@ CACHES = {
'LOCATION': 'localhost:11211',
'TIMEOUT': 900,
}
}
}
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 900
# email stuff
#EMAIL_BACKEND = CFG['email_backend']
#EMAIL_HOST = CFG['email_host']
#EMAIL_PORT = CFG['email_port']
#EMAIL_HOST_USER = CFG['email_host_user']
#EMAIL_HOST_PASSWORD = CFG['email_host_password']
#EMAIL_USE_TLS = CFG['email_use_tls']
#DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
# EMAIL_BACKEND = CFG['email_backend']
# EMAIL_HOST = CFG['email_host']
# EMAIL_PORT = CFG['email_port']
# EMAIL_HOST_USER = CFG['email_host_user']
# EMAIL_HOST_PASSWORD = CFG['email_host_password']
# EMAIL_USE_TLS = CFG['email_use_tls']
# DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
EMAIL_BACKEND = 'django_ses.SESBackend'
@@ -435,7 +429,7 @@ OAUTH2_PROVIDER = {
'APPLICATION_MODEL': 'oauth2_provider.Application',
'REFRESH_TOKEN_MODEL': 'oauth2_provider.RefreshToken',
'ACCESS_TOKEN_EXPIRE_SECONDS': 36000,
#'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore'
# 'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore'
}
@@ -446,26 +440,26 @@ REST_FRAMEWORK = {
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
# 'rest_framework.permissions.DjangoModelPermissions'
# 'rest_framework.permissions.DjangoModelPermissions'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
),
'PAGE_SIZE': 20,
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.LimitOffsetPagination',
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
}
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'basic': {
'type':'basic'
'type': 'basic'
},
'oauth2': {
'type':'oauth2',
'authorizationUrl':'/rowers/o/authorize',
'type': 'oauth2',
'authorizationUrl': '/rowers/o/authorize',
'flow': 'implicit',
},
'api_key': {
@@ -477,7 +471,7 @@ SWAGGER_SETTINGS = {
'SHOW_REQUEST_HEADERS': True,
'USE_SESSION_AUTH': True,
'JSON_EDITOR': True,
}
}
# Analytics
+13 -12
View File
@@ -21,8 +21,6 @@ for element in sys.argv:
if 'test' in element:
TESTING = True
if TESTING or use_sqlite:
DATABASES = {
'default': {
@@ -31,7 +29,8 @@ if TESTING or use_sqlite:
'HOST': 'localhost',
'USER': '',
'PASSWORD': 'roeidata',
'PORT': '3306', },
'PORT': '3306',
},
# 'TEST': {
# 'CHARSET': 'utf8',
# 'COLLATION': 'utf8_general_ci',
@@ -63,10 +62,10 @@ DEBUG = True
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
ALLOWED_HOSTS = ['localhost','127.0.0.1','dunav.ngrok.io']
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'dunav.ngrok.io']
# INSTALLED_APPS += ['debug_toolbar',]
#INSTALLED_APPS += ["sslserver"]
# INSTALLED_APPS += ["sslserver"]
# MIDDLEWARE_CLASSES += ['debug_toolbar.middleware.DebugToolbarMiddleware',]
@@ -75,17 +74,19 @@ CACHES = {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR, 'django_cache'),
}
}
}
# Application definition
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR
#STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'static/plots'),]
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'static/plots'),
]
INTERNAL_IPS = ['127.0.0.1']
@@ -99,10 +100,10 @@ SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
SITE_URL = "http://localhost:8000"
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_BACKEND = 'django_ses.SESBackend'
-104
View File
@@ -1,104 +0,0 @@
"""
Django settings for rowsandall_app project.
Generated by 'django-admin startproject' using Django 1.9.5.
For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""
import os
from .settings import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# 'HOST': 'localhost',
},
# 'TEST': {
# 'CHARSET': 'utf8',
# 'COLLATION': 'utf8_general_ci',
# },
# 'slave': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'rowsanda_107501',
# 'USER': 'rowsanda_107501',
# 'PASSWORD': 'roeidata',
# 'HOST': 'store3.rosti.cz',
# 'PORT': '3306',
# }
}
#BROKER_URL = 'redis://localhost:6379/0'
#CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
#CELERY_IGNORE_RESULT = False
#CELERY_ACCEPT_CONTENT = ['json']
#CELERY_TASK_SERIALIZER = 'json'
#CELERY_RESULT_SERIALIZER = 'json'
#CELERY_TRACK_STARTED = True
#CELERY_SEND_TASK_SENT_EVENT = True
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
ALLOWED_HOSTS = []
INSTALLED_APPS += ['debug_toolbar',]
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware',]
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR, 'django_cache'),
}
}
# Application definition
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR
STATICFILES_DIRS = [os.path.join(BASE_DIR,'static/plots'),os.path.join(BASE_DIR,'static'),]
# INTERNAL_IPS = ['127.0.0.1']
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
LOGIN_REDIRECT_URL = '/rowers/list-workouts/'
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
SITE_URL = "http://localhost:8000"
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
#EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_SES_REGION_NAME = 'eu-west-1'
AWS_SES_REGION_ENDPOINT = 'email.eu-west-1.amazonaws.com'
EMAIL_HOST = CFG['aws_smtp']
EMAIL_PORT = CFG['aws_port']
EMAIL_HOST_USER = CFG['aws_smtp_username']
EMAIL_HOST_PASSWORD = CFG['aws_smtp_password']
EMAIL_USE_TLS = CFG['email_use_tls']
DEFAULT_FROM_EMAIL = 'info@rowsandall.com'
SETTINGS_NAME = 'rowsandall_app.settings_thinkpad'
+50 -36
View File
@@ -25,69 +25,80 @@ from rowers import views as rowersviews
from survey import views as surveyviews
import django
import django.views.i18n
# admin look
admin.site.enable_nav_sidebar = False
import django.views.i18n
urlpatterns = [
re_path('^', include('django.contrib.auth.urls')),
re_path(r'^password_change_done/$',auth_views.PasswordChangeDoneView.as_view(),name='password_change_done'),
re_path(r'^password_change/$',auth_views.PasswordChangeView.as_view(),name='password_change'),
re_path(r'^password_reset/$',
re_path(
r'^password_change_done/$',
auth_views.PasswordChangeDoneView.as_view(),
name='password_change_done'),
re_path(
r'^password_change/$',
auth_views.PasswordChangeView.as_view(),
name='password_change'),
re_path(
r'^password_reset/$',
auth_views.PasswordResetView.as_view(),
{'template_name': 'rowers/templates/registration/password_reset.html'},
name='password_reset'),
re_path(r'^password_reset/done/$',
re_path(
r'^password_reset/done/$',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
re_path(
r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
re_path(r'^reset/done/$',
re_path(
r'^reset/done/$',
auth_views.PasswordResetCompleteView.as_view(),
name='password_reset_complete'),
]
]
urlpatterns += [
re_path(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt',
re_path(r'^robots\.txt$', TemplateView.as_view(
template_name='robots.txt',
content_type='text/plain')),
re_path(r'^admin/', admin.site.urls),
re_path(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework2')),
re_path(r'^$',landingview),
re_path(r'^landing/$',landingview),
re_path(r'^getblogs/$',rowersviews.get_blog_posts),
re_path(r'^$', landingview),
re_path(r'^landing/$', landingview),
re_path(r'^getblogs/$', rowersviews.get_blog_posts),
re_path(r'^login/',
# auth_views.LoginView,
# auth_views.LoginView,
auth_views.LoginView.as_view(),
name='login'),
re_path(r'^logout/$',
auth_views.LogoutView.as_view(),
{'next_page': '/'},
name='logout',),
re_path(r'^rowers/',include('rowers.urls')),
# re_path(r'^survey/',include('survey.urls')),
# re_path(r'^cvkbrno/',include('cvkbrno.urls')),
# re_path(r'^admin/rq/',include('django_rq_dashboard.urls')),
re_path(r'^call\_back',rowersviews.rower_process_callback),
re_path(r'^nk\_callback',rowersviews.rower_process_nkcallback),
re_path(r'^stravacall\_back',rowersviews.rower_process_stravacallback),
re_path(r'^garmin\_callback',rowersviews.rower_process_garmincallback),
re_path(r'^sporttracks\_callback',rowersviews.rower_process_sporttrackscallback),
re_path(r'^polarflowcallback',rowersviews.rower_process_polarcallback),
re_path(r'^tp\_callback',rowersviews.rower_process_tpcallback),
re_path(r'^rp3\_callback',rowersviews.rower_process_rp3callback),
re_path(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
re_path(r'^rowers/', include('rowers.urls')),
# re_path(r'^survey/',include('survey.urls')),
# re_path(r'^cvkbrno/',include('cvkbrno.urls')),
# re_path(r'^admin/rq/',include('django_rq_dashboard.urls')),
re_path(r'^call\_back', rowersviews.rower_process_callback),
re_path(r'^nk\_callback', rowersviews.rower_process_nkcallback),
re_path(r'^stravacall\_back', rowersviews.rower_process_stravacallback),
re_path(r'^garmin\_callback', rowersviews.rower_process_garmincallback),
re_path(r'^sporttracks\_callback', rowersviews.rower_process_sporttrackscallback),
re_path(r'^polarflowcallback', rowersviews.rower_process_polarcallback),
re_path(r'^tp\_callback', rowersviews.rower_process_tpcallback),
re_path(r'^rp3\_callback', rowersviews.rower_process_rp3callback),
re_path(r'^twitter\_callback', rowersviews.rower_process_twittercallback),
re_path(r'^i18n/', include('django.conf.urls.i18n')),
re_path(r'^tz_detect/', include('tz_detect.urls')),
re_path(r'^logo/',logoview),
re_path(r'^media/(?P<filename>.*\.fit)$',rowersviews.download_fit),
re_path(r'^logo/', logoview),
re_path(r'^media/(?P<filename>.*\.fit)$', rowersviews.download_fit),
path('django-rq/', include('django_rq.urls')),
# path('500/', rowersviews.error500_view),
# re_path(r'^jsi18n/', django.views.i18n.javascript_catalog,name='jsi18n'),
]
# path('500/', rowersviews.error500_view),
# re_path(r'^jsi18n/', django.views.i18n.javascript_catalog,name='jsi18n'),
]
js_info_dict = {
'packages': ('recurrence', ),
@@ -109,10 +120,13 @@ if settings.DEBUG: # pragma: no cover
kwargs={'document_root': settings.STATIC_ROOT+'plots/'})
]
urlpatterns += [
# re_path(r'^__debug__/','debug_toolbar.urls'),
re_path(r'^static/(?P<path>.*)$',
# re_path(r'^__debug__/','debug_toolbar.urls'),
re_path(
r'^static/(?P<path>.*)$',
django.views.static.serve,
kwargs={'document_root': settings.STATIC_ROOT,
'show_indexes': True}
kwargs={
'document_root': settings.STATIC_ROOT,
'show_indexes': True
}
)
]
+20 -21
View File
@@ -9,13 +9,14 @@ from rowingdata import main as rmain
import random
def landingview(request):
loginform = LoginForm()
return render(request,
def landingview(request):
return render(
request,
'landingpage.html',
)
def logoview(request): # pragma: no cover
image_data = open(settings.STATIC_ROOT+"/img/apple-icon-144x144.png", "rb").read()
return HttpResponse(image_data, content_type="image/png")
@@ -27,48 +28,46 @@ def rootview(request): # pragma: no cover
planoffering = {
'name': 'PLAN',
'image':'/static/img/Plan.png',
'text':'We offer a fully integrated way for you or your coach to set up a training plan. Compare plan vs execution based on time, distance, heart rate or power.'
'image': '/static/img/Plan.png',
'text': 'We offer a fully integrated way for you or your coach to set up a training plan. Compare plan vs execution based on time, distance, heart rate or power.'
}
uploadoffering = {
'name': 'SYNC',
'image':'/static/img/upload.png',
'text':'Easily upload data from the most popular devices and apps'
'image': '/static/img/upload.png',
'text': 'Easily upload data from the most popular devices and apps'
}
logoffering = {
'name': 'LOG',
'image':'/static/img/log.png',
'text':'Maintain a consistent log for all your rowing (indoor and on the water)'
'image': '/static/img/log.png',
'text': 'Maintain a consistent log for all your rowing (indoor and on the water)'
}
analyzeoffering = {
'name': 'ANALYZE',
'image':'/static/img/analyze.png',
'text':'Analyze your workouts with a consistent set of tools'
'image': '/static/img/analyze.png',
'text': 'Analyze your workouts with a consistent set of tools'
}
compareoffering = {
'name': 'COMPARE',
'image':'/static/img/compare.png',
'text':'Compare your results between workouts and with other rowers in your team'
'image': '/static/img/compare.png',
'text': 'Compare your results between workouts and with other rowers in your team'
}
raceoffering = {
'name': 'RACE',
'image':'/static/img/Race 01.png',
'text':'Virtual regattas are an informal way to add a competitive element to your training and can be used as a quick way to set up small regattas'
'image': '/static/img/Race 01.png',
'text': 'Virtual regattas are an informal way to add a competitive element to your training and can be used as a quick way to set up small regattas'
}
coachoffering = {
'name': 'COACHING',
'image':'/static/img/Remote coaching.png',
'text':'Rowsandall.com is the ideal platform for remote rowing coaching. As a coach, you can easily manage your athletes, set up plans and monitor execution and technique'
'image': '/static/img/Remote coaching.png',
'text': 'Rowsandall.com is the ideal platform for remote rowing coaching. As a coach, you can easily manage your athletes, set up plans and monitor execution and technique'
}
allofferings = [
planoffering,
uploadoffering,
@@ -88,6 +87,6 @@ def rootview(request): # pragma: no cover
'frontpage.html',
{
'versionstring': magicsentence,
'form':loginform,
'offerings':offerings,
'form': loginform,
'offerings': offerings,
})
+2 -2
View File
@@ -1,4 +1,4 @@
[flake8]
ignore = F405, F403, E722, E226, W504, F401, W605
ignore = F405, F403, E722, E226, W504, F401, W605, E501
max-line-length = 120
exclude = .git, rowers/migrations
exclude = .git, rowers/migrations, rowers/tests, rowers/admin.py