diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py index 52022e06..7bf213f7 100644 --- a/rowers/management/commands/processemail.py +++ b/rowers/management/commands/processemail.py @@ -188,7 +188,7 @@ class Command(BaseCommand): res = polarstuff.get_all_new_workouts(polar_available) # Concept2 - rowers = Rower.objects.filter(c2_auto_import=True) + rowers = Rower.objects.filter(c2_auto_import=True).exclude(rowerplan='basic') for r in rowers: c2stuff.get_c2_workouts(r) @@ -287,7 +287,7 @@ class Command(BaseCommand): message.delete() # Strava - rowers = Rower.objects.filter(strava_auto_import=True) + rowers = Rower.objects.filter(strava_auto_import=True).exclude(rowerplan='basic') for r in rowers: stravastuff.get_strava_workouts(r) diff --git a/rowers/models.py b/rowers/models.py index 93dcfa58..ac7b00d1 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1024,6 +1024,25 @@ def checkworkoutuser(user,workout): except Rower.DoesNotExist: 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): try: r = user.rower diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 756cf751..c8a2e2a8 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -473,13 +473,14 @@ def remove_rower_session(r,ps): return 1 -def get_dates_timeperiod(request,startdatestring='',enddatestring=''): +def get_dates_timeperiod(request,startdatestring='',enddatestring='', + defaulttimeperiod='thisweek'): # set start end date according timeperiod timeperiod = request.GET.get('when') if not timeperiod: - timeperiod = 'thisweek' + timeperiod = defaulttimeperiod startdatestring = request.GET.get('startdate') enddatestring = request.GET.get('enddate') @@ -536,6 +537,10 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring=''): enddate = startdate+timezone.timedelta(days=32) enddate = enddate.replace(day=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): tstartdatestring = daterangetester.match(timeperiod).group(1) tenddatestring = daterangetester.match(timeperiod).group(2) diff --git a/rowers/tasks.py b/rowers/tasks.py index cbf98d8d..efc0cf44 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -68,6 +68,7 @@ from rowers.dataprepnodjango import ( # create_strava_stroke_data_db ) +from rowers.opaque import encoder from django.core.mail import ( send_mail, @@ -1890,7 +1891,8 @@ def handle_sendemailnewresponse(first_name, last_name, if 'sessiontype' in kwargs: 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: commentlink = kwargs.pop('commentlink') @@ -1940,7 +1942,8 @@ def handle_sendemailnewcomment(first_name, if 'sessiontype' in kwargs: 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: commentlink = kwargs.pop('commentlink') @@ -1951,7 +1954,7 @@ def handle_sendemailnewcomment(first_name, 'comment':comment, 'workoutname':workoutname, 'siteurl':siteurl, - 'workoutid':workoutid, + 'workoutid':encoder.encode_hex(workoutid), 'sessiontype':sessiontype, 'commentlink':commentlink, } diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index bfac39a8..b4066432 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -129,7 +129,7 @@ {% if workouts.has_next %} {% if request.GET.q %} - + {% else %} - + @@ -216,7 +216,7 @@ {% if team %}
+ + Add, remove or change workouts for this session +
Please correct the error{{ form.errors|pluralize }} below.
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 83269444..e44015eb 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -470,7 +470,7 @@ def userurl(path,member):
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)
@@ -478,7 +478,7 @@ def userurl(path,member):
replaced = pattern.sub(userstring,path)
else:
replaced = path+userstring
-
+
return replaced
@register.filter
@@ -489,7 +489,7 @@ def teamurl(path,team):
# remove user
upattern = re.compile('\/user\/\d+/')
if upattern.search(path) is not None:
- path = upattern.sub('',path)
+ path = upattern.sub('/',path)
if pattern.search(path) is not None:
@@ -497,6 +497,7 @@ def teamurl(path,team):
else:
replaced = path+teamstring
+
return replaced
@register.filter
diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py
index a902d2fb..a84f7982 100644
--- a/rowers/tests/test_permissions.py
+++ b/rowers/tests/test_permissions.py
@@ -958,6 +958,31 @@ class PermissionsViewTests(TestCase):
response = self.c.get(url)
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
def test_team_member_request_pro_pro(self):
@@ -1416,8 +1441,7 @@ class PermissionsCoachingTests(TestCase):
## 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
diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz
index 6bd4febc..c9b47c1d 100644
Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ
diff --git a/rowers/views/statements.py b/rowers/views/statements.py
index e7e2305e..3f1ec013 100644
--- a/rowers/views/statements.py
+++ b/rowers/views/statements.py
@@ -367,6 +367,14 @@ def get_workout_permitted(user,id):
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):
perc = 0
total = 1
@@ -944,7 +952,9 @@ from rowers.utils import (
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
def iscoachmember(user):
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index b49af87d..73e01c79 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -590,7 +590,9 @@ def workouts_join_select(request,
})
# 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,
startdatestring="",
enddatestring="",
@@ -695,11 +697,6 @@ def team_comparison_select(request,
except Team.DoesNotExist:
theteam = 0
- if requestrower.rowerplan == 'basic' and theteam==0:
- if requestrower.protrialexpires is None or requestrower.protrialexpires