Merge branch 'feature/asynchronousranking' into develop
This commit is contained in:
+27
-10
@@ -26,7 +26,7 @@ from rowingdata import (
|
||||
MysteryParser, BoatCoachOTWParser,
|
||||
painsledDesktopParser, speedcoachParser, ErgStickParser,
|
||||
SpeedCoach2Parser, FITParser, fitsummarydata,
|
||||
make_cumvalues,
|
||||
make_cumvalues,cumcpdata,
|
||||
summarydata, get_file_type,
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ import itertools
|
||||
import math
|
||||
from tasks import (
|
||||
handle_sendemail_unrecognized, handle_sendemail_breakthrough,
|
||||
handle_sendemail_hard, handle_updatecp
|
||||
handle_sendemail_hard, handle_updatecp,handle_updateergcp
|
||||
)
|
||||
|
||||
from django.conf import settings
|
||||
@@ -426,20 +426,22 @@ def paceformatsecs(values):
|
||||
|
||||
return out
|
||||
|
||||
def getcpdata_sql(rower_id):
|
||||
def getcpdata_sql(rower_id,table='cpdata'):
|
||||
engine = create_engine(database_url, echo=False)
|
||||
query = sa.text('SELECT delta,cp from cpdata WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id
|
||||
query = sa.text('SELECT * from {table} WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
connection = engine.raw_connection()
|
||||
df = pd.read_sql_query(query, engine)
|
||||
|
||||
return df
|
||||
|
||||
def deletecpdata_sql(rower_id):
|
||||
def deletecpdata_sql(rower_id,table='cpdata'):
|
||||
engine = create_engine(database_url, echo=False)
|
||||
query = sa.text('DELETE from cpdata WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id
|
||||
query = sa.text('DELETE from {table} WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
with engine.connect() as conn, conn.begin():
|
||||
try:
|
||||
@@ -451,7 +453,7 @@ def deletecpdata_sql(rower_id):
|
||||
|
||||
|
||||
|
||||
def updatecpdata_sql(rower_id,delta,cp):
|
||||
def updatecpdata_sql(rower_id,delta,cp,table='cpdata',distance=[]):
|
||||
deletecpdata_sql(rower_id)
|
||||
df = pd.DataFrame(
|
||||
{
|
||||
@@ -461,9 +463,12 @@ def updatecpdata_sql(rower_id,delta,cp):
|
||||
}
|
||||
)
|
||||
|
||||
if not distance.empty:
|
||||
df['distance'] = distance
|
||||
|
||||
engine = create_engine(database_url, echo=False)
|
||||
with engine.connect() as conn, conn.begin():
|
||||
df.to_sql('cpdata', engine, if_exists='append', index=False)
|
||||
df.to_sql(table, engine, if_exists='append', index=False)
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
@@ -484,6 +489,18 @@ def runcpupdate(rower):
|
||||
else:
|
||||
res = queue.enqueue(handle_updatecp,rower.id,theids)
|
||||
|
||||
def fetchcperg(rower,theworkouts):
|
||||
theids = [int(w.id) for w in theworkouts]
|
||||
thefilenames = [w.csvfilename for w in theworkouts]
|
||||
cpdf = getcpdata_sql(rower.id,table='ergcpdata')
|
||||
|
||||
if settings.DEBUG:
|
||||
res = handle_updateergcp.delay(rower.id,thefilenames,debug=True)
|
||||
else:
|
||||
res = queue.enqueue(handle_updateergcp,rower.id,thefilenames)
|
||||
|
||||
return cpdf
|
||||
|
||||
|
||||
def fetchcp(rower,theworkouts):
|
||||
# get all power data from database (plus workoutid)
|
||||
|
||||
@@ -548,14 +548,30 @@ def read_df_sql(id,debug=False):
|
||||
engine.dispose()
|
||||
return df
|
||||
|
||||
def deletecpdata_sql(rower_id,debug=False):
|
||||
def getcpdata_sql(rower_id,table='cpdata',debug=False):
|
||||
if debug:
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
query = sa.text('DELETE from cpdata WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id
|
||||
query = sa.text('SELECT * from {table} WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
connection = engine.raw_connection()
|
||||
df = pd.read_sql_query(query, engine)
|
||||
|
||||
return df
|
||||
|
||||
def deletecpdata_sql(rower_id,table='cpdata',debug=False):
|
||||
if debug:
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
query = sa.text('DELETE from {table} WHERE user={rower_id};'.format(
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
with engine.connect() as conn, conn.begin():
|
||||
try:
|
||||
@@ -567,8 +583,8 @@ def deletecpdata_sql(rower_id,debug=False):
|
||||
|
||||
|
||||
|
||||
def updatecpdata_sql(rower_id,delta,cp,debug=False):
|
||||
deletecpdata_sql(rower_id,debug=debug)
|
||||
def updatecpdata_sql(rower_id,delta,cp,table='cpdata',distance=pd.Series([]),debug=False):
|
||||
deletecpdata_sql(rower_id,table=table,debug=debug)
|
||||
df = pd.DataFrame(
|
||||
{
|
||||
'delta':delta,
|
||||
@@ -577,19 +593,24 @@ def updatecpdata_sql(rower_id,delta,cp,debug=False):
|
||||
}
|
||||
)
|
||||
|
||||
if not distance.empty:
|
||||
df['distance'] = distance
|
||||
|
||||
if debug:
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
df.to_sql('cpdata', engine, if_exists='append', index=False)
|
||||
df.to_sql(table, engine, if_exists='append', index=False)
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def smalldataprep(therows,xparam,yparam1,yparam2):
|
||||
df = pd.DataFrame()
|
||||
if yparam2 == 'None':
|
||||
|
||||
+7
-2
@@ -152,6 +152,11 @@ class WorkFlowMiddlePanelElement(forms.Form):
|
||||
|
||||
# The form to indicate additional actions to be performed immediately
|
||||
# after a successful upload
|
||||
|
||||
nextpages = list(landingpages)
|
||||
nextpages.append(('workout_upload_view','Upload Another File'))
|
||||
nextpages = tuple(nextpages)
|
||||
|
||||
class UploadOptionsForm(forms.Form):
|
||||
plotchoices = (
|
||||
('timeplot','Time Plot'),
|
||||
@@ -181,9 +186,9 @@ class UploadOptionsForm(forms.Form):
|
||||
makeprivate = forms.BooleanField(initial=False,required=False,
|
||||
label='Make Workout Private')
|
||||
|
||||
landingpage = forms.ChoiceField(choices=landingpages,
|
||||
landingpage = forms.ChoiceField(choices=nextpages,
|
||||
initial='workout_edit_view',
|
||||
label='Landing Page')
|
||||
label='After Upload, go to')
|
||||
|
||||
class Meta:
|
||||
fields = ['make_plot','plottype','upload_toc2','makeprivate']
|
||||
|
||||
+14
-14
@@ -41,6 +41,7 @@ import pandas as pd
|
||||
from pytz import timezone as tz,utc
|
||||
from django.utils.timezone import get_current_timezone
|
||||
from django.utils.timezone import activate
|
||||
from django.utils import timezone
|
||||
activate(settings.TIME_ZONE)
|
||||
thetimezone = get_current_timezone()
|
||||
|
||||
@@ -1065,10 +1066,9 @@ def interactive_otwcpchart(powerdf,promember=0):
|
||||
|
||||
return [script,div,p1,ratio,message]
|
||||
|
||||
def interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
def interactive_cpchart(rower,thedistances,thesecs,theavpower,
|
||||
theworkouts,promember=0):
|
||||
|
||||
|
||||
message = 0
|
||||
# plot tools
|
||||
if (promember==1):
|
||||
@@ -1108,6 +1108,7 @@ def interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
paulslope = 5.0/np.log10(2.0)
|
||||
paulintercept = p[0]-paulslope*np.log10(thedistances[0])
|
||||
|
||||
|
||||
fitx = pd.Series(np.arange(100)*2*max(np.log10(thedistances))/100.)
|
||||
|
||||
fitp = paulslope*fitx+paulintercept
|
||||
@@ -1198,16 +1199,14 @@ def interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
plot.xaxis.axis_label = "Duration (seconds)"
|
||||
plot.yaxis.axis_label = "Power (W)"
|
||||
|
||||
therows = []
|
||||
for workout in theworkouts:
|
||||
f1 = workout.csvfilename
|
||||
rowdata = rdata(f1)
|
||||
if rowdata != 0:
|
||||
therows.append(rowdata)
|
||||
|
||||
cpdata = cumcpdata(therows)
|
||||
cpdata = dataprep.fetchcperg(rower, theworkouts)
|
||||
|
||||
velo = cpdata['Distance']/cpdata['Delta']
|
||||
if cpdata.empty:
|
||||
message = 'Calculations are running in the background. Please refresh this page to see updated results'
|
||||
return ['','',paulslope,paulintercept,p1,message]
|
||||
|
||||
velo = cpdata['distance']/cpdata['delta']
|
||||
|
||||
p = 500./velo
|
||||
|
||||
@@ -1215,12 +1214,12 @@ def interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
|
||||
source2 = ColumnDataSource(
|
||||
data = dict(
|
||||
duration = cpdata['Delta'],
|
||||
power = cpdata['CP'],
|
||||
duration = cpdata['delta'],
|
||||
power = cpdata['cp'],
|
||||
tim = niceformat(
|
||||
cpdata['Delta'].fillna(method='ffill').apply(lambda x: timedeltaconv(x))
|
||||
cpdata['delta'].fillna(method='ffill').apply(lambda x: timedeltaconv(x))
|
||||
),
|
||||
dist = cpdata['Distance'],
|
||||
dist = cpdata['distance'],
|
||||
pace = nicepaceformat(p2),
|
||||
)
|
||||
)
|
||||
@@ -1252,6 +1251,7 @@ def interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
|
||||
script, div = components(plot)
|
||||
|
||||
|
||||
return [script,div,paulslope,paulintercept,p1,message]
|
||||
|
||||
def interactive_windchart(id=0,promember=0):
|
||||
|
||||
@@ -653,6 +653,18 @@ class cpdata(models.Model):
|
||||
index_together = ['user']
|
||||
app_label = 'rowers'
|
||||
|
||||
# Storing data for the OTW CP chart
|
||||
class ergcpdata(models.Model):
|
||||
delta = models.IntegerField(default=0)
|
||||
cp = models.FloatField(default=0)
|
||||
distance = models.FloatField(default=0)
|
||||
user = models.IntegerField(default=0)
|
||||
|
||||
class Meta:
|
||||
db_table = 'ergcpdata'
|
||||
index_together = ['user']
|
||||
app_label = 'rowers'
|
||||
|
||||
# A wrapper around the png files
|
||||
class GraphImage(models.Model):
|
||||
filename = models.CharField(default='',max_length=150,blank=True,null=True)
|
||||
|
||||
+18
-1
@@ -400,7 +400,24 @@ def handle_otwsetpower(f1, boattype, weightvalue,
|
||||
|
||||
return 1
|
||||
|
||||
# This function generates all the static (PNG image) plots
|
||||
|
||||
@app.task
|
||||
def handle_updateergcp(rower_id,workoutfilenames,debug=False):
|
||||
therows = []
|
||||
for f1 in workoutfilenames:
|
||||
rowdata = rdata(f1)
|
||||
if rowdata != 0:
|
||||
therows.append(rowdata)
|
||||
|
||||
cpdata = rowingdata.cumcpdata(therows)
|
||||
cpdata.columns = cpdata.columns.str.lower()
|
||||
|
||||
updatecpdata_sql(rower_id,cpdata['delta'],cpdata['cp'],
|
||||
table='ergcpdata',distance=cpdata['distance'],
|
||||
debug=debug)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@app.task
|
||||
def handle_updatecp(rower_id,workoutids,debug=False):
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ urlpatterns = [
|
||||
url(r'^graph/(?P<id>\d+)/deleteconfirm$',views.graph_delete_confirm_view),
|
||||
url(r'^graph/(?P<id>\d+)/delete$',views.graph_delete_view),
|
||||
url(r'^workout/upload/team/$',views.team_workout_upload_view),
|
||||
url(r'^workout/upload/$',views.workout_upload_view),
|
||||
url(r'^workout/upload/$',views.workout_upload_view,name='workout_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/histo$',views.workout_histo_view),
|
||||
url(r'^workout/(?P<id>\d+)/task$',views.workout_test_task_view),
|
||||
url(r'^workout/(?P<id>\d+)/forcecurve$',views.workout_forcecurve_view),
|
||||
|
||||
+9
-2
@@ -2733,6 +2733,7 @@ def rankings_view(request,theuser=0,
|
||||
rankingdurations.append(datetime.time(minute=1))
|
||||
rankingdurations.append(datetime.time(minute=4))
|
||||
rankingdurations.append(datetime.time(minute=30))
|
||||
rankingdurations.append(datetime.time(hour=1,minute=15))
|
||||
rankingdurations.append(datetime.time(hour=1))
|
||||
|
||||
thedistances = []
|
||||
@@ -2787,8 +2788,10 @@ def rankings_view(request,theuser=0,
|
||||
|
||||
# create interactive plot
|
||||
if len(thedistances) !=0 :
|
||||
res = interactive_cpchart(thedistances,thesecs,theavpower,
|
||||
theworkouts,promember=promember)
|
||||
res = interactive_cpchart(
|
||||
r,thedistances,thesecs,theavpower,
|
||||
theworkouts,promember=promember
|
||||
)
|
||||
script = res[0]
|
||||
div = res[1]
|
||||
paulslope = res[2]
|
||||
@@ -7803,10 +7806,14 @@ def workout_upload_view(request,
|
||||
else:
|
||||
messages.error(request,message)
|
||||
|
||||
if landingpage != 'workout_upload_view':
|
||||
url = reverse(landingpage,
|
||||
kwargs = {
|
||||
'id':w.id,
|
||||
})
|
||||
else:
|
||||
url = reverse(landingpage)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
response = render(request,
|
||||
|
||||
Reference in New Issue
Block a user