Merge branch 'release/v5.47'
This commit is contained in:
@@ -13,6 +13,7 @@ import itertools
|
|||||||
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
||||||
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation
|
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation
|
||||||
from bokeh.charts import Histogram,HeatMap,Area,BoxPlot,Bar
|
from bokeh.charts import Histogram,HeatMap,Area,BoxPlot,Bar
|
||||||
|
from bokeh.charts.attributes import CatAttr
|
||||||
from bokeh.resources import CDN,INLINE
|
from bokeh.resources import CDN,INLINE
|
||||||
from bokeh.embed import components
|
from bokeh.embed import components
|
||||||
from bokeh.layouts import layout,widgetbox
|
from bokeh.layouts import layout,widgetbox
|
||||||
@@ -227,6 +228,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
|||||||
return "",""
|
return "",""
|
||||||
|
|
||||||
dates = []
|
dates = []
|
||||||
|
dates_sorting = []
|
||||||
types = []
|
types = []
|
||||||
rowers = []
|
rowers = []
|
||||||
durations = []
|
durations = []
|
||||||
@@ -234,8 +236,10 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
|||||||
for w in workouts:
|
for w in workouts:
|
||||||
if w.privacy == 'visible':
|
if w.privacy == 'visible':
|
||||||
dd = w.date.strftime('%m/%d')
|
dd = w.date.strftime('%m/%d')
|
||||||
|
dd2 = w.date.strftime('%Y/%m/%d')
|
||||||
du = w.duration.hour*60+w.duration.minute
|
du = w.duration.hour*60+w.duration.minute
|
||||||
dates.append(dd)
|
dates.append(dd)
|
||||||
|
dates_sorting.append(dd2)
|
||||||
durations.append(du)
|
durations.append(du)
|
||||||
types.append(w.workouttype)
|
types.append(w.workouttype)
|
||||||
try:
|
try:
|
||||||
@@ -253,9 +257,10 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# add dates with no activity
|
||||||
while d<=enddate:
|
while d<=enddate:
|
||||||
dates.append(d.strftime('%m/%d'))
|
dates.append(d.strftime('%m/%d'))
|
||||||
|
dates_sorting.append(d.strftime('%Y/%m/%d'))
|
||||||
durations.append(0)
|
durations.append(0)
|
||||||
types.append('rower')
|
types.append('rower')
|
||||||
rowers.append('Sander')
|
rowers.append('Sander')
|
||||||
@@ -263,12 +268,19 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
|
|||||||
|
|
||||||
df = pd.DataFrame({
|
df = pd.DataFrame({
|
||||||
'date':dates,
|
'date':dates,
|
||||||
|
'date_sorting':dates_sorting,
|
||||||
'duration':durations,
|
'duration':durations,
|
||||||
'type':types,
|
'type':types,
|
||||||
'rower':rowers,
|
'rower':rowers,
|
||||||
})
|
})
|
||||||
|
|
||||||
p = Bar(df,'date',values='duration',title='Activity',
|
df.sort_values('date_sorting',inplace=True)
|
||||||
|
|
||||||
|
p = Bar(df,values='duration',
|
||||||
|
label = CatAttr(columns=['date'], sort=False),
|
||||||
|
xlabel='Date',
|
||||||
|
ylabel='Time',
|
||||||
|
title='Activity',
|
||||||
stack=stack,
|
stack=stack,
|
||||||
plot_width=350,
|
plot_width=350,
|
||||||
plot_height=250,
|
plot_height=250,
|
||||||
|
|||||||
+11
-4
@@ -354,14 +354,21 @@ def getagegrouprecord(age,sex='male',weightcategory='hwt',
|
|||||||
|
|
||||||
p0 = [700,120,700,10,100,100]
|
p0 = [700,120,700,10,100,100]
|
||||||
|
|
||||||
p1, success = optimize.leastsq(errfunc,p0[:],
|
try:
|
||||||
|
p1, success = optimize.leastsq(errfunc,p0[:],
|
||||||
args = (ages,powers))
|
args = (ages,powers))
|
||||||
|
except:
|
||||||
|
p1 = p0
|
||||||
|
success = 0
|
||||||
|
|
||||||
power = fitfunc(p1, float(age))
|
if success:
|
||||||
|
power = fitfunc(p1, float(age))
|
||||||
|
|
||||||
#power = np.polyval(poly_coefficients,age)
|
#power = np.polyval(poly_coefficients,age)
|
||||||
|
|
||||||
power = 0.5*(np.abs(power)+power)
|
power = 0.5*(np.abs(power)+power)
|
||||||
|
else:
|
||||||
|
power = 0
|
||||||
else:
|
else:
|
||||||
power = 0
|
power = 0
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ def long_test_task2(self,aantal,**kwargs):
|
|||||||
|
|
||||||
return longtask.longtask2(aantal,**kwargs)
|
return longtask.longtask2(aantal,**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# create workout
|
# create workout
|
||||||
@app.task
|
@app.task
|
||||||
def handle_new_workout_from_file(r, f2,
|
def handle_new_workout_from_file(r, f2,
|
||||||
|
|||||||
@@ -5,6 +5,25 @@
|
|||||||
{% block title %}Workouts{% endblock %}
|
{% block title %}Workouts{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{% include "monitorjobs.html" %}
|
{% include "monitorjobs.html" %}
|
||||||
|
<script type='text/javascript'
|
||||||
|
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function($) {
|
||||||
|
console.log('loading script');
|
||||||
|
console.log('{{ recalc }}');
|
||||||
|
if ('{{ recalc }}' == 'True') {
|
||||||
|
theurl = '/rowers/ajax_agegroup/{{ age }}/{{ weightcategory }}/{{ sex }}/{{ user.id }}'
|
||||||
|
console.log(theurl);
|
||||||
|
$.getJSON(window.location.protocol + '//'+window.location.host + theurl, function(json) {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('No need to reload');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ urlpatterns = [
|
|||||||
url(r'^imports/$', TemplateView.as_view(template_name='imports.html'), name='imports'),
|
url(r'^imports/$', TemplateView.as_view(template_name='imports.html'), name='imports'),
|
||||||
url(r'^agegroupcp/(?P<age>\d+)$',views.agegroupcpview),
|
url(r'^agegroupcp/(?P<age>\d+)$',views.agegroupcpview),
|
||||||
url(r'^agegroupcp/(?P<age>\d+)/(?P<normalize>\d+)$',views.agegroupcpview),
|
url(r'^agegroupcp/(?P<age>\d+)/(?P<normalize>\d+)$',views.agegroupcpview),
|
||||||
|
url(r'^ajax_agegroup/(?P<age>\d+)/(?P<weightcategory>\w+.*)/(?P<sex>\w+.*)/(?P<userid>\d+)$',
|
||||||
|
views.ajax_agegrouprecords),
|
||||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<distance>\d+)m$',
|
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<distance>\d+)m$',
|
||||||
views.agegrouprecordview),
|
views.agegrouprecordview),
|
||||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<duration>\d+)min$',
|
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<duration>\d+)min$',
|
||||||
|
|||||||
+137
-44
@@ -2957,9 +2957,15 @@ def histo(request,theuser=0,
|
|||||||
if 'options' in request.session:
|
if 'options' in request.session:
|
||||||
options = request.session['options']
|
options = request.session['options']
|
||||||
|
|
||||||
workouttypes = options['workouttypes']
|
try:
|
||||||
includereststrokes = options['includereststrokes']
|
workouttypes = options['workouttypes']
|
||||||
waterboattype = options['waterboattype']
|
includereststrokes = options['includereststrokes']
|
||||||
|
waterboattype = options['waterboattype']
|
||||||
|
except KeyError:
|
||||||
|
workouttypes = ['water','rower','dynamic','slides']
|
||||||
|
waterboattype = ['1x','2x','2-','4x','4-','8+']
|
||||||
|
includereststrokes = False
|
||||||
|
|
||||||
workstrokesonly = not includereststrokes
|
workstrokesonly = not includereststrokes
|
||||||
|
|
||||||
|
|
||||||
@@ -3509,6 +3515,66 @@ def rankings_view(request,theuser=0,
|
|||||||
'teams':get_my_teams(request.user),
|
'teams':get_my_teams(request.user),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def ajax_agegrouprecords(request,
|
||||||
|
age=25,
|
||||||
|
sex='female',
|
||||||
|
weightcategory='hwt',
|
||||||
|
userid=0):
|
||||||
|
|
||||||
|
wcdurations = []
|
||||||
|
wcpower = []
|
||||||
|
durations = [1,4,30,60]
|
||||||
|
distances = [100,500,1000,2000,5000,6000,10000,21097,42195]
|
||||||
|
for distance in distances:
|
||||||
|
worldclasspower = metrics.getagegrouprecord(
|
||||||
|
age,
|
||||||
|
sex=sex,
|
||||||
|
distance=distance,
|
||||||
|
weightcategory=weightcategory
|
||||||
|
)
|
||||||
|
velo = (worldclasspower/2.8)**(1./3.)
|
||||||
|
try:
|
||||||
|
duration = distance/velo
|
||||||
|
wcdurations.append(duration)
|
||||||
|
wcpower.append(worldclasspower)
|
||||||
|
except ZeroDivisionError:
|
||||||
|
pass
|
||||||
|
for duration in durations:
|
||||||
|
worldclasspower = metrics.getagegrouprecord(
|
||||||
|
age,
|
||||||
|
sex=sex,
|
||||||
|
duration=duration,
|
||||||
|
weightcategory=weightcategory
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
velo = (worldclasspower/2.8)**(1./3.)
|
||||||
|
distance = int(60*duration*velo)
|
||||||
|
wcdurations.append(60.*duration)
|
||||||
|
wcpower.append(worldclasspower)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options['wcpower'] = wcpower
|
||||||
|
options['wcdurations'] = wcdurations
|
||||||
|
|
||||||
|
thenowtime = timezone.now().isoformat()
|
||||||
|
options['lastupdated'] = thenowtime
|
||||||
|
options['userid'] = userid
|
||||||
|
|
||||||
|
request.session['options'] = options
|
||||||
|
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
{
|
||||||
|
'wcdurations': wcdurations,
|
||||||
|
'wcpower': wcpower,
|
||||||
|
'lastupdated': thenowtime,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Show ranking distances including predicted paces
|
# Show ranking distances including predicted paces
|
||||||
@login_required()
|
@login_required()
|
||||||
def rankings_view2(request,theuser=0,
|
def rankings_view2(request,theuser=0,
|
||||||
@@ -3534,49 +3600,61 @@ def rankings_view2(request,theuser=0,
|
|||||||
|
|
||||||
if theuser == 0:
|
if theuser == 0:
|
||||||
theuser = request.user.id
|
theuser = request.user.id
|
||||||
|
else:
|
||||||
|
lastupdated = "01-01-1900"
|
||||||
|
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
if not request.user.is_anonymous():
|
if not request.user.is_anonymous():
|
||||||
r = getrower(request.user)
|
r = getrower(theuser)
|
||||||
wcdurations = []
|
wcdurations = []
|
||||||
wcpower = []
|
wcpower = []
|
||||||
|
|
||||||
|
lastupdated = "01-01-1900"
|
||||||
|
userid = 0
|
||||||
|
if 'options' in request.session:
|
||||||
|
options = request.session['options']
|
||||||
|
try:
|
||||||
|
wcdurations = options['wcdurations']
|
||||||
|
wcpower = options['wcpower']
|
||||||
|
lastupdated = options['lastupdated']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
userid = options['userid']
|
||||||
|
except KeyError:
|
||||||
|
userid = 0
|
||||||
|
else:
|
||||||
|
options = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lastupdatedtime = arrow.get(lastupdated).timestamp
|
||||||
|
current_time = arrow.utcnow().timestamp
|
||||||
|
|
||||||
|
deltatime_seconds = current_time - lastupdatedtime
|
||||||
|
recalc = False
|
||||||
|
if str(userid) != str(theuser) or deltatime_seconds > 3600:
|
||||||
|
recalc = True
|
||||||
|
else:
|
||||||
|
recalc = False
|
||||||
|
|
||||||
|
options['userid'] = theuser
|
||||||
|
|
||||||
if r.birthdate:
|
if r.birthdate:
|
||||||
age = calculate_age(r.birthdate)
|
age = calculate_age(r.birthdate)
|
||||||
durations = [1,4,30,60]
|
|
||||||
distances = [100,500,1000,2000,5000,6000,10000,21097,42195]
|
|
||||||
for distance in distances:
|
|
||||||
worldclasspower = metrics.getagegrouprecord(
|
|
||||||
age,
|
|
||||||
sex=r.sex,
|
|
||||||
distance=distance,
|
|
||||||
weightcategory=r.weightcategory
|
|
||||||
)
|
|
||||||
velo = (worldclasspower/2.8)**(1./3.)
|
|
||||||
try:
|
|
||||||
duration = distance/velo
|
|
||||||
wcdurations.append(duration)
|
|
||||||
wcpower.append(worldclasspower)
|
|
||||||
except ZeroDivisionError:
|
|
||||||
pass
|
|
||||||
for duration in durations:
|
|
||||||
worldclasspower = metrics.getagegrouprecord(
|
|
||||||
age,
|
|
||||||
sex=r.sex,
|
|
||||||
duration=duration,
|
|
||||||
weightcategory=r.weightcategory
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
velo = (worldclasspower/2.8)**(1./3.)
|
|
||||||
distance = int(60*duration*velo)
|
|
||||||
wcdurations.append(60.*duration)
|
|
||||||
wcpower.append(worldclasspower)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
worldclasspower = None
|
worldclasspower = None
|
||||||
age = 0
|
age = 0
|
||||||
|
|
||||||
|
options['wcpower'] = wcpower
|
||||||
|
options['wcdurations'] = wcdurations
|
||||||
|
if theuser:
|
||||||
|
options['userid'] = theuser
|
||||||
|
|
||||||
|
request.session['options'] = options
|
||||||
|
|
||||||
|
|
||||||
result = request.user.is_authenticated() and ispromember(request.user)
|
result = request.user.is_authenticated() and ispromember(request.user)
|
||||||
if result:
|
if result:
|
||||||
promember=1
|
promember=1
|
||||||
@@ -3852,6 +3930,7 @@ def rankings_view2(request,theuser=0,
|
|||||||
'theuser':uu,
|
'theuser':uu,
|
||||||
'age':age,
|
'age':age,
|
||||||
'sex':r.sex,
|
'sex':r.sex,
|
||||||
|
'recalc':recalc,
|
||||||
'weightcategory':r.weightcategory,
|
'weightcategory':r.weightcategory,
|
||||||
'startdate':startdate,
|
'startdate':startdate,
|
||||||
'enddate':enddate,
|
'enddate':enddate,
|
||||||
@@ -5688,14 +5767,24 @@ def boxplot_view_data(request,userid=0,
|
|||||||
if 'options' in request.session:
|
if 'options' in request.session:
|
||||||
options = request.session['options']
|
options = request.session['options']
|
||||||
|
|
||||||
includereststrokes = options['includereststrokes']
|
try:
|
||||||
spmmin = options['spmmin']
|
includereststrokes = options['includereststrokes']
|
||||||
spmmax = options['spmmax']
|
spmmin = options['spmmin']
|
||||||
workmin = options['workmin']
|
spmmax = options['spmmax']
|
||||||
workmax = options['workmax']
|
workmin = options['workmin']
|
||||||
ids = options['ids']
|
workmax = options['workmax']
|
||||||
userid = options['userid']
|
ids = options['ids']
|
||||||
plotfield = options['plotfield']
|
userid = options['userid']
|
||||||
|
plotfield = options['plotfield']
|
||||||
|
except KeyError:
|
||||||
|
includereststrokes = False
|
||||||
|
spmmin = 15
|
||||||
|
spmmax = 55
|
||||||
|
workmin = 0
|
||||||
|
workmax = 55
|
||||||
|
ids = []
|
||||||
|
userid = 0
|
||||||
|
plotfield = 'spm'
|
||||||
|
|
||||||
|
|
||||||
workstrokesonly = not includereststrokes
|
workstrokesonly = not includereststrokes
|
||||||
@@ -5768,7 +5857,12 @@ def boxplot_view(request,userid=0,
|
|||||||
if 'options' in request.session:
|
if 'options' in request.session:
|
||||||
options = request.session['options']
|
options = request.session['options']
|
||||||
|
|
||||||
includereststrokes = options['includereststrokes']
|
try:
|
||||||
|
includereststrokes = options['includereststrokes']
|
||||||
|
except KeyError:
|
||||||
|
includereststrokes = False
|
||||||
|
options['includereststrokes'] = False
|
||||||
|
|
||||||
workstrokesonly = not includereststrokes
|
workstrokesonly = not includereststrokes
|
||||||
|
|
||||||
if userid==0:
|
if userid==0:
|
||||||
@@ -5887,7 +5981,6 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
activity_enddate = enddate
|
activity_enddate = enddate
|
||||||
|
|
||||||
|
|
||||||
if teamid:
|
if teamid:
|
||||||
try:
|
try:
|
||||||
theteam = Team.objects.get(id=teamid)
|
theteam = Team.objects.get(id=teamid)
|
||||||
|
|||||||
Reference in New Issue
Block a user