Date: Fri, 22 Feb 2019 13:51:08 +0100
Subject: [PATCH 5/9] list view improved
---
rowers/models.py | 19 +++++++++++++++
rowers/plannedsessions.py | 9 +++++--
rowers/templates/list_workouts.html | 12 ++++------
rowers/templatetags/rowerfilters.py | 5 ++--
rowers/tests/test_permissions.py | 37 +++++++++++++++++++++++++++--
rowers/views/statements.py | 12 +++++++++-
rowers/views/workoutviews.py | 23 ++++++------------
7 files changed, 86 insertions(+), 31 deletions(-)
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/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 %}
|
{% if workout|may_edit:request %}
-
+
{{ workout.user.user.first_name }}
{{ workout.user.user.last_name }}
@@ -245,18 +245,14 @@
|
- {% if workout|may_edit:request %}
- {% else %}
-
- {% endif %}
|
- {% if workout.user.user == user or user == team.manager %}
+ {% if workout|may_edit:request %}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 83269444..a51203ad 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
@@ -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..76ee8dab 100644
--- a/rowers/tests/test_permissions.py
+++ b/rowers/tests/test_permissions.py
@@ -958,6 +958,40 @@ 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)
+
+ # compare
+ url = reverse('team_comparison_select',
+ 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 +1450,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/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..ff8f6acc 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -737,8 +737,8 @@ def team_comparison_select(request,
if id:
firstworkout = get_workout(id)
- if not checkworkoutuser(request.user,firstworkout):
- raise PermissionDenied("You are not allowed to sue this workout")
+ if not checkworkoutuserview(request.user,firstworkout):
+ raise PermissionDenied("You are not allowed to use this workout")
firstworkoutquery = Workout.objects.filter(id=encoder.decode_hex(id))
workouts = firstworkoutquery | workouts
@@ -1160,10 +1160,9 @@ def multi_compare_view(request,id=0,userid=0):
# List Workouts
@login_required()
def workouts_view(request,message='',successmessage='',
- startdatestring='',
- enddatestring='',
teamid=0,rankingonly=False,rowerid=0,userid=0):
+ startdate,enddate = get_dates_timeperiod(request,defaulttimeperiod='lastyear')
request.session['referer'] = absolute(request)['PATH']
r = getrequestrower(request,rowerid=rowerid,userid=userid)
@@ -1171,15 +1170,6 @@ def workouts_view(request,message='',successmessage='',
if not checkviewworkouts(request.user,r):
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())
@@ -1352,7 +1342,7 @@ def workouts_view(request,message='',successmessage='',
'name':'Workouts'
},
]
-
+ timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
return render(request, 'list_workouts.html',
{'workouts': workouts,
'active': 'nav-workouts',
@@ -1368,6 +1358,7 @@ def workouts_view(request,message='',successmessage='',
'teams':get_my_teams(request.user),
'interactiveplot':script,
'the_div':div,
+ 'timeperiod':timeperiod,
})
@@ -2489,7 +2480,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
# prepare data frame
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')
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
@@ -2725,7 +2716,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
- row = get_workout_permitted(request.user,id)
+ row = get_workout_permittedview(request.user,id)
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
From fb2d193ed5466599544dd861769a867b4db98afe Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Fri, 22 Feb 2019 15:28:02 +0100
Subject: [PATCH 6/9] bugfix new comment email
---
rowers/tasks.py | 9 ++++++---
rowers/templates/menu_workout.html | 2 +-
rowers/templatetags/rowerfilters.py | 2 +-
3 files changed, 8 insertions(+), 5 deletions(-)
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/menu_workout.html b/rowers/templates/menu_workout.html
index 84ff5c97..b87876bb 100644
--- a/rowers/templates/menu_workout.html
+++ b/rowers/templates/menu_workout.html
@@ -41,7 +41,7 @@
-
+
Compare
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index a51203ad..e44015eb 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -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:
From 631164f4ef1f2b4f4d12c32cebc3b36913350dcc Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Fri, 22 Feb 2019 18:59:41 +0100
Subject: [PATCH 7/9] updated paid plans page
---
rowers/management/commands/processemail.py | 4 ++--
rowers/templates/paidplans.html | 20 +++++++++++++++++---
rowers/templates/rower_exportsettings.html | 5 +++++
rowers/tests/test_permissions.py | 9 ---------
rowers/tests/testdata/testdata.csv.gz | Bin 11457 -> 12537 bytes
rowers/views/workoutviews.py | 16 ++++++++--------
6 files changed, 32 insertions(+), 22 deletions(-)
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/templates/paidplans.html b/rowers/templates/paidplans.html
index b091b9e5..fd5e4655 100644
--- a/rowers/templates/paidplans.html
+++ b/rowers/templates/paidplans.html
@@ -94,7 +94,14 @@
| ✔ |
- | Create Training plans, tests and challenges for yourself. Track your performance
+ | Create and manage groups. |
+ |
+ ✔ |
+ ✔ |
+ ✔ |
+
+
+ | Create Training plans, tests and challenges for yourself and your training group. Track your performance
against plan. |
|
|
@@ -110,14 +117,21 @@
✔ |
- | Create and manage teams. |
+ Manage your athlete's workouts |
|
|
|
✔ |
- | Manage your athlete's workouts |
+ Run analytics for your athletes |
+ |
+ |
+ |
+ ✔ |
+
+
+ | Change zone intensities and other workout related settings for your athletes |
|
|
|
diff --git a/rowers/templates/rower_exportsettings.html b/rowers/templates/rower_exportsettings.html
index 8e4fd953..5138566c 100644
--- a/rowers/templates/rower_exportsettings.html
+++ b/rowers/templates/rower_exportsettings.html
@@ -4,6 +4,11 @@
{% block main %}
Import and Export Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}
+
+{% if user.rower.rowerplan == 'basic' %}
+The auto import and export settings only work on a paid plan.
+{% endif %}
+
{% if form.errors %}
Please correct the error{{ form.errors|pluralize }} below.
diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py
index 76ee8dab..a84f7982 100644
--- a/rowers/tests/test_permissions.py
+++ b/rowers/tests/test_permissions.py
@@ -982,15 +982,6 @@ class PermissionsViewTests(TestCase):
response = self.c.get(url)
self.assertEqual(response.status_code,200)
-
- # compare
- url = reverse('team_comparison_select',
- 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
diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz
index 6bd4febc272d292970ea5fdf9cf603951930b5d7..8a0e0dd6f2e2346910aae6c6628277a057771f54 100644
GIT binary patch
literal 12537
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
zʩ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 |