coverage related changes
This commit is contained in:
@@ -322,7 +322,7 @@ def update_subscription(rower,data,method='up'):
|
|||||||
|
|
||||||
return False,0
|
return False,0
|
||||||
|
|
||||||
return False,0
|
return False,0 # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
def create_subscription(rower,data):
|
def create_subscription(rower,data):
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ def coordinate_in_path(latitude,longitude, p):
|
|||||||
return p.contains_points([(latitude,longitude)])[0]
|
return p.contains_points([(latitude,longitude)])[0]
|
||||||
|
|
||||||
class InvalidTrajectoryError(Exception):
|
class InvalidTrajectoryError(Exception):
|
||||||
def __init__(self,value):
|
def __init__(self,value): # pragma: no cover
|
||||||
self.value=value
|
self.value=value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self): # pragma: no cover
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
||||||
|
|
||||||
if df.empty:
|
if df.empty: # pragma: no cover
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
latitude = df.latitude
|
latitude = df.latitude
|
||||||
@@ -33,12 +33,12 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
|||||||
|
|
||||||
if maxmin=='max':
|
if maxmin=='max':
|
||||||
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
|
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
|
||||||
else:
|
else: # pragma: no cover
|
||||||
b = (~df['inpolygon']).shift(1)+df['inpolygon']
|
b = (~df['inpolygon']).shift(1)+df['inpolygon']
|
||||||
|
|
||||||
|
|
||||||
if len(df[b==2]):
|
if len(df[b==2]):
|
||||||
if logfile is not None:
|
if logfile is not None: # pragma: no cover
|
||||||
t = time.localtime()
|
t = time.localtime()
|
||||||
timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8')
|
timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8')
|
||||||
with open(logfile,'ab') as f:
|
with open(logfile,'ab') as f:
|
||||||
@@ -57,12 +57,12 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
|||||||
f.write(b' passes found')
|
f.write(b' passes found')
|
||||||
else:
|
else:
|
||||||
f.write(b' pass found')
|
f.write(b' pass found')
|
||||||
if getall:
|
if getall: # pragma: no cover
|
||||||
return df[b==2]['time'],df[b==2]['cum_dist']
|
return df[b==2]['time'],df[b==2]['cum_dist']
|
||||||
else:
|
else:
|
||||||
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
|
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
|
||||||
|
|
||||||
if logfile is not None:
|
if logfile is not None: # pragma: no cover
|
||||||
t = time.localtime()
|
t = time.localtime()
|
||||||
timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8')
|
timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8')
|
||||||
with open(logfile,'ab') as f:
|
with open(logfile,'ab') as f:
|
||||||
@@ -78,10 +78,10 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
|||||||
f.write(bytes(str(len(df[b==2])),'utf-8'))
|
f.write(bytes(str(len(df[b==2])),'utf-8'))
|
||||||
f.write(b' ')
|
f.write(b' ')
|
||||||
f.write(b' pass not found')
|
f.write(b' pass not found')
|
||||||
raise InvalidTrajectoryError("Trajectory doesn't go through path")
|
raise InvalidTrajectoryError("Trajectory doesn't go through path") # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
return 0
|
return 0 # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
def coursetime_first(data,paths,polygons=[],logfile=None):
|
def coursetime_first(data,paths,polygons=[],logfile=None):
|
||||||
@@ -97,7 +97,7 @@ def coursetime_first(data,paths,polygons=[],logfile=None):
|
|||||||
try:
|
try:
|
||||||
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max',name=polygons[0][1],logfile=logfile)
|
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max',name=polygons[0][1],logfile=logfile)
|
||||||
coursecompleted = True
|
coursecompleted = True
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError: # pragma: no cover
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
entrydistance = data['cum_dist'].max()
|
entrydistance = data['cum_dist'].max()
|
||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
@@ -113,8 +113,8 @@ def coursetime_paths(data,paths,finalmaxmin='min',polygons=[],logfile=None):
|
|||||||
polygons = [(0,str(i)) for i in range(len(paths))]
|
polygons = [(0,str(i)) for i in range(len(paths))]
|
||||||
|
|
||||||
# corner case - empty list of paths
|
# corner case - empty list of paths
|
||||||
if len(paths) == 0:
|
if len(paths) == 0: # pragma: no cover
|
||||||
return 0,True
|
return 0,0,True
|
||||||
|
|
||||||
# end - just the Finish polygon
|
# end - just the Finish polygon
|
||||||
if len(paths) == 1:
|
if len(paths) == 1:
|
||||||
@@ -124,7 +124,7 @@ def coursetime_paths(data,paths,finalmaxmin='min',polygons=[],logfile=None):
|
|||||||
entrydistance
|
entrydistance
|
||||||
) = time_in_path(data,paths[0],maxmin=finalmaxmin,name = polygons[0][1],logfile=logfile)
|
) = time_in_path(data,paths[0],maxmin=finalmaxmin,name = polygons[0][1],logfile=logfile)
|
||||||
coursecompleted = True
|
coursecompleted = True
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError: # pragma: no cover
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
entrydistance = data['cum_dist'].max()
|
entrydistance = data['cum_dist'].max()
|
||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
@@ -142,9 +142,9 @@ def coursetime_paths(data,paths,finalmaxmin='min',polygons=[],logfile=None):
|
|||||||
coursecompleted
|
coursecompleted
|
||||||
) = coursetime_paths(data,paths[1:],polygons=polygons[1:],logfile=logfile)
|
) = coursetime_paths(data,paths[1:],polygons=polygons[1:],logfile=logfile)
|
||||||
return time+timenext, dist+distnext,coursecompleted
|
return time+timenext, dist+distnext,coursecompleted
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError: # pragma: no cover
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
entrydistance = data['cum_dist'].max()
|
entrydistance = data['cum_dist'].max()
|
||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
|
|
||||||
return entrytime, entrydistance, coursecompleted
|
return entrytime, entrydistance, coursecompleted # pragma: no cover
|
||||||
|
|||||||
@@ -1210,7 +1210,7 @@ def fetchcp_new(rower,workouts):
|
|||||||
try:
|
try:
|
||||||
df = df[df['cp'] == df.groupby(['delta'])['cp'].transform('max')]
|
df = df[df['cp'] == df.groupby(['delta'])['cp'].transform('max')]
|
||||||
except KeyError: # pragma: no cover
|
except KeyError: # pragma: no cover
|
||||||
pd.Series(),pd.Series(),0,pd.Series(),pd.Series()
|
return pd.Series(),pd.Series(),0,pd.Series(),pd.Series()
|
||||||
|
|
||||||
|
|
||||||
df = df.sort_values(['delta']).reset_index()
|
df = df.sort_values(['delta']).reset_index()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ rpetotss = {
|
|||||||
10:140,
|
10:140,
|
||||||
}
|
}
|
||||||
|
|
||||||
def updatecp(delta,cpvalues,r,workouttype='water'):
|
def updatecp(delta,cpvalues,r,workouttype='water'): # pragma: no cover
|
||||||
if workouttype in otwtypes:
|
if workouttype in otwtypes:
|
||||||
p0 = r.p0
|
p0 = r.p0
|
||||||
p1 = r.p1
|
p1 = r.p1
|
||||||
@@ -88,7 +88,7 @@ def cpfit(powerdf,fraclimit=0.0001,nmax=1000):
|
|||||||
if len(thesecs)>=4:
|
if len(thesecs)>=4:
|
||||||
try:
|
try:
|
||||||
p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower))
|
p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower))
|
||||||
except:
|
except: # pragma: no cover
|
||||||
factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
|
factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
|
||||||
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
|
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ def getlogarr(maxt):
|
|||||||
for la in logarr:
|
for la in logarr:
|
||||||
try:
|
try:
|
||||||
v = 5+int(10.**(la))
|
v = 5+int(10.**(la))
|
||||||
except ValueError:
|
except ValueError: # pragma: no cover
|
||||||
v = 0
|
v = 0
|
||||||
res.append(v)
|
res.append(v)
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ def getlogarr(maxt):
|
|||||||
logarr = logarr.values
|
logarr = logarr.values
|
||||||
return logarr
|
return logarr
|
||||||
|
|
||||||
def getsinglecp(df):
|
def getsinglecp(df): # pragma: no cover
|
||||||
thesecs = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min()
|
thesecs = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min()
|
||||||
if thesecs != 0:
|
if thesecs != 0:
|
||||||
maxt = 1.05*thesecs
|
maxt = 1.05*thesecs
|
||||||
@@ -164,12 +164,12 @@ def getsinglecp(df):
|
|||||||
|
|
||||||
return delta,cpvalue,avgpower
|
return delta,cpvalue,avgpower
|
||||||
|
|
||||||
def getcp_new(dfgrouped,logarr):
|
def getcp_new(dfgrouped,logarr): # pragma: no cover
|
||||||
delta = []
|
delta = []
|
||||||
cpvalue = []
|
cpvalue = []
|
||||||
avgpower = {}
|
avgpower = {}
|
||||||
|
|
||||||
print(dfgrouped)
|
#print(dfgrouped)
|
||||||
|
|
||||||
|
|
||||||
for id, group in dfgrouped:
|
for id, group in dfgrouped:
|
||||||
@@ -307,7 +307,7 @@ def getcp(dfgrouped,logarr):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
avgpower[id] = int(ww.mean())
|
avgpower[id] = int(ww.mean())
|
||||||
except ValueError:
|
except ValueError: # pragma: no cover
|
||||||
avgpower[id] = '---'
|
avgpower[id] = '---'
|
||||||
if not np.isnan(ww.mean()):
|
if not np.isnan(ww.mean()):
|
||||||
length = len(ww)
|
length = len(ww)
|
||||||
@@ -375,7 +375,7 @@ def getmaxwattinterval(tt,ww,i):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
wmax = 0
|
wmax = 0
|
||||||
deltat = 0
|
deltat = 0
|
||||||
else:
|
else: # pragma: no cover
|
||||||
wmax = 0
|
wmax = 0
|
||||||
deltat = 0
|
deltat = 0
|
||||||
|
|
||||||
@@ -386,10 +386,10 @@ def getfastest(df,thevalue,mode='distance'):
|
|||||||
dd = df['cumdist'].copy()
|
dd = df['cumdist'].copy()
|
||||||
|
|
||||||
tmax = tt.max()
|
tmax = tt.max()
|
||||||
if mode == 'distance':
|
if mode == 'distance': # pragma: no cover
|
||||||
if dd.max() < thevalue:
|
if dd.max() < thevalue:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else: # pragma: no cover
|
||||||
if tt.max() < thevalue:
|
if tt.max() < thevalue:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ def getfastest(df,thevalue,mode='distance'):
|
|||||||
endtime = starttime+duration
|
endtime = starttime+duration
|
||||||
#print(duration,starttime,endtime,'aa')
|
#print(duration,starttime,endtime,'aa')
|
||||||
return duration[0]/1000.,starttime[0]/1000.,endtime[0]/1000.
|
return duration[0]/1000.,starttime[0]/1000.,endtime[0]/1000.
|
||||||
else:
|
else: # pragma: no cover
|
||||||
distance = griddata(restime,distance,[thevalue*60*1000],method='linear',rescale=True)
|
distance = griddata(restime,distance,[thevalue*60*1000],method='linear',rescale=True)
|
||||||
starttime = griddata(restime,starttimes,[thevalue*60*1000],method='linear',rescale=True)
|
starttime = griddata(restime,starttimes,[thevalue*60*1000],method='linear',rescale=True)
|
||||||
duration = griddata(restime,restime,[thevalue*60*1000],method='linear',rescale=True)
|
duration = griddata(restime,restime,[thevalue*60*1000],method='linear',rescale=True)
|
||||||
@@ -471,4 +471,4 @@ def getfastest(df,thevalue,mode='distance'):
|
|||||||
print(distance,starttime,endtime )
|
print(distance,starttime,endtime )
|
||||||
return distance[0],starttime[0]/1000.,endtime[0]/1000.
|
return distance[0],starttime[0]/1000.,endtime[0]/1000.
|
||||||
|
|
||||||
return 0
|
return 0 # pragma: no cover
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ TEST_CLIENT_SECRET = "aapnootmies"
|
|||||||
|
|
||||||
TEST_REDIRECT_URI = "http://localhost:8000/rowers/test_callback"
|
TEST_REDIRECT_URI = "http://localhost:8000/rowers/test_callback"
|
||||||
|
|
||||||
def custom_exception_handler(exc,message):
|
def custom_exception_handler(exc,message): # pragma: no cover
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
"errors": [
|
"errors": [
|
||||||
@@ -60,7 +60,7 @@ def custom_exception_handler(exc,message):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def do_refresh_token(refreshtoken):
|
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",
|
post_data = {"grant_type": "refresh_token",
|
||||||
"client_secret": TEST_CLIENT_SECRET,
|
"client_secret": TEST_CLIENT_SECRET,
|
||||||
@@ -88,7 +88,7 @@ def do_refresh_token(refreshtoken):
|
|||||||
return [thetoken,expires_in,refresh_token]
|
return [thetoken,expires_in,refresh_token]
|
||||||
|
|
||||||
|
|
||||||
def get_token(code):
|
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",
|
post_data = {"grant_type": "authorization_code",
|
||||||
"code": code,
|
"code": code,
|
||||||
@@ -114,7 +114,7 @@ def get_token(code):
|
|||||||
|
|
||||||
return [thetoken,expires_in,refresh_token]
|
return [thetoken,expires_in,refresh_token]
|
||||||
|
|
||||||
def make_authorization_url(request):
|
def make_authorization_url(request): # pragma: no cover
|
||||||
# Generate a random string for the state parameter
|
# Generate a random string for the state parameter
|
||||||
# Save it for use later to prevent xsrf attacks
|
# Save it for use later to prevent xsrf attacks
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
@@ -133,7 +133,7 @@ def make_authorization_url(request):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
def rower_ownapi_token_refresh(user):
|
def rower_ownapi_token_refresh(user): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
res = do_refresh_token(r.ownapirefreshtoken)
|
res = do_refresh_token(r.ownapirefreshtoken)
|
||||||
access_token = res[0]
|
access_token = res[0]
|
||||||
@@ -149,7 +149,7 @@ def rower_ownapi_token_refresh(user):
|
|||||||
r.save()
|
r.save()
|
||||||
return r.ownapitoken
|
return r.ownapitoken
|
||||||
|
|
||||||
def get_ownapi_workout_list(user):
|
def get_ownapi_workout_list(user): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.ownapitoken == '') or (r.ownapitoken is None):
|
if (r.ownapitoken == '') or (r.ownapitoken is None):
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
@@ -169,7 +169,7 @@ def get_ownapi_workout_list(user):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def get_ownapi_workout(user,ownapiid):
|
def get_ownapi_workout(user,ownapiid): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.ownapitoken == '') or (r.ownapitoken is None):
|
if (r.ownapitoken == '') or (r.ownapitoken is None):
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
@@ -188,7 +188,7 @@ def get_ownapi_workout(user,ownapiid):
|
|||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def createownapiworkoutdata(w):
|
def createownapiworkoutdata(w): # pragma: no cover
|
||||||
filename = w.csvfilename
|
filename = w.csvfilename
|
||||||
row = rowingdata(csvfile=filename)
|
row = rowingdata(csvfile=filename)
|
||||||
averagehr = int(row.df[' HRCur (bpm)'].mean())
|
averagehr = int(row.df[' HRCur (bpm)'].mean())
|
||||||
@@ -277,7 +277,7 @@ def createownapiworkoutdata(w):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getidfromresponse(response):
|
def getidfromresponse(response): # pragma: no cover
|
||||||
t = json.loads(response.text)
|
t = json.loads(response.text)
|
||||||
uri = t['uris'][0]
|
uri = t['uris'][0]
|
||||||
id = uri[len(uri)-13:len(uri)-5]
|
id = uri[len(uri)-13:len(uri)-5]
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ from rowers.utils import NoTokenError, custom_exception_handler
|
|||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
|
|
||||||
# Exchange access code for long-lived access token
|
# Exchange access code for long-lived access token
|
||||||
def get_token(code):
|
def get_token(code): # pragma: no cover
|
||||||
|
|
||||||
post_data = {"grant_type": "authorization_code",
|
post_data = {"grant_type": "authorization_code",
|
||||||
"code": code,
|
"code": code,
|
||||||
@@ -130,7 +130,7 @@ def get_polar_notifications():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
except ConnectionError:
|
except ConnectionError: # pragma: no cover
|
||||||
response = {
|
response = {
|
||||||
'status_code':400,
|
'status_code':400,
|
||||||
}
|
}
|
||||||
@@ -170,10 +170,10 @@ def get_polar_workouts(user):
|
|||||||
if (r.polartoken == '') or (r.polartoken is None):
|
if (r.polartoken == '') or (r.polartoken is None):
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
elif (timezone.now()>r.polartokenexpirydate):
|
elif (timezone.now()>r.polartokenexpirydate): # pragma: no cover
|
||||||
s = "Token expired. Needs to refresh"
|
s = "Token expired. Needs to refresh"
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
else:
|
else: # pragma: no cover
|
||||||
authorizationstring = str('Bearer ' + r.polartoken)
|
authorizationstring = str('Bearer ' + r.polartoken)
|
||||||
headers = {'Authorization':authorizationstring,
|
headers = {'Authorization':authorizationstring,
|
||||||
'Accept': 'application/json'}
|
'Accept': 'application/json'}
|
||||||
@@ -247,7 +247,7 @@ def get_polar_workouts(user):
|
|||||||
|
|
||||||
return exercise_list
|
return exercise_list
|
||||||
|
|
||||||
def get_polar_user_info(user,physical=False):
|
def get_polar_user_info(user,physical=False): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.polartoken == '') or (r.polartoken is None):
|
if (r.polartoken == '') or (r.polartoken is None):
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
@@ -285,7 +285,7 @@ def get_polar_user_info(user,physical=False):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def get_polar_workout(user,id,transactionid):
|
def get_polar_workout(user,id,transactionid): # pragma: no cover
|
||||||
|
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.polartoken == '') or (r.polartoken is None):
|
if (r.polartoken == '') or (r.polartoken is None):
|
||||||
|
|||||||
@@ -14,21 +14,21 @@ import uuid
|
|||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
def format_pace_tick(x,pos=None):
|
def format_pace_tick(x,pos=None): # pragma: no cover
|
||||||
minu=int(x/60)
|
minu=int(x/60)
|
||||||
sec=int(x-minu*60.)
|
sec=int(x-minu*60.)
|
||||||
sec_str=str(sec).zfill(2)
|
sec_str=str(sec).zfill(2)
|
||||||
template='%d:%s'
|
template='%d:%s'
|
||||||
return template % (minu,sec_str)
|
return template % (minu,sec_str)
|
||||||
|
|
||||||
def format_time_tick(x,pos=None):
|
def format_time_tick(x,pos=None): # pragma: no cover
|
||||||
hour=int(x/3600)
|
hour=int(x/3600)
|
||||||
min=int((x-hour*3600.)/60)
|
min=int((x-hour*3600.)/60)
|
||||||
min_str=str(min).zfill(2)
|
min_str=str(min).zfill(2)
|
||||||
template='%d:%s'
|
template='%d:%s'
|
||||||
return template % (hour,min_str)
|
return template % (hour,min_str)
|
||||||
|
|
||||||
def format_pace(x,pos=None):
|
def format_pace(x,pos=None): # pragma: no cover
|
||||||
if isinf(x) or isnan(x):
|
if isinf(x) or isnan(x):
|
||||||
x=0
|
x=0
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ def format_pace(x,pos=None):
|
|||||||
|
|
||||||
return str1
|
return str1
|
||||||
|
|
||||||
def format_time(x,pos=None):
|
def format_time(x,pos=None): # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
min = int(x/60.)
|
min = int(x/60.)
|
||||||
@@ -60,7 +60,7 @@ def validate_image_extension(value):
|
|||||||
ext = os.path.splitext(value.name)[1].lower()
|
ext = os.path.splitext(value.name)[1].lower()
|
||||||
valid_extension = ['.jpg','.jpeg','.png','.gif']
|
valid_extension = ['.jpg','.jpeg','.png','.gif']
|
||||||
|
|
||||||
if not ext in valid_extension:
|
if not ext in valid_extension: # pragma: no cover
|
||||||
raise ValidationError(u'File not supported')
|
raise ValidationError(u'File not supported')
|
||||||
|
|
||||||
def validate_file_extension(value):
|
def validate_file_extension(value):
|
||||||
@@ -69,25 +69,25 @@ def validate_file_extension(value):
|
|||||||
valid_extensions = ['.tcx','.csv','.TCX','.gpx','.GPX',
|
valid_extensions = ['.tcx','.csv','.TCX','.gpx','.GPX',
|
||||||
'.CSV','.fit','.FIT','.zip','.ZIP',
|
'.CSV','.fit','.FIT','.zip','.ZIP',
|
||||||
'.gz','.GZ','.xls']
|
'.gz','.GZ','.xls']
|
||||||
if not ext in valid_extensions:
|
if not ext in valid_extensions: # pragma: no cover
|
||||||
raise ValidationError(u'File not supported!')
|
raise ValidationError(u'File not supported!')
|
||||||
|
|
||||||
def must_be_csv(value):
|
def must_be_csv(value):
|
||||||
import os
|
import os
|
||||||
ext = os.path.splitext(value.name)[1]
|
ext = os.path.splitext(value.name)[1]
|
||||||
valid_extensions = ['.csv','.CSV']
|
valid_extensions = ['.csv','.CSV']
|
||||||
if not ext in valid_extensions:
|
if not ext in valid_extensions: # pragma: no cover
|
||||||
raise ValidationError(u'File not supported!')
|
raise ValidationError(u'File not supported!')
|
||||||
|
|
||||||
def validate_kml(value):
|
def validate_kml(value):
|
||||||
import os
|
import os
|
||||||
ext = os.path.splitext(value.name)[1]
|
ext = os.path.splitext(value.name)[1]
|
||||||
valid_extensions = ['.kml','.KML']
|
valid_extensions = ['.kml','.KML']
|
||||||
if not ext in valid_extensions:
|
if not ext in valid_extensions: # pragma: no cover
|
||||||
raise ValidationError(u'File not supported!')
|
raise ValidationError(u'File not supported!')
|
||||||
|
|
||||||
|
|
||||||
def handle_uploaded_image(i):
|
def handle_uploaded_image(i): # pragma: no cover
|
||||||
from io import StringIO, BytesIO
|
from io import StringIO, BytesIO
|
||||||
from PIL import Image, ImageOps, ExifTags
|
from PIL import Image, ImageOps, ExifTags
|
||||||
import os
|
import os
|
||||||
@@ -121,7 +121,7 @@ def handle_uploaded_image(i):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if exif[orientation] == 3:
|
if exif[orientation] == 3:
|
||||||
mage=image.rotate(180, expand=True)
|
image=image.rotate(180, expand=True)
|
||||||
elif exif[orientation] == 6:
|
elif exif[orientation] == 6:
|
||||||
image=image.rotate(270, expand=True)
|
image=image.rotate(270, expand=True)
|
||||||
elif exif[orientation] == 8:
|
elif exif[orientation] == 8:
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ def rp3_open(user):
|
|||||||
return imports_open(user, oauth_data)
|
return imports_open(user, oauth_data)
|
||||||
|
|
||||||
# Refresh ST token using refresh token
|
# Refresh ST token using refresh token
|
||||||
def do_refresh_token(refreshtoken):
|
def do_refresh_token(refreshtoken): # pragma: no cover
|
||||||
return imports_do_refresh_token(refreshtoken, oauth_data)
|
return imports_do_refresh_token(refreshtoken, oauth_data)
|
||||||
|
|
||||||
# Exchange access code for long-lived access token
|
# Exchange access code for long-lived access token
|
||||||
def get_token(code):
|
def get_token(code): # pragma: no cover
|
||||||
client_auth = requests.auth.HTTPBasicAuth(RP3_CLIENT_KEY, RP3_CLIENT_SECRET)
|
client_auth = requests.auth.HTTPBasicAuth(RP3_CLIENT_KEY, RP3_CLIENT_SECRET)
|
||||||
post_data = {
|
post_data = {
|
||||||
"client_id":RP3_CLIENT_KEY,
|
"client_id":RP3_CLIENT_KEY,
|
||||||
@@ -124,7 +124,7 @@ def get_rp3_workout_list(user):
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_rp3_workouts(rower,do_async=True):
|
def get_rp3_workouts(rower,do_async=True): # pragma: no cover
|
||||||
try:
|
try:
|
||||||
auth_token = rp3_open(rower.user)
|
auth_token = rp3_open(rower.user)
|
||||||
except NoTokenError:
|
except NoTokenError:
|
||||||
@@ -160,7 +160,7 @@ def get_rp3_workouts(rower,do_async=True):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def download_rp3_file(url,auth_token,filename):
|
def download_rp3_file(url,auth_token,filename): # pragma: no cover
|
||||||
headers = {'Authorization': 'Bearer ' + auth_token }
|
headers = {'Authorization': 'Bearer ' + auth_token }
|
||||||
|
|
||||||
res = requests.get(url,headers=headers)
|
res = requests.get(url,headers=headers)
|
||||||
@@ -171,7 +171,7 @@ def download_rp3_file(url,auth_token,filename):
|
|||||||
|
|
||||||
return res.status_code
|
return res.status_code
|
||||||
|
|
||||||
def get_rp3_workout_token(workout_id,auth_token,waittime=3,max_attempts=20):
|
def get_rp3_workout_token(workout_id,auth_token,waittime=3,max_attempts=20): # pragma: no cover
|
||||||
headers = {'Authorization': 'Bearer ' + auth_token }
|
headers = {'Authorization': 'Bearer ' + auth_token }
|
||||||
|
|
||||||
get_download_link = """{
|
get_download_link = """{
|
||||||
@@ -211,7 +211,7 @@ def get_rp3_workout_token(workout_id,auth_token,waittime=3,max_attempts=20):
|
|||||||
return download_url
|
return download_url
|
||||||
|
|
||||||
|
|
||||||
def get_rp3_workout_link(user,workout_id,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)
|
r = Rower.objects.get(user=user)
|
||||||
auth_token = rp3_open(user)
|
auth_token = rp3_open(user)
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class PlannedSessionSerializer(serializers.ModelSerializer):
|
|||||||
'fitfile'
|
'fitfile'
|
||||||
)
|
)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data): # pragma: no cover
|
||||||
if self.context['request'].user.is_authenticated:
|
if self.context['request'].user.is_authenticated:
|
||||||
r = Rower.objects.get(user=self.context['request'].user)
|
r = Rower.objects.get(user=self.context['request'].user)
|
||||||
else:
|
else:
|
||||||
@@ -206,7 +206,7 @@ class WorkoutSerializer(serializers.ModelSerializer):
|
|||||||
'rankingpiece'
|
'rankingpiece'
|
||||||
)
|
)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data): # pragma: no cover
|
||||||
if self.context['request'].user.is_authenticated:
|
if self.context['request'].user.is_authenticated:
|
||||||
r = Rower.objects.get(user=self.context['request'].user)
|
r = Rower.objects.get(user=self.context['request'].user)
|
||||||
else:
|
else:
|
||||||
@@ -263,7 +263,7 @@ class StrokeDataSerializer(serializers.Serializer):
|
|||||||
workoutid = serializers.IntegerField
|
workoutid = serializers.IntegerField
|
||||||
strokedata = serializers.JSONField
|
strokedata = serializers.JSONField
|
||||||
|
|
||||||
def create(self, workoutid, strokedata):
|
def create(self, workoutid, strokedata): # pragma: no cover
|
||||||
"""
|
"""
|
||||||
Create and enter a new set of stroke data into the DB
|
Create and enter a new set of stroke data into the DB
|
||||||
"""
|
"""
|
||||||
@@ -307,7 +307,7 @@ class GeoCourseSerializer(serializers.ModelSerializer):
|
|||||||
'polygons',
|
'polygons',
|
||||||
)
|
)
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data): # pragma: no cover
|
||||||
instance.name = validated_data.get('name',instance.name)
|
instance.name = validated_data.get('name',instance.name)
|
||||||
instance.country = validated_data.get('country',instance.country)
|
instance.country = validated_data.get('country',instance.country)
|
||||||
instance.notes = validated_data.get('notes',instance.notes)
|
instance.notes = validated_data.get('notes',instance.notes)
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ def get_token(code):
|
|||||||
return imports_get_token(code,oauth_data)
|
return imports_get_token(code,oauth_data)
|
||||||
|
|
||||||
# Make authorization URL including random string
|
# Make authorization URL including random string
|
||||||
def make_authorization_url(request):
|
def make_authorization_url(request): # pragma: no cover
|
||||||
return imports_make_authorization_url(oauth_data)
|
return imports_make_authorization_url(oauth_data)
|
||||||
|
|
||||||
# This is token refresh. Looks for tokens in our database, then refreshes
|
# This is token refresh. Looks for tokens in our database, then refreshes
|
||||||
def rower_sporttracks_token_refresh(user):
|
def rower_sporttracks_token_refresh(user): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
res = do_refresh_token(r.sporttracksrefreshtoken)
|
res = do_refresh_token(r.sporttracksrefreshtoken)
|
||||||
access_token = res[0]
|
access_token = res[0]
|
||||||
@@ -82,7 +82,7 @@ def get_sporttracks_workout_list(user):
|
|||||||
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
|
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
elif (timezone.now()>r.sporttrackstokenexpirydate):
|
elif (timezone.now()>r.sporttrackstokenexpirydate): # pragma: no cover
|
||||||
s = "Token expired. Needs to refresh."
|
s = "Token expired. Needs to refresh."
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
else:
|
else:
|
||||||
@@ -99,10 +99,10 @@ def get_sporttracks_workout_list(user):
|
|||||||
# Get workout summary data by SportTracks ID
|
# Get workout summary data by SportTracks ID
|
||||||
def get_workout(user,sporttracksid,do_async=False):
|
def get_workout(user,sporttracksid,do_async=False):
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
|
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None): # pragma: no cover
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
elif (timezone.now()>r.sporttrackstokenexpirydate):
|
elif (timezone.now()>r.sporttrackstokenexpirydate): # pragma: no cover
|
||||||
s = "Token expired. Needs to refresh."
|
s = "Token expired. Needs to refresh."
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
else:
|
else:
|
||||||
@@ -129,13 +129,13 @@ def createsporttracksworkoutdata(w):
|
|||||||
filename = w.csvfilename
|
filename = w.csvfilename
|
||||||
try:
|
try:
|
||||||
row = rowingdata(csvfile=filename)
|
row = rowingdata(csvfile=filename)
|
||||||
except:
|
except: # pragma: no cover
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
averagehr = int(row.df[' HRCur (bpm)'].mean())
|
averagehr = int(row.df[' HRCur (bpm)'].mean())
|
||||||
maxhr = int(row.df[' HRCur (bpm)'].max())
|
maxhr = int(row.df[' HRCur (bpm)'].max())
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
averagehr = 0
|
averagehr = 0
|
||||||
maxhr = 0
|
maxhr = 0
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ def createsporttracksworkoutdata(w):
|
|||||||
try:
|
try:
|
||||||
lat = row.df[' latitude'].values
|
lat = row.df[' latitude'].values
|
||||||
lon = row.df[' longitude'].values
|
lon = row.df[' longitude'].values
|
||||||
if not lat.std() and not lon.std():
|
if not lat.std() and not lon.std(): # pragma: no cover
|
||||||
haslatlon = 0
|
haslatlon = 0
|
||||||
except KeyError:
|
except KeyError:
|
||||||
haslatlon = 0
|
haslatlon = 0
|
||||||
@@ -171,7 +171,7 @@ def createsporttracksworkoutdata(w):
|
|||||||
haspower = 1
|
haspower = 1
|
||||||
try:
|
try:
|
||||||
power = row.df[' Power (watts)'].astype(int).values
|
power = row.df[' Power (watts)'].astype(int).values
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
haspower = 0
|
haspower = 0
|
||||||
|
|
||||||
locdata = []
|
locdata = []
|
||||||
@@ -259,13 +259,13 @@ def getidfromresponse(response):
|
|||||||
|
|
||||||
return int(id)
|
return int(id)
|
||||||
|
|
||||||
def default(o):
|
def default(o): # pragma: no cover
|
||||||
if isinstance(o, numpy.int64): return int(o)
|
if isinstance(o, numpy.int64): return int(o)
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def workout_sporttracks_upload(user,w,asynchron=False):
|
def workout_sporttracks_upload(user,w,asynchron=False): # pragma: no cover
|
||||||
message = "Uploading to SportTracks"
|
message = "Uploading to SportTracks"
|
||||||
stid = 0
|
stid = 0
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
@@ -325,7 +325,7 @@ def add_workout_from_data(user,importid,data,strokedata,source='sporttracks',
|
|||||||
workoutsource='sporttracks'):
|
workoutsource='sporttracks'):
|
||||||
try:
|
try:
|
||||||
workouttype = data['type']
|
workouttype = data['type']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
workouttype = 'other'
|
workouttype = 'other'
|
||||||
|
|
||||||
if workouttype not in [x[0] for x in Workout.workouttypes]:
|
if workouttype not in [x[0] for x in Workout.workouttypes]:
|
||||||
@@ -339,7 +339,7 @@ def add_workout_from_data(user,importid,data,strokedata,source='sporttracks',
|
|||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
try:
|
try:
|
||||||
rowdatetime = iso8601.parse_date(data['start_time'])
|
rowdatetime = iso8601.parse_date(data['start_time'])
|
||||||
except iso8601.ParseError:
|
except iso8601.ParseError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
rowdatetime = datetime.datetime.strptime(data['start_time'],"%Y-%m-%d %H:%M:%S")
|
rowdatetime = datetime.datetime.strptime(data['start_time'],"%Y-%m-%d %H:%M:%S")
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
||||||
@@ -354,14 +354,14 @@ def add_workout_from_data(user,importid,data,strokedata,source='sporttracks',
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
title = data['name']
|
title = data['name']
|
||||||
except:
|
except: # pragma: no cover
|
||||||
title = "Imported data"
|
title = "Imported data"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = splitstdata(data['distance'])
|
res = splitstdata(data['distance'])
|
||||||
distance = res[1]
|
distance = res[1]
|
||||||
times_distance = res[0]
|
times_distance = res[0]
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
res = splitstdata(data['heartrate'])
|
res = splitstdata(data['heartrate'])
|
||||||
times_distance = res[0]
|
times_distance = res[0]
|
||||||
@@ -388,14 +388,14 @@ def add_workout_from_data(user,importid,data,strokedata,source='sporttracks',
|
|||||||
times_location = times_distance
|
times_location = times_distance
|
||||||
latcoord = np.zeros(len(times_distance))
|
latcoord = np.zeros(len(times_distance))
|
||||||
loncoord = np.zeros(len(times_distance))
|
loncoord = np.zeros(len(times_distance))
|
||||||
if workouttype in mytypes.otwtypes:
|
if workouttype in mytypes.otwtypes: # pragma: no cover
|
||||||
workouttype = 'rower'
|
workouttype = 'rower'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = splitstdata(data['cadence'])
|
res = splitstdata(data['cadence'])
|
||||||
times_spm = res[0]
|
times_spm = res[0]
|
||||||
spm = res[1]
|
spm = res[1]
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
times_spm = times_distance
|
times_spm = times_distance
|
||||||
spm = 0*times_distance
|
spm = 0*times_distance
|
||||||
|
|
||||||
|
|||||||
@@ -533,7 +533,7 @@
|
|||||||
"time": [3200, 6700, 10099],
|
"time": [3200, 6700, 10099],
|
||||||
"spm": [16.4, 21.2, 19.8],
|
"spm": [16.4, 21.2, 19.8],
|
||||||
"pace": [155068, 144402, 138830],
|
"pace": [155068, 144402, 138830],
|
||||||
"power": [84,6, 117.2, 141.3],
|
"power": [84.6, 117.2, 141.3],
|
||||||
"hr": [85, 91, 95]
|
"hr": [85, 91, 95]
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
@@ -586,7 +586,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>GET, POST</td>
|
<td>GET, POST</td>
|
||||||
<td>
|
<td>
|
||||||
<pre>[
|
<pre>{
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
"time": 3200.0000476837,
|
"time": 3200.0000476837,
|
||||||
@@ -613,7 +613,7 @@
|
|||||||
"spm": 19.8095238095
|
"spm": 19.8095238095
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
}
|
||||||
</pre>
|
</pre>
|
||||||
You can only post stroke data to an existing workout with
|
You can only post stroke data to an existing workout with
|
||||||
workout number {id}. If the workout already has stroke data, you
|
workout number {id}. If the workout already has stroke data, you
|
||||||
|
|||||||
185
rowers/tests/test_api.py
Normal file
185
rowers/tests/test_api.py
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
#from __future__ import print_function
|
||||||
|
from .statements import *
|
||||||
|
nu = datetime.datetime.now()
|
||||||
|
|
||||||
|
|
||||||
|
import rowers
|
||||||
|
from rowers import dataprep
|
||||||
|
from rowers import tasks
|
||||||
|
from rowers import c2stuff
|
||||||
|
from rowers import stravastuff
|
||||||
|
import urllib
|
||||||
|
import json
|
||||||
|
import pandas as pd
|
||||||
|
from rowers.opaque import encoder
|
||||||
|
|
||||||
|
from rest_framework.test import APIRequestFactory, force_authenticate
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from rowers.ownapistuff import *
|
||||||
|
from rowers.views.apiviews import *
|
||||||
|
|
||||||
|
class OwnApi(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.u = UserFactory()
|
||||||
|
|
||||||
|
self.r = Rower.objects.create(user=self.u,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach',subscription_id=1)
|
||||||
|
|
||||||
|
workoutsbox = Mailbox.objects.create(name='workouts')
|
||||||
|
workoutsbox.save()
|
||||||
|
failbox = Mailbox.objects.create(name='Failed')
|
||||||
|
failbox.save()
|
||||||
|
|
||||||
|
self.c = Client()
|
||||||
|
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
|
||||||
|
self.factory = RequestFactory()
|
||||||
|
self.password = faker.word()
|
||||||
|
self.u.set_password(self.password)
|
||||||
|
self.u.save()
|
||||||
|
|
||||||
|
self.factory = APIRequestFactory()
|
||||||
|
|
||||||
|
|
||||||
|
def test_strokedataform(self):
|
||||||
|
login = self.c.login(username=self.u.username, password=self.password)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
w = self.user_workouts[0]
|
||||||
|
|
||||||
|
url = reverse('strokedataform',kwargs={'id':encoder.encode_hex(w.id)})
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
url = reverse('strokedatajson',kwargs={'id':w.id})
|
||||||
|
|
||||||
|
request = self.factory.get(url)
|
||||||
|
request.user = self.u
|
||||||
|
force_authenticate(request, user=self.u)
|
||||||
|
response = strokedatajson(request,id=w.id)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
# response must be json
|
||||||
|
strokedata = json.loads(response.content)
|
||||||
|
df = pd.DataFrame(strokedata)
|
||||||
|
self.assertFalse(df.empty)
|
||||||
|
|
||||||
|
form_data = {
|
||||||
|
"distance": [23, 46, 48],
|
||||||
|
"time": [3200, 6700, 10099],
|
||||||
|
"spm": [16.4, 21.2, 19.8],
|
||||||
|
"pace": [155068, 144402, 138830],
|
||||||
|
"power": [84.6, 117.2, 141.3],
|
||||||
|
"hr": [85, 91, 95]
|
||||||
|
}
|
||||||
|
|
||||||
|
result = get_random_file(filename='rowers/tests/testdata/thyro.csv')
|
||||||
|
w2 = Workout.objects.create(
|
||||||
|
user=self.r,
|
||||||
|
csvfilename=result['filename'],
|
||||||
|
duration=result['duration'],
|
||||||
|
startdatetime=result['startdatetime'],
|
||||||
|
workouttype='water',
|
||||||
|
starttime=result['starttime'],
|
||||||
|
)
|
||||||
|
|
||||||
|
url = reverse('strokedatajson',kwargs={'id':w2.id})
|
||||||
|
|
||||||
|
request = self.factory.post(url,{'strokedata':form_data},format='json')
|
||||||
|
request.user = self.u
|
||||||
|
request.data = json.dumps({'strokedata':form_data})
|
||||||
|
strokedata = json.loads(request.data)['strokedata']
|
||||||
|
|
||||||
|
force_authenticate(request, user=self.u)
|
||||||
|
with patch('rowers.dataprep.getrowdata_db') as mock_getrowdata:
|
||||||
|
mock_getrowdata.return_value = (pd.DataFrame(),None)
|
||||||
|
response = strokedatajson(request,id=w.id)
|
||||||
|
self.assertEqual(response.status_code,201)
|
||||||
|
|
||||||
|
def test_strokedataform_v2(self):
|
||||||
|
login = self.c.login(username=self.u.username, password=self.password)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
w = self.user_workouts[0]
|
||||||
|
|
||||||
|
url = reverse('strokedataform_v2',kwargs={'id':encoder.encode_hex(w.id)})
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
url = reverse('strokedatajson_v2',kwargs={'id':w.id})
|
||||||
|
|
||||||
|
request = self.factory.get(url)
|
||||||
|
request.user = self.u
|
||||||
|
force_authenticate(request, user=self.u)
|
||||||
|
response = strokedatajson_v2(request,id=w.id)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
# response must be json
|
||||||
|
strokedata = json.loads(response.content)
|
||||||
|
df = pd.DataFrame(strokedata)
|
||||||
|
self.assertFalse(df.empty)
|
||||||
|
|
||||||
|
|
||||||
|
form_data = {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"time": 3200.0000476837,
|
||||||
|
"pace": 155068.4885951763,
|
||||||
|
"hr": 85.7857142857,
|
||||||
|
"power": 84.6531131591,
|
||||||
|
"distance": 23,
|
||||||
|
"spm": 16.380952381
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 6700.0000476837,
|
||||||
|
"pace" : 144402.6407586741,
|
||||||
|
"hr": 91.2142857143,
|
||||||
|
"power": 117.458827834,
|
||||||
|
"distance": 36,
|
||||||
|
"spm": 21.1666666667
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 10099.9999046326,
|
||||||
|
"pace": 138830.8712654931,
|
||||||
|
"hr": 95.7142857143,
|
||||||
|
"power": 141.31057207,
|
||||||
|
"distance": 48,
|
||||||
|
"spm": 19.8095238095
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result = get_random_file(filename='rowers/tests/testdata/thyro.csv')
|
||||||
|
w2 = Workout.objects.create(
|
||||||
|
user=self.r,
|
||||||
|
csvfilename=result['filename'],
|
||||||
|
duration=result['duration'],
|
||||||
|
startdatetime=result['startdatetime'],
|
||||||
|
workouttype='water',
|
||||||
|
starttime=result['starttime'],
|
||||||
|
)
|
||||||
|
|
||||||
|
url = reverse('strokedatajson_v2',kwargs={'id':w2.id})
|
||||||
|
|
||||||
|
request = self.factory.post(url,form_data,format='json')
|
||||||
|
request.user = self.u
|
||||||
|
request.data = json.dumps(form_data)
|
||||||
|
|
||||||
|
force_authenticate(request, user=self.u)
|
||||||
|
with patch('rowers.dataprep.getrowdata_db') as mock_getrowdata:
|
||||||
|
mock_getrowdata.return_value = (pd.DataFrame(),None)
|
||||||
|
response = strokedatajson_v2(request,id=w.id)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
@@ -4,6 +4,122 @@ from __future__ import print_function
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .statements import *
|
from .statements import *
|
||||||
|
import rowers.courses as courses
|
||||||
|
import rowers.dataprep as dataprep
|
||||||
|
from rowers.courseutils import *
|
||||||
|
from rowingdata import rowingdata as rdata
|
||||||
|
from rowers.models import polygon_to_path
|
||||||
|
|
||||||
|
class CourseUnitTest(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Client()
|
||||||
|
self.u = User.objects.create_user('john',
|
||||||
|
'sander@ds.ds',
|
||||||
|
'koeinsloot')
|
||||||
|
self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach',
|
||||||
|
)
|
||||||
|
self.nu = datetime.datetime.now()
|
||||||
|
|
||||||
|
cs = courses.kmltocourse('rowers/tests/testdata/thyro.kml')
|
||||||
|
course = cs[0]
|
||||||
|
cname = course['name']
|
||||||
|
cnotes = course['description']
|
||||||
|
self.polygons = course['polygons']
|
||||||
|
pstart = self.polygons[0]
|
||||||
|
self.ThyroBaantje = courses.createcourse(self.r,cname,self.polygons,notes=cnotes)
|
||||||
|
self.start = GeoPolygon.objects.filter(course=self.ThyroBaantje,order_in_course=0)[0]
|
||||||
|
self.ThyroBaantje.save()
|
||||||
|
|
||||||
|
result = get_random_file(filename='rowers/tests/testdata/thyro.csv')
|
||||||
|
self.wthyro = WorkoutFactory(user=self.r,
|
||||||
|
csvfilename=result['filename'],
|
||||||
|
starttime=result['starttime'],
|
||||||
|
startdatetime=result['startdatetime'],
|
||||||
|
duration=result['duration'],
|
||||||
|
distance=result['totaldist'],
|
||||||
|
workouttype = 'water',
|
||||||
|
)
|
||||||
|
|
||||||
|
self.wthyro.startdatetime = arrow.get(self.nu).datetime
|
||||||
|
self.wthyro.date = self.nu.date()
|
||||||
|
self.wthyro.save()
|
||||||
|
|
||||||
|
def test_time_in_path(self):
|
||||||
|
row = rdata(csvfile='rowers/tests/testdata/thyro.csv')
|
||||||
|
|
||||||
|
time = row.df['TimeStamp (sec)']
|
||||||
|
lat = row.df[' latitude']
|
||||||
|
lon = row.df[' longitude']
|
||||||
|
cum_dist = row.df['cum_dist']
|
||||||
|
|
||||||
|
data = pd.DataFrame(
|
||||||
|
{
|
||||||
|
'time':time,
|
||||||
|
'latitude':lat,
|
||||||
|
'longitude':lon,
|
||||||
|
'cum_dist':cum_dist,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
startpath = polygon_to_path(self.start)
|
||||||
|
|
||||||
|
mintime,mindist = time_in_path(data,startpath)
|
||||||
|
self.assertEqual(mintime,78)
|
||||||
|
self.assertEqual(mindist,207.1)
|
||||||
|
|
||||||
|
def test_coursetime_first(self):
|
||||||
|
row = rdata(csvfile='rowers/tests/testdata/thyro.csv')
|
||||||
|
|
||||||
|
time = row.df['TimeStamp (sec)']
|
||||||
|
lat = row.df[' latitude']
|
||||||
|
lon = row.df[' longitude']
|
||||||
|
cum_dist = row.df['cum_dist']
|
||||||
|
|
||||||
|
data = pd.DataFrame(
|
||||||
|
{
|
||||||
|
'time':time,
|
||||||
|
'latitude':lat,
|
||||||
|
'longitude':lon,
|
||||||
|
'cum_dist':cum_dist,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
paths = []
|
||||||
|
polygons = GeoPolygon.objects.filter(course=self.ThyroBaantje).order_by("order_in_course")
|
||||||
|
for p in polygons:
|
||||||
|
paths.append(polygon_to_path(p))
|
||||||
|
|
||||||
|
entrytime,entrydistance,coursecompleted = coursetime_first(data,paths)
|
||||||
|
self.assertEqual(entrytime,78)
|
||||||
|
self.assertEqual(entrydistance,207.1)
|
||||||
|
self.assertTrue(coursecompleted)
|
||||||
|
|
||||||
|
def test_coursetime_paths(self):
|
||||||
|
row = rdata(csvfile='rowers/tests/testdata/thyro.csv')
|
||||||
|
|
||||||
|
time = row.df['TimeStamp (sec)']
|
||||||
|
lat = row.df[' latitude']
|
||||||
|
lon = row.df[' longitude']
|
||||||
|
cum_dist = row.df['cum_dist']
|
||||||
|
|
||||||
|
data = pd.DataFrame(
|
||||||
|
{
|
||||||
|
'time':time,
|
||||||
|
'latitude':lat,
|
||||||
|
'longitude':lon,
|
||||||
|
'cum_dist':cum_dist,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
paths = []
|
||||||
|
polygons = GeoPolygon.objects.filter(course=self.ThyroBaantje).order_by("order_in_course")
|
||||||
|
for p in polygons:
|
||||||
|
paths.append(polygon_to_path(p))
|
||||||
|
|
||||||
|
entrytime,entrydistance,coursecompleted = coursetime_paths(data,paths)
|
||||||
|
self.assertEqual(entrytime,435)
|
||||||
|
self.assertEqual(entrydistance,1348.8)
|
||||||
|
self.assertTrue(coursecompleted)
|
||||||
|
|
||||||
class CoursesTest(TestCase):
|
class CoursesTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
1081
rowers/tests/testdata/thyro2.csv
vendored
Normal file
1081
rowers/tests/testdata/thyro2.csv
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@ def get_token(code):
|
|||||||
|
|
||||||
# Make authorization URL including random string
|
# Make authorization URL including random string
|
||||||
def make_authorization_url(request):
|
def make_authorization_url(request):
|
||||||
return imports_make_authorization_url(oauth_data)
|
return imports_make_authorization_url(oauth_data) # pragma: no cover
|
||||||
|
|
||||||
# Get list of workouts available on Underarmour
|
# Get list of workouts available on Underarmour
|
||||||
def get_underarmour_workout_list(user):
|
def get_underarmour_workout_list(user):
|
||||||
@@ -72,7 +72,7 @@ def get_underarmour_workout_list(user):
|
|||||||
# Get workout summary data by Underarmour ID
|
# Get workout summary data by Underarmour ID
|
||||||
def get_workout(user,underarmourid,do_async=False):
|
def get_workout(user,underarmourid,do_async=False):
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
if (r.underarmourtoken == '') or (r.underarmourtoken is None):
|
if (r.underarmourtoken == '') or (r.underarmourtoken is None): # pragma: no cover
|
||||||
return custom_exception_handler(401,s)
|
return custom_exception_handler(401,s)
|
||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
else:
|
else:
|
||||||
@@ -99,7 +99,7 @@ def createunderarmourworkoutdata(w):
|
|||||||
filename = w.csvfilename
|
filename = w.csvfilename
|
||||||
try:
|
try:
|
||||||
row = rowingdata(csvfile=filename)
|
row = rowingdata(csvfile=filename)
|
||||||
except:
|
except: # pragma: no cover
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
st = w.startdatetime.astimezone(pytz.timezone(w.timezone))
|
st = w.startdatetime.astimezone(pytz.timezone(w.timezone))
|
||||||
@@ -151,7 +151,7 @@ def createunderarmourworkoutdata(w):
|
|||||||
|
|
||||||
haslatlon=1
|
haslatlon=1
|
||||||
|
|
||||||
try:
|
try: # pragma: no cover
|
||||||
lat = row.df[' latitude']
|
lat = row.df[' latitude']
|
||||||
lon = row.df[' longitude']
|
lon = row.df[' longitude']
|
||||||
if not lat.std() and not lon.std():
|
if not lat.std() and not lon.std():
|
||||||
@@ -161,7 +161,7 @@ def createunderarmourworkoutdata(w):
|
|||||||
|
|
||||||
|
|
||||||
# path data
|
# path data
|
||||||
if haslatlon:
|
if haslatlon: # pragma: no cover
|
||||||
locdata = []
|
locdata = []
|
||||||
for e in zip(t,lat.values,lon.values):
|
for e in zip(t,lat.values,lon.values):
|
||||||
point = {
|
point = {
|
||||||
@@ -248,7 +248,7 @@ def getidfromresponse(response):
|
|||||||
|
|
||||||
return int(id)
|
return int(id)
|
||||||
|
|
||||||
def refresh_ua_actlist(user):
|
def refresh_ua_actlist(user): # pragma: no cover
|
||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
authorizationstring = str('Bearer ' + r.underarmourtoken)
|
authorizationstring = str('Bearer ' + r.underarmourtoken)
|
||||||
headers = {'Authorization': authorizationstring,
|
headers = {'Authorization': authorizationstring,
|
||||||
@@ -312,17 +312,17 @@ def get_userid(access_token):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
res = me_json['id']
|
res = me_json['id']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
res = 0
|
res = 0
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def default(o):
|
def default(o): # pragma: no cover
|
||||||
if isinstance(o, numpy.int64): return int(o)
|
if isinstance(o, numpy.int64): return int(o)
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
|
|
||||||
def workout_ua_upload(user,w):
|
def workout_ua_upload(user,w): # pragma: no cover
|
||||||
message = "Uploading to MapMyFitness"
|
message = "Uploading to MapMyFitness"
|
||||||
uaid = 0
|
uaid = 0
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
comments = data['notes']
|
comments = data['notes']
|
||||||
except:
|
except: # pragma: no cover
|
||||||
comments = ''
|
comments = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -394,7 +394,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
try:
|
try:
|
||||||
rowdatetime = iso8601.parse_date(data['start_datetime'])
|
rowdatetime = iso8601.parse_date(data['start_datetime'])
|
||||||
except iso8601.ParseError:
|
except iso8601.ParseError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
rowdatetime = datetime.strptime(data['start_datetime'],"%Y-%m-%d %H:%M:%S")
|
rowdatetime = datetime.strptime(data['start_datetime'],"%Y-%m-%d %H:%M:%S")
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
||||||
@@ -410,7 +410,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
title = data['name']
|
title = data['name']
|
||||||
except:
|
except: # pragma: no cover
|
||||||
title = "Imported data"
|
title = "Imported data"
|
||||||
|
|
||||||
timeseries = data['time_series']
|
timeseries = data['time_series']
|
||||||
@@ -421,7 +421,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
res = splituadata(timeseries['distance'])
|
res = splituadata(timeseries['distance'])
|
||||||
distance = res[1]
|
distance = res[1]
|
||||||
times_distance = res[0]
|
times_distance = res[0]
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
message = "Error. No distance data"
|
message = "Error. No distance data"
|
||||||
return (0,message)
|
return (0,message)
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
lon = coord['lng']
|
lon = coord['lng']
|
||||||
latcoord.append(lat)
|
latcoord.append(lat)
|
||||||
loncoord.append(lon)
|
loncoord.append(lon)
|
||||||
except:
|
except: # pragma: no cover
|
||||||
times_location = times_distance
|
times_location = times_distance
|
||||||
latcoord = np.zeros(len(times_distance))
|
latcoord = np.zeros(len(times_distance))
|
||||||
loncoord = np.zeros(len(times_distance))
|
loncoord = np.zeros(len(times_distance))
|
||||||
@@ -451,7 +451,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
res = splituadata(timeseries['cadence'])
|
res = splituadata(timeseries['cadence'])
|
||||||
times_spm = res[0]
|
times_spm = res[0]
|
||||||
spm = res[1]
|
spm = res[1]
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
times_spm = times_distance
|
times_spm = times_distance
|
||||||
spm = 0*times_distance
|
spm = 0*times_distance
|
||||||
|
|
||||||
@@ -459,7 +459,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
|||||||
res = splituadata(timeseries['heartrate'])
|
res = splituadata(timeseries['heartrate'])
|
||||||
hr = res[1]
|
hr = res[1]
|
||||||
times_hr = res[0]
|
times_hr = res[0]
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
times_hr = times_distance
|
times_hr = times_distance
|
||||||
hr = 0*times_distance
|
hr = 0*times_distance
|
||||||
|
|
||||||
|
|||||||
@@ -234,8 +234,10 @@ urlpatterns = [
|
|||||||
re_path(r'^', include(router.urls)),
|
re_path(r'^', include(router.urls)),
|
||||||
re_path(r'^api-docs/$', views.schema_view,name='schema_view'),
|
re_path(r'^api-docs/$', views.schema_view,name='schema_view'),
|
||||||
re_path(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
re_path(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||||
re_path(r'^api/workouts/(?P<id>\b[0-9A-Fa-f]+\b)/strokedata/$',views.strokedatajson,name='strokedatajson'),
|
re_path(r'^api/workouts/(?P<id>\b[0-9A-Fa-f]+\b)/strokedata/$',views.strokedatajson,
|
||||||
re_path(r'^api/v2/workouts/(?P<id>\b[0-9A-Fa-f]+\b)/strokedata/$',views.strokedatajson_v2,name='strokedatajson_v2'),
|
name='strokedatajson'),
|
||||||
|
re_path(r'^api/v2/workouts/(?P<id>\b[0-9A-Fa-f]+\b)/strokedata/$',views.strokedatajson_v2,
|
||||||
|
name='strokedatajson_v2'),
|
||||||
re_path(r'^500v/$',views.error500_view,name='error500_view'),
|
re_path(r'^500v/$',views.error500_view,name='error500_view'),
|
||||||
path('502/', TemplateView.as_view(template_name='502.html'),name='502'),
|
path('502/', TemplateView.as_view(template_name='502.html'),name='502'),
|
||||||
path('500/', TemplateView.as_view(template_name='500.html'),name='500'),
|
path('500/', TemplateView.as_view(template_name='500.html'),name='500'),
|
||||||
@@ -714,8 +716,10 @@ urlpatterns = [
|
|||||||
re_path(r'^edittarget/(?P<pk>\d+)/$',login_required(
|
re_path(r'^edittarget/(?P<pk>\d+)/$',login_required(
|
||||||
views.TrainingTargetUpdate.as_view()),
|
views.TrainingTargetUpdate.as_view()),
|
||||||
name='trainingtarget_update_view'),
|
name='trainingtarget_update_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/test\_strokedata/$',views.strokedataform),
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/test\_strokedata/$',views.strokedataform,
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/v2/test\_strokedata/$',views.strokedataform_v2),
|
name='strokedataform'),
|
||||||
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/v2/test\_strokedata/$',views.strokedataform_v2,
|
||||||
|
name='strokedataform_v2'),
|
||||||
re_path(r'^sessions/library/$',views.template_library_view,name="template_library_view"),
|
re_path(r'^sessions/library/$',views.template_library_view,name="template_library_view"),
|
||||||
re_path(r'^sessions/teamcreate/user/(?P<userid>\d+)/$',views.plannedsession_teamcreate_view,
|
re_path(r'^sessions/teamcreate/user/(?P<userid>\d+)/$',views.plannedsession_teamcreate_view,
|
||||||
name='plannedsession_teamcreate_view'),
|
name='plannedsession_teamcreate_view'),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
from rowers.tasks import handle_calctrimp
|
from rowers.tasks import handle_calctrimp
|
||||||
from rowers.mailprocessing import send_confirm
|
from rowers.mailprocessing import send_confirm
|
||||||
|
from rowers.opaque import encoder
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import arrow
|
import arrow
|
||||||
@@ -14,14 +15,11 @@ import arrow
|
|||||||
@login_required()
|
@login_required()
|
||||||
def strokedataform(request,id=0):
|
def strokedataform(request,id=0):
|
||||||
|
|
||||||
try:
|
id = encoder.decode_hex(id)
|
||||||
id=int(id)
|
|
||||||
except ValueError:
|
|
||||||
id = 0
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
w = Workout.objects.get(id=id)
|
w = Workout.objects.get(id=id)
|
||||||
except Workout.DoesNotExist:
|
except Workout.DoesNotExist: # pragma: no cover
|
||||||
raise Http404("Workout doesn't exist")
|
raise Http404("Workout doesn't exist")
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
@@ -33,7 +31,7 @@ def strokedataform(request,id=0):
|
|||||||
'id':id,
|
'id':id,
|
||||||
'workout':w,
|
'workout':w,
|
||||||
})
|
})
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST': # pragma: no cover
|
||||||
form = StrokeDataForm()
|
form = StrokeDataForm()
|
||||||
|
|
||||||
return render(request, 'strokedata_form.html',
|
return render(request, 'strokedata_form.html',
|
||||||
@@ -42,19 +40,17 @@ def strokedataform(request,id=0):
|
|||||||
'teams':get_my_teams(request.user),
|
'teams':get_my_teams(request.user),
|
||||||
'id':id,
|
'id':id,
|
||||||
'workout':w,
|
'workout':w,
|
||||||
})
|
}) # pragma: no cover
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def strokedataform_v2(request,id=0):
|
def strokedataform_v2(request,id=0):
|
||||||
|
|
||||||
try:
|
id = encoder.decode_hex(id)
|
||||||
id=int(id)
|
|
||||||
except ValueError:
|
|
||||||
id = 0
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
w = Workout.objects.get(id=id)
|
w = Workout.objects.get(id=id)
|
||||||
except Workout.DoesNotExist:
|
except Workout.DoesNotExist: # pragma: no cover
|
||||||
raise Http404("Workout doesn't exist")
|
raise Http404("Workout doesn't exist")
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
@@ -66,7 +62,7 @@ def strokedataform_v2(request,id=0):
|
|||||||
'id':id,
|
'id':id,
|
||||||
'workout':w,
|
'workout':w,
|
||||||
})
|
})
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST': # pragma: no cover
|
||||||
form = StrokeDataForm()
|
form = StrokeDataForm()
|
||||||
|
|
||||||
return render(request, 'strokedata_form_v2.html',
|
return render(request, 'strokedata_form_v2.html',
|
||||||
@@ -95,7 +91,7 @@ def strokedatajson_v2(request,id):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
row = get_object_or_404(Workout,pk=id)
|
row = get_object_or_404(Workout,pk=id)
|
||||||
if row.user != request.user.rower:
|
if row.user != request.user.rower: # pragma: no cover
|
||||||
return HttpResponse("You do not have permission to perform this action",status=403)
|
return HttpResponse("You do not have permission to perform this action",status=403)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -124,7 +120,7 @@ def strokedatajson_v2(request,id):
|
|||||||
for d in request.data['data']:
|
for d in request.data['data']:
|
||||||
logfile.write(json.dumps(d))
|
logfile.write(json.dumps(d))
|
||||||
logfile.write("\n")
|
logfile.write("\n")
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
for d in request.data['strokedata']:
|
for d in request.data['strokedata']:
|
||||||
logfile.write(json.dumps(d))
|
logfile.write(json.dumps(d))
|
||||||
@@ -134,14 +130,14 @@ def strokedatajson_v2(request,id):
|
|||||||
except (AttributeError,TypeError):
|
except (AttributeError,TypeError):
|
||||||
logfile.write("No data in request\n")
|
logfile.write("No data in request\n")
|
||||||
checkdata, r = dataprep.getrowdata_db(id=row.id)
|
checkdata, r = dataprep.getrowdata_db(id=row.id)
|
||||||
if not checkdata.empty:
|
if not checkdata.empty: # pragma: no cover
|
||||||
return HttpResponse("Duplicate Error",status=409)
|
return HttpResponse("Duplicate Error",status=409)
|
||||||
|
|
||||||
df = pd.DataFrame()
|
df = pd.DataFrame()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
df = pd.DataFrame(request.data['data'])
|
df = pd.DataFrame(request.data['data'])
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
df = pd.DataFrame(request.data['strokedata'])
|
df = pd.DataFrame(request.data['strokedata'])
|
||||||
except:
|
except:
|
||||||
@@ -154,7 +150,7 @@ def strokedatajson_v2(request,id):
|
|||||||
#time, pace, distance,spm
|
#time, pace, distance,spm
|
||||||
try:
|
try:
|
||||||
time = df['time']/1.e3
|
time = df['time']/1.e3
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
time = df['t']/10.
|
time = df['t']/10.
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -162,12 +158,12 @@ def strokedatajson_v2(request,id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
spm = df['spm']
|
spm = df['spm']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
return HttpResponse("Missing spm",status=400)
|
return HttpResponse("Missing spm",status=400)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
distance = df['distance']
|
distance = df['distance']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
distance = df['d']/10.
|
distance = df['d']/10.
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -175,7 +171,7 @@ def strokedatajson_v2(request,id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
pace = df['pace']/1.e3
|
pace = df['pace']/1.e3
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
try:
|
try:
|
||||||
pace = df['p']/10.
|
pace = df['p']/10.
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -185,7 +181,7 @@ def strokedatajson_v2(request,id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
power = df['power']
|
power = df['power']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
power = 0*time
|
power = 0*time
|
||||||
try:
|
try:
|
||||||
drivelength = df['drivelength']
|
drivelength = df['drivelength']
|
||||||
@@ -245,7 +241,7 @@ def strokedatajson_v2(request,id):
|
|||||||
lapidx = 0*time
|
lapidx = 0*time
|
||||||
try:
|
try:
|
||||||
hr = df['hr']
|
hr = df['hr']
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
hr = 0*df['time']
|
hr = 0*df['time']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -331,7 +327,7 @@ def strokedatajson_v2(request,id):
|
|||||||
|
|
||||||
isbreakthrough, ishard = dataprep.checkbreakthrough(row, r)
|
isbreakthrough, ishard = dataprep.checkbreakthrough(row, r)
|
||||||
|
|
||||||
if r.getemailnotifications and not r.emailbounced:
|
if r.getemailnotifications and not r.emailbounced: # pragma: no cover
|
||||||
link = settings.SITE_URL+reverse(
|
link = settings.SITE_URL+reverse(
|
||||||
r.defaultlandingpage,
|
r.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@@ -354,7 +350,7 @@ def strokedatajson_v2(request,id):
|
|||||||
}))
|
}))
|
||||||
#return(HttpResponse(encoder.encode_hex(row.id),status=201))
|
#return(HttpResponse(encoder.encode_hex(row.id),status=201))
|
||||||
|
|
||||||
return HttpResponseNotAllowed("Method not supported")
|
return HttpResponseNotAllowed("Method not supported") # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -362,18 +358,19 @@ def strokedatajson_v2(request,id):
|
|||||||
@login_required()
|
@login_required()
|
||||||
@api_view(['GET','POST'])
|
@api_view(['GET','POST'])
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
def strokedatajson(request,id):
|
def strokedatajson(request,id=0):
|
||||||
"""
|
"""
|
||||||
POST: Add Stroke data to workout
|
POST: Add Stroke data to workout
|
||||||
GET: Get stroke data of workout
|
GET: Get stroke data of workout
|
||||||
"""
|
"""
|
||||||
|
|
||||||
row = get_object_or_404(Workout,pk=id)
|
row = get_object_or_404(Workout,pk=id)
|
||||||
if row.user != request.user.rower:
|
if row.user != request.user.rower: # pragma: no cover
|
||||||
raise PermissionDenied("You have no access to this workout")
|
raise PermissionDenied("You have no access to this workout")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError: # pragma: no cover
|
||||||
return HttpResponse("Not a valid workout number",status=403)
|
return HttpResponse("Not a valid workout number",status=403)
|
||||||
|
|
||||||
|
|
||||||
@@ -389,39 +386,46 @@ def strokedatajson(request,id):
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
with open('apilog.log','a') as logfile:
|
with open('apilog.log','a') as logfile:
|
||||||
logfile.write(str(timezone.now())+": ")
|
logfile.write(str(timezone.now())+": ")
|
||||||
logfile.write(request.user.username+"(strokedatjson POST) \n")
|
logfile.write(request.user.username+"(strokedatajson POST) \n")
|
||||||
checkdata,r = dataprep.getrowdata_db(id=row.id)
|
checkdata,r = dataprep.getrowdata_db(id=row.id)
|
||||||
if not checkdata.empty:
|
if not checkdata.empty: # pragma: no cover
|
||||||
return HttpResponse("Duplicate Error",status=409)
|
return HttpResponse("Duplicate Error",status=409)
|
||||||
# strokedata = request.POST['strokedata']
|
# strokedata = request.POST['strokedata']
|
||||||
# checking/validating and cleaning
|
# checking/validating and cleaning
|
||||||
try:
|
try:
|
||||||
strokedata = json.loads(request.data['strokedata'])
|
strokedata = json.loads(request.data)['strokedata']
|
||||||
except:
|
except: # pragma: no cover
|
||||||
return HttpResponse("No JSON object could be decoded",status=400)
|
try:
|
||||||
|
s = json.dumps(request.data)
|
||||||
|
strokedata = json.loads(s)['strokedata']
|
||||||
|
except: # pragma: no cover
|
||||||
|
return HttpResponse("No JSON object could be decoded",status=400)
|
||||||
|
|
||||||
df = pd.DataFrame(strokedata)
|
try:
|
||||||
|
df = pd.DataFrame(strokedata)
|
||||||
|
except ValueError: # pragma: no cover
|
||||||
|
return HttpResponse("Arrays must all be same length",status=400)
|
||||||
df.index = df.index.astype(int)
|
df.index = df.index.astype(int)
|
||||||
df.sort_index(inplace=True)
|
df.sort_index(inplace=True)
|
||||||
# time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx
|
# time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx
|
||||||
try:
|
try:
|
||||||
time = df['time']/1.e3
|
time = df['time']/1.e3
|
||||||
except KeyError:
|
except KeyError: # pragma: no cover
|
||||||
return HttpResponse("There must be time values",status=400)
|
return HttpResponse("There must be time values",status=400)
|
||||||
aantal = len(time)
|
aantal = len(time)
|
||||||
pace = df['pace']/1.e3
|
pace = df['pace']/1.e3
|
||||||
if len(pace) != aantal:
|
if len(pace) != aantal: # pragma: no cover
|
||||||
return HttpResponse("Pace array has incorrect length",status=400)
|
return HttpResponse("Pace array has incorrect length",status=400)
|
||||||
distance = df['distance']
|
distance = df['distance']
|
||||||
if len(distance) != aantal:
|
if len(distance) != aantal: # pragma: no cover
|
||||||
return HttpResponse("Distance array has incorrect length",status=400)
|
return HttpResponse("Distance array has incorrect length",status=400)
|
||||||
|
|
||||||
spm = df['spm']
|
spm = df['spm']
|
||||||
if len(spm) != aantal:
|
if len(spm) != aantal: # pragma: no cover
|
||||||
return HttpResponse("SPM array has incorrect length",status=400)
|
return HttpResponse("SPM array has incorrect length",status=400)
|
||||||
|
|
||||||
res = dataprep.testdata(time,distance,pace,spm)
|
res = dataprep.testdata(time,distance,pace,spm)
|
||||||
if not res:
|
if not res: # pragma: no cover
|
||||||
return HttpResponse("Data are not numerical",status=400)
|
return HttpResponse("Data are not numerical",status=400)
|
||||||
|
|
||||||
power = trydf(df,aantal,'power')
|
power = trydf(df,aantal,'power')
|
||||||
@@ -503,4 +507,4 @@ def strokedatajson(request,id):
|
|||||||
return HttpResponse(encoder.encode_hex(row.id),status=201)
|
return HttpResponse(encoder.encode_hex(row.id),status=201)
|
||||||
|
|
||||||
#Method not supported
|
#Method not supported
|
||||||
return HttpResponseNotAllowed("Method not supported")
|
return HttpResponseNotAllowed("Method not supported") # pragma: no cover
|
||||||
|
|||||||
Reference in New Issue
Block a user