moved workout creation to dataprep for workout_upload
This commit is contained in:
@@ -15,11 +15,23 @@ from pytz import timezone as tz,utc
|
|||||||
|
|
||||||
from django.utils.timezone import get_current_timezone
|
from django.utils.timezone import get_current_timezone
|
||||||
thetimezone = get_current_timezone()
|
thetimezone = get_current_timezone()
|
||||||
|
from rowingdata import (
|
||||||
|
TCXParser,RowProParser,ErgDataParser,TCXParserNoHR,
|
||||||
|
BoatCoachParser,RowPerfectParser,BoatCoachAdvancedParser,
|
||||||
|
MysteryParser,
|
||||||
|
painsledDesktopParser,speedcoachParser,ErgStickParser,
|
||||||
|
SpeedCoach2Parser,FITParser,fitsummarydata,
|
||||||
|
make_cumvalues,
|
||||||
|
summarydata,get_file_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
import os
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
|
from tasks import handle_sendemail_unrecognized
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
@@ -212,10 +224,46 @@ def new_workout_from_file(r,f2,
|
|||||||
workouttype='rower',
|
workouttype='rower',
|
||||||
title='Workout',
|
title='Workout',
|
||||||
notes=''):
|
notes=''):
|
||||||
|
message = None
|
||||||
fileformat = get_file_type(f2)
|
fileformat = get_file_type(f2)
|
||||||
summary = ''
|
summary = ''
|
||||||
# handle non-Painsled
|
if len(fileformat)==3 and fileformat[0]=='zip':
|
||||||
|
f_to_be_deleted = f2
|
||||||
|
with zipfile.ZipFile(f2) as z:
|
||||||
|
# for now, we're getting only the first file
|
||||||
|
# from the NK zip file (issue #69 on bitbucket)
|
||||||
|
f2 = z.extract(z.namelist()[0],path='media/')
|
||||||
|
fileformat = fileformat[2]
|
||||||
|
os.remove(f_to_be_deleted)
|
||||||
|
|
||||||
|
# Some people try to upload Concept2 logbook summaries
|
||||||
|
if fileformat == 'c2log':
|
||||||
|
os.remove(f2)
|
||||||
|
message = "This C2 logbook summary does not contain stroke data. Please download the Export Stroke Data file from the workout details on the C2 logbook."
|
||||||
|
return (0,message)
|
||||||
|
|
||||||
|
# Some people try to upload RowPro summary logs
|
||||||
|
if fileformat == 'rowprolog':
|
||||||
|
os.remove(f2)
|
||||||
|
message = "This RowPro logbook summary does not contain stroke data. Please use the Stroke Data CSV file for the individual workout in your log."
|
||||||
|
return (0,message)
|
||||||
|
|
||||||
|
# Sometimes people try an unsupported file type.
|
||||||
|
# Send an email to info@rowsandall.com with the file attached
|
||||||
|
# for me to check if it is a bug, or a new file type
|
||||||
|
# worth supporting
|
||||||
|
if fileformat == 'unknown':
|
||||||
|
message = "We couldn't recognize the file type"
|
||||||
|
if settings.DEBUG:
|
||||||
|
res = handle_sendemail_unrecognized.delay(f2,
|
||||||
|
request.user.email)
|
||||||
|
|
||||||
|
else:
|
||||||
|
res = queuehigh.enqueue(handle_sendemail_unrecognized,
|
||||||
|
f2,request.user.email)
|
||||||
|
return (0,'message')
|
||||||
|
|
||||||
|
# handle non-Painsled by converting it to painsled compatible CSV
|
||||||
if (fileformat != 'csv'):
|
if (fileformat != 'csv'):
|
||||||
# handle RowPro:
|
# handle RowPro:
|
||||||
if (fileformat == 'rp'):
|
if (fileformat == 'rp'):
|
||||||
@@ -232,10 +280,18 @@ def new_workout_from_file(r,f2,
|
|||||||
if (fileformat == 'tcxnohr'):
|
if (fileformat == 'tcxnohr'):
|
||||||
row = TCXParserNoHR(f2)
|
row = TCXParserNoHR(f2)
|
||||||
|
|
||||||
|
# handle RowPerfect
|
||||||
|
if (fileformat == 'rowperfect3'):
|
||||||
|
row = RowPerfectParser(f2)
|
||||||
|
|
||||||
# handle ErgData
|
# handle ErgData
|
||||||
if (fileformat == 'ergdata'):
|
if (fileformat == 'ergdata'):
|
||||||
row = ErgDataParser(f2)
|
row = ErgDataParser(f2)
|
||||||
|
|
||||||
|
# handle Mike
|
||||||
|
if (fileformat == 'bcmike'):
|
||||||
|
row = BoatCoachAdvancedParser(f2)
|
||||||
|
|
||||||
# handle BoatCoach
|
# handle BoatCoach
|
||||||
if (fileformat == 'boatcoach'):
|
if (fileformat == 'boatcoach'):
|
||||||
row = BoatCoachParser(f2)
|
row = BoatCoachParser(f2)
|
||||||
@@ -251,7 +307,10 @@ def new_workout_from_file(r,f2,
|
|||||||
# handle speed coach GPS 2
|
# handle speed coach GPS 2
|
||||||
if (fileformat == 'speedcoach2'):
|
if (fileformat == 'speedcoach2'):
|
||||||
row = SpeedCoach2Parser(f2)
|
row = SpeedCoach2Parser(f2)
|
||||||
summary = row.allstats()
|
try:
|
||||||
|
summary = row.allstats()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# handle ErgStick
|
# handle ErgStick
|
||||||
@@ -266,24 +325,30 @@ def new_workout_from_file(r,f2,
|
|||||||
summary = s.summarytext
|
summary = s.summarytext
|
||||||
|
|
||||||
|
|
||||||
f_to_be_deleted = f2
|
f_to_be_deleted = f2
|
||||||
# should delete file
|
# should delete file
|
||||||
f2 = f2[:-4]+'o.csv'
|
f2 = f2[:-4]+'o.csv'
|
||||||
row.write_csv(f2,gzip=True)
|
row.write_csv(f2,gzip=True)
|
||||||
|
|
||||||
#os.remove(f2)
|
#os.remove(f2)
|
||||||
try:
|
try:
|
||||||
os.remove(f_to_be_deleted)
|
os.remove(f_to_be_deleted)
|
||||||
except:
|
except:
|
||||||
os.remove(f_to_be_deleted+'.gz')
|
os.remove(f_to_be_deleted+'.gz')
|
||||||
|
|
||||||
|
powerperc = 100*np.array([r.pw_ut2,
|
||||||
|
r.pw_ut1,
|
||||||
|
r.pw_at,
|
||||||
|
r.pw_tr,r.pw_an])/r.ftp
|
||||||
|
|
||||||
# make workout and put in database
|
# make workout and put in database
|
||||||
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
||||||
hrut1=r.ut1,hrat=r.at,
|
hrut1=r.ut1,hrat=r.at,
|
||||||
hrtr=r.tr,hran=r.an,ftp=r.ftp)
|
hrtr=r.tr,hran=r.an,ftp=r.ftp,
|
||||||
|
powerperc=powerperc,powerzones=r.powerzones)
|
||||||
row = rdata(f2,rower=rr)
|
row = rdata(f2,rower=rr)
|
||||||
if row == 0:
|
if row == 0:
|
||||||
return HttpResponse("Error: CSV Data File Not Found")
|
return (0,'Error: CSV data file not found')
|
||||||
|
|
||||||
# auto smoothing
|
# auto smoothing
|
||||||
pace = row.df[' Stroke500mPace (sec/500m)'].values
|
pace = row.df[' Stroke500mPace (sec/500m)'].values
|
||||||
@@ -336,6 +401,10 @@ def new_workout_from_file(r,f2,
|
|||||||
totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
|
totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
|
||||||
|
|
||||||
hours = int(totaltime/3600.)
|
hours = int(totaltime/3600.)
|
||||||
|
if hours>23:
|
||||||
|
message = 'Warning: The workout duration was longer than 23 hours'
|
||||||
|
hours = 23
|
||||||
|
|
||||||
minutes = int((totaltime - 3600.*hours)/60.)
|
minutes = int((totaltime - 3600.*hours)/60.)
|
||||||
seconds = int(totaltime - 3600.*hours - 60.*minutes)
|
seconds = int(totaltime - 3600.*hours - 60.*minutes)
|
||||||
tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
|
tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
|
||||||
@@ -362,9 +431,10 @@ def new_workout_from_file(r,f2,
|
|||||||
|
|
||||||
w.save()
|
w.save()
|
||||||
# put stroke data in database
|
# put stroke data in database
|
||||||
res = dataprep(row.df,id=w.id,bands=True,barchart=True,otwpower=True,empower=True)
|
res = dataprep(row.df,id=w.id,bands=True,
|
||||||
|
barchart=True,otwpower=True,empower=True)
|
||||||
|
|
||||||
return True
|
return (w.id,message)
|
||||||
|
|
||||||
# Compare the data from the CSV file and the database
|
# Compare the data from the CSV file and the database
|
||||||
# Currently only calculates number of strokes. To be expanded with
|
# Currently only calculates number of strokes. To be expanded with
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ from rowers.tasks import (
|
|||||||
inviteduration = 14 # days
|
inviteduration = 14 # days
|
||||||
|
|
||||||
def update_team(t,name,manager,private,notes):
|
def update_team(t,name,manager,private,notes):
|
||||||
|
if t.manager != manager:
|
||||||
|
return (0,'You are not the manager of this team')
|
||||||
try:
|
try:
|
||||||
t.name = name
|
t.name = name
|
||||||
t.manager = manager
|
t.manager = manager
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ urlpatterns = [
|
|||||||
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)/s/(?P<successmessage>\w+.*)$',views.workout_edit_view),
|
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)/s/(?P<successmessage>\w+.*)$',views.workout_edit_view),
|
||||||
url(r'^workout/(?P<id>\d+)/edit/c/(?P<message>.+.*)$',views.workout_edit_view),
|
url(r'^workout/(?P<id>\d+)/edit/c/(?P<message>.+.*)$',views.workout_edit_view),
|
||||||
url(r'^workout/(?P<id>\d+)/edit/s/(?P<successmessage>.+.*)$',views.workout_edit_view),
|
url(r'^workout/(?P<id>\d+)/edit/s/(?P<successmessage>.+.*)$',views.workout_edit_view),
|
||||||
url(r'^workout/(\d+)/edit$',views.workout_edit_view),
|
url(r'^workout/(?P<id>\d+)/edit$',views.workout_edit_view),
|
||||||
url(r'^workout/(?P<id>\d+)/advanced/c/(?P<message>.+.*)$',views.workout_advanced_view),
|
url(r'^workout/(?P<id>\d+)/advanced/c/(?P<message>.+.*)$',views.workout_advanced_view),
|
||||||
url(r'^workout/(?P<id>\d+)/advanced/s/(?P<successmessage>.+.*)$',views.workout_advanced_view),
|
url(r'^workout/(?P<id>\d+)/advanced/s/(?P<successmessage>.+.*)$',views.workout_advanced_view),
|
||||||
url(r'^workout/(?P<id>\d+)/geeky$',views.workout_geeky_view),
|
url(r'^workout/(?P<id>\d+)/geeky$',views.workout_geeky_view),
|
||||||
|
|||||||
358
rowers/views.py
358
rowers/views.py
@@ -4053,6 +4053,7 @@ def workout_getc2workout_view(request,c2id):
|
|||||||
|
|
||||||
# This is the main view for processing uploaded files
|
# This is the main view for processing uploaded files
|
||||||
@login_required()
|
@login_required()
|
||||||
|
def workout_upload_view(request,message=""):
|
||||||
r = Rower.objects.get(user=request.user)
|
r = Rower.objects.get(user=request.user)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = DocumentsForm(request.POST,request.FILES)
|
form = DocumentsForm(request.POST,request.FILES)
|
||||||
@@ -4070,283 +4071,82 @@ def workout_upload_view(request,message=""):
|
|||||||
|
|
||||||
|
|
||||||
f1 = res[0] # file name
|
f1 = res[0] # file name
|
||||||
f2 = res[1] # file name incl media directory
|
|
||||||
|
|
||||||
# get file type (ErgData, NK, BoatCoach, etc
|
|
||||||
fileformat = get_file_type(f2)
|
|
||||||
if len(fileformat)==3 and fileformat[0]=='zip':
|
|
||||||
f_to_be_deleted = f2
|
|
||||||
with zipfile.ZipFile(f2) as z:
|
|
||||||
# for now, we're getting only the first file
|
|
||||||
# from the NK zip file (issue #69 on bitbucket)
|
|
||||||
f2 = z.extract(z.namelist()[0],path='media/')
|
|
||||||
fileformat = fileformat[2]
|
|
||||||
f2 = res[1] # file name incl media directory
|
f2 = res[1] # file name incl media directory
|
||||||
|
|
||||||
# Some people try to upload Concept2 logbook summaries
|
|
||||||
if fileformat == 'c2log':
|
id,message = dataprep.new_workout_from_file(r,f2,
|
||||||
os.remove(f2)
|
workouttype=workouttype,
|
||||||
|
title = t,
|
||||||
|
notes='')
|
||||||
if not id:
|
if not id:
|
||||||
url = reverse(workout_upload_view,
|
url = reverse(workout_upload_view,
|
||||||
args=[str(message)])
|
args=[str(message)])
|
||||||
response = HttpResponseRedirect(url)
|
response = HttpResponseRedirect(url)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
# Some people try to upload RowPro summary logs
|
else:
|
||||||
if fileformat == 'rowprolog':
|
if message:
|
||||||
os.remove(f2)
|
url = reverse(workout_edit_view,
|
||||||
message = "This RowPro logbook summary does not contain stroke data. Please use the Stroke Data CSV file for the individual workout in your log."
|
kwargs = {
|
||||||
url = reverse(workout_upload_view,
|
'id':id,
|
||||||
args=[str(message)])
|
'message':message,
|
||||||
response = HttpResponseRedirect(url)
|
})
|
||||||
|
else:
|
||||||
|
url = reverse(workout_edit_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':id,
|
||||||
|
})
|
||||||
|
|
||||||
|
response = HttpResponseRedirect(url)
|
||||||
w = Workout.objects.get(id=id)
|
w = Workout.objects.get(id=id)
|
||||||
|
|
||||||
# Sometimes people try an unsupported file type.
|
if (make_plot):
|
||||||
# Send an email to info@rowsandall.com with the file attached
|
imagename = f1[:-4]+'.png'
|
||||||
# for me to check if it is a bug, or a new file type
|
fullpathimagename = 'static/plots/'+imagename
|
||||||
# worth supporting
|
|
||||||
if fileformat == 'unknown':
|
|
||||||
message = "We couldn't recognize the file type"
|
|
||||||
url = reverse(workout_upload_view,
|
|
||||||
args=[str(message)])
|
|
||||||
response = HttpResponseRedirect(url)
|
|
||||||
if settings.DEBUG:
|
|
||||||
res = handle_sendemail_unrecognized.delay(f2,
|
|
||||||
request.user.email)
|
|
||||||
|
|
||||||
else:
|
|
||||||
res = queuehigh.enqueue(handle_sendemail_unrecognized,
|
|
||||||
f2,request.user.email)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
summary = ''
|
|
||||||
# handle non-Painsled by converting it to painsled
|
|
||||||
# compatible CSV
|
|
||||||
try:
|
|
||||||
if (fileformat != 'csv'):
|
|
||||||
# handle RowPro:
|
|
||||||
if (fileformat == 'rp'):
|
|
||||||
row = RowProParser(f2)
|
|
||||||
# handle TCX
|
|
||||||
if (fileformat == 'tcx'):
|
|
||||||
row = TCXParser(f2)
|
|
||||||
|
|
||||||
# handle Mystery
|
|
||||||
if (fileformat == 'mystery'):
|
|
||||||
row = MysteryParser(f2)
|
|
||||||
|
|
||||||
# handle RowPerfect
|
|
||||||
if (fileformat == 'rowperfect3'):
|
|
||||||
row = RowPerfectParser(f2)
|
|
||||||
|
|
||||||
# handle TCX no HR
|
|
||||||
if (fileformat == 'tcxnohr'):
|
|
||||||
row = TCXParserNoHR(f2)
|
|
||||||
|
|
||||||
# handle ErgData
|
|
||||||
if (fileformat == 'ergdata'):
|
|
||||||
row = ErgDataParser(f2)
|
|
||||||
|
|
||||||
# handle Mike
|
|
||||||
if (fileformat == 'bcmike'):
|
|
||||||
row = BoatCoachAdvancedParser(f2)
|
|
||||||
|
|
||||||
# handle BoatCoach
|
|
||||||
if (fileformat == 'boatcoach'):
|
|
||||||
row = BoatCoachParser(f2)
|
|
||||||
|
|
||||||
# handle painsled desktop
|
|
||||||
if (fileformat == 'painsleddesktop'):
|
|
||||||
row = painsledDesktopParser(f2)
|
|
||||||
|
|
||||||
# handle speed coach GPS
|
|
||||||
if (fileformat == 'speedcoach'):
|
|
||||||
row = speedcoachParser(f2)
|
|
||||||
|
|
||||||
# handle speed coach GPS 2
|
|
||||||
if (fileformat == 'speedcoach2'):
|
|
||||||
row = SpeedCoach2Parser(f2)
|
|
||||||
try:
|
|
||||||
summary = row.allstats()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# handle ErgStick
|
|
||||||
if (fileformat == 'ergstick'):
|
|
||||||
row = ErgStickParser(f2)
|
|
||||||
|
|
||||||
# handle FIT
|
|
||||||
if (fileformat == 'fit'):
|
|
||||||
row = FITParser(f2)
|
|
||||||
# The FIT files have nice lap/split summaries
|
|
||||||
# so we make use of it
|
|
||||||
s = fitsummarydata(f2)
|
|
||||||
s.setsummary()
|
|
||||||
summary = s.summarytext
|
|
||||||
|
|
||||||
# Save the Painsled compatible CSV file and delete
|
|
||||||
# the uploaded file
|
|
||||||
f_to_be_deleted = f2
|
|
||||||
# should delete file
|
|
||||||
f2 = f2[:-4]+'o.csv'
|
|
||||||
row.write_csv(f2,gzip=True)
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.remove(f_to_be_deleted)
|
|
||||||
except:
|
|
||||||
os.remove(f_to_be_deleted+'.gz')
|
|
||||||
|
|
||||||
u = request.user
|
u = request.user
|
||||||
r = Rower.objects.get(user=request.user)
|
r = Rower.objects.get(user=request.user)
|
||||||
powerperc = 100*np.array([r.pw_ut2,
|
powerperc = 100*np.array([r.pw_ut2,
|
||||||
r.pw_ut1,
|
r.pw_ut1,
|
||||||
r.pw_at,
|
r.pw_at,
|
||||||
r.pw_tr,r.pw_an])/r.ftp
|
r.pw_tr,r.pw_an])/r.ftp
|
||||||
|
|
||||||
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
hrpwrdata = {
|
||||||
hrut1=r.ut1,hrat=r.at,
|
'hrmax':r.max,
|
||||||
hrtr=r.tr,hran=r.an,ftp=r.ftp,
|
'hrut2':r.ut2,
|
||||||
powerperc=powerperc,powerzones=r.powerzones)
|
'hrut1':r.ut1,
|
||||||
row = rdata(f2,rower=rr)
|
'hrat':r.at,
|
||||||
if row == 0:
|
'hrtr':r.tr,
|
||||||
|
'hran':r.an,
|
||||||
|
'ftp':r.ftp,
|
||||||
|
'powerperc':serialize_list(powerperc),
|
||||||
|
'powerzones':serialize_list(r.powerzones),
|
||||||
}
|
}
|
||||||
|
|
||||||
# auto smoothing
|
# make plot - asynchronous task
|
||||||
pace = row.df[' Stroke500mPace (sec/500m)'].values
|
plotnrs = {
|
||||||
velo = 500./pace
|
'timeplot':1,
|
||||||
|
'distanceplot':2,
|
||||||
f = row.df['TimeStamp (sec)'].diff().mean()
|
'pieplot':3,
|
||||||
windowsize = 2*(int(10./(f)))+1
|
|
||||||
if not 'originalvelo' in row.df:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if windowsize > 3 and windowsize<len(velo):
|
plotnr = plotnrs[plottype]
|
||||||
|
if (workouttype=='water'):
|
||||||
|
plotnr = plotnr+3
|
||||||
|
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
res = handle_makeplot.delay(f1,f2,t,
|
||||||
|
hrpwrdata,plotnr,
|
||||||
imagename)
|
imagename)
|
||||||
else:
|
else:
|
||||||
velo2 = velo
|
res = queue.enqueue(handle_makeplot,f1,f2,
|
||||||
|
t,hrpwrdata,
|
||||||
velo3 = pd.Series(velo2)
|
|
||||||
velo3 = velo3.replace([-np.inf,np.inf],np.nan)
|
|
||||||
velo3 = velo3.fillna(method='ffill')
|
|
||||||
|
|
||||||
pace2 = 500./abs(velo3)
|
|
||||||
|
|
||||||
row.df[' Stroke500mPace (sec/500m)'] = pace2
|
|
||||||
|
|
||||||
row.df = row.df.fillna(0)
|
|
||||||
|
|
||||||
row.write_csv(f2,gzip=True)
|
|
||||||
try:
|
|
||||||
os.remove(f2)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# recalculate power data
|
|
||||||
if workouttype == 'rower' or workouttype == 'dynamic' or workouttype == 'slides':
|
|
||||||
try:
|
|
||||||
row.erg_recalculatepower()
|
|
||||||
row.write_csv(f2,gzip=True)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if fileformat != 'fit' and summary == '':
|
|
||||||
summary = row.summary()
|
|
||||||
summary += '\n'
|
|
||||||
summary += row.intervalstats_painsled()
|
|
||||||
|
|
||||||
averagehr = row.df[' HRCur (bpm)'].mean()
|
|
||||||
maxhr = row.df[' HRCur (bpm)'].max()
|
|
||||||
|
|
||||||
totaldist = row.df['cum_dist'].max()
|
|
||||||
totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
|
|
||||||
totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
|
|
||||||
|
|
||||||
hours = int(totaltime/3600.)
|
|
||||||
minutes = int((totaltime - 3600.*hours)/60.)
|
|
||||||
seconds = int(totaltime - 3600.*hours - 60.*minutes)
|
|
||||||
tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
|
|
||||||
|
|
||||||
|
|
||||||
duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
|
|
||||||
|
|
||||||
workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
|
|
||||||
workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
|
|
||||||
workoutstartdatetime = thetimezone.localize(row.rowdatetime).astimezone(utc)
|
|
||||||
|
|
||||||
# check for duplicate start times
|
|
||||||
r = Rower.objects.get(user=request.user)
|
|
||||||
|
|
||||||
ws = Workout.objects.filter(starttime=workoutstarttime,
|
|
||||||
user=r)
|
|
||||||
if (len(ws) != 0):
|
|
||||||
message = "Warning: This workout probably already exists in the database"
|
|
||||||
|
|
||||||
w = Workout(user=r,name=t,date=workoutdate,
|
|
||||||
workouttype=workouttype,
|
|
||||||
duration=duration,distance=totaldist,
|
|
||||||
weightcategory=r.weightcategory,
|
|
||||||
starttime=workoutstarttime,
|
|
||||||
csvfilename=f2,notes=notes,summary=summary,
|
|
||||||
maxhr=maxhr,averagehr=averagehr,
|
|
||||||
startdatetime=workoutstartdatetime)
|
|
||||||
|
|
||||||
w.save()
|
|
||||||
|
|
||||||
# put stroke data in database
|
|
||||||
res = dataprep.dataprep(row.df,id=w.id,
|
|
||||||
bands=True,barchart=True,
|
|
||||||
otwpower=True,empower=True)
|
|
||||||
|
|
||||||
# Make Plot
|
|
||||||
if (make_plot):
|
|
||||||
imagename = f1[:-4]+'.png'
|
|
||||||
fullpathimagename = 'static/plots/'+imagename
|
|
||||||
u = request.user
|
|
||||||
r = Rower.objects.get(user=request.user)
|
|
||||||
powerperc = 100*np.array([r.pw_ut2,
|
|
||||||
r.pw_ut1,
|
|
||||||
r.pw_at,
|
|
||||||
r.pw_tr,r.pw_an])/r.ftp
|
|
||||||
|
|
||||||
|
|
||||||
hrpwrdata = {
|
|
||||||
'hrmax':r.max,
|
|
||||||
'hrut2':r.ut2,
|
|
||||||
'hrut1':r.ut1,
|
|
||||||
'hrat':r.at,
|
|
||||||
'hrtr':r.tr,
|
|
||||||
'hran':r.an,
|
|
||||||
'ftp':r.ftp,
|
|
||||||
'powerperc':serialize_list(powerperc),
|
|
||||||
'powerzones':serialize_list(r.powerzones),
|
|
||||||
}
|
|
||||||
|
|
||||||
# make plot - asynchronous task
|
|
||||||
plotnrs = {
|
|
||||||
'timeplot':1,
|
|
||||||
'distanceplot':2,
|
|
||||||
'pieplot':3,
|
|
||||||
}
|
|
||||||
|
|
||||||
plotnr = plotnrs[plottype]
|
|
||||||
if (workouttype=='water'):
|
|
||||||
plotnr,imagename)
|
plotnr,imagename)
|
||||||
|
|
||||||
|
|
||||||
if settings.DEBUG:
|
i = GraphImage(workout=w,
|
||||||
res = handle_makeplot.delay(f1,f2,t,
|
creationdatetime=timezone.now(),
|
||||||
hrpwrdata,plotnr,
|
filename=fullpathimagename)
|
||||||
imagename)
|
|
||||||
else:
|
|
||||||
res = queue.enqueue(handle_makeplot,f1,f2,
|
|
||||||
t,hrpwrdata,
|
|
||||||
plotnr,imagename)
|
|
||||||
|
|
||||||
|
|
||||||
i = GraphImage(workout=w,
|
|
||||||
creationdatetime=timezone.now(),
|
|
||||||
filename=fullpathimagename)
|
|
||||||
i.save()
|
i.save()
|
||||||
|
|
||||||
# upload to C2
|
# upload to C2
|
||||||
@@ -4355,7 +4155,6 @@ def workout_upload_view(request,message=""):
|
|||||||
thetoken = c2_open(request.user)
|
thetoken = c2_open(request.user)
|
||||||
except C2NoTokenError:
|
except C2NoTokenError:
|
||||||
return HttpResponseRedirect("/rowers/me/c2authorize/")
|
return HttpResponseRedirect("/rowers/me/c2authorize/")
|
||||||
try:
|
|
||||||
try:
|
try:
|
||||||
c2userid = c2stuff.get_userid(thetoken)
|
c2userid = c2stuff.get_userid(thetoken)
|
||||||
data = c2stuff.createc2workoutdata(w)
|
data = c2stuff.createc2workoutdata(w)
|
||||||
@@ -4383,28 +4182,29 @@ def workout_upload_view(request,message=""):
|
|||||||
s= json.loads(response.text)
|
s= json.loads(response.text)
|
||||||
c2id = s['data']['id']
|
c2id = s['data']['id']
|
||||||
w.uploadedtoc2 = c2id
|
w.uploadedtoc2 = c2id
|
||||||
w.save()
|
w.save()
|
||||||
|
except:
|
||||||
except:
|
message = "C2 upload failed"
|
||||||
message = "C2 upload failed"
|
url = reverse(workout_edit_view,
|
||||||
url = reverse(workout_edit_view,
|
|
||||||
kwargs={
|
kwargs={
|
||||||
'message':message,
|
'message':message,
|
||||||
'id':str(w.id),
|
'id':str(w.id),
|
||||||
})
|
})
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
# redirect to workout edit page
|
|
||||||
url = "/rowers/workout/"+str(w.id)+"/edit"
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
except:
|
|
||||||
if settings.DEBUG:
|
|
||||||
errorstring = str(sys.exc_info()[0])
|
|
||||||
print errorstring
|
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
url = reverse(workout_upload_view,
|
|
||||||
args=[str(message)])
|
if message:
|
||||||
|
url = reverse(workout_edit_view,
|
||||||
|
kwargs={
|
||||||
|
'message':message,
|
||||||
|
'id':w.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
else:
|
||||||
|
url = reverse(workout_edit_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':w.id,
|
||||||
|
})
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
else:
|
else:
|
||||||
response = render(request,
|
response = render(request,
|
||||||
|
|||||||
Reference in New Issue
Block a user