diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 1f9c708d..6168cb56 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -16,7 +16,7 @@ queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
from rowers.models import (
- Rower, Workout,
+ Rower, Workout,Team,
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
TrainingPlan,PlannedSession,
)
@@ -70,9 +70,57 @@ def timefield_to_seconds_duration(t):
duration += t.microsecond/1.e6
return duration
-
+
+def get_session_metrics(ps):
+ rowers = ps.rower.all()
+ rscore = []
+ trimp = []
+ duration = []
+ distance = []
+ firstname = []
+ lastname = []
+
+ for r in rowers:
+ rscorev = 0
+ trimpv = 0
+ durationv = 0
+ distancev = 0
+
+
+ ws = Workout.objects.filter(user=r,plannedsession=ps)
+ if len(ws) != 0:
+ for w in ws:
+ distancev += w.distance
+ durationv += timefield_to_seconds_duration(w.duration)
+ trimpv += dataprep.workout_trimp(w)
+ rscorev += dataprep.workout_rscore(w)
+
+
+ durationv /= 60.
+
+ trimp.append(int(trimpv))
+ duration.append(int(durationv))
+ distance.append(int(distancev))
+ rscore.append(int(rscorev))
+ firstname.append(r.user.first_name)
+ lastname.append(r.user.last_name)
+
+ thedict = {
+ 'first_name':firstname,
+ 'last_name':lastname,
+ 'duration':duration,
+ 'distance':distance,
+ 'rscore':rscore,
+ 'trimp':trimp
+ }
+
+ return thedict
+
def is_session_complete(r,ps):
status = 'not done'
+
+ if r not in ps.rower.all():
+ return 0,'not assigned'
ws = Workout.objects.filter(user=r,plannedsession=ps)
@@ -208,6 +256,25 @@ def get_dates_timeperiod(timeperiod):
return startdate,enddate
+def get_sessions_manager(m,teamid=0,startdate=date.today(),
+ enddate=date.today()+timezone.timedelta(+1000)):
+ if teamid:
+ t = Team.objects.get(id=teamid)
+ sps = PlannedSession.objects.filter(
+ team__in=[t],
+ manager=m,
+ startdate__lte=enddate,
+ enddate__gte=startdate,
+ ).order_by("startdate","enddate")
+ else:
+ sps = PlannedSession.objects.filter(
+ manager=m,
+ startdate__lte=enddate,
+ enddate__gte=startdate,
+ ).order_by("startdate","enddate")
+
+ return sps
+
def get_sessions(r,startdate=date.today(),
enddate=date.today()+timezone.timedelta(+1000)):
@@ -219,17 +286,6 @@ def get_sessions(r,startdate=date.today(),
return sps
-def get_sessions_manager(manager,startdate=date.today(),
- enddate=date.today()+timezone.timedelta(+1000)):
-
- sps = PlannedSession.objects.filter(
- manager=manager,
- startdate__lte=enddate,
- enddate__gte=startdate,
- ).order_by("startdate","enddate").exclude(team__isnull=True)
-
- return sps
-
def get_workouts_session(r,ps):
ws = Workout.objects.filter(user=r,plannedsession=ps)
diff --git a/rowers/templates/plannedsessionscoach.html b/rowers/templates/plannedsessionscoach.html
new file mode 100644
index 00000000..8a888c22
--- /dev/null
+++ b/rowers/templates/plannedsessionscoach.html
@@ -0,0 +1,181 @@
+{% extends "base.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block title %}Planned Sessions{% endblock %}
+
+{% block content %}
+
+ {% include "planningbuttons.html" %}
+
+
+ {% if theteam %}
+
Coach Overview. Team {{ theteam.name }}
+ {% else %}
+ Coach Overview
+ {% endif %}
+
+
+
+
+
+{% if user.is_authenticated and user|is_manager %}
+
+
+{% endif %}
+
+
+
+
+
+ | On or after |
+ On or before |
+ Name |
+ {% for r in rowers %}
+
+ {{ r.user.first_name }} {{ r.user.last_name }}
+ |
+ {% endfor %}
+
+
+
+ {% for key, thedict in statusdict.items %}
+
+ |
+ {{ thedict|lookup:'startdate'|date:"Y-m-d" }}
+ |
+
+ {{ thedict|lookup:'enddate'|date:"Y-m-d" }}
+ |
+
+
+ {{ thedict|lookup:'name' }}
+
+ |
+ {% for r in rowers %}
+
+ {% if thedict|lookup:'results'|lookup:r.id == 'completed' %}
+
+ {% elif thedict|lookup:'results'|lookup:r.id == 'partial' %}
+
+ {% elif thedict|lookup:'results'|lookup:r.id == 'not done' %}
+
+ {% elif thedict|lookup:'results'|lookup:r.id == 'not assigned' %}
+
+ {% else %}
+
+ {% endif %}
+ |
+ {% endfor %}
+
+ {% endfor %}
+
+
+
+ {% if unmatchedworkouts %}
+
Workouts that are not linked to any session
+
+
+
+ | Rower |
+ Date |
+ Time |
+ Name |
+ Type |
+ Distance |
+ Duration |
+ Avg HR |
+ Max HR |
+
+
+
+ {% for workout in unmatchedworkouts %}
+
+ | {{ workout.user.user.first_name }} {{ workout.user.user.last_name }} |
+ {{ workout.date|date:"Y-m-d" }} |
+ {{ workout.starttime|date:"H:i" }} |
+ {% 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 |
+ {% endif %}
+ {% endif %}
+ {{ workout.workouttype }} |
+ {{ workout.distance }}m |
+ {{ workout.duration |durationprint:"%H:%M:%S.%f" }} |
+ {{ workout.averagehr }} |
+ {{ workout.maxhr }} |
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+
+
+
+
+
+
+{% endblock %}
diff --git a/rowers/templates/plannedsessionview.html b/rowers/templates/plannedsessionview.html
index be61c544..b15bbde9 100644
--- a/rowers/templates/plannedsessionview.html
+++ b/rowers/templates/plannedsessionview.html
@@ -9,6 +9,17 @@
{% include "planningbuttons.html" %}
+
+
+ {% if user.is_authenticated and psdict.id.1|is_session_manager:user %}
+
+ Edit Session
+ {% else %}
+
+ {% endif %}
+
+
+
Session {{ psdict.name.1 }}
@@ -22,9 +33,6 @@
{% endfor %}
{% endfor %}
-
Result
-
Status: {{ status }}
-
Percentage complete: {{ ratio }}
Workouts attached
@@ -53,7 +61,38 @@
-
-
+
+
+
+
Result
+
Status: {{ status }}
+
Percentage complete: {{ ratio }}
+
+
+
Stats
+
+
+
+ | Name |
+ Minutes |
+ Meters |
+ rScore |
+ TRIMP |
+
+
+
+ {% for id, value in results.items %}
+
+ | {{ value|lookup:'first_name' }} {{ value|lookup:'last_name' }} |
+ {{ value|lookup:'duration' }} |
+ {{ value|lookup:'distance' }} |
+ {{ value|lookup:'rscore' }} |
+ {{ value|lookup:'trimp' }} |
+
+ {% endfor %}
+
+
+
+
{% endblock %}
diff --git a/rowers/templates/planningbuttons.html b/rowers/templates/planningbuttons.html
index 6f57cfd4..20648d28 100644
--- a/rowers/templates/planningbuttons.html
+++ b/rowers/templates/planningbuttons.html
@@ -32,12 +32,23 @@
{% endif %}
-
+
+
+ {% if user.is_authenticated and user|is_manager %}
+ {% if timeperiod %}
+
Coach Overview
+ {% else %}
+
Coach Overview
{% endif %}
{% else %}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index bfdf2751..cd9acd8b 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -100,6 +100,16 @@ def ualookup(dict, key):
return s
+from rowers.models import PlannedSession
+@register.filter
+def is_session_manager(id,user):
+ try:
+ ps = PlannedSession.objects.get(id=id)
+ except PlannedSession.DoesNotExist:
+ return False
+
+ return ps.manager == user
+
@register.filter(name='times')
def times(number):
return range(number)
diff --git a/rowers/urls.py b/rowers/urls.py
index d502a7d2..b630c026 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -448,6 +448,11 @@ urlpatterns = [
views.plannedsessions_manage_view),
url(r'^sessions/manage/(?P
[\w\ ]+.*)$',
views.plannedsessions_manage_view),
+ url(r'^sessions/coach$',views.plannedsessions_coach_view),
+ url(r'^sessions/coach/(?P[\w\ ]+.*)/team/(?P\d+)$',
+ views.plannedsessions_coach_view),
+ url(r'^sessions/coach/(?P[\w\ ]+.*)$',
+ views.plannedsessions_coach_view),
url(r'^sessions/?$',views.plannedsessions_view),
url(r'^sessions/rower/(?P\d+)$',views.plannedsessions_view),
url(r'^sessions/(?P[\w\ ]+.*)/rower/(?P\d+)$',views.plannedsessions_view),
diff --git a/rowers/utils.py b/rowers/utils.py
index 27fad934..cdb92131 100644
--- a/rowers/utils.py
+++ b/rowers/utils.py
@@ -294,6 +294,7 @@ def calculate_age(born):
def my_dict_from_instance(instance,model):
thedict = {}
+ thedict['id'] = instance.id
for attr, value in instance.__dict__.iteritems():
try:
diff --git a/rowers/views.py b/rowers/views.py
index 32cf2fb6..eb9a46bc 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -166,6 +166,8 @@ class JSONResponse(HttpResponse):
super(JSONResponse, self).__init__(content, **kwargs)
+
+
def getrower(user):
try:
r = Rower.objects.get(user=user)
@@ -176,8 +178,21 @@ def getrower(user):
return r
+def get_workout(id):
+ try:
+ w = Workout.objects.get(id=id)
+ except Workout.DoesNotExist:
+ raise Http404("Workout doesn't exist")
+ return w
+def get_workout_permitted(user,id):
+ w = get_workout(id)
+
+ if (checkworkoutuser(user,w)==False):
+ raise PermissionDenied("Access denied")
+
+ return w
def getvalue(data):
perc = 0
@@ -513,12 +528,8 @@ def get_stored_tasks_status(request):
@login_required()
def get_thumbnails(request,id):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
- if (checkworkoutuser(request.user,row)==False):
- raise PermissionDenied("Access denied")
+ row = get_workout_permitted(request.user,id)
+
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
@@ -557,13 +568,7 @@ def get_thumbnails(request,id):
@login_required()
def get_testscript(request,id):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
- if (checkworkoutuser(request.user,row)==False):
- raise PermissionDenied("Access denied")
-
+ row = get_workout_permitted(request.user,id)
r = getrower(request.user)
object = {
@@ -780,17 +785,6 @@ def hasplannedsessions(user):
return result
-def getrower(user):
- try:
- r = Rower.objects.get(user=user)
- except Rower.DoesNotExist:
- r = Rower(user=user)
- r.save()
-
- return r
-
-
-
# Check if a user is a Pro member
def ispromember(user):
if not user.is_anonymous():
@@ -1627,10 +1621,7 @@ def workout_tcxemail_view(request,id=0):
message = ""
successmessage = ""
r = getrower(request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
if (checkworkoutuser(request.user,w)):
tcxfile,tcxmessg = stravastuff.createstravaworkoutdata(w,dozip=False)
if tcxfile == 0:
@@ -1674,10 +1665,8 @@ def workout_gpxemail_view(request,id=0):
message = ""
successmessage = ""
r = Rower.objects.get(user=request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+
if (checkworkoutuser(request.user,w)):
filename = w.csvfilename
row = rdata(filename)
@@ -1714,10 +1703,8 @@ def workout_gpxemail_view(request,id=0):
def workout_csvemail_view(request,id=0):
message = ""
r = getrower(request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+
if (checkworkoutuser(request.user,w)):
csvfile = w.csvfilename
res = myqueue(queuehigh,handle_sendemailcsv,r.user.first_name,
@@ -1748,10 +1735,8 @@ def workout_csvemail_view(request,id=0):
def workout_csvtoadmin_view(request,id=0):
message = ""
r = getrower(request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+
csvfile = w.csvfilename
res = myqueue(queuehigh,
@@ -1784,11 +1769,9 @@ def workout_tp_upload_view(request,id=0):
return HttpResponseRedirect("/rowers/me/tpauthorize/")
# ready to upload. Hurray
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout_permitted(request.user,id)
+ r = w.user
+
if (checkworkoutuser(request.user,w)):
tcxfile = tpstuff.createtpworkoutdata(w)
if tcxfile:
@@ -1841,11 +1824,8 @@ def workout_strava_upload_view(request,id=0):
return HttpResponseRedirect("/rowers/me/stravaauthorize/")
else:
# ready to upload. Hurray
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout_permitted(request.user,id)
+ r = w.user
if (checkworkoutuser(request.user,w)):
try:
tcxfile,tcxmessg = stravastuff.createstravaworkoutdata(w)
@@ -1931,11 +1911,9 @@ def workout_strava_upload_view(request,id=0):
def workout_c2_upload_view(request,id=0):
message = ""
# ready to upload. Hurray
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+ r = w.user
+
try:
message,c2id = c2stuff.workout_c2_upload(request.user,w)
@@ -1959,11 +1937,8 @@ def workout_c2_upload_view(request,id=0):
@login_required()
def workout_runkeeper_upload_view(request,id=0):
message = ""
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+ r = w.user
try:
thetoken = runkeeper_open(r.user)
@@ -2024,11 +1999,8 @@ def workout_runkeeper_upload_view(request,id=0):
@login_required()
def workout_underarmour_upload_view(request,id=0):
message = ""
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+ r = w.user
try:
thetoken = underarmour_open(r.user)
@@ -2091,11 +2063,8 @@ def workout_underarmour_upload_view(request,id=0):
def workout_sporttracks_upload_view(request,id=0):
message = ""
# ready to upload. Hurray
- try:
- w = Workout.objects.get(id=id)
- r = w.user
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
+ r = w.user
try:
thetoken = sporttracks_open(r.user)
@@ -2932,10 +2901,7 @@ def cum_flex(request,theuser=0,
# Show the EMpower Oarlock generated Stroke Profile
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_forcecurve_view(request,id=0,workstrokesonly=False):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
promember=0
mayedit=0
@@ -2989,10 +2955,7 @@ def workout_test_task_view(request,id=0):
# Show Stroke power histogram for a workout
@login_required()
def workout_histo_view(request,id=0):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
promember=0
mayedit=0
@@ -4081,10 +4044,7 @@ def rankings_view2(request,theuser=0,
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_update_cp_view(request,id=0):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -4691,10 +4651,7 @@ def oterankings_view(request,theuser=0,
# Reload the workout and calculate the summary from the stroke data (lapIDx)
@login_required()
def workout_recalcsummary_view(request,id=0):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -4728,10 +4685,8 @@ def workout_recalcsummary_view(request,id=0):
def workout_makepublic_view(request,id,
message='',
successmessage=''):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -4762,10 +4717,7 @@ def workout_makepublic_view(request,id,
def workout_setprivate_view(request,id,
message='',
successmessage=''):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -5498,10 +5450,18 @@ def multiflex_data(request,userid=0,
datadf['days ago'] = map(lambda x : x.days, datadf.date - today)
if groupby != 'date':
- bins = np.arange(datadf[groupby].min()-binsize,
- datadf[groupby].max()+binsize,
- binsize)
- groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False))
+ try:
+ bins = np.arange(datadf[groupby].min()-binsize,
+ datadf[groupby].max()+binsize,
+ binsize)
+ groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False))
+ except ValueError:
+ messages.error(
+ request,
+ "Unable to compete. Probably not enough data selected"
+ )
+ url = reverse(user_multiflex_select)
+ return HttpResponseRedirect(url)
else:
bins = np.arange(datadf['days ago'].min()-binsize,
datadf['days ago'].max()+binsize,
@@ -6291,10 +6251,8 @@ def workout_comparison_list(request,id=0,message='',successmessage='',
workouts = paginator.page(1)
except EmptyPage:
workouts = paginator.page(paginator.num_pages)
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+
+ row = get_workout(id)
messages.error(request,message)
messages.info(request,successmessage)
@@ -6371,11 +6329,7 @@ def workout_fusion_list(request,id=0,message='',successmessage='',
workouts = paginator.page(1)
except EmptyPage:
workouts = paginator.page(paginator.num_pages)
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
-
+ row = get_workout(id)
messages.info(request,successmessage)
messages.error(request,message)
@@ -6490,11 +6444,10 @@ def workout_view(request,id=0):
# Resets stroke data to raw data (pace)
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
-def workout_undo_smoothenpace_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+def workout_undo_smoothenpace_view(
+ request,id=0,message="",successmessage=""
+):
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -6523,10 +6476,7 @@ def workout_undo_smoothenpace_view(request,id=0,message="",successmessage=""):
# Data smoothing of pace data
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -6564,10 +6514,7 @@ def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
# Process CrewNerd Summary CSV and update summary
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if request.method == 'POST':
form = CNsummaryForm(request.POST,request.FILES)
@@ -6620,10 +6567,7 @@ def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
def workout_downloadwind_view(request,id=0,
airportcode=None,
message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
f1 = row.csvfilename
if (checkworkoutuser(request.user,row)==False):
@@ -6689,10 +6633,7 @@ def workout_downloadwind_view(request,id=0,
def workout_downloadmetar_view(request,id=0,
airportcode=None,
message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
f1 = row.csvfilename
if (checkworkoutuser(request.user,row)==False):
@@ -6757,10 +6698,7 @@ def workout_downloadmetar_view(request,id=0,
# Show form to update wind data
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_wind_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -6877,10 +6815,7 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
# Show form to update River stream data (for river dwellers)
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_stream_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -6946,10 +6881,7 @@ def workout_stream_view(request,id=0,message="",successmessage=""):
# Form to set average crew weight and boat type, then run power calcs
@user_passes_test(ispromember, login_url="/",redirect_field_name=None)
def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
@@ -7052,10 +6984,7 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
@login_required()
def instroke_view(request,id=0):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
form = WorkoutForm(instance=row)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
@@ -7085,10 +7014,7 @@ def instroke_view(request,id=0):
# A special Edit page with all the Geeky functionality for the workout
@login_required()
def workout_geeky_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
form = WorkoutForm(instance=row)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
@@ -7150,10 +7076,7 @@ def workout_geeky_view(request,id=0,message="",successmessage=""):
# generate instroke chart
@login_required()
def instroke_chart(request,id=0,metric=''):
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
if (checkworkoutuser(request.user,w)==False):
message = "You are not allowed to edit this workout"
@@ -7475,10 +7398,7 @@ def cumstats(request,theuser=0,
def workout_stats_view(request,id=0,message="",successmessage=""):
r = getrower(request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
workstrokesonly = True
if request.method == 'POST' and 'workstrokesonly' in request.POST:
@@ -7624,10 +7544,8 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
# The Advanced edit page
@login_required()
def workout_advanced_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
+
form = WorkoutForm(instance=row)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
for i in g:
@@ -7909,12 +7827,7 @@ def workout_workflow_view(request,id):
request.session['referer'] = absolute(request)['PATH']
request.session['lastworkout'] = id
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
- if (checkworkoutuser(request.user,row)==False):
- raise PermissionDenied("Access denied")
+ row = get_workout_permitted(request.user,id)
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
@@ -8005,11 +7918,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
except:
favoritenr = -1
-
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
promember=0
mayedit=0
@@ -8228,10 +8137,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
# The interactive plot with the colored Heart rate zones
def workout_biginteractive_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
# check if user is owner of this workout
@@ -8272,10 +8178,7 @@ def workout_biginteractive_view(request,id=0,message="",successmessage=""):
# The interactive plot with wind corrected pace for OTW outings
def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
# check if user is owner of this workout
@@ -8315,10 +8218,7 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
@login_required()
def workout_export_view(request,id=0, message="", successmessage=""):
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
try:
thetoken = c2_open(request.user)
@@ -8375,10 +8275,7 @@ def workout_export_view(request,id=0, message="", successmessage=""):
#
@login_required()
def workout_unsubscribe_view(request,id=0):
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
if w.privacy == 'private' and w.user.user != request.user:
return HttpResponseForbidden("Permission error")
@@ -8408,10 +8305,7 @@ def workout_unsubscribe_view(request,id=0):
# list of comments to a workout
@login_required()
def workout_comment_view(request,id=0):
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
if w.privacy == 'private' and w.user.user != request.user:
return HttpResponseForbidden("Permission error")
@@ -8511,12 +8405,9 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
request.session['referer'] = absolute(request)['PATH']
- try:
- # check if valid ID exists (workout exists)
- row = Workout.objects.get(id=id)
- form = WorkoutForm(instance=row)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
+
+ form = WorkoutForm(instance=row)
if request.method == 'POST':
# Form was submitted
@@ -8598,11 +8489,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
#else: # form not POSTed
form = WorkoutForm(instance=row)
-
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
for i in g:
@@ -8690,12 +8577,7 @@ def workout_map_view(request,id=0):
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
request.session['referer'] = absolute(request)['PATH']
-
- try:
- # check if valid ID exists (workout exists)
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
# create interactive plot
f1 = row.csvfilename
@@ -8745,13 +8627,8 @@ def workout_edit_view_navionics(request,id=0,message="",successmessage=""):
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
request.session['referer'] = absolute(request)['PATH']
-
- try:
- # check if valid ID exists (workout exists)
- row = Workout.objects.get(id=id)
- form = WorkoutForm(instance=row)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
+ form = WorkoutForm(instance=row)
if request.method == 'POST':
# Form was submitted
@@ -8829,11 +8706,7 @@ def workout_edit_view_navionics(request,id=0,message="",successmessage=""):
#else: # form not POSTed
form = WorkoutForm(instance=row)
-
- try:
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout(id)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
for i in g:
@@ -8918,10 +8791,7 @@ def workout_uploadimage_view(request,id):
r = getrower(request.user)
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
if not checkworkoutuser(request.user,w):
raise PermissionDenied("You are not allowed to edit this workout")
@@ -9002,10 +8872,8 @@ def workout_uploadimage_view(request,id):
# Generic chart creation
@login_required()
def workout_add_chart_view(request,id,plotnr=1):
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+
+ w = get_workout(id)
plotnr = int(plotnr)
@@ -9360,10 +9228,7 @@ def workout_getstravaworkout_view(request,stravaid):
id,message = add_workout_from_strokedata(request.user,stravaid,data,strokedata,
source='strava',
workoutsource='strava')
- try:
- w = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ w = get_workout(id)
w.uploadedtostrava=stravaid
w.save()
@@ -9664,16 +9529,8 @@ def workout_toggle_ranking(request,id=0):
if request.is_ajax():
is_ajax = True
- try:
- # check if valid ID exists (workout exists)
- row = Workout.objects.get(id=id)
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout_permitted(request.user,id)
- if not checkworkoutuser(request.user,row):
- raise PermissionDenied("You are not allowed to change this workout")
-
- # we are still here - we own the workout
row.rankingpiece = not row.rankingpiece
row.save()
@@ -10398,12 +10255,7 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
# Split a workout
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def workout_split_view(request,id=id):
- try:
- row = Workout.objects.get(id=id)
- if (checkworkoutuser(request.user,row)==False):
- raise PermissionDenied("You are not allowed to edit this workout")
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout_permitted(request.user,id)
r = row.user
@@ -10533,12 +10385,7 @@ def workout_fusion_view(request,id1=0,id2=1):
@login_required()
def workout_summary_edit_view(request,id,message="",successmessage=""
):
- try:
- row = Workout.objects.get(id=id)
- if (checkworkoutuser(request.user,row)==False):
- raise PermissionDenied("You are not allowed to edit this workout")
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout_permitted(request.user,id)
s = ""
# still here - this is a workout we may edit
@@ -11175,12 +11022,8 @@ def strokedatajson(request,id):
POST: Add Stroke data to workout
GET: Get stroke data of workout
"""
- try:
- row = Workout.objects.get(id=id)
- if (checkworkoutuser(request.user,row)==False):
- return HttpResponseForbidden("Permission error")
- except Workout.DoesNotExist:
- raise Http404("Workout doesn't exist")
+ row = get_workout_permitted(request.user,id)
+
try:
id = int(id)
except ValueError:
@@ -12011,6 +11854,68 @@ def plannedsession_teamedit_view(request,timeperiod='thisweek',
'plannedsessions':sps,
})
+@user_passes_test(iscoachmember,login_url="/rowers/planmembership/",
+ redirect_field_name=None)
+def plannedsessions_coach_view(request,timeperiod='thisweek',
+ teamid=0):
+
+ startdate,enddate = get_dates_timeperiod(timeperiod)
+
+ if teamid != 0:
+ try:
+ theteam = Team.objects.get(id=teamid)
+ except Team.DoesNotExist:
+ theteam = False
+ else:
+ theteam = False
+
+ sps = get_sessions_manager(request.user,teamid=teamid,
+ enddate=enddate,
+ startdate=startdate)
+
+ rowers = []
+ for ps in sps:
+ rowers += ps.rower.all()
+
+ rowers = list(set(rowers))
+
+ statusdict = {}
+
+ for ps in sps:
+ rowerstatus = {}
+ for r in rowers:
+ ratio, status = is_session_complete(r,ps)
+ rowerstatus[r.id] = status
+ sessiondict = {
+ 'results':rowerstatus,
+ 'name': ps.name,
+ 'startdate': ps.startdate,
+ 'enddate': ps.enddate,
+ }
+ statusdict[ps.id] = sessiondict
+
+ unmatchedworkouts = []
+ for r in rowers:
+ unmatchedworkouts += Workout.objects.filter(
+ user=r,
+ plannedsession=None,
+ date__gte=startdate,date__lte=enddate)
+
+
+ myteams = Team.objects.filter(manager=request.user)
+
+ return render(request,'plannedsessionscoach.html',
+ {
+ 'myteams':myteams,
+ 'plannedsessions':sps,
+ 'statusdict':statusdict,
+ 'timeperiod':timeperiod,
+ 'rowers':rowers,
+ 'theteam':theteam,
+ 'unmatchedworkouts':unmatchedworkouts,
+ 'rower':getrower(request.user)
+ }
+ )
@login_required()
def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
@@ -12319,6 +12224,7 @@ def plannedsession_view(request,id=0,rowerid=0):
m = getrower(request.user)
+
if not rowerid:
r = m
else:
@@ -12333,8 +12239,11 @@ def plannedsession_view(request,id=0,rowerid=0):
if ps.manager != request.user and r not in ps.rower.all():
raise PermissionDenied("You do not have access to this session")
+ resultsdict = get_session_metrics(ps)
+ resultsdict = pd.DataFrame(resultsdict).transpose().to_dict()
psdict = my_dict_from_instance(ps,PlannedSession)
+ print psdict
ws = get_workouts_session(r,ps)
@@ -12353,7 +12262,8 @@ def plannedsession_view(request,id=0,rowerid=0):
'manager':m,
'rower':r,
'ratio':ratio,
- 'status':status
+ 'status':status,
+ 'results':resultsdict,
}
)
diff --git a/static/css/rowsandall.css b/static/css/rowsandall.css
index 36fe4242..f8d66d68 100644
--- a/static/css/rowsandall.css
+++ b/static/css/rowsandall.css
@@ -139,9 +139,10 @@ cox {
.listtable tbody tr:nth-of-type(even) { background-color: #DDD; }
.listtable thead th {
- font-weight: bold;
+ font-weight: bold;
}
+
.shortpadded td { padding: 3px 3px }
.paddedtable td { padding: 1px 20px }