Private
Public Access
1
0

Merge branch 'release/v9.29'

This commit is contained in:
Sander Roosendaal
2019-02-22 21:14:50 +01:00
20 changed files with 172 additions and 66 deletions
+5 -2
View File
@@ -24,7 +24,7 @@ class RowerInline(admin.StackedInline):
('Billing Details', ('Billing Details',
{'fields':('street_address','city','postal_code','country','paymentprocessor','customer_id')}), {'fields':('street_address','city','postal_code','country','paymentprocessor','customer_id')}),
('Rower Plan', ('Rower Plan',
{'fields':('paidplan','rowerplan','paymenttype','planexpires','teamplanexpires','protrialexpires','plantrialexpires',)}), {'fields':('paidplan','rowerplan','paymenttype','planexpires','teamplanexpires','protrialexpires','plantrialexpires','clubsize','offercoaching')}),
('Rower Settings', ('Rower Settings',
{'fields': {'fields':
('gdproptin','gdproptindate','weightcategory','sex','adaptiveclass','birthdate','getemailnotifications', ('gdproptin','gdproptindate','weightcategory','sex','adaptiveclass','birthdate','getemailnotifications',
@@ -60,7 +60,7 @@ class RowerInline(admin.StackedInline):
#class UserAdmin(UserAdmin): #class UserAdmin(UserAdmin):
class UserAdmin(admin.ModelAdmin): class UserAdmin(admin.ModelAdmin):
inlines = (RowerInline,) inlines = (RowerInline,)
list_display = ('username','email','first_name','last_name','rowerplan') list_display = ('username','email','first_name','last_name','rowerplan','clubsize')
fieldsets = ( fieldsets = (
('Personal info', ('Personal info',
@@ -75,6 +75,9 @@ class UserAdmin(admin.ModelAdmin):
def rowerplan(self, obj): def rowerplan(self, obj):
return obj.rower.rowerplan return obj.rower.rowerplan
def clubsize(self, obj):
return obj.rower.clubsize
class WorkoutAdmin(admin.ModelAdmin): class WorkoutAdmin(admin.ModelAdmin):
list_display = ('date','user','name','workouttype','boattype') list_display = ('date','user','name','workouttype','boattype')
+2 -2
View File
@@ -188,7 +188,7 @@ class Command(BaseCommand):
res = polarstuff.get_all_new_workouts(polar_available) res = polarstuff.get_all_new_workouts(polar_available)
# Concept2 # Concept2
rowers = Rower.objects.filter(c2_auto_import=True) rowers = Rower.objects.filter(c2_auto_import=True).exclude(rowerplan='basic')
for r in rowers: for r in rowers:
c2stuff.get_c2_workouts(r) c2stuff.get_c2_workouts(r)
@@ -287,7 +287,7 @@ class Command(BaseCommand):
message.delete() message.delete()
# Strava # Strava
rowers = Rower.objects.filter(strava_auto_import=True) rowers = Rower.objects.filter(strava_auto_import=True).exclude(rowerplan='basic')
for r in rowers: for r in rowers:
stravastuff.get_strava_workouts(r) stravastuff.get_strava_workouts(r)
+19
View File
@@ -1024,6 +1024,25 @@ def checkworkoutuser(user,workout):
except Rower.DoesNotExist: except Rower.DoesNotExist:
return False return False
# Check if workout may be viewed by this user
def checkworkoutuserview(user,workout):
if user.is_anonymous():
return False
try:
r = Rower.objects.get(user=user)
if workout.user == r:
return True
teams = workout.user.team.all()
for team in teams:
if team in r.team.all():
return True
return False
except Rower.DoesNotExist:
return False
return False
def checkviewworkouts(user,rower): def checkviewworkouts(user,rower):
try: try:
r = user.rower r = user.rower
+7 -2
View File
@@ -473,13 +473,14 @@ def remove_rower_session(r,ps):
return 1 return 1
def get_dates_timeperiod(request,startdatestring='',enddatestring=''): def get_dates_timeperiod(request,startdatestring='',enddatestring='',
defaulttimeperiod='thisweek'):
# set start end date according timeperiod # set start end date according timeperiod
timeperiod = request.GET.get('when') timeperiod = request.GET.get('when')
if not timeperiod: if not timeperiod:
timeperiod = 'thisweek' timeperiod = defaulttimeperiod
startdatestring = request.GET.get('startdate') startdatestring = request.GET.get('startdate')
enddatestring = request.GET.get('enddate') enddatestring = request.GET.get('enddate')
@@ -536,6 +537,10 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring=''):
enddate = startdate+timezone.timedelta(days=32) enddate = startdate+timezone.timedelta(days=32)
enddate = enddate.replace(day=1) enddate = enddate.replace(day=1)
enddate = enddate-timezone.timedelta(days=1) enddate = enddate-timezone.timedelta(days=1)
elif timeperiod=='lastyear':
today = date.today()
startdate = today-timezone.timedelta(days=365)
enddate = today+timezone.timedelta(days=1)
elif daterangetester.match(timeperiod): elif daterangetester.match(timeperiod):
tstartdatestring = daterangetester.match(timeperiod).group(1) tstartdatestring = daterangetester.match(timeperiod).group(1)
tenddatestring = daterangetester.match(timeperiod).group(2) tenddatestring = daterangetester.match(timeperiod).group(2)
+6 -3
View File
@@ -68,6 +68,7 @@ from rowers.dataprepnodjango import (
# create_strava_stroke_data_db # create_strava_stroke_data_db
) )
from rowers.opaque import encoder
from django.core.mail import ( from django.core.mail import (
send_mail, send_mail,
@@ -1890,7 +1891,8 @@ def handle_sendemailnewresponse(first_name, last_name,
if 'sessiontype' in kwargs: if 'sessiontype' in kwargs:
sessiontype=kwargs.pop('sessiontype') sessiontype=kwargs.pop('sessiontype')
commentlink = '/rowers/workout/{workoutid}/comment/'.format(workoutid=workoutid) commentlink = '/rowers/workout/{workoutid}/comment/'.format(
workoutid=encoder.encode_hex(workoutid))
if 'commentlink' in kwargs: if 'commentlink' in kwargs:
commentlink = kwargs.pop('commentlink') commentlink = kwargs.pop('commentlink')
@@ -1940,7 +1942,8 @@ def handle_sendemailnewcomment(first_name,
if 'sessiontype' in kwargs: if 'sessiontype' in kwargs:
sessiontype=kwargs.pop('sessiontype') sessiontype=kwargs.pop('sessiontype')
commentlink = '/rowers/workout/{workoutid}/comment/'.format(workoutid=workoutid) commentlink = '/rowers/workout/{workoutid}/comment/'.format(
workoutid=encoder.encode_hex(workoutid))
if 'commentlink' in kwargs: if 'commentlink' in kwargs:
commentlink = kwargs.pop('commentlink') commentlink = kwargs.pop('commentlink')
@@ -1951,7 +1954,7 @@ def handle_sendemailnewcomment(first_name,
'comment':comment, 'comment':comment,
'workoutname':workoutname, 'workoutname':workoutname,
'siteurl':siteurl, 'siteurl':siteurl,
'workoutid':workoutid, 'workoutid':encoder.encode_hex(workoutid),
'sessiontype':sessiontype, 'sessiontype':sessiontype,
'commentlink':commentlink, 'commentlink':commentlink,
} }
+21 -6
View File
@@ -111,16 +111,20 @@ def remove_team(id):
def add_coach(coach,rower): def add_coach(coach,rower):
# get coaching group # get coaching group
coachgroup = coach.mycoachgroup coachgroup = coach.mycoachgroup
if coachgroup is None: if coachgroup is None:
coachgroup = CoachingGroup(name=coach.user.first_name) coachgroup = CoachingGroup(name=coach.user.first_name)
coachgroup.save() coachgroup.save()
coach.mycoachgroup = coachgroup coach.mycoachgroup = coachgroup
coach.save() coach.save()
rower.coachinggroups.add(coach.mycoachgroup)
return (1,"Added Coach") if get_coach_club_size(coach)<coach.clubsize:
rower.coachinggroups.add(coach.mycoachgroup)
return (1,"Added Coach")
else:
return (0,"Maximum number of athletes reached")
def add_member(id,rower): def add_member(id,rower):
t= Team.objects.get(id=id) t= Team.objects.get(id=id)
@@ -287,6 +291,15 @@ def create_request(team,user):
return (0,'Something went wrong in create_request') return (0,'Something went wrong in create_request')
def get_coach_club_size(coach):
rs = Rower.objects.filter(coachinggroups__in=[coach.mycoachgroup])
rekwests = CoachOffer.objects.filter(coach=coach)
result = len(rs)+len(rekwests)
return result
# request by coach to coach user # request by coach to coach user
def create_coaching_offer(coach,user): def create_coaching_offer(coach,user):
r = user.rower r = user.rower
@@ -299,13 +312,15 @@ def create_coaching_offer(coach,user):
while code in codes: while code in codes:
code = uuid.uuid4().hex[:10].upper() code = uuid.uuid4().hex[:10].upper()
if coach.rowerplan == 'coach': if coach.rowerplan == 'coach' and get_coach_club_size(coach)<coach.clubsize:
rekwest = CoachOffer(coach=coach,user=user,code=code) rekwest = CoachOffer(coach=coach,user=user,code=code)
rekwest.save() rekwest.save()
send_coacheerequest_email(rekwest) send_coacheerequest_email(rekwest)
return (rekwest.id,'The request was created') return (rekwest.id,'The request was created')
elif get_coach_club_size(coach)>=coach.clubsize:
return(0,'You have reached the maximum number of athletes')
else: else:
return (0,'You are not a coach') return (0,'You are not a coach')
@@ -634,7 +649,7 @@ def process_coachrequest_code(coach,code):
result = add_coach(coach,rekwest.user.rower) result = add_coach(coach,rekwest.user.rower)
if not result: if not result:
return (result,"Something went wrong") return result
else: else:
send_coachrequest_accepted_email(rekwest) send_coachrequest_accepted_email(rekwest)
@@ -655,7 +670,7 @@ def process_coachoffer_code(user,code):
result = add_coach(rekwest.coach,rekwest.user.rower) result = add_coach(rekwest.coach,rekwest.user.rower)
if not result: if not result:
return (result,"Something went wrong") return result
else: else:
send_coachoffer_accepted_email(rekwest) send_coachoffer_accepted_email(rekwest)
+1 -1
View File
@@ -43,7 +43,7 @@
</p> </p>
<p> <p>
Looking for the <a href="/rowers/downgrade">downgrade</a> option? Looking for the <a href="/rowers/upgrade">upgrade</a> option?
</p> </p>
</li> </li>
<li class="grid_3"> <li class="grid_3">
+4 -8
View File
@@ -129,7 +129,7 @@
{% if workouts.has_next %} {% if workouts.has_next %}
{% if request.GET.q %} {% if request.GET.q %}
<a href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/?page={{ workouts.next_page_number }}&q={{ request.GET.q }}"> <a href="{{ request.path }}?page={{ workouts.next_page_number }}&q={{ request.GET.q }}&when={{ timeperiod }}">
<i class="fas fa-arrow-alt-right"></i> <i class="fas fa-arrow-alt-right"></i>
</a> </a>
<a <a
@@ -137,7 +137,7 @@
<i class="fas fa-arrow-alt-to-right"></i> <i class="fas fa-arrow-alt-to-right"></i>
</a> </a>
{% else %} {% else %}
<a href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/?page={{ workouts.next_page_number }}"> <a href="{{ request.path }}?page={{ workouts.next_page_number }}&when={{ timeperiod }}">
<i class="fas fa-arrow-alt-right"></i> <i class="fas fa-arrow-alt-right"></i>
</a> </a>
<a href="?page={{ workouts.paginator.num_pages }}"> <a href="?page={{ workouts.paginator.num_pages }}">
@@ -216,7 +216,7 @@
{% if team %} {% if team %}
<td colspan="2"> <td colspan="2">
{% if workout|may_edit:request %} {% if workout|may_edit:request %}
<a class="small" href="/rowers/{{ workout.user.id }}/list-workouts/"> <a class="small" href="/rowers/list-workouts/user/{{ workout.user.user.id }}/">
{{ workout.user.user.first_name }} {{ workout.user.user.first_name }}
{{ workout.user.user.last_name }} {{ workout.user.user.last_name }}
</a> </a>
@@ -245,18 +245,14 @@
</a> </a>
</td> </td>
<td> <td>
{% if workout|may_edit:request %}
<a class="small" <a class="small"
href="/rowers/workout/{{ workout.id|encode }}/stats/" href="/rowers/workout/{{ workout.id|encode }}/stats/"
title="Stats"> title="Stats">
<i class="fal fa-table fa-fw"></i> <i class="fal fa-table fa-fw"></i>
</a> </a>
{% else %}
&nbsp;
{% endif %}
</td> </td>
<td> <td>
{% if workout.user.user == user or user == team.manager %} {% if workout|may_edit:request %}
<a class="small" href="/rowers/workout/{{ workout.id|encode }}/delete/" <a class="small" href="/rowers/workout/{{ workout.id|encode }}/delete/"
title="Delete"> title="Delete">
<i class="fas fa-trash-alt fa-fw"></i> <i class="fas fa-trash-alt fa-fw"></i>
+1 -1
View File
@@ -63,7 +63,7 @@
</li> </li>
<li id="plan-teamsession"> <li id="plan-teamsession">
<a href="/rowers/sessions/teamcreate/?when={{ timeperiod }}"> <a href="/rowers/sessions/teamcreate/?when={{ timeperiod }}">
<i class="fas fa-whistle fa-fw"></i>&nbsp;Add Team Session <i class="fas fa-whistle fa-fw"></i>&nbsp;Add Group Session
</a> </a>
</li> </li>
<li id="plan-microcycle"> <li id="plan-microcycle">
+1 -1
View File
@@ -41,7 +41,7 @@
</a> </a>
</li> </li>
<li id="compare"> <li id="compare">
<a href="/rowers/multi-compare/workout/{{ workout.id|encode }}/"> <a href="/rowers/team-compare-select/workout/{{ workout.id|encode }}/">
<i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare <i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare
</a> </a>
</li> </li>
+17 -3
View File
@@ -94,7 +94,14 @@
<td>&#10004;</td> <td>&#10004;</td>
</tr> </tr>
<tr> <tr>
<td>Create Training plans, tests and challenges for yourself. Track your performance <td>Create and manage groups.</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Create Training plans, tests and challenges for yourself and your training group. Track your performance
against plan.</td> against plan.</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -110,14 +117,21 @@
<td>&#10004;</td> <td>&#10004;</td>
</tr> </tr>
<tr> <tr>
<td>Create and manage teams.</td> <td>Manage your athlete's workouts</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&#10004;</td> <td>&#10004;</td>
</tr> </tr>
<tr> <tr>
<td>Manage your athlete's workouts</td> <td>Run analytics for your athletes</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Change zone intensities and other workout related settings for your athletes</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
+1 -1
View File
@@ -90,7 +90,7 @@
</li> </li>
<li class="grid_2"> <li class="grid_2">
{% csrf_token %} {% csrf_token %}
<input class="button green" type="submit" value="Submit"> <input type="submit" value="Submit">
</li> </li>
</ul> </ul>
+4
View File
@@ -96,6 +96,10 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<p>
<a href="/rowers/sessions/manage/session/{{ psdict.id.1 }}/">
Add, remove or change workouts for this session</a>
</p>
</li> </li>
<li class="grid_2"> <li class="grid_2">
<h2>{{ rower.user.first_name }} {{ rower.user.last_name }}</h2> <h2>{{ rower.user.first_name }} {{ rower.user.last_name }}</h2>
@@ -4,6 +4,11 @@
{% block main %} {% block main %}
<h1>Import and Export Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1> <h1>Import and Export Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
{% if user.rower.rowerplan == 'basic' %}
The auto import and export settings only work on <a href="/rowers/paidplans/">a paid plan</a>.
{% endif %}
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
+4 -3
View File
@@ -470,7 +470,7 @@ def userurl(path,member):
userstring = 'user/%s/' % member.id userstring = 'user/%s/' % member.id
# remove team # remove team
tpattern = re.compile('\/team\/\d+/') tpattern = re.compile('team\/\d+/')
if tpattern.search(path) is not None: if tpattern.search(path) is not None:
path = tpattern.sub('',path) path = tpattern.sub('',path)
@@ -478,7 +478,7 @@ def userurl(path,member):
replaced = pattern.sub(userstring,path) replaced = pattern.sub(userstring,path)
else: else:
replaced = path+userstring replaced = path+userstring
return replaced return replaced
@register.filter @register.filter
@@ -489,7 +489,7 @@ def teamurl(path,team):
# remove user # remove user
upattern = re.compile('\/user\/\d+/') upattern = re.compile('\/user\/\d+/')
if upattern.search(path) is not None: if upattern.search(path) is not None:
path = upattern.sub('',path) path = upattern.sub('/',path)
if pattern.search(path) is not None: if pattern.search(path) is not None:
@@ -497,6 +497,7 @@ def teamurl(path,team):
else: else:
replaced = path+teamstring replaced = path+teamstring
return replaced return replaced
@register.filter @register.filter
+29 -5
View File
@@ -20,7 +20,7 @@ class PermissionsBasicsTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach, self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(), gdproptin=True,gdproptindate=timezone.now(),
rowerplan='coach') rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create() self.coachinggroup = CoachingGroup.objects.create()
@@ -280,7 +280,7 @@ class PermissionsViewTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach, self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(), gdproptin=True,gdproptindate=timezone.now(),
rowerplan='coach') rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create() self.coachinggroup = CoachingGroup.objects.create()
@@ -958,6 +958,31 @@ class PermissionsViewTests(TestCase):
response = self.c.get(url) response = self.c.get(url)
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
# stats
url = reverse('workout_view',
kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
)
response = self.c.get(url)
self.assertEqual(response.status_code,200)
# workflow
url = reverse('workout_workflow_view',
kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
)
response = self.c.get(url)
self.assertEqual(response.status_code,200)
# stats
url = reverse('workout_stats_view',
kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
)
response = self.c.get(url)
self.assertEqual(response.status_code,200)
## Pro users (and higher) can join group led by other Pro (or higher) user ## Pro users (and higher) can join group led by other Pro (or higher) user
def test_team_member_request_pro_pro(self): def test_team_member_request_pro_pro(self):
@@ -1009,7 +1034,7 @@ class PermissionsCoachingTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach, self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(), gdproptin=True,gdproptindate=timezone.now(),
rowerplan='coach') rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create() self.coachinggroup = CoachingGroup.objects.create()
@@ -1416,8 +1441,7 @@ class PermissionsCoachingTests(TestCase):
## Basic users can subscribe to any race ## 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 ## group members can see but not edit each other's plans
Binary file not shown.
+11 -1
View File
@@ -367,6 +367,14 @@ def get_workout_permitted(user,id):
return w return w
def get_workout_permittedview(user,id):
w = get_workout(id)
if (checkworkoutuserview(user,w)==False):
raise PermissionDenied("Access denied")
return w
def getvalue(data): def getvalue(data):
perc = 0 perc = 0
total = 1 total = 1
@@ -944,7 +952,9 @@ from rowers.utils import (
import rowers.datautils as datautils import rowers.datautils as datautils
from rowers.models import checkworkoutuser,checkaccessuser,checkviewworkouts from rowers.models import (
checkworkoutuser,checkaccessuser,checkviewworkouts,checkworkoutuserview
)
# Check if a user is a Coach member # Check if a user is a Coach member
def iscoachmember(user): def iscoachmember(user):
+5 -1
View File
@@ -189,7 +189,9 @@ def rower_teams_view(request,message='',successmessage=''):
coachrequests = CoachRequest.objects.filter(coach=r) coachrequests = CoachRequest.objects.filter(coach=r)
invitedathletes = [rekwest.user for rekwest in mycoachoffers] invitedathletes = [rekwest.user for rekwest in mycoachoffers]
invitedcoaches = [rekwest.coach for rekwest in mycoachrequests] invitedcoaches = [rekwest.coach for rekwest in mycoachrequests ]
invitedcoaches += [rekwest.coach for rekwest in coachoffers]
invitingathletes = [rekwest.user for rekwest in coachrequests]
coaches = teams.rower_get_coaches(r) coaches = teams.rower_get_coaches(r)
@@ -200,6 +202,7 @@ def rower_teams_view(request,message='',successmessage=''):
] ]
potentialcoaches = list(set(potentialcoaches+offercoaches)) potentialcoaches = list(set(potentialcoaches+offercoaches))
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches] potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
potentialcoaches = [c for c in potentialcoaches if teams.get_coach_club_size(c.rower)<c.rower.clubsize]
coachees = teams.coach_getcoachees(r) coachees = teams.coach_getcoachees(r)
@@ -213,6 +216,7 @@ def rower_teams_view(request,message='',successmessage=''):
else: else:
potentialathletes = [] potentialathletes = []
potentialathletes = [a for a in potentialathletes if a.user not in invitingathletes]
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user) # clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
# max_clubsize = r.clubsize # max_clubsize = r.clubsize
+29 -26
View File
@@ -590,7 +590,9 @@ def workouts_join_select(request,
}) })
# Team comparison # Team comparison
@login_required() @user_passes_test(ispromember,login_url='/rowers/paidplans/',
message="This functionality requires a Pro plan or higher",
redirect_field_name=None)
def team_comparison_select(request, def team_comparison_select(request,
startdatestring="", startdatestring="",
enddatestring="", enddatestring="",
@@ -695,11 +697,6 @@ def team_comparison_select(request,
except Team.DoesNotExist: except Team.DoesNotExist:
theteam = 0 theteam = 0
if requestrower.rowerplan == 'basic' and theteam==0:
if requestrower.protrialexpires is None or requestrower.protrialexpires<datetime.date.today():
raise PermissionDenied("Access denied")
if theteam and (theteam.viewing == 'allmembers' or theteam.manager == request.user): if theteam and (theteam.viewing == 'allmembers' or theteam.manager == request.user):
workouts = Workout.objects.filter(team=theteam, workouts = Workout.objects.filter(team=theteam,
startdatetime__gte=startdate, startdatetime__gte=startdate,
@@ -737,8 +734,8 @@ def team_comparison_select(request,
if id: if id:
firstworkout = get_workout(id) firstworkout = get_workout(id)
if not checkworkoutuser(request.user,firstworkout): if not checkworkoutuserview(request.user,firstworkout):
raise PermissionDenied("You are not allowed to sue this workout") raise PermissionDenied("You are not allowed to use this workout")
firstworkoutquery = Workout.objects.filter(id=encoder.decode_hex(id)) firstworkoutquery = Workout.objects.filter(id=encoder.decode_hex(id))
workouts = firstworkoutquery | workouts workouts = firstworkoutquery | workouts
@@ -840,6 +837,17 @@ def virtualevent_compare_view(request,id=0):
workoutids = [result.workoutid for result in results] workoutids = [result.workoutid for result in results]
if len(workoutids) == 0:
url = reverse('virtualevent_view',
kwargs={
'id':race.id,
})
messages.info(request,'There are no results to display')
return HttpResponseRedirect(url)
if request.method == 'GET': if request.method == 'GET':
xparam = race.sessionmode if race.sessionmode in ['distance','time'] else 'time' xparam = race.sessionmode if race.sessionmode in ['distance','time'] else 'time'
yparam = 'pace' yparam = 'pace'
@@ -1149,26 +1157,17 @@ def multi_compare_view(request,id=0,userid=0):
# List Workouts # List Workouts
@login_required() @login_required()
def workouts_view(request,message='',successmessage='', def workouts_view(request,message='',successmessage='',
startdatestring='',
enddatestring='',
teamid=0,rankingonly=False,rowerid=0,userid=0): teamid=0,rankingonly=False,rowerid=0,userid=0):
startdate,enddate = get_dates_timeperiod(request,defaulttimeperiod='lastyear')
request.session['referer'] = absolute(request)['PATH'] request.session['referer'] = absolute(request)['PATH']
r = getrequestrower(request,rowerid=rowerid,userid=userid) r = getrequestrower(request,rowerid=rowerid,userid=userid)
# check if access is allowed # check if access is allowed
if not checkviewworkouts(request.user,r): if not checkviewworkouts(request.user,r):
raise PermissionDenied("Access denied") raise PermissionDenied("Access denied")
if startdatestring:
startdate = iso8601.parse_date(startdatestring)
else:
startdate = datetime.date.today()-datetime.timedelta(days=365)
if enddatestring:
enddate = iso8601.parse_date(enddatestring)
else:
enddate = datetime.date.today()
startdate = datetime.datetime.combine(startdate,datetime.time()) startdate = datetime.datetime.combine(startdate,datetime.time())
@@ -1341,7 +1340,7 @@ def workouts_view(request,message='',successmessage='',
'name':'Workouts' 'name':'Workouts'
}, },
] ]
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
return render(request, 'list_workouts.html', return render(request, 'list_workouts.html',
{'workouts': workouts, {'workouts': workouts,
'active': 'nav-workouts', 'active': 'nav-workouts',
@@ -1357,6 +1356,7 @@ def workouts_view(request,message='',successmessage='',
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
'interactiveplot':script, 'interactiveplot':script,
'the_div':div, 'the_div':div,
'timeperiod':timeperiod,
}) })
@@ -2478,7 +2478,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
# prepare data frame # prepare data frame
datadf,row = dataprep.getrowdata_db(id=encoder.decode_hex(id)) datadf,row = dataprep.getrowdata_db(id=encoder.decode_hex(id))
if (checkworkoutuser(request.user,row)==False): if (checkworkoutuserview(request.user,row)==False):
raise PermissionDenied('Access Denied') raise PermissionDenied('Access Denied')
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
@@ -2714,7 +2714,7 @@ def workout_workflow_view(request,id):
request.session['referer'] = absolute(request)['PATH'] request.session['referer'] = absolute(request)['PATH']
request.session['lastworkout'] = id request.session['lastworkout'] = id
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
row = get_workout_permitted(request.user,id) row = get_workout_permittedview(request.user,id)
r = getrower(request.user) r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user) result = request.user.is_authenticated() and ispromember(request.user)
@@ -4198,7 +4198,8 @@ def workout_upload_view(request,
# This is the main view for processing uploaded files # This is the main view for processing uploaded files
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None) @user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None,
message="This functionality requires a Coach plan or higher")
def team_workout_upload_view(request,message="", def team_workout_upload_view(request,message="",
successmessage="", successmessage="",
uploadoptions={ uploadoptions={
@@ -4439,7 +4440,7 @@ def graph_show_view(request,id):
'name':'Workouts' 'name':'Workouts'
}, },
{ {
'url':get_workout_default_page(request,w.id), 'url':get_workout_default_page(request,encoder.encode_hex(w.id)),
'name': w.name 'name': w.name
}, },
{ {
@@ -4514,7 +4515,9 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
# Split a workout # Split a workout
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher",redirect_field_name=None) @user_passes_test(ispromember,login_url="/rowers/paidplans",
message="This functionality requires a Pro plan or higher",
redirect_field_name=None)
def workout_split_view(request,id=0): def workout_split_view(request,id=0):
row = get_workout_permitted(request.user,id) row = get_workout_permitted(request.user,id)