Merge branch 'release/v5.22'
This commit is contained in:
@@ -18,3 +18,6 @@ def hello_world(request):
|
||||
return {
|
||||
'helloworld': 'hi Sander'
|
||||
}
|
||||
|
||||
def warning_message(request):
|
||||
return {'WARNING_MESSAGE': settings.WARNING_MESSAGE}
|
||||
|
||||
+38
-18
@@ -916,6 +916,16 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
w.startdatetime = timezone.now()
|
||||
w.save()
|
||||
|
||||
|
||||
if privacy == 'visible':
|
||||
ts = Team.objects.filter(rower=r)
|
||||
for t in ts:
|
||||
w.team.add(t)
|
||||
|
||||
# put stroke data in database
|
||||
res = dataprep(row.df, id=w.id, bands=True,
|
||||
barchart=True, otwpower=True, empower=True, inboard=inboard)
|
||||
|
||||
isbreakthrough = False
|
||||
ishard = False
|
||||
if workouttype == 'water':
|
||||
@@ -981,14 +991,6 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
else:
|
||||
pass
|
||||
|
||||
if privacy == 'visible':
|
||||
ts = Team.objects.filter(rower=r)
|
||||
for t in ts:
|
||||
w.team.add(t)
|
||||
|
||||
# put stroke data in database
|
||||
res = dataprep(row.df, id=w.id, bands=True,
|
||||
barchart=True, otwpower=True, empower=True, inboard=inboard)
|
||||
|
||||
return (w.id, message)
|
||||
|
||||
@@ -1150,14 +1152,6 @@ def new_workout_from_file(r, f2,
|
||||
a = MessageAttachment(message=msg,document=f3)
|
||||
a.save()
|
||||
|
||||
# res = myqueue(
|
||||
# queuelow,
|
||||
# handle_zip_file,
|
||||
# r.user.email,
|
||||
# title,
|
||||
# f2
|
||||
# )
|
||||
|
||||
return -1, message, f2
|
||||
|
||||
# Some people try to upload Concept2 logbook summaries
|
||||
@@ -1547,8 +1541,27 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True):
|
||||
|
||||
def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True):
|
||||
prepmultipledata(ids)
|
||||
data = read_cols_df_sql(ids, columns)
|
||||
data,extracols = read_cols_df_sql(ids, columns)
|
||||
if extracols and len(ids)==1:
|
||||
w = Workout.objects.get(id=ids[0])
|
||||
row = rdata(w.csvfilename)
|
||||
f = row.df['TimeStamp (sec)'].diff().mean()
|
||||
if f != 0 and not np.isnan(f):
|
||||
windowsize = 2 * (int(10. / (f))) + 1
|
||||
else:
|
||||
windowsize = 1
|
||||
for c in extracols:
|
||||
try:
|
||||
cdata = row.df[c]
|
||||
cdata.fillna(inplace=True,method='bfill')
|
||||
# This doesn't work because sometimes data are duplicated at save
|
||||
cdata2 = savgol_filter(cdata.values,windowsize,3)
|
||||
|
||||
print len(cdata),len(cdata2),'mies'
|
||||
data[c] = cdata2
|
||||
except KeyError:
|
||||
data[c] = 0
|
||||
|
||||
# convert newtons
|
||||
|
||||
if doclean:
|
||||
@@ -1622,10 +1635,15 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
|
||||
# axx = [ax[0] for ax in axes]
|
||||
axx = [f.name for f in StrokeData._meta.get_fields()]
|
||||
|
||||
extracols = []
|
||||
|
||||
|
||||
for c in columns:
|
||||
if not c in axx:
|
||||
columns.remove(c)
|
||||
extracols.append(c)
|
||||
|
||||
|
||||
columns = list(columns) + ['distance', 'spm', 'workoutid']
|
||||
columns = [x for x in columns if x != 'None']
|
||||
columns = list(set(columns))
|
||||
@@ -1673,7 +1691,7 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
|
||||
'averageforce'] * lbstoN
|
||||
|
||||
engine.dispose()
|
||||
return df
|
||||
return df,extracols
|
||||
|
||||
# Read stroke data from the DB for a Workout ID. Returns a pandas dataframe
|
||||
|
||||
@@ -1973,6 +1991,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if bands:
|
||||
# HR bands
|
||||
data['hr_ut2'] = rowdatadf.ix[:, 'hr_ut2']
|
||||
@@ -2133,6 +2152,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
# write data if id given
|
||||
if id != 0:
|
||||
data['workoutid'] = id
|
||||
|
||||
engine = create_engine(database_url, echo=False)
|
||||
with engine.connect() as conn, conn.begin():
|
||||
data.to_sql('strokedata', engine, if_exists='append', index=False)
|
||||
|
||||
+39
-12
@@ -2175,13 +2175,19 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
except KeyError:
|
||||
y1mean = 0
|
||||
|
||||
|
||||
|
||||
rowdata['xname'] = axlabels[xparam]
|
||||
rowdata['yname1'] = axlabels[yparam1]
|
||||
try:
|
||||
rowdata['yname1'] = axlabels[yparam1]
|
||||
except KeyError:
|
||||
rowdata['yname1'] = yparam1
|
||||
if yparam2 != 'None':
|
||||
rowdata['yname2'] = axlabels[yparam2]
|
||||
try:
|
||||
rowdata['yname2'] = axlabels[yparam2]
|
||||
except KeyError:
|
||||
rowdata['yname2'] = yparam2
|
||||
else:
|
||||
rowdata['yname2'] = axlabels[yparam1]
|
||||
rowdata['yname2'] = rowdata['yname1']
|
||||
|
||||
|
||||
# prepare data
|
||||
@@ -2281,7 +2287,12 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
plot.title.text_font_size=value("1.0em")
|
||||
|
||||
plot.xaxis.axis_label = axlabels[xparam]
|
||||
plot.yaxis.axis_label = axlabels[yparam1]
|
||||
try:
|
||||
yaxlabel = axlabels[yparam1]
|
||||
except KeyError:
|
||||
yaxlabel = yparam1
|
||||
|
||||
plot.yaxis.axis_label = yaxlabel
|
||||
|
||||
|
||||
|
||||
@@ -2289,7 +2300,13 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
plot.y_range = yrange1
|
||||
|
||||
if (xparam != 'time') and (xparam != 'distance') and (xparam != 'cumdist'):
|
||||
xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam])
|
||||
try:
|
||||
xrange1 = Range1d(start=yaxminima[xparam],
|
||||
end=yaxmaxima[xparam])
|
||||
except KeyError:
|
||||
xrange1 = Range1d(start=rowdata[xparam].min(),
|
||||
end=rowdata[xparam].max())
|
||||
|
||||
plot.x_range = xrange1
|
||||
|
||||
if xparam == 'time':
|
||||
@@ -2313,22 +2330,32 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
|
||||
|
||||
if yparam2 != 'None':
|
||||
yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2])
|
||||
try:
|
||||
yrange2 = Range1d(start=yaxminima[yparam2],
|
||||
end=yaxmaxima[yparam2])
|
||||
except KeyError:
|
||||
yrange2 = Range1d(start=rowdata[yparam2].min(),
|
||||
end=rowdata[yparam2].max())
|
||||
|
||||
plot.extra_y_ranges["yax2"] = yrange2
|
||||
#= {"yax2": yrange2}
|
||||
try:
|
||||
axlegend = axlabels[yparam2]
|
||||
except KeyError:
|
||||
axlegend = str(yparam2)+' '
|
||||
|
||||
if plottype=='line':
|
||||
plot.line('x1','y2',color="red",y_range_name="yax2",
|
||||
legend=axlabels[yparam2],
|
||||
legend=axlegend,
|
||||
source=source2)
|
||||
|
||||
elif plottype=='scatter':
|
||||
plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2]
|
||||
,fill_alpha=0.4,
|
||||
plot.scatter('x1','y2',source=source2,legend=axlegend,
|
||||
fill_alpha=0.4,
|
||||
line_color=None,color="red",y_range_name="yax2")
|
||||
|
||||
plot.add_layout(LinearAxis(y_range_name="yax2",
|
||||
axis_label=axlabels[yparam2]),'right')
|
||||
axis_label=axlegend),'right')
|
||||
|
||||
y2means = Span(location=y2mean,dimension='width',line_color='red',
|
||||
line_dash=[6,6],line_width=2,y_range_name="yax2")
|
||||
@@ -2336,7 +2363,7 @@ def interactive_flex_chart2(id=0,promember=0,
|
||||
|
||||
plot.add_layout(y2means)
|
||||
y2label = Label(x=100,y=70,x_units='screen',y_units='screen',
|
||||
text=axlabels[yparam2]+": {y2mean:6.2f}".format(y2mean=y2mean),
|
||||
text=axlegend+": {y2mean:6.2f}".format(y2mean=y2mean),
|
||||
background_fill_alpha=.7,
|
||||
background_fill_color='white',
|
||||
text_color='red',
|
||||
|
||||
@@ -94,7 +94,15 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if promember %}
|
||||
{% for key, value in extrametrics.items %}
|
||||
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for key, value in extrametrics.items %}
|
||||
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,6 +127,15 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if promember %}
|
||||
{% for key, value in extrametrics.items %}
|
||||
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for key, value in extrametrics.items %}
|
||||
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+5
-5
@@ -363,12 +363,12 @@ urlpatterns = [
|
||||
url(r'^register/thankyou/$', TemplateView.as_view(template_name='registerthankyou.html'), name='registerthankyou'),
|
||||
url(r'^workout/(?P<id>\d+)/workflow$',views.workout_workflow_view,
|
||||
name='workout_workflow_view'),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart$',views.workout_flexchart3_view),
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/(?P<plottype>\w+.*)$',views.workout_comparison_view2),
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/$',views.workout_comparison_view2),
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/(?P<plottype>[\w\ ]+.*)$',views.workout_comparison_view2),
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||
url(r'^test\_callback',views.rower_process_testcallback),
|
||||
url(r'^workout/(?P<id>\d+)/test\_strokedata$',views.strokedataform),
|
||||
]
|
||||
|
||||
+61
-47
@@ -6455,7 +6455,10 @@ def instroke_view(request,id=0):
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
rowdata = rrdata(csvfile=row.csvfilename)
|
||||
instrokemetrics = rowdata.get_instroke_columns()
|
||||
try:
|
||||
instrokemetrics = rowdata.get_instroke_columns()
|
||||
except AttributeError:
|
||||
instrokemetrics = []
|
||||
|
||||
|
||||
return render(request,
|
||||
@@ -7491,7 +7494,12 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
if yparam2 == name:
|
||||
yparam2 = 'spm'
|
||||
messages.info(request,'To use '+d['verbose_name']+', you have to be Pro member')
|
||||
|
||||
|
||||
# bring back slashes
|
||||
yparam1 = yparam1.replace('_slsh_','/')
|
||||
yparam2 = yparam2.replace('_slsh_','/')
|
||||
xparam = xparam.replace('_slsh_','/')
|
||||
|
||||
# create interactive plot
|
||||
try:
|
||||
script,div,js_resources,css_resources,workstrokesonly = interactive_flex_chart2(id,xparam=xparam,yparam1=yparam1,
|
||||
@@ -7517,55 +7525,61 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
if d['mode'] == 'erg':
|
||||
axchoicespro.pop(name)
|
||||
|
||||
return render(request,
|
||||
'flexchart3otw.html',
|
||||
{'the_script':script,
|
||||
'the_div':div,
|
||||
'js_res': js_resources,
|
||||
'css_res':css_resources,
|
||||
'id':int(id),
|
||||
'teams':get_my_teams(request.user),
|
||||
'xparam':xparam,
|
||||
'yparam1':yparam1,
|
||||
'yparam2':yparam2,
|
||||
'plottype':plottype,
|
||||
'favoritechartnotes':favoritechartnotes,
|
||||
'mayedit':mayedit,
|
||||
'promember':promember,
|
||||
'axchoicesbasic':axchoicesbasic,
|
||||
'axchoicespro':axchoicespro,
|
||||
'noylist':noylist,
|
||||
'workstrokesonly': not workstrokesonly,
|
||||
'favoritenr':favoritenr,
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
else:
|
||||
for name,d in rowingmetrics:
|
||||
if d['mode'] == 'water':
|
||||
axchoicespro.pop(name)
|
||||
|
||||
return render(request,
|
||||
'flexchart3otw.html',
|
||||
{'the_script':script,
|
||||
'the_div':div,
|
||||
'js_res': js_resources,
|
||||
'css_res':css_resources,
|
||||
'teams':get_my_teams(request.user),
|
||||
'id':int(id),
|
||||
'xparam':xparam,
|
||||
'yparam1':yparam1,
|
||||
'yparam2':yparam2,
|
||||
'plottype':plottype,
|
||||
'axchoicesbasic':axchoicesbasic,
|
||||
'axchoicespro':axchoicespro,
|
||||
'favoritechartnotes':favoritechartnotes,
|
||||
'noylist':noylist,
|
||||
'mayedit':mayedit,
|
||||
'promember':promember,
|
||||
'workstrokesonly': not workstrokesonly,
|
||||
'favoritenr':favoritenr,
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
|
||||
|
||||
rowdata = rdata(row.csvfilename)
|
||||
additionalmetrics = rowdata.get_additional_metrics()
|
||||
|
||||
|
||||
extrametrics = {m.replace('/','_slsh_'):m for m in additionalmetrics}
|
||||
|
||||
try:
|
||||
extrametrics.pop('originalvelo')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
extrametrics.pop('cumdist')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
extrametrics.pop(' Cadence (strokes_slsh_min)')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
extrametrics.pop(' WorkPerStroke (joules)')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return render(request,
|
||||
'flexchart3otw.html',
|
||||
{'the_script':script,
|
||||
'the_div':div,
|
||||
'js_res': js_resources,
|
||||
'css_res':css_resources,
|
||||
'teams':get_my_teams(request.user),
|
||||
'id':int(id),
|
||||
'xparam':xparam,
|
||||
'yparam1':yparam1,
|
||||
'yparam2':yparam2,
|
||||
'plottype':plottype,
|
||||
'axchoicesbasic':axchoicesbasic,
|
||||
'axchoicespro':axchoicespro,
|
||||
'extrametrics':extrametrics,
|
||||
'favoritechartnotes':favoritechartnotes,
|
||||
'noylist':noylist,
|
||||
'mayedit':mayedit,
|
||||
'promember':promember,
|
||||
'workstrokesonly': not workstrokesonly,
|
||||
'favoritenr':favoritenr,
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
|
||||
|
||||
# The interactive plot with the colored Heart rate zones
|
||||
|
||||
@@ -117,6 +117,7 @@ TEMPLATES = [
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'django.template.context_processors.i18n',
|
||||
'context_processors.google_analytics',
|
||||
'context_processors.warning_message',
|
||||
],
|
||||
# 'loaders': [
|
||||
# 'django.template.loaders.app_directories.Loader',
|
||||
@@ -383,3 +384,9 @@ TWEET_ACCESS_TOKEN_SECRET = CFG['tweet_access_token_secret']
|
||||
TWEET_CONSUMER_KEY = CFG['tweet_consumer_key']
|
||||
TWEET_CONSUMER_SECRET = CFG['tweet_consumer_secret']
|
||||
|
||||
# Environment
|
||||
|
||||
try:
|
||||
WARNING_MESSAGE = CFG['warning_message']
|
||||
except KeyError:
|
||||
WARNING_MESSAGE = ''
|
||||
|
||||
@@ -202,6 +202,11 @@
|
||||
|
||||
<div class="clear"></div>
|
||||
<div id="messaging" class="grid_12">
|
||||
{% if WARNING_MESSAGE != '' %}
|
||||
<p class="message">
|
||||
{{ WARNING_MESSAGE }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||
|
||||
Reference in New Issue
Block a user