438 lines
16 KiB
Python
438 lines
16 KiB
Python
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
from __future__ import unicode_literals
|
|
|
|
from rowers.views.statements import *
|
|
|
|
|
|
# Stroke data form to test API upload
|
|
@login_required()
|
|
def strokedataform(request,id=0):
|
|
|
|
try:
|
|
id=int(id)
|
|
except ValueError:
|
|
id = 0
|
|
|
|
try:
|
|
w = Workout.objects.get(id=id)
|
|
except Workout.DoesNotExist:
|
|
raise Http404("Workout doesn't exist")
|
|
|
|
if request.method == 'GET':
|
|
form = StrokeDataForm()
|
|
return render(request, 'strokedata_form.html',
|
|
{
|
|
'form':form,
|
|
'teams':get_my_teams(request.user),
|
|
'id':id,
|
|
'workout':w,
|
|
})
|
|
elif request.method == 'POST':
|
|
form = StrokeDataForm()
|
|
|
|
return render(request, 'strokedata_form.html',
|
|
{
|
|
'form':form,
|
|
'teams':get_my_teams(request.user),
|
|
'id':id,
|
|
'workout':w,
|
|
})
|
|
|
|
@login_required()
|
|
def strokedataform_v2(request,id=0):
|
|
|
|
try:
|
|
id=int(id)
|
|
except ValueError:
|
|
id = 0
|
|
|
|
try:
|
|
w = Workout.objects.get(id=id)
|
|
except Workout.DoesNotExist:
|
|
raise Http404("Workout doesn't exist")
|
|
|
|
if request.method == 'GET':
|
|
form = StrokeDataForm()
|
|
return render(request, 'strokedata_form_v2.html',
|
|
{
|
|
'form':form,
|
|
'teams':get_my_teams(request.user),
|
|
'id':id,
|
|
'workout':w,
|
|
})
|
|
elif request.method == 'POST':
|
|
form = StrokeDataForm()
|
|
|
|
return render(request, 'strokedata_form_v2.html',
|
|
{
|
|
'form':form,
|
|
'teams':get_my_teams(request.user),
|
|
'id':id,
|
|
'workout':w,
|
|
})
|
|
|
|
|
|
# Process the POSTed stroke data according to the API definition
|
|
# Return the GET stroke data according to the API definition
|
|
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
|
|
|
|
@csrf_exempt
|
|
@login_required()
|
|
@api_view(["GET","POST"])
|
|
@permission_classes([IsAuthenticated])
|
|
def strokedatajson_v2(request,id):
|
|
"""
|
|
POST: Add Stroke data to workout
|
|
GET: Get stroke data of workout
|
|
This v2 API works on stroke based data dict:
|
|
{"data": [{"hr": 110, "p": 3600, "spm": 53, "d": 6, "t": 12}, {"hr": 111, "p": 3600, "spm": 53, "d": 6, "t": 12}, {"hr": 111, "p": 3600, "spm": 64, "d": 6, "t": 22}, {"hr": 110, "p": 3600, "spm": 16, "d": 14, "t": 55}, {"hr": 110, "p": 3600, "spm": 16, "d": 14, "t": 82}, {"hr": 107, "p": 3600, "spm": 12, "d": 22, "t": 109}, {"hr": 107, "p": 3600, "spm": 12, "d": 22, "t": 133}, {"hr": 108, "p": 3600, "spm": 12, "d": 32, "t": 157}, {"hr": 108, "p": 3577, "spm": 12, "d": 32, "t": 157}, {"hr": 108, "p": 3411, "spm": 12, "d": 32, "t": 157}, {"hr": 108, "p": 2649, "spm": 12, "d": 32, "t": 157}, {"hr": 108, "p": 3099, "spm": 12, "d": 32, "t": 157}, {"hr": 108, "p": 3600, "spm": 12, "d": 32, "t": 157}, {"hr": 100, "p": 3600, "spm": 44, "d": 115, "t": 292}, {"hr": 99, "p": 3600, "spm": 27, "d": 129, "t": 305}, {"hr": 97, "p": 3600, "spm": 34, "d": 161, "t": 330}, {"hr": 96, "p": 3600, "spm": 25, "d": 177, "t": 344}, {"hr": 96, "p": 3494, "spm": 43, "d": 196, "t": 357}, {"hr": 98, "p": 2927, "spm": 26, "d": 235, "t": 377}, {"hr": 102, "p": 2718, "spm": 27, "d": 380, "t": 455}, {"hr": 102, "p": 2753, "spm": 9, "d": 398, "t": 472}, {"hr": 102, "p": 2864, "spm": 61, "d": 406, "t": 477}, {"hr": 101, "p": 2780, "spm": 15, "d": 484, "t": 515}, {"hr": 101, "p": 2365, "spm": 16, "d": 583, "t": 554}, {"hr": 103, "p": 1965, "spm": 16, "d": 681, "t": 592}, {"hr": 104, "
|
|
"""
|
|
|
|
row = get_object_or_404(Workout,pk=id)
|
|
if row.user != request.user.rower:
|
|
return HttpResponse("You do not have permission to perform this action",status=403)
|
|
|
|
try:
|
|
id = int(id)
|
|
except ValueError:
|
|
return HttpResponse("Not a valid workout number",status=404)
|
|
|
|
if request.method == 'GET':
|
|
columns = ['spm','time','hr','pace','power','distance']
|
|
datadf = dataprep.getsmallrowdata_db(columns,ids=[id])
|
|
with open('media/apilog.log','a') as logfile:
|
|
logfile.write(str(timezone.now())+": ")
|
|
logfile.write(request.user.username+"(GET) \n")
|
|
|
|
data = datadf.to_json(orient='records')
|
|
|
|
return JSONResponse(data)
|
|
|
|
if request.method == 'POST':
|
|
checkdata, r = dataprep.getrowdata_db(id=row.id)
|
|
if not checkdata.empty:
|
|
return HttpResponse("Duplicate Error",status=409)
|
|
|
|
df = pd.DataFrame()
|
|
|
|
try:
|
|
df = pd.DataFrame(request.data['data'])
|
|
except KeyError:
|
|
try:
|
|
df = pd.DataFrame(request.data['strokedata'])
|
|
except:
|
|
return HttpResponse("No JSON object could be decoded",status=400)
|
|
|
|
|
|
df.index = df.index.astype(int)
|
|
df.sort_index(inplace=True)
|
|
|
|
#time, pace, distance,spm
|
|
try:
|
|
time = df['time']/1.e3
|
|
except KeyError:
|
|
try:
|
|
time = df['t']/10.
|
|
except KeyError:
|
|
return HttpResponse("Missing time",status=400)
|
|
|
|
try:
|
|
spm = df['spm']
|
|
except KeyError:
|
|
return HttpResponse("Missing spm",status=400)
|
|
|
|
try:
|
|
distance = df['distance']
|
|
except KeyError:
|
|
try:
|
|
distance = df['d']/10.
|
|
except KeyError:
|
|
return HttpResponse("Missing distance",status=400)
|
|
|
|
try:
|
|
pace = df['pace']/1.e3
|
|
except KeyError:
|
|
try:
|
|
pace = df['p']/10.
|
|
except KeyError:
|
|
return HttpResponse("Missing pace",status=400)
|
|
|
|
|
|
|
|
try:
|
|
power = df['power']
|
|
except KeyError:
|
|
power = 0*time
|
|
try:
|
|
drivelength = df['drivelength']
|
|
except KeyError:
|
|
drivelength = 0*time
|
|
try:
|
|
drivespeed = df['drivespeed']
|
|
except KeyError:
|
|
drivespeed = 0*time
|
|
try:
|
|
dragfactor = df['dragfactor']
|
|
except KeyError:
|
|
dragfactor = 0*time
|
|
try:
|
|
drivetime = df['drivetime']
|
|
except KeyError:
|
|
drivetime = 0*time
|
|
try:
|
|
strokerecoverytime = df['strokerecoverytime']
|
|
except KeyError:
|
|
strokerecoverytime = 0*time
|
|
try:
|
|
averagedriveforce = df['averagedriveforce']
|
|
except KeyError:
|
|
averagedriveforce = 0*time
|
|
try:
|
|
peakdriveforce = df['peakdriveforce']
|
|
except KeyError:
|
|
peakdriveforce = 0*time
|
|
try:
|
|
wash = df['wash']
|
|
except KeyError:
|
|
wash = 0*time
|
|
try:
|
|
catch = df['catch']
|
|
except KeyError:
|
|
catch = 0*time
|
|
try:
|
|
finish = df['finish']
|
|
except KeyError:
|
|
finish = 0*time
|
|
try:
|
|
peakforceangle = df['peakforceangle']
|
|
except KeyError:
|
|
peakforceangle = 0*time
|
|
try:
|
|
driveenergy = df['driveenergy']
|
|
except KeyError:
|
|
driveenergy = 60.*power/spm
|
|
try:
|
|
slip = df['slip']
|
|
except KeyError:
|
|
slip = 0*time
|
|
try:
|
|
lapidx = df['lapidx']
|
|
except KeyError:
|
|
lapidx = 0*time
|
|
try:
|
|
hr = df['hr']
|
|
except KeyError:
|
|
hr = 0*df['time']
|
|
|
|
|
|
|
|
starttime = totimestamp(row.startdatetime)+time[0]
|
|
unixtime = starttime+time
|
|
|
|
with open('media/apilog.log','a') as logfile:
|
|
logfile.write(str(starttime)+": ")
|
|
logfile.write(request.user.username+"(POST) \r\n")
|
|
|
|
|
|
data = pd.DataFrame({'TimeStamp (sec)':unixtime,
|
|
' Horizontal (meters)': distance,
|
|
' Cadence (stokes/min)':spm,
|
|
' HRCur (bpm)':hr,
|
|
' DragFactor':dragfactor,
|
|
' Stroke500mPace (sec/500m)':pace,
|
|
' Power (watts)':power,
|
|
' DriveLength (meters)':drivelength,
|
|
' DriveTime (ms)':drivetime,
|
|
' StrokeRecoveryTime (ms)':strokerecoverytime,
|
|
' AverageDriveForce (lbs)':averagedriveforce,
|
|
' PeakDriveForce (lbs)':peakdriveforce,
|
|
' lapIdx':lapidx,
|
|
' ElapsedTime (sec)':time,
|
|
'catch':catch,
|
|
'slip':slip,
|
|
'finish':finish,
|
|
'wash':wash,
|
|
'driveenergy':driveenergy,
|
|
'peakforceangle':peakforceangle,
|
|
})
|
|
|
|
r = getrower(request.user)
|
|
|
|
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
|
|
csvfilename ='media/Import_'+timestr+'.csv'
|
|
|
|
res = data.to_csv(csvfilename+'.gz',index_label='index',
|
|
compression='gzip')
|
|
row.csvfilename = csvfilename
|
|
row.save()
|
|
|
|
powerperc = 100*np.array([r.pw_ut2,
|
|
r.pw_ut1,
|
|
r.pw_at,
|
|
r.pw_tr,r.pw_an])/r.ftp
|
|
|
|
ftp = float(r.ftp)
|
|
if row.workouttype in mytypes.otwtypes:
|
|
ftp = ftp*(100.-r.otwslack)/100.
|
|
|
|
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
|
hrut1=r.ut1,hrat=r.at,
|
|
hrtr=r.tr,hran=r.an,ftp=ftp,
|
|
powerperc=powerperc,powerzones=r.powerzones)
|
|
rowdata = rdata(row.csvfilename,rower=rr).df
|
|
|
|
datadf = dataprep.dataprep(rowdata,id=row.id,bands=True,barchart=True,otwpower=True,empower=True)
|
|
|
|
|
|
return(HttpResponse(encoder.encode_hex(row.id),status=201))
|
|
|
|
return HttpResponseNotAllowed("Method not supported")
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
@login_required()
|
|
@api_view(['GET','POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def strokedatajson(request,id):
|
|
"""
|
|
POST: Add Stroke data to workout
|
|
GET: Get stroke data of workout
|
|
"""
|
|
row = get_object_or_404(Workout,pk=id)
|
|
if row.user != request.user.rower:
|
|
raise PermissionDenied("You have no access to this workout")
|
|
|
|
try:
|
|
id = int(id)
|
|
except ValueError:
|
|
return HttpResponse("Not a valid workout number",status=403)
|
|
|
|
|
|
if request.method == 'GET':
|
|
# currently only returns a subset.
|
|
columns = ['spm','time','hr','pace','power','distance']
|
|
datadf = dataprep.getsmallrowdata_db(columns,ids=[id])
|
|
with open('media/apilog.log','a') as logfile:
|
|
logfile.write(str(timezone.now())+": ")
|
|
logfile.write(request.user.username+"(GET) \n")
|
|
return JSONResponse(datadf)
|
|
|
|
if request.method == 'POST':
|
|
checkdata,r = dataprep.getrowdata_db(id=row.id)
|
|
if not checkdata.empty:
|
|
return HttpResponse("Duplicate Error",status=409)
|
|
# strokedata = request.POST['strokedata']
|
|
# checking/validating and cleaning
|
|
try:
|
|
strokedata = json.loads(request.data['strokedata'])
|
|
except:
|
|
return HttpResponse("No JSON object could be decoded",status=400)
|
|
|
|
df = pd.DataFrame(strokedata)
|
|
df.index = df.index.astype(int)
|
|
df.sort_index(inplace=True)
|
|
# time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx
|
|
try:
|
|
time = df['time']/1.e3
|
|
except KeyError:
|
|
return HttpResponse("There must be time values",status=400)
|
|
aantal = len(time)
|
|
pace = df['pace']/1.e3
|
|
if len(pace) != aantal:
|
|
return HttpResponse("Pace array has incorrect length",status=400)
|
|
distance = df['distance']
|
|
if len(distance) != aantal:
|
|
return HttpResponse("Distance array has incorrect length",status=400)
|
|
|
|
spm = df['spm']
|
|
if len(spm) != aantal:
|
|
return HttpResponse("SPM array has incorrect length",status=400)
|
|
|
|
res = dataprep.testdata(time,distance,pace,spm)
|
|
if not res:
|
|
return HttpResponse("Data are not numerical",status=400)
|
|
|
|
power = trydf(df,aantal,'power')
|
|
drivelength = trydf(df,aantal,'drivelength')
|
|
drivespeed = trydf(df,aantal,'drivespeed')
|
|
dragfactor = trydf(df,aantal,'dragfactor')
|
|
drivetime = trydf(df,aantal,'drivetime')
|
|
strokerecoverytime = trydf(df,aantal,'strokerecoverytime')
|
|
averagedriveforce = trydf(df,aantal,'averagedriveforce')
|
|
peakdriveforce = trydf(df,aantal,'peakdriveforce')
|
|
wash = trydf(df,aantal,'wash')
|
|
catch = trydf(df,aantal,'catch')
|
|
finish = trydf(df,aantal,'finish')
|
|
peakforceangle = trydf(df,aantal,'peakforceangle')
|
|
driveenergy = trydf(df,aantal,'driveenergy')
|
|
slip = trydf(df,aantal,'slip')
|
|
lapidx = trydf(df,aantal,'lapidx')
|
|
hr = trydf(df,aantal,'hr')
|
|
|
|
starttime = totimestamp(row.startdatetime)+time[0]
|
|
unixtime = starttime+time
|
|
|
|
with open('media/apilog.log','a') as logfile:
|
|
logfile.write(str(starttime)+": ")
|
|
logfile.write(request.user.username+"(POST) \r\n")
|
|
|
|
data = pd.DataFrame({'TimeStamp (sec)':unixtime,
|
|
' Horizontal (meters)': distance,
|
|
' Cadence (stokes/min)':spm,
|
|
' HRCur (bpm)':hr,
|
|
' DragFactor':dragfactor,
|
|
' Stroke500mPace (sec/500m)':pace,
|
|
' Power (watts)':power,
|
|
' DriveLength (meters)':drivelength,
|
|
' DriveTime (ms)':drivetime,
|
|
' StrokeRecoveryTime (ms)':strokerecoverytime,
|
|
' AverageDriveForce (lbs)':averagedriveforce,
|
|
' PeakDriveForce (lbs)':peakdriveforce,
|
|
' lapIdx':lapidx,
|
|
' ElapsedTime (sec)':time,
|
|
'catch':catch,
|
|
'slip':slip,
|
|
'finish':finish,
|
|
'wash':wash,
|
|
'driveenergy':driveenergy,
|
|
'peakforceangle':peakforceangle,
|
|
})
|
|
|
|
|
|
r = getrower(request.user)
|
|
|
|
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
|
|
csvfilename ='media/Import_'+timestr+'.csv'
|
|
|
|
res = data.to_csv(csvfilename+'.gz',index_label='index',
|
|
compression='gzip')
|
|
row.csvfilename = csvfilename
|
|
row.save()
|
|
|
|
powerperc = 100*np.array([r.pw_ut2,
|
|
r.pw_ut1,
|
|
r.pw_at,
|
|
r.pw_tr,r.pw_an])/r.ftp
|
|
|
|
ftp = float(r.ftp)
|
|
if row.workouttype in mytypes.otwtypes:
|
|
ftp = ftp*(100.-r.otwslack)/100.
|
|
|
|
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
|
hrut1=r.ut1,hrat=r.at,
|
|
hrtr=r.tr,hran=r.an,ftp=ftp,
|
|
powerperc=powerperc,powerzones=r.powerzones)
|
|
rowdata = rdata(row.csvfilename,rower=rr).df
|
|
|
|
datadf = dataprep.dataprep(rowdata,id=row.id,bands=True,barchart=True,otwpower=True,empower=True)
|
|
# mangling
|
|
|
|
#
|
|
return HttpResponse(encoder.encode_hex(row.id),status=201)
|
|
|
|
#Method not supported
|
|
return HttpResponseNotAllowed("Method not supported")
|