first attempt, untested
This commit is contained in:
@@ -37,6 +37,138 @@ def strokedataform(request, id=0):
|
|||||||
'workout': w,
|
'workout': w,
|
||||||
}) # pragma: no cover
|
}) # pragma: no cover
|
||||||
|
|
||||||
|
def api_get_dataframe(startdatetime, df):
|
||||||
|
try:
|
||||||
|
time = df['time']/1.e3
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
try:
|
||||||
|
time = df['t']/10.
|
||||||
|
except KeyError:
|
||||||
|
return 400, "Missing time", pd.DataFrame()
|
||||||
|
|
||||||
|
try:
|
||||||
|
spm = df['spm']
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
return 400, "Missing spm", pd.DataFrame()
|
||||||
|
try:
|
||||||
|
distance = df['distance']
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
try:
|
||||||
|
distance = df['d']/10.
|
||||||
|
except KeyError:
|
||||||
|
return 400, "Missing distance", pd.DataFrame()
|
||||||
|
|
||||||
|
try:
|
||||||
|
pace = df['pace']/1.e3
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
try:
|
||||||
|
pace = df['p']/10.
|
||||||
|
except KeyError:
|
||||||
|
return 400, "Missing pace", pd.DataFrame()
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
power = df['power']
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
power = 0*time
|
||||||
|
try:
|
||||||
|
drivelength = df['drivelength']
|
||||||
|
except KeyError:
|
||||||
|
drivelength = 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: # pragma: no cover
|
||||||
|
hr = 0*df['time']
|
||||||
|
|
||||||
|
try:
|
||||||
|
latitude = df['latitude']
|
||||||
|
except KeyError:
|
||||||
|
latitude = 0*df['time']
|
||||||
|
|
||||||
|
try:
|
||||||
|
longitude = df['longitude']
|
||||||
|
except KeyError:
|
||||||
|
longitude = 0*df['time']
|
||||||
|
|
||||||
|
starttime = totimestamp(startdatetime)+time[0]
|
||||||
|
unixtime = starttime+time
|
||||||
|
|
||||||
|
dologging('apilog.log',"(strokedatajson_v2/3 POST - data parsed)")
|
||||||
|
|
||||||
|
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,
|
||||||
|
' latitude': latitude,
|
||||||
|
' longitude': longitude,
|
||||||
|
})
|
||||||
|
|
||||||
|
return 200, "", data
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def strokedataform_v2(request, id=0):
|
def strokedataform_v2(request, id=0):
|
||||||
@@ -69,10 +201,135 @@ def strokedataform_v2(request, id=0):
|
|||||||
}) # pragma: no cover
|
}) # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
@login_required()
|
||||||
|
@api_view(["POST"])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
def strokedatajson_v3(request):
|
||||||
|
"""
|
||||||
|
POST: Add Stroke data to workout
|
||||||
|
GET: Get stroke data of workout
|
||||||
|
This v2 API works on stroke based data dict:
|
||||||
|
{"startdatetime":"2023-01-16 12:34:45",
|
||||||
|
"totalDistance":11233,
|
||||||
|
"elapsedTime":"65:23.10",
|
||||||
|
"summary":"Some summary",
|
||||||
|
"timezone":"UTC",
|
||||||
|
"workouttype":"rower",
|
||||||
|
"boattype":"1x",
|
||||||
|
"notes":"some notes",
|
||||||
|
"title":"Workout title",
|
||||||
|
"rpe":4,
|
||||||
|
"data":
|
||||||
|
[
|
||||||
|
{"hr": 110, "p": 3600, "spm": 53, "d": 6, "t": 12, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 111, "p": 3600, "spm": 53, "d": 6, "t": 12, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 111, "p": 3600, "spm": 64, "d": 6, "t": 22, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 110, "p": 3600, "spm": 16, "d": 14, "t": 55, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 110, "p": 3600, "spm": 16, "d": 14, "t": 82, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 107, "p": 3600, "spm": 12, "d": 22, "t": 109, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 107, "p": 3600, "spm": 12, "d": 22, "t": 133, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 3600, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 3577, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 3411, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 2649, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 3099, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 108, "p": 3600, "spm": 12, "d": 32, "t": 157, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 100, "p": 3600, "spm": 44, "d": 115, "t": 292, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 99, "p": 3600, "spm": 27, "d": 129, "t": 305, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 97, "p": 3600, "spm": 34, "d": 161, "t": 330, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 96, "p": 3600, "spm": 25, "d": 177, "t": 344, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 96, "p": 3494, "spm": 43, "d": 196, "t": 357, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 98, "p": 2927, "spm": 26, "d": 235, "t": 377, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 102, "p": 2718, "spm": 27, "d": 380, "t": 455, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 102, "p": 2753, "spm": 9, "d": 398, "t": 472, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 102, "p": 2864, "spm": 61, "d": 406, "t": 477, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 101, "p": 2780, "spm": 15, "d": 484, "t": 515, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 101, "p": 2365, "spm": 16, "d": 583, "t": 554, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
{"hr": 103, "p": 1965, "spm": 16, "d": 681, "t": 592, "latitude": 52.343, "longitude": -6.342},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
if request.method != 'POST':
|
||||||
|
return HttpResponse("Not allowed", status=409)
|
||||||
|
|
||||||
|
dologging('apilog.log', request.user.username+" (strokedatajson_v3 POST)")
|
||||||
|
|
||||||
|
title = request.data.get('title','')
|
||||||
|
try:
|
||||||
|
elapsedTime = request.data['elapsedTime']
|
||||||
|
except KeyError:
|
||||||
|
return HttpResponse("Missing Elapsed Time", status=400)
|
||||||
|
try:
|
||||||
|
totalDistance = request.data['totalDistance']
|
||||||
|
except KeyError:
|
||||||
|
return HttpResponse("Missing Total Distance", status=400)
|
||||||
|
summary = request.data.get('summary','')
|
||||||
|
timezone = request.data.get('timezone','UTC')
|
||||||
|
workouttype = request.data.get('workouttype','rower')
|
||||||
|
boattype = request.data.get('boattype','1x')
|
||||||
|
notes = request.data.get('notes','')
|
||||||
|
rpe = request.data.get('rpe',0)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
status, comment, data = api_get_dataframe(startdatetime, df)
|
||||||
|
|
||||||
|
if status != 200:
|
||||||
|
return HttpResponse(comment, status=status)
|
||||||
|
|
||||||
|
|
||||||
|
csvfilename = 'media/{code}.csv'.format(code=uuid4().hex[:16])
|
||||||
|
_ = data.to_csv(csvfilename+'.gz', index_label='index', compression='gzip')
|
||||||
|
|
||||||
|
uploadoptions = {
|
||||||
|
'secret': UPLOAD_SERVICE_SECRET,
|
||||||
|
'user': userid,
|
||||||
|
'file': csvfilename,
|
||||||
|
'title': title,
|
||||||
|
'workouttype': workouttype,
|
||||||
|
'boattype': boattype,
|
||||||
|
'summary': summary,
|
||||||
|
'elapsedTime': elapsedTime/1000., # in seconds
|
||||||
|
'totalDistance': totalDistance,
|
||||||
|
'rpe': rpe,
|
||||||
|
'notes': notes,
|
||||||
|
'timezone': timezone,
|
||||||
|
}
|
||||||
|
session = requests.session()
|
||||||
|
newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||||
|
session.headers.update(newHeaders)
|
||||||
|
|
||||||
|
response = session.post(UPLOAD_SERVICE_URL, json=uploadoptions)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
return HttpResponse(response.text, response.status_code)
|
||||||
|
|
||||||
|
try:
|
||||||
|
workoutid = response.json()['id']
|
||||||
|
except KeyError:
|
||||||
|
workoutid = 1
|
||||||
|
|
||||||
|
return JsonResponse(
|
||||||
|
{"workout public id": encoder.encode_hex(workoutid),
|
||||||
|
"status": "success",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
# Process the POSTed stroke data according to the API definition
|
# Process the POSTed stroke data according to the API definition
|
||||||
# Return the GET stroke data according to the API definition
|
# Return the GET stroke data according to the API definition
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
@login_required()
|
@login_required()
|
||||||
@api_view(["GET", "POST"])
|
@api_view(["GET", "POST"])
|
||||||
@@ -161,135 +418,10 @@ def strokedatajson_v2(request, id):
|
|||||||
df.index = df.index.astype(int)
|
df.index = df.index.astype(int)
|
||||||
df.sort_index(inplace=True)
|
df.sort_index(inplace=True)
|
||||||
|
|
||||||
try:
|
status, comment, data = api_get_dataframe(row.startdatetime, df)
|
||||||
time = df['time']/1.e3
|
if status != 200:
|
||||||
except KeyError: # pragma: no cover
|
return HttpResponse(comment, status=status)
|
||||||
try:
|
|
||||||
time = df['t']/10.
|
|
||||||
except KeyError:
|
|
||||||
return HttpResponse("Missing time", status=400)
|
|
||||||
|
|
||||||
try:
|
|
||||||
spm = df['spm']
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
return HttpResponse("Missing spm", status=400)
|
|
||||||
|
|
||||||
try:
|
|
||||||
distance = df['distance']
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
try:
|
|
||||||
distance = df['d']/10.
|
|
||||||
except KeyError:
|
|
||||||
return HttpResponse("Missing distance", status=400)
|
|
||||||
|
|
||||||
try:
|
|
||||||
pace = df['pace']/1.e3
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
try:
|
|
||||||
pace = df['p']/10.
|
|
||||||
except KeyError:
|
|
||||||
return HttpResponse("Missing pace", status=400)
|
|
||||||
|
|
||||||
try:
|
|
||||||
power = df['power']
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
power = 0*time
|
|
||||||
try:
|
|
||||||
drivelength = df['drivelength']
|
|
||||||
except KeyError:
|
|
||||||
drivelength = 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: # pragma: no cover
|
|
||||||
hr = 0*df['time']
|
|
||||||
|
|
||||||
try:
|
|
||||||
latitude = df['latitude']
|
|
||||||
except KeyError:
|
|
||||||
latitude = 0*df['time']
|
|
||||||
|
|
||||||
try:
|
|
||||||
longitude = df['longitude']
|
|
||||||
except KeyError:
|
|
||||||
longitude = 0*df['time']
|
|
||||||
|
|
||||||
starttime = totimestamp(row.startdatetime)+time[0]
|
|
||||||
unixtime = starttime+time
|
|
||||||
|
|
||||||
dologging('apilog.log',"(strokedatajson_v2 POST - data parsed)")
|
|
||||||
|
|
||||||
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,
|
|
||||||
' latitude': latitude,
|
|
||||||
' longitude': longitude,
|
|
||||||
})
|
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
|
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
|
||||||
|
|||||||
Reference in New Issue
Block a user