diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py
index aa9f45c1..a17c74f0 100644
--- a/rowers/interactiveplots.py
+++ b/rowers/interactiveplots.py
@@ -102,6 +102,22 @@ def interactive_boxchart(datadf,fieldname):
plot.xaxis.axis_label = 'Date'
plot.yaxis.axis_label = axlabels[fieldname]
+
+ # add watermark
+ plot.extra_y_ranges = {"watermark": watermarkrange}
+ plot.extra_x_ranges = {"watermark": watermarkrange}
+
+ plot.image_url([watermarkurl],watermarkx,watermarky,
+ watermarkw,watermarkh,
+ global_alpha=watermarkalpha,
+ w_units='screen',
+ h_units='screen',
+ anchor=watermarkanchor,
+ dilate=True,
+ x_range_name = "watermark",
+ y_range_name = "watermark",
+ )
+
plot.xaxis.formatter = DatetimeTickFormatter(
days=["%d %B %Y"],
@@ -1023,6 +1039,23 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
datadf.dropna(axis=1,how='all',inplace=True)
datadf.dropna(axis=0,how='any',inplace=True)
+
+ # test if we have drive energy
+ nowork = 1
+ try:
+ test = datadf['driveenergy'].mean()
+ nowork = 0
+ except KeyError:
+ datadf['driveenergy'] = 500.
+
+ # test if we have power
+ nopower = 1
+ try:
+ test = datadf['power'].mean()
+ nopower = 0
+ except KeyError:
+ datadf['power'] = 50.
+
yparamname1 = axlabels[yparam1]
if yparam2 != 'None':
@@ -1336,8 +1369,7 @@ def interactive_flex_chart2(id=0,promember=0,
'time','pace','workoutstate','time']
rowdata = dataprep.getsmallrowdata_db(columns,ids=[id],doclean=True,
- workstrokesonly=workstrokesonly,
- convertnewtons=False)
+ workstrokesonly=workstrokesonly)
try:
tests = rowdata[yparam2]
@@ -1352,6 +1384,22 @@ def interactive_flex_chart2(id=0,promember=0,
rowdata.dropna(axis=1,how='all',inplace=True)
rowdata.dropna(axis=0,how='any',inplace=True)
+ # test if we have drive energy
+ nowork = 1
+ try:
+ test = rowdata['driveenergy'].mean()
+ nowork = 0
+ except KeyError:
+ rowdata['driveenergy'] = 500.
+
+ # test if we have power
+ nopower = 1
+ try:
+ test = rowdata['power'].mean()
+ nopower = 0
+ except KeyError:
+ rowdata['power'] = 50.
+
row = Workout.objects.get(id=id)
if rowdata.empty:
return "","No valid data"
@@ -1437,6 +1485,7 @@ def interactive_flex_chart2(id=0,promember=0,
else:
rowdata['yname2'] = axlabels[yparam1]
+
# prepare data
source = ColumnDataSource(
rowdata
@@ -1611,6 +1660,7 @@ def interactive_flex_chart2(id=0,promember=0,
hover.mode = 'mouse'
+
callback = CustomJS(args = dict(source=source,source2=source2,
x1means=x1means,
y1means=y1means,
@@ -1626,13 +1676,13 @@ def interactive_flex_chart2(id=0,promember=0,
var y1 = data['y1']
var y2 = data['y2']
var spm1 = data['spm']
- var driveenergy1 = data['driveenergy']
var time1 = data['time']
var pace1 = data['pace']
var hr1 = data['hr']
var fpace1 = data['fpace']
var distance1 = data['distance']
var power1 = data['power']
+ var driveenergy1 = data['driveenergy']
var xname = data['xname'][0]
var yname1 = data['yname1'][0]
var yname2 = data['yname2'][0]
@@ -1683,7 +1733,7 @@ def interactive_flex_chart2(id=0,promember=0,
xm += x1[i]
ym1 += y1[i]
ym2 += y2[i]
- }
+ }
}
}
}
@@ -1733,7 +1783,7 @@ def interactive_flex_chart2(id=0,promember=0,
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
title="Min Distance",callback=callback)
callback.args["mindist"] = slider_dist_min
-
+
slider_dist_max = Slider(start=0,end=distmax,value=distmax,
step=1,
title="Max Distance",callback=callback)
diff --git a/rowers/templates/cum_flex.html b/rowers/templates/cum_flex.html
index 22acd20a..4d712ba2 100644
--- a/rowers/templates/cum_flex.html
+++ b/rowers/templates/cum_flex.html
@@ -24,7 +24,28 @@
-
Stroke Analysis
+
+ {% if theuser %}
+
{{ theuser.first_name }}'s Stroke Analysis
+ {% else %}
+ {{ user.first_name }}'s Stroke Analysis
+ {% endif %}
+
+
+ {% if user.is_authenticated and user|is_manager %}
+
diff --git a/rowers/templates/cumstats.html b/rowers/templates/cumstats.html
index 7d814c62..84d41d5c 100644
--- a/rowers/templates/cumstats.html
+++ b/rowers/templates/cumstats.html
@@ -35,11 +35,28 @@
-
Workout Statistics
-
- This is an experimental page which just lists a bunch of statistics for
- your workouts. This page is under rapid development.
-
+
+ {% if theuser %}
+
{{ theuser.first_name }}'s Workout Statistics
+ {% else %}
+ {{ user.first_name }}'s Workout Statistics
+ {% endif %}
+
+
+ {% if user.is_authenticated and user|is_manager %}
+
diff --git a/rowers/templates/histo.html b/rowers/templates/histo.html
index 8fa50f6f..fe9b1024 100644
--- a/rowers/templates/histo.html
+++ b/rowers/templates/histo.html
@@ -35,7 +35,28 @@
-
Indoor Rower Power Histogram
+
+ {% if theuser %}
+
{{ theuser.first_name }}'s Indoor Rower Power Histogram
+ {% else %}
+ {{ user.first_name }}'s Indoor Rower Power Histogram
+ {% endif %}
+
+
+ {% if user.is_authenticated and user|is_manager %}
+
diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html
index 9adf278b..02c69c36 100644
--- a/rowers/templates/list_workouts.html
+++ b/rowers/templates/list_workouts.html
@@ -33,55 +33,59 @@
-
- {% if team %}
-
- {% include "teambuttons.html" with teamid=team.id %}
-
-
{{ team.name }} Team Workouts
- {% else %}
-
My Workouts
- {% endif %}
+{% if team %}
+
+ {% include "teambuttons.html" with teamid=team.id team=team %}
+
+{% endif %}
- {% if workouts %}
-
-
-
- | Date |
- Time |
- Name |
- Type |
- Distance |
- Duration |
- Avg HR |
- Max HR |
- {% if not team %}
- |
- |
- {% else %}
-
- Owner
- |
- {% endif %}
-
+
+
+ {% if team %}
+
{{ team.name }} Team Workouts
+ {% else %}
+
My Workouts
+ {% endif %}
+
+ {% if workouts %}
+
+
+
+ | Date |
+ Time |
+ Name |
+ Type |
+ Distance |
+ Duration |
+ Avg HR |
+ Max HR |
+ {% if not team %}
+ |
+ |
+ {% else %}
+
+ Owner
+ |
+ {% endif %}
+
-
- {% for workout in workouts %}
-
- | {{ workout.date |truncatechars:15}} |
- {{ workout.starttime }} |
-
- {% if workout.user.user == user or user == team.manager %}
- {% if workout.name != '' %}
- {{ workout.name }} |
- {% else %}
- No Name
+
+ {% for workout in workouts %}
+
+ | {{ workout.date |truncatechars:15}} |
+ {{ workout.starttime }} |
+
+ {% if workout.user.user == user or user == team.manager %}
+ {% if workout.name != '' %}
+ {{ workout.name }} |
+ {% else %}
+ No Name
{% endif %}
{% else %}
- {% if workout.name != '' %}
- {{ workout.name }}
- {% else %}
- No Name
+{% if workout.name != '' %}
+{{ workout.name }}
+{% else %}
+No Name
{% endif %}
{% endif %}
{{ workout.workouttype }} |
@@ -114,6 +118,7 @@
{% endif %}
+
{% if team %}
@@ -152,7 +157,7 @@
-
+
diff --git a/rowers/templates/multicompare.html b/rowers/templates/multicompare.html
index dfc5d717..74c16d61 100644
--- a/rowers/templates/multicompare.html
+++ b/rowers/templates/multicompare.html
@@ -34,11 +34,12 @@
+
+ {% include "teambuttons.html" with teamid=teamid team=team %}
+
+
Interactive Comparison
-
- {% include "teambuttons.html" with teamid=teamid%}
-
+
diff --git a/rowers/templates/rankings.html b/rowers/templates/rankings.html
index 441961d3..dc3ac9a6 100644
--- a/rowers/templates/rankings.html
+++ b/rowers/templates/rankings.html
@@ -35,7 +35,28 @@
-
Ranking Pieces (Indoor Rower)
+
+ {% if theuser %}
+
{{ theuser.first_name }}'s Ranking Pieces
+ {% else %}
+ {{ user.first_name }}'s Ranking Pieces
+ {% endif %}
+
+
+ {% if user.is_authenticated and user|is_manager %}
+
diff --git a/rowers/templates/team.html b/rowers/templates/team.html
index b045a4c5..d112ea92 100644
--- a/rowers/templates/team.html
+++ b/rowers/templates/team.html
@@ -3,11 +3,13 @@
{% block title %}Team {% endblock %}
{% block content %}
-
-
{{ team.name }}
-
+
{% include "teambuttons.html" with teamid=team.id %}
+
+
+
{{ team.name }}
+
{{ team.notes }}
Manager: {{ team.manager.first_name }} {{ team.manager.last_name }}
@@ -90,7 +92,7 @@
{% endif %}
-
+
diff --git a/rowers/templates/team_compare_select.html b/rowers/templates/team_compare_select.html
index 162a36ee..0b3e8e5b 100644
--- a/rowers/templates/team_compare_select.html
+++ b/rowers/templates/team_compare_select.html
@@ -8,9 +8,7 @@
-
- {% include "teambuttons.html" with teamid=team.id %}
-
+ {% include "teambuttons.html" with teamid=team.id team=team %}
{{ team.name }} Team Workouts
diff --git a/rowers/templates/teambuttons.html b/rowers/templates/teambuttons.html
index 12351b95..e45b807e 100644
--- a/rowers/templates/teambuttons.html
+++ b/rowers/templates/teambuttons.html
@@ -14,7 +14,7 @@
Team Page
-
+
{% if user|is_manager and user|has_teams %}
Upload Workout
@@ -23,3 +23,14 @@
{% endif %}
+
+ {% if team and team.manager == user %}
+
+
+ Team Stats
+
+
+ {% else %}
+
+ {% endif %}
+
diff --git a/rowers/templates/teamstats.html b/rowers/templates/teamstats.html
new file mode 100644
index 00000000..312097f4
--- /dev/null
+++ b/rowers/templates/teamstats.html
@@ -0,0 +1,33 @@
+{% extends "base.html" %}
+
+{% block title %}Team {% endblock %}
+
+{% block content %}
+
+ {% include "teambuttons.html" with teamid=team.id team=team %}
+
+
+
{{ team.name }} Stats
+
+ Links to the cumulative statistics pages for your team's members
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/rowers/templates/user_boxplot_select.html b/rowers/templates/user_boxplot_select.html
index e5e5c611..cb9ee37f 100644
--- a/rowers/templates/user_boxplot_select.html
+++ b/rowers/templates/user_boxplot_select.html
@@ -7,17 +7,34 @@
{% block content %}
+ {% if team %}
-
- {% include "teambuttons.html" with teamid=team.id %}
-
+ {% include "teambuttons.html" with teamid=team.id team=team %}
+{% endif %}
- {% if theuser %}
-
{{ theuser.first_name }}'s Workouts
- {% else %}
-
{{ user.first_name }}'s Workouts
- {% endif %}
+
+ {% if theuser %}
+
{{ theuser.first_name }}'s Workouts
+ {% else %}
+ {{ user.first_name }}'s Workouts
+ {% endif %}
+
+
+ {% if user.is_authenticated and user|is_manager %}
+
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 31dc8a04..840d74d4 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -125,3 +125,17 @@ def has_teams(user):
return False
return False
+
+@register.filter
+def team_members(user):
+ try:
+ therower = Rower.objects.get(user=user)
+ if therower.rowerplan != 'coach':
+ return []
+ teams = Team.objects.filter(manager=user)
+ members = Rower.objects.filter(team__in=teams)
+ return [rower.user for rower in members]
+ except TypeError:
+ return []
+
+ return []
diff --git a/rowers/tpstuff.py b/rowers/tpstuff.py
index f0b0ef67..2a3a84c3 100644
--- a/rowers/tpstuff.py
+++ b/rowers/tpstuff.py
@@ -311,7 +311,7 @@ def workout_tp_upload(user,w):
tcxfile = createtpworkoutdata(w)
if tcxfile:
res,reason,status_code,headers = uploadactivity(
- r.tptoken,tcxfile,
+ thetoken,tcxfile,
name=w.name
)
if res == 0:
diff --git a/rowers/urls.py b/rowers/urls.py
index d7b8f857..d8086872 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -124,7 +124,7 @@ urlpatterns = [
url(r'^team-compare-select/team/(?P
\d+)/$',views.team_comparison_select),
url(r'^team-compare-select/(?P\w+.*)/(?P\w+.*)$',views.team_comparison_select),
url(r'^team-compare-select/$',views.team_comparison_select),
- url(r'^user-boxplot-select/team/(?P\d+)/(?P\w+.*)/(?P\w+.*)$',views.user_boxplot_select),
+ url(r'^user-boxplot-select/user/(?P\d+)/(?P\w+.*)/(?P\w+.*)$',views.user_boxplot_select),
url(r'^user-boxplot-select/user/(?P\d+)/$',views.user_boxplot_select),
url(r'^user-boxplot-select/(?P\w+.*)/(?P\w+.*)$',views.user_boxplot_select),
url(r'^user-boxplot-select/$',views.user_boxplot_select),
@@ -135,16 +135,19 @@ urlpatterns = [
url(r'^ote-bests/(?P\d+)$',views.rankings_view),
url(r'^ote-bests/$',views.rankings_view),
url(r'^(?P\d+)/ote-bests/$',views.rankings_view),
-
+ url(r'^(?P\d+)/flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)$',views.cum_flex),
url(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)$',views.cum_flex),
url(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)$',views.cum_flex),
url(r'^flexall/$',views.cum_flex),
+ url(r'^histo/u/(?P\d+)$',views.histo),
+ url(r'^flexall/u/(?P\d+)$',views.cum_flex),
url(r'^(?P\d+)/histo/(?P\w+.*)/(?P\w+.*)$',views.histo),
url(r'^(?P\d+)/histo/(?P\d+)$',views.histo),
url(r'^histo/(?P\w+.*)/(?P\w+.*)$',views.histo),
url(r'^histo/(?P\d+)$',views.histo),
url(r'^histo/$',views.histo),
+ url(r'^cumstats/u/(?P\d+)$',views.cumstats),
url(r'^cumstats/(?P\w+.*)/(?P\w+.*)/p/(?P\w+.*)$',views.cumstats),
url(r'^(?P\d+)/cumstats/(?P\w+.*)/(?P\w+.*)/p/(?P\w+.*)$',views.cumstats),
url(r'^(?P\d+)/cumstats/(?P\w+.*)/(?P\w+.*)$',views.cumstats),
@@ -227,6 +230,7 @@ urlpatterns = [
url(r'^user-boxplot$',views.boxplot_view),
url(r'^me/teams/$',views.rower_teams_view),
url(r'^team/(?P\d+)/$',views.team_view),
+ url(r'^team/(?P\d+)/memberstats$',views.team_members_stats_view),
url(r'^team/(?P\d+)/edit$',views.team_edit_view),
url(r'^team/(?P\d+)/leaveconfirm/$',views.team_leaveconfirm_view),
url(r'^team/(?P\d+)/leave/$',views.team_leave_view),
diff --git a/rowers/views.py b/rowers/views.py
index 506fb65a..38370f4b 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -2004,8 +2004,8 @@ def cum_flex(request,theuser=0,
if result:
promember=1
- if not promember:
- return HttpResponseRedirect("/rowers/about/")
+ #if not promember:
+ #return HttpResponseRedirect("/rowers/about/")
# get all indoor rows of in date range
@@ -7706,3 +7706,28 @@ def team_delete_view(request,id):
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
+
+@user_passes_test(iscoachmember,login_url="/",redirect_field_name=None)
+def team_members_stats_view(request,id):
+ r = Rower.objects.get(user=request.user)
+ try:
+ t = Team.objects.get(id=id)
+ except Team.DoesNotExist:
+ raise Http404("This team doesn't exist")
+ if t.manager != request.user:
+ raise PermissionDenied("You are not allowed to see this page")
+
+ members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
+
+ theusers = [member.user for member in members]
+
+
+
+ response = render(request,'teamstats.html',
+ {
+ 'teams':get_my_teams(request.user),
+ 'team':t,
+ 'theusers':theusers,
+ })
+
+ return response