Private
Public Access
1
0

Merge branch 'release/v9.26'

This commit is contained in:
Sander Roosendaal
2019-02-19 21:25:44 +01:00
15 changed files with 159 additions and 63 deletions
+1 -1
View File
@@ -172,7 +172,7 @@ def update_subscription(rower,data,method='up'):
if rower.paidplan != 'coach':
try:
coachgroup = coach.mycoachgroup
coachgroup = rower.mycoachgroup
except CoachingGroup.DoesNotExist:
coachgroup = CoachingGroup()
coachgroup.save()
+27
View File
@@ -1023,6 +1023,33 @@ def checkworkoutuser(user,workout):
except Rower.DoesNotExist:
return False
def checkviewworkouts(user,rower):
try:
r = user.rower
if rower == r:
return True
teams = Team.objects.filter(manager=user)
print Rower.objects.filter(team__in=teams)
if rower in Rower.objects.filter(team__in=teams):
return True
except Rower.DoesNotExist:
return False
# check if user is plan and rower is in his group
def checkaccessplanuser(user,rower):
try:
r = Rower.objects.get(user=user)
if rower == r:
return True
team_managers = [t.manager for t in rower.team.all() if t.manager.rower.rowerplan in ['plan','coach']]
if user.rower.rowerplan != 'basic':
return user in team_managers
else:
return False
return False
except Rower.DoesNotExist:
return False
# Check if user is coach or rower
def checkaccessuser(user,rower):
+18 -1
View File
@@ -189,7 +189,7 @@
</td>
<td> {{ workout.date|date:"Y-m-d" }} </td>
<td> {{ workout.starttime|date:"H:i" }} </td>
{% if workout.user.user == user or user == team.manager %}
{% if workout|may_edit:request %}
{% if workout.name != '' %}
<td>
<a href={% url rower.defaultlandingpage id=workout.id|encode %}>
@@ -215,18 +215,27 @@
<td> {{ workout.maxhr }} </td>
{% if team %}
<td colspan="2">
{% if workout|may_edit:request %}
<a class="small" href="/rowers/{{ workout.user.id }}/list-workouts/">
{{ workout.user.user.first_name }}
{{ workout.user.user.last_name }}
</a>
{% else %}
{{ workout.user.user.first_name }}
{{ workout.user.user.last_name }}
{% endif %}
</td>
{% endif %}
<td>
{% if workout|may_edit:request %}
<a class="small"
href="/rowers/workout/{{ workout.id|encode }}/edit/"
title="Edit">
<i class="fas fa-pencil-alt fa-fw"></i>
</a>
{% else %}
&nbsp;
{% endif %}
</td>
<td>
<a class="small"
@@ -236,17 +245,25 @@
</a>
</td>
<td>
{% if workout|may_edit:request %}
<a class="small"
href="/rowers/workout/{{ workout.id|encode }}/stats/"
title="Stats">
<i class="fal fa-table fa-fw"></i>
</a>
{% else %}
&nbsp;
{% endif %}
</td>
<td>
{% if workout.user.user == user or user == team.manager %}
<a class="small" href="/rowers/workout/{{ workout.id|encode }}/delete/"
title="Delete">
<i class="fas fa-trash-alt fa-fw"></i>
</a>
{% else %}
&nbsp;
{% endif %}
</td>
</tr>
+16 -17
View File
@@ -40,7 +40,7 @@
</li>
<li id="sessions-coach">
<a href="/rowers/sessions/coach/?when={{ timeperiod }}">
<i class="fas fa-bullhorn fa-fw"></i>&nbsp;Coach View
<i class="fas fa-bullhorn fa-fw"></i>&nbsp;Training Group View
</a>
</li>
<li id="sessions-print">
@@ -82,27 +82,26 @@
<p>&nbsp;</p>
{% if user.is_authenticated and user|is_manager %}
{% if user.is_authenticated and user|is_planmember %}
<p>&nbsp;</p>
{% if user|coach_rowers %}
{% if user|team_members %}
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
<input type="checkbox" name="athlete-selector" id="athlete-selector">
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Group Members</label>
<ul>
{% for member in user|coach_rowers %}
<a href={{ request.path|userurl:member.user }}?when={{ timeperiod }}>
<i class="fas fa-user fa-fw"></i>
{% if member.user == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.user.first_name }} {{ member.user.last_name }}
</a>
{% for member in user|team_members %}
<li>
<a href={{ request.path|userurl:member }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user%}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.first_name }} {{ member.last_name }}
</a>
</li>
{% endfor %}
</ul>
</li>
+12 -11
View File
@@ -45,8 +45,11 @@
</li>
</ul> <!-- cd-accordion-menu -->
{% if user.is_authenticated and user|is_manager %}
<p>&nbsp;</p>
{% if user|coach_rowers %}
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
@@ -54,17 +57,15 @@
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<ul>
{% for member in user|coach_rowers %}
<li>
<a href={{ request.path|userurl:member.user }}>
<i class="fas fa-user fa-fw"></i>
{% if member.user == rower.user and not team %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.user.first_name }} {{ member.user.last_name }}
</a>
</li>
<a href={{ request.path|userurl:member.user }}?when={{ timeperiod }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.user.first_name }} {{ member.user.last_name }}
</a>
{% endfor %}
</ul>
</li>
+6 -6
View File
@@ -346,7 +346,7 @@ def has_teams(user):
def team_members(user):
try:
therower = Rower.objects.get(user=user)
if therower.rowerplan != 'coach':
if therower.rowerplan == 'basic':
return []
teams = Team.objects.filter(manager=user)
members = Rower.objects.filter(
@@ -364,7 +364,7 @@ def team_members(user):
def team_rowers(user):
try:
therower = Rower.objects.get(user=user)
if therower.rowerplan != 'coach':
if therower.rowerplan == 'basic':
return []
teams = Team.objects.filter(manager=user)
members = Rower.objects.filter(team__in=teams).distinct().order_by(
@@ -464,11 +464,11 @@ def is_final(race):
@register.filter
def userurl(path,member):
pattern = re.compile('user\/\d+')
pattern = re.compile('user\/\d+/')
userstring = 'user/%s/' % member.id
# remove team
tpattern = re.compile('\/team\/\d+')
tpattern = re.compile('\/team\/\d+/')
if tpattern.search(path) is not None:
path = tpattern.sub('',path)
@@ -481,11 +481,11 @@ def userurl(path,member):
@register.filter
def teamurl(path,team):
pattern = re.compile('team\/\d+')
pattern = re.compile('team\/\d+/')
teamstring = 'team/%s/' % team.id
# remove user
upattern = re.compile('\/user\/\d+')
upattern = re.compile('\/user\/\d+/')
if upattern.search(path) is not None:
path = upattern.sub('',path)
+7
View File
@@ -1414,3 +1414,10 @@ class PermissionsCoachingTests(TestCase):
## Basic and Pro users can create races
## Basic users can subscribe to any race
# group related
## group members can see but not edit each other's workouts and charts
## group members can see but not edit each other's plans
Binary file not shown.
+1 -1
View File
@@ -638,7 +638,7 @@ urlpatterns = [
name='plannedsessions_manage_view'),
url(r'^sessions/coach/$',views.plannedsessions_coach_view,
name='plannedsessions_coach_view'),
url(r'^sessions/coach/user/\d+/$',views.plannedsessions_coach_view,
url(r'^sessions/coach/user/(?P<userid>\d+)/$',views.plannedsessions_coach_view,
name='plannedsessions_coach_view'),
url(r'^sessions/print/?/$',views.plannedsessions_print_view,
name='plannedsessions_print_view'),
+15 -13
View File
@@ -2,7 +2,7 @@ from statements import *
@login_required()
def plannedsession_comment_view(request,id=0,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
try:
ps = PlannedSession.objects.get(id=id)
@@ -170,7 +170,7 @@ def plannedsession_multiclone_view(
request,
userid=0,):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request)
@@ -301,7 +301,7 @@ def plannedsession_create_view(request,
startdatestring='',
enddatestring=''):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
@@ -442,7 +442,7 @@ def plannedsession_multicreate_view(request,
extrasessions=int(extrasessions)
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request)
@@ -547,12 +547,13 @@ def plannedsession_multicreate_view(request,
return render(request,'plannedsession_multicreate.html',context)
# Manager creates sessions for entire team
@user_passes_test(iscoachmember,login_url="/rowers/paidplans/",
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_teamcreate_view(request,
teamid=0,userid=0):
therower = getrequestrower(request,userid=userid)
therower = getrequestplanrower(request,userid=userid)
@@ -716,11 +717,12 @@ def plannedsession_teamcreate_view(request,
# Manager edits sessions for entire team
@user_passes_test(iscoachmember,login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_teamedit_view(request,
sessionid=0,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
try:
@@ -880,7 +882,7 @@ def plannedsessions_coach_view(request,
teamid=0,userid=0):
therower = getrower(request.user)
therower = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request)
@@ -984,7 +986,7 @@ from rowers.plannedsessions import cratiocolors
def plannedsessions_view(request,
userid=0,startdatestring='',enddatestring=''):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
if startdatestring:
try:
@@ -1127,7 +1129,7 @@ def plannedsessions_view(request,
@login_required()
def plannedsessions_print_view(request,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
@@ -1330,7 +1332,7 @@ def plannedsessions_manage_view(request,userid=0,
redirect_field_name=None)
def plannedsession_clone_view(request,id=0,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request)
@@ -1391,7 +1393,7 @@ def plannedsession_clone_view(request,id=0,userid=0):
redirect_field_name=None)
def plannedsession_edit_view(request,id=0,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
@@ -1536,7 +1538,7 @@ def plannedsession_detach_view(request,id=0,psid=0):
@login_required()
def plannedsession_view(request,id=0,userid=0):
r = getrequestrower(request,userid=userid)
r = getrequestplanrower(request,userid=userid)
+35 -2
View File
@@ -88,7 +88,7 @@ from rowers.models import (
microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates,
TrainingMesoCycleForm, TrainingMicroCycleForm,
RaceLogo,RowerBillingAddressForm,PaidPlan,
PlannedSessionComment,CoachRequest,CoachOffer,
PlannedSessionComment,CoachRequest,CoachOffer,checkaccessplanuser
)
from rowers.models import (
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
@@ -300,6 +300,39 @@ def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
return r
def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False):
userid = int(userid)
rowerid = int(rowerid)
if notpermanent == False:
if rowerid == 0 and 'rowerid' in request.session:
rowerid = request.session['rowerid']
if userid != 0:
rowerid = 0
try:
if rowerid != 0:
r = Rower.objects.get(id=rowerid)
elif userid != 0:
u = User.objects.get(id=userid)
r = getrower(u)
else:
r = getrower(request.user)
except Rower.DoesNotExist:
raise Http404("Rower doesn't exist")
if not checkaccessplanuser(request.user,r):
raise PermissionDenied("You have no access to this user")
if notpermanent == False:
request.session['rowerid'] = r.id
return r
def getrower(user):
try:
@@ -911,7 +944,7 @@ from rowers.utils import (
import rowers.datautils as datautils
from rowers.models import checkworkoutuser,checkaccessuser
from rowers.models import checkworkoutuser,checkaccessuser,checkviewworkouts
# Check if a user is a Coach member
def iscoachmember(user):
+14 -7
View File
@@ -186,15 +186,22 @@ def rower_teams_view(request,message='',successmessage=''):
invitedcoaches = [rekwest.coach for rekwest in mycoachrequests]
coaches = teams.rower_get_coaches(r)
potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches ]
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches]
print coaches,'aap'
potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches and t.manager.rower.rowerplan == 'coach']
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
coachees = teams.coach_getcoachees(r)
potentialathletes = Rower.objects.filter(
team__in=myteams).exclude(
user__in=invitedathletes).exclude(
user=request.user
).exclude(coachinggroups__in=[request.user.rower.mycoachgroup])
if request.user.rower.rowerplan == 'coach':
potentialathletes = Rower.objects.filter(
team__in=myteams).exclude(
user__in=invitedathletes).exclude(
user=request.user
).exclude(coachinggroups__in=[request.user.rower.mycoachgroup])
else:
potentialathletes = []
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
+2 -2
View File
@@ -856,7 +856,7 @@ def virtualevent_compare_view(request,id=0):
workouts = []
for id in workoutids:
try:
workouts.append(Workout.objects.get(id=encode.decode_hex(id)))
workouts.append(Workout.objects.get(id=id))
except Workout.DoesNotExist:
pass
@@ -1157,7 +1157,7 @@ def workouts_view(request,message='',successmessage='',
r = getrequestrower(request,rowerid=rowerid,userid=userid)
# check if access is allowed
if not checkaccessuser(request.user,r):
if not checkviewworkouts(request.user,r):
raise PermissionDenied("Access denied")
if startdatestring:
+1
View File
@@ -75,6 +75,7 @@ urlpatterns += [
url(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^tz_detect/', include('tz_detect.urls')),
url(r'^jsi18n/', 'django.views.i18n.javascript_catalog',name='jsi18n'),
]
+4 -2
View File
@@ -12,7 +12,7 @@
<title>{% block title %}Rowsandall Rowing Data Analytics{% endblock %}</title>
{% block scripts %} {% endblock %}
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/jsi18n/"></script>
<script type="text/javascript" src="/static/admin/js/core.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
@@ -31,7 +31,9 @@
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>