Merge branch 'develop' into feature/metrics
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+4
-1
@@ -148,6 +148,7 @@ psycopg2==2.8.1
|
|||||||
ptyprocess==0.6.0
|
ptyprocess==0.6.0
|
||||||
py==1.8.0
|
py==1.8.0
|
||||||
pyarrow==0.15.0
|
pyarrow==0.15.0
|
||||||
|
pycairo==1.19.0
|
||||||
pycparser==2.19
|
pycparser==2.19
|
||||||
Pygments==2.3.1
|
Pygments==2.3.1
|
||||||
pyparsing==2.3.1
|
pyparsing==2.3.1
|
||||||
@@ -173,9 +174,10 @@ ratelim==0.1.6
|
|||||||
redis==3.2.1
|
redis==3.2.1
|
||||||
requests==2.21.0
|
requests==2.21.0
|
||||||
requests-oauthlib==1.2.0
|
requests-oauthlib==1.2.0
|
||||||
rowingdata==2.5.7
|
rowingdata==2.6.7
|
||||||
rowingphysics==0.5.0
|
rowingphysics==0.5.0
|
||||||
rq==0.13.0
|
rq==0.13.0
|
||||||
|
rules==2.1
|
||||||
scipy==1.2.1
|
scipy==1.2.1
|
||||||
SecretStorage==3.1.1
|
SecretStorage==3.1.1
|
||||||
Send2Trash==1.5.0
|
Send2Trash==1.5.0
|
||||||
@@ -194,6 +196,7 @@ testpath==0.4.2
|
|||||||
text-unidecode==1.2
|
text-unidecode==1.2
|
||||||
thrift==0.11.0
|
thrift==0.11.0
|
||||||
timezonefinder==4.0.1
|
timezonefinder==4.0.1
|
||||||
|
tk==0.1.0
|
||||||
toolz==0.10.0
|
toolz==0.10.0
|
||||||
tornado==6.0.1
|
tornado==6.0.1
|
||||||
tqdm==4.31.1
|
tqdm==4.31.1
|
||||||
|
|||||||
+3
-2
@@ -14,6 +14,7 @@ import datetime
|
|||||||
from requests import Request, Session
|
from requests import Request, Session
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
from rowers.mytypes import otwtypes
|
from rowers.mytypes import otwtypes
|
||||||
|
from rowers.rower_rules import is_workout_user,ispromember
|
||||||
from iso8601 import ParseError
|
from iso8601 import ParseError
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
@@ -155,7 +156,7 @@ def add_stroke_data(user,c2id,workoutid,startdatetime,csvfilename,
|
|||||||
|
|
||||||
def get_c2_workouts(rower):
|
def get_c2_workouts(rower):
|
||||||
|
|
||||||
if not isprorower(rower):
|
if not ispromember(rower.user):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -863,7 +864,7 @@ def workout_c2_upload(user,w):
|
|||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
c2userid = get_userid(r.c2token)
|
c2userid = get_userid(r.c2token)
|
||||||
if not c2userid:
|
if not c2userid:
|
||||||
raise NoTokenError("User has no token")
|
raise NoTokenError("User has no token")
|
||||||
|
|||||||
@@ -140,10 +140,10 @@ def timedeltaconv(x):
|
|||||||
|
|
||||||
def rdata(file,rower=rrower()):
|
def rdata(file,rower=rrower()):
|
||||||
try:
|
try:
|
||||||
res = rrdata(file,rower=rower)
|
res = rrdata(csvfile=file,rower=rower)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
res = rrdata(file+'.gz',rower=rower)
|
res = rrdata(csvfile=file+'.gz',rower=rower)
|
||||||
except IOError:
|
except IOError:
|
||||||
res = 0
|
res = 0
|
||||||
|
|
||||||
@@ -948,7 +948,7 @@ def smalldataprep(therows,xparam,yparam1,yparam2):
|
|||||||
f1 = workout.csvfilename
|
f1 = workout.csvfilename
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rowdata = dataprep(rrdata(f1).df)
|
rowdata = dataprep(rrdata(csvfile=f1).df)
|
||||||
|
|
||||||
rowdata = pd.DataFrame({xparam: rowdata[xparam],
|
rowdata = pd.DataFrame({xparam: rowdata[xparam],
|
||||||
yparam1: rowdata[yparam1],
|
yparam1: rowdata[yparam1],
|
||||||
@@ -960,7 +960,7 @@ def smalldataprep(therows,xparam,yparam1,yparam2):
|
|||||||
df = pd.concat([df,rowdata],ignore_index=True)
|
df = pd.concat([df,rowdata],ignore_index=True)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = dataprep(rrdata(f1+'.gz').df)
|
rowdata = dataprep(rrdata(csvfile=f1+'.gz').df)
|
||||||
rowdata = pd.DataFrame({xparam: rowdata[xparam],
|
rowdata = pd.DataFrame({xparam: rowdata[xparam],
|
||||||
yparam1: rowdata[yparam1],
|
yparam1: rowdata[yparam1],
|
||||||
yparam2: rowdata[yparam2],
|
yparam2: rowdata[yparam2],
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from __future__ import print_function
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required,user_passes_test
|
from django.contrib.auth.decorators import login_required,user_passes_test
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
@@ -29,6 +30,9 @@ def user_passes_test(test_func, message=default_message,login_url=None,redirect_
|
|||||||
def decorator(view_func):
|
def decorator(view_func):
|
||||||
@wraps(view_func, assigned=available_attrs(view_func))
|
@wraps(view_func, assigned=available_attrs(view_func))
|
||||||
def _wrapped_view(request, *args, **kwargs):
|
def _wrapped_view(request, *args, **kwargs):
|
||||||
|
if request.user.is_anonymous:
|
||||||
|
url = reverse('login')+'?next='+request.path
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
if not test_func(request.user):
|
if not test_func(request.user):
|
||||||
messages.error(request, message)
|
messages.error(request, message)
|
||||||
return HttpResponseRedirect(login_url)
|
return HttpResponseRedirect(login_url)
|
||||||
@@ -48,4 +52,3 @@ def login_required_message(function=None, message=default_message):
|
|||||||
if function:
|
if function:
|
||||||
return actual_decorator(function)
|
return actual_decorator(function)
|
||||||
return actual_decorator
|
return actual_decorator
|
||||||
|
|
||||||
|
|||||||
@@ -1404,6 +1404,7 @@ class FlexAxesForm(forms.Form):
|
|||||||
extrametrics = kwargs.pop('extrametrics',[])
|
extrametrics = kwargs.pop('extrametrics',[])
|
||||||
super(FlexAxesForm, self).__init__(*args, **kwargs)
|
super(FlexAxesForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
rower = Rower.objects.get(user=request.user)
|
rower = Rower.objects.get(user=request.user)
|
||||||
|
|
||||||
axchoicespro = (
|
axchoicespro = (
|
||||||
|
|||||||
+2
-3
@@ -43,7 +43,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
# from .models import Profile
|
# from .models import Profile
|
||||||
from rowingdata import rowingdata, make_cumvalues
|
from rowingdata import rowingdata, make_cumvalues
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from rowers.models import Rower,Workout,checkworkoutuser,TombStone
|
from rowers.models import Rower,Workout,TombStone
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
||||||
@@ -54,7 +54,7 @@ from rowsandall_app.settings import (
|
|||||||
|
|
||||||
from rowers.utils import (
|
from rowers.utils import (
|
||||||
NoTokenError, custom_exception_handler, ewmovingaverage,
|
NoTokenError, custom_exception_handler, ewmovingaverage,
|
||||||
geo_distance,isprorower,uniqify
|
geo_distance,uniqify
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -309,4 +309,3 @@ def imports_token_refresh(user,tokenname,refreshtokenname,expirydatename,oauth_d
|
|||||||
|
|
||||||
r.save()
|
r.save()
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
|||||||
@@ -2680,7 +2680,10 @@ def interactive_windchart(id=0,promember=0):
|
|||||||
if rowdata == 0:
|
if rowdata == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
dist = rowdata.df.loc[:,'cum_dist']
|
dist = rowdata.df.loc[:,'cum_dist']
|
||||||
|
except KeyError:
|
||||||
|
return ['','No Data Found']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vwind = rowdata.df.loc[:,'vwind']
|
vwind = rowdata.df.loc[:,'vwind']
|
||||||
@@ -2770,7 +2773,10 @@ def interactive_streamchart(id=0,promember=0):
|
|||||||
if rowdata == 0:
|
if rowdata == 0:
|
||||||
return "","No Valid Data Available"
|
return "","No Valid Data Available"
|
||||||
|
|
||||||
|
try:
|
||||||
dist = rowdata.df.loc[:,'cum_dist']
|
dist = rowdata.df.loc[:,'cum_dist']
|
||||||
|
except KeyError:
|
||||||
|
return ['','No Data found']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vstream = rowdata.df.loc[:,'vstream']
|
vstream = rowdata.df.loc[:,'vstream']
|
||||||
|
|||||||
@@ -64,18 +64,18 @@ def send_confirm(user, name, link, options):
|
|||||||
def rdata(file, rower=rrower()):
|
def rdata(file, rower=rrower()):
|
||||||
""" Reads rowingdata data or returns 0 on Error """
|
""" Reads rowingdata data or returns 0 on Error """
|
||||||
try:
|
try:
|
||||||
result = rrdata(file, rower=rower)
|
result = rrdata(csvfile=file, rower=rower)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
result = rrdata(file + '.gz', rower=rower)
|
result = rrdata(csvfile=file + '.gz', rower=rower)
|
||||||
except IOError:
|
except IOError:
|
||||||
result = 0
|
result = 0
|
||||||
except TypeError:
|
except TypeError:
|
||||||
try:
|
try:
|
||||||
result = rrdata(file)
|
result = rrdata(csvfile=file)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
result = rrdata(file+'.gz', rower=rower)
|
result = rrdata(csvfile=file+'.gz', rower=rower)
|
||||||
except IOError:
|
except IOError:
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
|
|||||||
+98
-110
@@ -39,6 +39,10 @@ import pandas as pd
|
|||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
#from rules.contrib.models import RulesModel
|
||||||
|
|
||||||
|
from rowers.rower_rules import *
|
||||||
|
|
||||||
from rowers.rows import validate_file_extension
|
from rowers.rows import validate_file_extension
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from timezonefinder import TimezoneFinder
|
from timezonefinder import TimezoneFinder
|
||||||
@@ -53,6 +57,10 @@ from rowsandall_app.settings import (
|
|||||||
TWEET_CONSUMER_SECRET,
|
TWEET_CONSUMER_SECRET,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# END PERMISSIONS
|
||||||
|
|
||||||
tweetapi = twitter.Api(consumer_key=TWEET_CONSUMER_KEY,
|
tweetapi = twitter.Api(consumer_key=TWEET_CONSUMER_KEY,
|
||||||
consumer_secret=TWEET_CONSUMER_SECRET,
|
consumer_secret=TWEET_CONSUMER_SECRET,
|
||||||
access_token_key=TWEET_ACCESS_TOKEN_KEY,
|
access_token_key=TWEET_ACCESS_TOKEN_KEY,
|
||||||
@@ -322,14 +330,7 @@ class C2WorldClassAgePerformance(models.Model):
|
|||||||
|
|
||||||
return thestring
|
return thestring
|
||||||
|
|
||||||
def is_not_basic(user):
|
|
||||||
if user.rower.rowerplan == 'basic':
|
|
||||||
raise ValidationError(
|
|
||||||
"Basic user cannot be team manager"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# For future Team functionality
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Team(models.Model):
|
class Team(models.Model):
|
||||||
choices = (
|
choices = (
|
||||||
@@ -344,27 +345,25 @@ class Team(models.Model):
|
|||||||
|
|
||||||
name = models.CharField(max_length=150,unique=True,verbose_name='Team Name')
|
name = models.CharField(max_length=150,unique=True,verbose_name='Team Name')
|
||||||
notes = models.CharField(blank=True,max_length=200,verbose_name='Team Purpose')
|
notes = models.CharField(blank=True,max_length=200,verbose_name='Team Purpose')
|
||||||
manager = models.ForeignKey(User, null=True,on_delete=models.CASCADE) # validators=[is_not_basic])
|
manager = models.ForeignKey(User, null=True,on_delete=models.CASCADE)
|
||||||
private = models.CharField(max_length=30,choices=choices,default='open',
|
private = models.CharField(max_length=30,choices=choices,default='open',
|
||||||
verbose_name='Team Type')
|
verbose_name='Team Type')
|
||||||
|
|
||||||
viewing = models.CharField(max_length=30,choices=viewchoices,default='allmembers',verbose_name='Sharing Behavior')
|
viewing = models.CharField(max_length=30,choices=viewchoices,default='allmembers',verbose_name='Sharing Behavior')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
manager = self.manager
|
manager = self.manager
|
||||||
if manager.rower.rowerplan == 'basic':
|
if not can_have_teams(manager):
|
||||||
if manager.rower.protrialexpires < datetime.date.today() and manager.rower.plantrialexpires < datetime.date.today():
|
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"Basic user cannot be team manager"
|
"Basic user cannot be team manager"
|
||||||
)
|
)
|
||||||
|
|
||||||
if manager.rower.rowerplan in ['plan','pro']:
|
if not can_add_team(manager):
|
||||||
otherteams = Team.objects.filter(manager=manager)
|
|
||||||
if otherteams.count() >= 1:
|
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"Pro and Self-Coach users cannot have more than one team"
|
"Pro and Self-Coach users cannot have more than one team"
|
||||||
)
|
)
|
||||||
@@ -658,6 +657,9 @@ class CoachingGroup(models.Model):
|
|||||||
rs = Rower.objects.filter(coachinggroups__in=[self])
|
rs = Rower.objects.filter(coachinggroups__in=[self])
|
||||||
return rs.count()
|
return rs.count()
|
||||||
|
|
||||||
|
def get_coaches(self):
|
||||||
|
return Rower.objects.filter(mycoachgroup=self)
|
||||||
|
|
||||||
# Extension of User with rowing specific data
|
# Extension of User with rowing specific data
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Rower(models.Model):
|
class Rower(models.Model):
|
||||||
@@ -896,6 +898,20 @@ class Rower(models.Model):
|
|||||||
|
|
||||||
super(Rower, self).save(*args, **kwargs)
|
super(Rower, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_managed_teams(self):
|
||||||
|
return Team.objects.filter(manager=self.user)
|
||||||
|
|
||||||
|
def get_coaches(self):
|
||||||
|
coaches = []
|
||||||
|
for group in self.coachinggroups.all():
|
||||||
|
try:
|
||||||
|
coach = Rower.objects.get(mycoachgroup=group)
|
||||||
|
coaches.append(coach)
|
||||||
|
except Rower.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return coaches
|
||||||
|
|
||||||
class DeactivateUserForm(forms.ModelForm):
|
class DeactivateUserForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
@@ -925,15 +941,16 @@ class CoachOffer(models.Model):
|
|||||||
|
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
|
|
||||||
|
|
||||||
def check_teams_on_change(sender, **kwargs):
|
def check_teams_on_change(sender, **kwargs):
|
||||||
instance = kwargs.pop('instance', None)
|
instance = kwargs.pop('instance', None)
|
||||||
action = kwargs.pop('action', None)
|
action = kwargs.pop('action', None)
|
||||||
pk_set = kwargs.pop('pk_set',None)
|
pk_set = kwargs.pop('pk_set',None)
|
||||||
if action == 'pre_add' and instance.rowerplan=='basic':
|
if action == 'pre_add':
|
||||||
if instance.protrialexpires < datetime.date.today() and instance.plantrialexpires < datetime.date.today():
|
#if instance.protrialexpires < datetime.date.today() and instance.plantrialexpires < datetime.date.today():
|
||||||
for id in pk_set:
|
for id in pk_set:
|
||||||
team = Team.objects.get(id=id)
|
team = Team.objects.get(id=id)
|
||||||
if team.manager.rower.rowerplan not in ['coach']:
|
if not can_join_team(instance.user,team):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"You cannot join a team led by a Pro, Free Coach Plan or Self-Coach user"
|
"You cannot join a team led by a Pro, Free Coach Plan or Self-Coach user"
|
||||||
)
|
)
|
||||||
@@ -1165,95 +1182,7 @@ class BasePlannedSessionFormSet(BaseFormSet):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# Check if workout is owned by this user
|
|
||||||
def checkworkoutuser(user,workout):
|
|
||||||
if user.is_anonymous:
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
if workout.user == r:
|
|
||||||
return True
|
|
||||||
coaches = []
|
|
||||||
for group in workout.user.coachinggroups.all():
|
|
||||||
coach = Rower.objects.get(mycoachgroup=group)
|
|
||||||
coaches.append(coach)
|
|
||||||
for coach in coaches:
|
|
||||||
if user.rower == coach and workout.privacy == 'visible':
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
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
|
|
||||||
if rower == r:
|
|
||||||
return True
|
|
||||||
teams = Team.objects.filter(manager=user)
|
|
||||||
|
|
||||||
if rower in Rower.objects.filter(team__in=teams):
|
|
||||||
return True
|
|
||||||
|
|
||||||
if rower in Rower.objects.filter(coachinggroups__in=[user.rower.mycoachgroup]):
|
|
||||||
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','freecoach']]
|
|
||||||
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):
|
|
||||||
try:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
if rower == r:
|
|
||||||
return True
|
|
||||||
coaches = []
|
|
||||||
for group in rower.coachinggroups.all():
|
|
||||||
coach = Rower.objects.get(mycoachgroup=group)
|
|
||||||
coaches.append(coach)
|
|
||||||
for coach in coaches:
|
|
||||||
if user.rower == coach:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
return False
|
|
||||||
|
|
||||||
timezones = (
|
timezones = (
|
||||||
(x,x) for x in pytz.common_timezones
|
(x,x) for x in pytz.common_timezones
|
||||||
@@ -1354,6 +1283,18 @@ class TrainingTarget(models.Model):
|
|||||||
|
|
||||||
return stri
|
return stri
|
||||||
|
|
||||||
|
def check_trainingtarget_on_change(sender,**kwargs):
|
||||||
|
instance = kwargs.pop('instance',None)
|
||||||
|
action = kwargs.pop('action',None)
|
||||||
|
pk_set = kwargs.pop('pk_set',None)
|
||||||
|
if action == 'pre_add':
|
||||||
|
for id in pk_set:
|
||||||
|
rower = Rower.objects.get(id=id)
|
||||||
|
if not can_plan_user(instance.manager.user,rower):
|
||||||
|
raise ValidationError("You cannot add this rower. Not your coachee")
|
||||||
|
|
||||||
|
m2m_changed.connect(check_trainingtarget_on_change, sender=TrainingTarget.rowers.through)
|
||||||
|
|
||||||
class TrainingTargetForm(ModelForm):
|
class TrainingTargetForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TrainingTarget
|
model = TrainingTarget
|
||||||
@@ -1423,13 +1364,13 @@ class TrainingPlan(models.Model):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
manager = self.manager
|
manager = self.manager
|
||||||
|
if not can_add_plan(manager.user):
|
||||||
if manager.rowerplan in ['basic','pro']:
|
|
||||||
if manager.plantrialexpires < timezone.now().date():
|
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"Basic user cannot have a training plan"
|
"Basic user cannot have a training plan"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if self.enddate < self.startdate:
|
if self.enddate < self.startdate:
|
||||||
startdate = self.startdate
|
startdate = self.startdate
|
||||||
enddate = self.enddate
|
enddate = self.enddate
|
||||||
@@ -1439,6 +1380,13 @@ class TrainingPlan(models.Model):
|
|||||||
if not self.enddate <= self.startdate:
|
if not self.enddate <= self.startdate:
|
||||||
super(TrainingPlan,self).save(*args, **kwargs)
|
super(TrainingPlan,self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
# only add athletes that are allowed to be added
|
||||||
|
for rower in self.rowers.all():
|
||||||
|
if can_plan_user(manager.user,rower):
|
||||||
|
self.rowers.add(rower)
|
||||||
|
else:
|
||||||
|
self.rowers.remove(rower)
|
||||||
|
|
||||||
if self.status:
|
if self.status:
|
||||||
otherplans = TrainingPlan.objects.filter(
|
otherplans = TrainingPlan.objects.filter(
|
||||||
status=True).exclude(
|
status=True).exclude(
|
||||||
@@ -1475,6 +1423,18 @@ class TrainingPlan(models.Model):
|
|||||||
else:
|
else:
|
||||||
createmacrofillers(self)
|
createmacrofillers(self)
|
||||||
|
|
||||||
|
def check_trainingplan_on_change(sender, **kwargs):
|
||||||
|
instance = kwargs.pop('instance',None)
|
||||||
|
action = kwargs.pop('action',None)
|
||||||
|
pk_set = kwargs.pop('pk_set',None)
|
||||||
|
if action == 'pre_add':
|
||||||
|
for id in pk_set:
|
||||||
|
rower = Rower.objects.get(id=id)
|
||||||
|
if not can_plan_user(instance.manager.user,rower):
|
||||||
|
raise ValidationError("You cannot add this rower. Not your coachee")
|
||||||
|
|
||||||
|
m2m_changed.connect(check_trainingplan_on_change, sender=TrainingPlan.rowers.through)
|
||||||
|
|
||||||
|
|
||||||
class TrainingPlanForm(ModelForm):
|
class TrainingPlanForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -2158,8 +2118,7 @@ class PlannedSession(models.Model):
|
|||||||
|
|
||||||
manager = self.manager
|
manager = self.manager
|
||||||
if self.sessiontype not in ['race','indoorrace']:
|
if self.sessiontype not in ['race','indoorrace']:
|
||||||
if manager.rower.rowerplan in ['basic','pro']:
|
if not can_add_session(self.manager):
|
||||||
if manager.rower.plantrialexpires < timezone.now().date():
|
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"You must be a Self-Coach user or higher to create a planned session"
|
"You must be a Self-Coach user or higher to create a planned session"
|
||||||
)
|
)
|
||||||
@@ -2342,6 +2301,35 @@ class PlannedSessionForm(ModelForm):
|
|||||||
self.fields['sessiontype'].choices = regularsessiontypechoices
|
self.fields['sessiontype'].choices = regularsessiontypechoices
|
||||||
|
|
||||||
|
|
||||||
|
class PlannedSessionTemplateForm(ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = PlannedSession
|
||||||
|
fields = [
|
||||||
|
'name',
|
||||||
|
'sessiontype',
|
||||||
|
'sessionmode',
|
||||||
|
'criterium',
|
||||||
|
'sessionvalue',
|
||||||
|
'sessionunit',
|
||||||
|
'course',
|
||||||
|
'comment',
|
||||||
|
]
|
||||||
|
|
||||||
|
dateTimeOptions = {
|
||||||
|
'format': 'yyyy-mm-dd',
|
||||||
|
'autoclose': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
widgets = {
|
||||||
|
'comment': forms.Textarea,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self,*args,**kwargs):
|
||||||
|
super(PlannedSessionTemplateForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
|
||||||
|
self.fields['sessiontype'].choices = regularsessiontypechoices
|
||||||
|
|
||||||
def get_course_timezone(course):
|
def get_course_timezone(course):
|
||||||
polygons = GeoPolygon.objects.filter(course = course)
|
polygons = GeoPolygon.objects.filter(course = course)
|
||||||
points = GeoPoint.objects.filter(polygon = polygons[0])
|
points = GeoPoint.objects.filter(polygon = polygons[0])
|
||||||
@@ -2740,7 +2728,7 @@ class Workout(models.Model):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
user = self.user
|
user = self.user
|
||||||
if self.user.rowerplan == 'freecoach':
|
if not can_add_workout(user.user):
|
||||||
raise forms.ValidationError("Free Coach User cannot have any workouts")
|
raise forms.ValidationError("Free Coach User cannot have any workouts")
|
||||||
|
|
||||||
super(Workout, self).save(*args, **kwargs)
|
super(Workout, self).save(*args, **kwargs)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from rowingdata import rowingdata
|
from rowingdata import rowingdata
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from rowers.models import Rower,Workout
|
from rowers.models import Rower,Workout
|
||||||
from rowers.models import checkworkoutuser
|
|
||||||
import rowers.dataprep as dataprep
|
import rowers.dataprep as dataprep
|
||||||
from rowers.dataprep import columndict
|
from rowers.dataprep import columndict
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ def get_polar_notifications():
|
|||||||
|
|
||||||
return available_data
|
return available_data
|
||||||
|
|
||||||
from rowers.utils import isprorower
|
from rowers.rower_rules import ispromember
|
||||||
|
|
||||||
def get_all_new_workouts(available_data,testing=False):
|
def get_all_new_workouts(available_data,testing=False):
|
||||||
for record in available_data:
|
for record in available_data:
|
||||||
@@ -146,7 +146,7 @@ def get_all_new_workouts(available_data,testing=False):
|
|||||||
try:
|
try:
|
||||||
r = Rower.objects.get(polaruserid=record['user-id'])
|
r = Rower.objects.get(polaruserid=record['user-id'])
|
||||||
u = r.user
|
u = r.user
|
||||||
if r.polar_auto_import and isprorower(r):
|
if r.polar_auto_import and ispromember(u):
|
||||||
exercise_list = get_polar_workouts(u)
|
exercise_list = get_polar_workouts(u)
|
||||||
if testing:
|
if testing:
|
||||||
print(exercise_list)
|
print(exercise_list)
|
||||||
@@ -337,7 +337,3 @@ def get_polar_workout(user,id,transactionid):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,708 @@
|
|||||||
|
import rules
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# PERMISSIONS
|
||||||
|
|
||||||
|
# USER permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
USER permissions
|
||||||
|
- There are 5 types of user: basic, pro, plan, coach, freecoach
|
||||||
|
- These methods exist on user
|
||||||
|
- user.rower
|
||||||
|
- user.is_anonymous
|
||||||
|
- user.is_staff
|
||||||
|
|
||||||
|
- These methods exist on rower
|
||||||
|
- rower.rowerplan
|
||||||
|
- rower.protrialexpires
|
||||||
|
- rower.plantrialexpires
|
||||||
|
- rower.mycoachgroup
|
||||||
|
- rower.coachinggroups
|
||||||
|
- rower.team
|
||||||
|
|
||||||
|
- These Rules apply to Rowers
|
||||||
|
- Coach can have any number of groups
|
||||||
|
- test_permissions.PermissionFreeCoach.test_coach_groupmanager
|
||||||
|
- test_permissions.PermissionsBasicsTests.test_coach_groupmanager
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_groups_create
|
||||||
|
- Pro and Plan users can have one group and not more
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_pro_groupmanager
|
||||||
|
- test_permissions.PermissionsViewTests.test_pro_groups_create
|
||||||
|
- Free Coach user cannot have workouts
|
||||||
|
- test_permissions.PermissionFreeCoach.test_add_workout_freecoach
|
||||||
|
- Free coach can create more than one group
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_plan_groupmanager
|
||||||
|
- Free Coach & Plan (Self Coach) can create planned sessions and team planned sessions
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_plan_create_session
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_coach_create_session
|
||||||
|
- Pro cannot create planned sessions or team planned sessions
|
||||||
|
- test_permissions.PermissionsViewTests.test_pro_create_session
|
||||||
|
- Basic cannot join groups led by Free Coach
|
||||||
|
- test_permissions.PermissionFreeCoach.test_add_basic_pro_or_plan
|
||||||
|
- Coach can edit athlete settings (if in coachinggroup)
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_prefs
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_prefs_not
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_settings
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_settings_not
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_account
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_account_not
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_exportsettings
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_exportsettings_not
|
||||||
|
- Coach can upload a workout on behalf of athlete
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload_not
|
||||||
|
- Pro and Plan cannot upload a workout on behalf of athlete
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_edit_athlete_upload
|
||||||
|
- Coach can run analytics for athlete
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_analysis
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_analysis_not
|
||||||
|
- test_permissions.PermissionsViewTests.test_pro_edit_athlete_analysis
|
||||||
|
- Pro and Plan user cannot run analysis for members of their groups
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_edit_athlete_analysis
|
||||||
|
- Pro and Plan user cannot edit athlete sessings
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_edit_athlete_settings
|
||||||
|
- test_permissions.PermissionsViewTests.test_pro_edit_athlete_settings
|
||||||
|
- Self-Coach and Pro cannot create more than one group
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_plan_groupmanager
|
||||||
|
- Pro users and higher can join group led by other Pro or higher user
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_add_proplan_pro_or_plan
|
||||||
|
- Pro or basic cannot create planned sessions or team planned sessions
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_pro_create_plannedsession
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# used in can_plan_user
|
||||||
|
@rules.predicate
|
||||||
|
def user_is_not_basic(user):
|
||||||
|
if user.rower.rowerplan != 'basic':
|
||||||
|
return True
|
||||||
|
|
||||||
|
if user.rower.protrialexpires >= datetime.date.today() and user.rower.plantrialexpires >= datetime.date.today():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_start_trial(user):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
return user.rower.protrialexpires == datetime.date(1970,1,1)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_start_plantrial(user):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return user.rower.plantrialexpires == datetime.date(1970,1,1)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_staff(user):
|
||||||
|
return user.is_staff
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_coach(user):
|
||||||
|
return user.rower.rowerplan in ['coach','freecoach']
|
||||||
|
|
||||||
|
def is_paid_coach(user):
|
||||||
|
return user.rower.rowerplan == 'coach'
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_planmember(user):
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return r.rowerplan in ['coach','plan'] # freecoach?
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_promember(user):
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return r.rowerplan in ['pro','coach','plan'] # freecoach?
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_protrial(user):
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if r.rowerplan == 'basic':
|
||||||
|
return r.protrialexpires >= datetime.date.today()
|
||||||
|
if r.rowerplan == 'freecoach':
|
||||||
|
if r.mycoachgroup is not None:
|
||||||
|
return len(r.mycoachgroup)>=4
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
ispromember = is_promember | is_protrial
|
||||||
|
|
||||||
|
can_have_teams = ispromember | is_coach
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_add_team(user):
|
||||||
|
if is_coach(user):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if ispromember(user):
|
||||||
|
otherteams = user.rower.get_managed_teams()
|
||||||
|
if otherteams.count() == 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_add_plan(user):
|
||||||
|
return isplanmember(user) or is_coach(user)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_add_workout(user):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return user.rower.rowerplan != 'freecoach'
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_plantrial(user):
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if r.rowerplan in ['basic','pro']:
|
||||||
|
return r.plantrialexpires >= datetime.date.today()
|
||||||
|
if r.rowerplan == 'freecoach':
|
||||||
|
if r.mycoachgroup is not None:
|
||||||
|
return len(r.mycoachgroup)>=4
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
isplanmember = is_planmember | is_plantrial
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_add_session(user):
|
||||||
|
return isplanmember(user) or is_coach(user)
|
||||||
|
|
||||||
|
# User / Coach relationships (Rower object)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_plan(user):
|
||||||
|
return user.rower.rowerplan in ['plan','coach','freecoach']
|
||||||
|
|
||||||
|
# checks if rower is coach of user (or is user himself)
|
||||||
|
@rules.predicate
|
||||||
|
def is_coach_user(usercoach,userrower):
|
||||||
|
if usercoach == userrower:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not is_coach(usercoach):
|
||||||
|
return False
|
||||||
|
|
||||||
|
r = userrower.rower
|
||||||
|
|
||||||
|
coaches = []
|
||||||
|
|
||||||
|
for group in r.coachinggroups.all():
|
||||||
|
newcoaches = group.get_coaches()
|
||||||
|
for coach in newcoaches:
|
||||||
|
coaches.append(coach)
|
||||||
|
|
||||||
|
for coach in coaches:
|
||||||
|
if usercoach.rower == coach:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# checks if rower is coach of user (or is user himself)
|
||||||
|
@rules.predicate
|
||||||
|
def is_anonymous_or_coach(usercoach,userrower):
|
||||||
|
print(usercoach,userrower)
|
||||||
|
if usercoach == userrower:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if userrower.is_anonymous and userrower.is_anonymous:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not is_coach(usercoach):
|
||||||
|
return False
|
||||||
|
|
||||||
|
r = userrower.rower
|
||||||
|
|
||||||
|
coaches = []
|
||||||
|
|
||||||
|
for group in r.coachinggroups.all():
|
||||||
|
newcoaches = group.get_coaches()
|
||||||
|
for coach in newcoaches:
|
||||||
|
coaches.append(coach)
|
||||||
|
|
||||||
|
for coach in coaches:
|
||||||
|
if usercoach.rower == coach:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# check if rower and user are members of the same team
|
||||||
|
@rules.predicate
|
||||||
|
def is_rower_team_member(user,rower):
|
||||||
|
if user.rower == rower:
|
||||||
|
return True
|
||||||
|
|
||||||
|
teams = rower.team.all()
|
||||||
|
|
||||||
|
for team in teams:
|
||||||
|
if team.private == 'open':
|
||||||
|
if team in rower.team.all():
|
||||||
|
return True
|
||||||
|
if team.manager == rower.user:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_add_workout_member(user,rower):
|
||||||
|
if not user:
|
||||||
|
return False
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user == rower.user:
|
||||||
|
return True
|
||||||
|
# only below tested - need test user == rower.user
|
||||||
|
return is_coach(user) and user.rower in rower.get_coaches()
|
||||||
|
|
||||||
|
# check if user can plan for the rower
|
||||||
|
@rules.predicate
|
||||||
|
def can_plan_user(user,rower):
|
||||||
|
# user must have planning permission
|
||||||
|
if not can_plan(user):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# if has planning permission, can always plan for himself
|
||||||
|
if rower == user.rower:
|
||||||
|
return True
|
||||||
|
|
||||||
|
teams = user.rower.get_managed_teams()
|
||||||
|
# free coach, plan etc cannot plan for basic
|
||||||
|
if not is_paid_coach(user) and user_is_not_basic(user):
|
||||||
|
for t in teams:
|
||||||
|
if rower in t.rower.all():
|
||||||
|
return True
|
||||||
|
|
||||||
|
# paying coach can plan for all kinds of rowers
|
||||||
|
if is_paid_coach(user):
|
||||||
|
for t in teams:
|
||||||
|
if rower in t.rower.all():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
rules.add_perm('rower.add_plan',can_plan_user) # replaces checkaccessplanuser
|
||||||
|
rules.add_perm('rower.is_coach',is_coach_user) # replaces checkaccessuser
|
||||||
|
rules.add_perm('rower.is_pro',ispromember)
|
||||||
|
rules.add_perm('rower.is_staff',is_staff)
|
||||||
|
|
||||||
|
# WORKOUT permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
WORKOUT permissions
|
||||||
|
- These methods exist on Workout
|
||||||
|
- workout.privacy
|
||||||
|
|
||||||
|
- These rules apply to workouts
|
||||||
|
- User can add, delete and change their own workouts
|
||||||
|
- test_aworkouts
|
||||||
|
- Coach can add and change workouts for their athletes, but not delete
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload_not
|
||||||
|
- Basic, Pro and Plan user can view but cannot add or change an athlete's workout
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_edit_athlete_workout
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_edit_athlete_upload
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_edit_athlete_workout
|
||||||
|
- test_permissions.PermissionsViewTests.test_basic_edit_athelte_workout
|
||||||
|
- Anonymous users can view team members' workout (but not see list of workouts)
|
||||||
|
- test_aworkouts
|
||||||
|
|
||||||
|
- Rules for Workouts are transferred to objects related to the Workout,
|
||||||
|
- Charts
|
||||||
|
- Video Analysis
|
||||||
|
- WorkoutComment?
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# check if user is owner or coach of owner of workout
|
||||||
|
@rules.predicate
|
||||||
|
def is_workout_user(user,workout):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if workout.user == r:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return is_coach_user(user,workout.user.user)
|
||||||
|
|
||||||
|
# check if user is in same team as owner of workout
|
||||||
|
@rules.predicate
|
||||||
|
def is_workout_team(user,workout):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = user.rower
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if workout.user == r:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return is_rower_team_member(user,workout.user)
|
||||||
|
|
||||||
|
# check if user can see workout
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_workout(user,workout):
|
||||||
|
if workout.privacy != 'private':
|
||||||
|
return True
|
||||||
|
return user.rower == workout.user
|
||||||
|
|
||||||
|
can_change_workout = is_workout_user
|
||||||
|
|
||||||
|
rules.add_perm('workout.change_workout',can_change_workout) # replaces checkworkoutuser
|
||||||
|
rules.add_perm('workout.view_workout',can_view_workout) # replaces checkworkoutuserview
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# checkviewworkouts
|
||||||
|
|
||||||
|
# PLANNING permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
- These rules apply to planning
|
||||||
|
- Free coach can create planned sessions and team planned sessions
|
||||||
|
- test_permissions.PermissionsViewTests.test_coach_create_session
|
||||||
|
- Self coach and higher can create planned sessions and team planned sessions
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_plan_create_session
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_coach_create_session
|
||||||
|
- Coach can create planned sessions and team planned sessions
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_plan_create_session
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_coach_create_session
|
||||||
|
- Self Coach and higher can create planned sessions and team planned sessions
|
||||||
|
- test_permissions.PermissionsViewTests.test_plan_create_session
|
||||||
|
- Pro or Basic cannot create planned sessions or team planned sessions
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_pro_create_plannedsession
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_basic_create_plannedsession
|
||||||
|
- WHO can comment (plannedsession_comment_view)
|
||||||
|
- Only Session manager can change session
|
||||||
|
- Strict View rules (stricter than workouts)
|
||||||
|
- Basic user cannot manage a training plan
|
||||||
|
|
||||||
|
- TrainingTarget
|
||||||
|
- rules for view, add, change, delete
|
||||||
|
- TrainingPlan
|
||||||
|
- rules for view, add, change, delete
|
||||||
|
- Cycle
|
||||||
|
- inherits rules from TrainingPlan
|
||||||
|
- PlannedSession
|
||||||
|
- rules for view, add, change, delete, clone, save as template
|
||||||
|
- check team
|
||||||
|
|
||||||
|
- Special rules for Race (cannot be edited ex post)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Training Target rules
|
||||||
|
|
||||||
|
# untested can_view_target to can_delete_target
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_target(user,target):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user == target.manager.user:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# a target's coach can view as well
|
||||||
|
if is_coach_user(user,target.manager.user):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# the object can view as well
|
||||||
|
if user.rower in target.rowers.all():
|
||||||
|
return True
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_target(user,target):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user == target.manager.user
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_target(user,target):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user == target.manager.user
|
||||||
|
|
||||||
|
rules.add_perm('target.view_target',can_view_target)
|
||||||
|
rules.add_perm('target.change_target',can_change_target)
|
||||||
|
rules.add_perm('target.delete_target',can_delete_target)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_plan(user,plan):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user == plan.manager.user:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# a plan's coach can view as well
|
||||||
|
# below untested
|
||||||
|
if is_coach_user(user,plan.manager.user):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# the object can view as well
|
||||||
|
if user.rower in plan.rowers.all():
|
||||||
|
return True
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_plan(user,plan):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user == plan.manager.user
|
||||||
|
|
||||||
|
# below untested
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_plan(user,plan):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user == plan.manager.user
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rules.add_perm('plan.view_plan',can_view_plan)
|
||||||
|
rules.add_perm('plan.change_plan',can_change_plan)
|
||||||
|
rules.add_perm('plan.delete_plan',can_delete_plan)
|
||||||
|
rules.add_perm('plan.can_add_plan',can_add_plan)
|
||||||
|
|
||||||
|
# untested
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_cycle(user,cycle):
|
||||||
|
try:
|
||||||
|
return can_view_cycle(user,cycle.plan)
|
||||||
|
except AttributeError:
|
||||||
|
return can_view_plan(user,cycle.plan)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_cycle(user,cycle):
|
||||||
|
try:
|
||||||
|
return can_change_cycle(user,cycle.plan)
|
||||||
|
except AttributeError:
|
||||||
|
return can_change_plan(user,cycle.plan)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_cycle(user,cycle):
|
||||||
|
try:
|
||||||
|
return can_delete_cycle(user,cycle.plan)
|
||||||
|
except AttributeError:
|
||||||
|
return can_delete_plan(user,cycle.plan)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
rules.add_perm('cycle.view_cycle',can_view_cycle)
|
||||||
|
rules.add_perm('cycle.change_cycle',can_change_cycle)
|
||||||
|
rules.add_perm('cycle.delete_cycle',can_delete_cycle)
|
||||||
|
|
||||||
|
|
||||||
|
# check if user has view access to session
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_session(user,session):
|
||||||
|
if session.sessiontype in ['race','indoorrace']:
|
||||||
|
return True
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
# session manager can view session
|
||||||
|
if user == session.manager:
|
||||||
|
return True
|
||||||
|
# if you're a rower in the session you can view it
|
||||||
|
# below untested
|
||||||
|
if user.rower in session.rower.all():
|
||||||
|
return True
|
||||||
|
# coach users can view sessions created by their team members
|
||||||
|
# below untested
|
||||||
|
if is_coach(user):
|
||||||
|
teams = user.rower.get_managed_teams()
|
||||||
|
teamusers = [member.u for member in t.rower.all()]
|
||||||
|
if session.manager in teamusers:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_session(user,session):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
# session part of a race should not be changed through the session interface
|
||||||
|
if session.sessiontype in ['race','indoorrace']:
|
||||||
|
return False
|
||||||
|
if user == session.manager:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_session(user,session):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if session.sessiontype in ['race','indoorrace']:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if user == session.manager:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rules.add_perm('plannedsession.add_session',can_add_session)
|
||||||
|
rules.add_perm('plannedsession.view_session',can_view_session)
|
||||||
|
rules.add_perm('plannedsession.change_session',can_change_session)
|
||||||
|
rules.add_perm('plannedsession.delete_session',can_delete_session)
|
||||||
|
|
||||||
|
# TEAM (group) permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
- These methods exist on team
|
||||||
|
- team.manager
|
||||||
|
- team.private
|
||||||
|
|
||||||
|
- These rules apply to a team
|
||||||
|
- A Pro or Plan rower can be manager of only 1 team
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_pro_groupmanager
|
||||||
|
- test_permissions.PermissionsViewTests.test_pro_groups_create
|
||||||
|
- A coach can have any number of teams (as manager)
|
||||||
|
- test_permissions.PermissionsBasicTest.test_coach_groupmanager
|
||||||
|
- Basic user cannot manage a group
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_basic_groupmanager
|
||||||
|
- Basic user cannot join groups led by Free Coach or Pro
|
||||||
|
- test_permissions.PermissionFreeCoach.test_add_basic_pro_or_plan
|
||||||
|
- Basic athletes can be member of Coach led group
|
||||||
|
- test_permissions.PermissionsBasicTest.test_add_coach
|
||||||
|
- Pro users (and higher) can join team led by other Pro (or higher) user
|
||||||
|
- test_permissions.PermissionsFreeCoach.test_add_proplan_pro_or_plan
|
||||||
|
- test_permissions.PermissionsViewTests.test_team_member_request_pro_pro
|
||||||
|
- test_permissions.PermissionsViewTests.test_team_member_request_basic_pro
|
||||||
|
- On downgrade, Coach users lose all but their oldest team (add test!)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# check if user is manager of the team
|
||||||
|
@rules.predicate
|
||||||
|
def is_team_manager(user,team):
|
||||||
|
return team.manager == user
|
||||||
|
|
||||||
|
# check is user is member of team - untested
|
||||||
|
@rules.predicate
|
||||||
|
def is_team_member(user,team):
|
||||||
|
members = team.rower.all()
|
||||||
|
return user in [member.user for member in members]
|
||||||
|
|
||||||
|
# check if user can view team
|
||||||
|
@rules.predicate
|
||||||
|
def can_view_team(user,team):
|
||||||
|
# user based - below untested
|
||||||
|
if user.rower.rowerplan == 'basic' and team.manager.rower.rowerplan != 'coach':
|
||||||
|
return False
|
||||||
|
# team is public
|
||||||
|
if team.private == 'open':
|
||||||
|
return True
|
||||||
|
# team is private - below untested
|
||||||
|
return is_team_member(user,team) | is_team_manager(user,team)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_team(user,team):
|
||||||
|
return is_team_manager(user,team)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_team(user,team):
|
||||||
|
return is_team_manager(user,team)
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_join_team(user,team):
|
||||||
|
return is_paid_coach(team.manager) or ispromember(user)
|
||||||
|
|
||||||
|
# For Team functionality
|
||||||
|
rules.add_perm('teams.view_team',can_view_team)
|
||||||
|
rules.add_perm('teams.add_team',user_is_not_basic)
|
||||||
|
rules.add_perm('teams.change_team',can_change_team)
|
||||||
|
rules.add_perm('teams.delete_team',can_delete_team)
|
||||||
|
|
||||||
|
# RACING permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
- VirtualRace
|
||||||
|
- rules to add, view, delete, change
|
||||||
|
- GeoCourse
|
||||||
|
- rules to add, view, delete, change
|
||||||
|
- RaceLogo
|
||||||
|
"""
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_course(user,course):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return course.manager == user.rower
|
||||||
|
|
||||||
|
# untested
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_course(user,course):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return course.manager == user.rower
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_delete_logo(user,logo):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return logo.user == user
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def can_change_race(user,race):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return race.manager == user
|
||||||
|
|
||||||
|
# everybody can view or add a course
|
||||||
|
rules.add_perm('course.change_course',can_change_course)
|
||||||
|
rules.add_perm('course.delete_course',can_delete_course)
|
||||||
|
|
||||||
|
rules.add_perm('racelogo.delete_logo',can_delete_logo)
|
||||||
|
|
||||||
|
# everybody can view a race
|
||||||
|
rules.add_perm('virtualevent.change_race',can_change_race)
|
||||||
|
# can races be deleted?
|
||||||
|
|
||||||
|
|
||||||
|
# ANALYSIS permissions
|
||||||
|
|
||||||
|
"""
|
||||||
|
- Conditions
|
||||||
|
- Alerts
|
||||||
|
- rules to add, view, delete, change
|
||||||
|
- cpdata
|
||||||
|
"""
|
||||||
@@ -7,6 +7,8 @@ from __future__ import unicode_literals, absolute_import
|
|||||||
from rowers.imports import *
|
from rowers.imports import *
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
||||||
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
||||||
@@ -285,7 +287,7 @@ def workout_runkeeper_upload(user,w):
|
|||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
|
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
data = createrunkeeperworkoutdata(w)
|
data = createrunkeeperworkoutdata(w)
|
||||||
if not data:
|
if not data:
|
||||||
message = "Data error in Runkeeper Upload"
|
message = "Data error in Runkeeper Upload"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from rowsandall_app.settings import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
|
||||||
oauth_data = {
|
oauth_data = {
|
||||||
'client_id': SPORTTRACKS_CLIENT_ID,
|
'client_id': SPORTTRACKS_CLIENT_ID,
|
||||||
@@ -265,7 +266,7 @@ def workout_sporttracks_upload(user,w):
|
|||||||
|
|
||||||
thetoken = sporttracks_open(user)
|
thetoken = sporttracks_open(user)
|
||||||
|
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
data = createsporttracksworkoutdata(w)
|
data = createsporttracksworkoutdata(w)
|
||||||
if not data:
|
if not data:
|
||||||
message = "Data error"
|
message = "Data error"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ queuehigh = django_rq.get_queue('low')
|
|||||||
|
|
||||||
from rowers.dataprep import columndict
|
from rowers.dataprep import columndict
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_workout_user,ispromember
|
||||||
|
|
||||||
import stravalib
|
import stravalib
|
||||||
from stravalib.exc import ActivityUploadFailed,TimeoutExceeded
|
from stravalib.exc import ActivityUploadFailed,TimeoutExceeded
|
||||||
|
|
||||||
@@ -123,7 +125,7 @@ def get_strava_workout_list(user,limit_n=0):
|
|||||||
# gets all new Strava workouts for a rower
|
# gets all new Strava workouts for a rower
|
||||||
def get_strava_workouts(rower):
|
def get_strava_workouts(rower):
|
||||||
|
|
||||||
if not isprorower(rower):
|
if not ispromember(rower.user):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -632,7 +634,7 @@ def workout_strava_upload(user,w):
|
|||||||
s = "Token doesn't exist. Need to authorize"
|
s = "Token doesn't exist. Need to authorize"
|
||||||
raise NoTokenError("Your hovercraft is full of eels")
|
raise NoTokenError("Your hovercraft is full of eels")
|
||||||
else:
|
else:
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
try:
|
try:
|
||||||
tcxfile,tcxmesg = createstravaworkoutdata(w)
|
tcxfile,tcxmesg = createstravaworkoutdata(w)
|
||||||
if tcxfile:
|
if tcxfile:
|
||||||
|
|||||||
+17
-34
@@ -26,6 +26,8 @@ from rowers.models import (
|
|||||||
CoachingGroup
|
CoachingGroup
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_team_manager,is_team_member,is_coach
|
||||||
|
|
||||||
from rowers.tasks import (
|
from rowers.tasks import (
|
||||||
handle_sendemail_invite,
|
handle_sendemail_invite,
|
||||||
handle_sendemail_request,
|
handle_sendemail_request,
|
||||||
@@ -60,7 +62,8 @@ def handle_add_workouts_team(ws,t):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def update_team(t,name,manager,private,notes,viewing):
|
def update_team(t,name,manager,private,notes,viewing):
|
||||||
if t.manager != manager:
|
|
||||||
|
if not is_team_manager(manager,t):
|
||||||
return (0,'You are not the manager of this team')
|
return (0,'You are not the manager of this team')
|
||||||
try:
|
try:
|
||||||
t.name = name
|
t.name = name
|
||||||
@@ -78,7 +81,7 @@ def create_team(name,manager,private='open',notes='',viewing='allmembers'):
|
|||||||
if manager.rower.rowerplan == 'basic':
|
if manager.rower.rowerplan == 'basic':
|
||||||
if manager.rower.protrialexpires < timezone.now().date() and manager.rower.plantrialexpires < timezone.now().date():
|
if manager.rower.protrialexpires < timezone.now().date() and manager.rower.plantrialexpires < timezone.now().date():
|
||||||
return (0,'You need to upgrade to a paid plan to establish a team')
|
return (0,'You need to upgrade to a paid plan to establish a team')
|
||||||
if manager.rower.rowerplan not in ('coach','freecoach'):
|
if not is_coach(manager):
|
||||||
ts = Team.objects.filter(manager=manager)
|
ts = Team.objects.filter(manager=manager)
|
||||||
if len(ts)>=1:
|
if len(ts)>=1:
|
||||||
return (0,'You need to upgrade to the Coach plan to have more than one team')
|
return (0,'You need to upgrade to the Coach plan to have more than one team')
|
||||||
@@ -99,19 +102,6 @@ def remove_team(id):
|
|||||||
send_team_delete_mail(t,r)
|
send_team_delete_mail(t,r)
|
||||||
return t.delete()
|
return t.delete()
|
||||||
|
|
||||||
#def set_teamplanexpires(rower):
|
|
||||||
# ts = Team.objects.filter(rower=rower)
|
|
||||||
|
|
||||||
# texp = datetime.date(timezone.now())
|
|
||||||
|
|
||||||
# for t in ts:
|
|
||||||
# print t.name
|
|
||||||
# mr = Rower.objects.get(user=t.manager)
|
|
||||||
# if mr.teamplanexpires > texp:
|
|
||||||
# rower.teamplanexpires = mr.teamplanexpires
|
|
||||||
|
|
||||||
# t.save()
|
|
||||||
|
|
||||||
return (1,'Updated rower team expiry')
|
return (1,'Updated rower team expiry')
|
||||||
|
|
||||||
def add_coach(coach,rower):
|
def add_coach(coach,rower):
|
||||||
@@ -179,24 +169,19 @@ def rower_get_managers(rower):
|
|||||||
return managers
|
return managers
|
||||||
|
|
||||||
def rower_get_coaches(rower):
|
def rower_get_coaches(rower):
|
||||||
coaches = []
|
return rower.get_coaches()
|
||||||
for group in rower.coachinggroups.all():
|
|
||||||
try:
|
|
||||||
coach = Rower.objects.get(mycoachgroup=group)
|
|
||||||
coaches.append(coach)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return coaches
|
|
||||||
|
|
||||||
|
|
||||||
def coach_getcoachees(coach):
|
def coach_getcoachees(coach):
|
||||||
if coach.mycoachgroup and coach.rowerplan in ('coach','freecoach'):
|
rowers = []
|
||||||
return Rower.objects.filter(
|
if coach.mycoachgroup and is_coach(coach.user):
|
||||||
|
rs = Rower.objects.filter(
|
||||||
coachinggroups__in=[coach.mycoachgroup]
|
coachinggroups__in=[coach.mycoachgroup]
|
||||||
).distinct().order_by("user__last_name","user__first_name")
|
).distinct().order_by("user__last_name","user__first_name")
|
||||||
else:
|
for r in rs:
|
||||||
return []
|
rowers.append(r)
|
||||||
|
|
||||||
|
return rowers
|
||||||
|
|
||||||
def coach_remove_athlete(coach,rower):
|
def coach_remove_athlete(coach,rower):
|
||||||
try:
|
try:
|
||||||
@@ -213,7 +198,7 @@ def coach_remove_athlete(coach,rower):
|
|||||||
|
|
||||||
def mgr_remove_member(id,manager,rower):
|
def mgr_remove_member(id,manager,rower):
|
||||||
t = Team.objects.get(id=id)
|
t = Team.objects.get(id=id)
|
||||||
if t.manager == manager:
|
if is_team_manager(manager,t):
|
||||||
remove_member(id,rower)
|
remove_member(id,rower)
|
||||||
send_email_member_dropped(id,rower)
|
send_email_member_dropped(id,rower)
|
||||||
return (id,'Member removed')
|
return (id,'Member removed')
|
||||||
@@ -345,7 +330,7 @@ def create_coaching_offer(coach,user):
|
|||||||
|
|
||||||
def create_invite(team,manager,user=None,email=''):
|
def create_invite(team,manager,user=None,email=''):
|
||||||
r = Rower.objects.get(user=manager)
|
r = Rower.objects.get(user=manager)
|
||||||
if team.manager != manager:
|
if not is_team_manager(manager,team):
|
||||||
return (0,'Not the team manager')
|
return (0,'Not the team manager')
|
||||||
if user:
|
if user:
|
||||||
try:
|
try:
|
||||||
@@ -433,7 +418,7 @@ def revoke_invite(manager,id):
|
|||||||
except TeamInvite.DoesNotExist:
|
except TeamInvite.DoesNotExist:
|
||||||
return (0,'The invitation is invalid')
|
return (0,'The invitation is invalid')
|
||||||
|
|
||||||
if invite.team.manager==manager:
|
if is_team_manager(manager,invite.team):
|
||||||
invite.delete()
|
invite.delete()
|
||||||
return (1,'Invitation revoked')
|
return (1,'Invitation revoked')
|
||||||
else:
|
else:
|
||||||
@@ -445,7 +430,7 @@ def reject_request(manager,id):
|
|||||||
except TeamRequest.DoesNotExist:
|
except TeamRequest.DoesNotExist:
|
||||||
return (0,'The request is invalid')
|
return (0,'The request is invalid')
|
||||||
|
|
||||||
if rekwest.team.manager==manager:
|
if is_team_manager(manager,rekwest.team):
|
||||||
send_request_reject_email(rekwest)
|
send_request_reject_email(rekwest)
|
||||||
rekwest.delete()
|
rekwest.delete()
|
||||||
return (1,'Request rejected')
|
return (1,'Request rejected')
|
||||||
@@ -743,5 +728,3 @@ def send_coachoffer_accepted_email(rekwest):
|
|||||||
res = myqueue(queuehigh,
|
res = myqueue(queuehigh,
|
||||||
handle_sendemail_coachoffer_accepted,
|
handle_sendemail_coachoffer_accepted,
|
||||||
coachemail,coachname,name)
|
coachemail,coachname,name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,4 @@
|
|||||||
</ul> <!-- cd-accordion-menu -->
|
</ul> <!-- cd-accordion-menu -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% include 'menuscript.html' %}
|
{% include 'menuscript.html' %}
|
||||||
|
|||||||
@@ -44,13 +44,13 @@
|
|||||||
|
|
||||||
{% if user.is_authenticated and user|is_manager and rower %}
|
{% if user.is_authenticated and user|is_manager and rower %}
|
||||||
<p> </p>
|
<p> </p>
|
||||||
{% if user|coach_rowers %}
|
{% if request.user|coach_rowers %}
|
||||||
<ul class="cd-accordion-menu animated">
|
<ul class="cd-accordion-menu animated">
|
||||||
<li class="has-children" id="athletes">
|
<li class="has-children" id="athletes">
|
||||||
<input type="checkbox" name="athlete-selector" id="athlete-selector">
|
<input type="checkbox" name="athlete-selector" id="athlete-selector">
|
||||||
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i> Athletes</label>
|
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i> Athletes</label>
|
||||||
<ul>
|
<ul>
|
||||||
{% for member in user|coach_rowers %}
|
{% for member in request.user|coach_rowers %}
|
||||||
<a href={{ request.path|userurl:member.user }}>
|
<a href={{ request.path|userurl:member.user }}>
|
||||||
<i class="fas fa-user fa-fw"></i>
|
<i class="fas fa-user fa-fw"></i>
|
||||||
{% if member.user == rower.user %}
|
{% if member.user == rower.user %}
|
||||||
|
|||||||
@@ -33,3 +33,4 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<noscript>Your browser does not support JavaScript</noscript>
|
||||||
|
|||||||
@@ -108,6 +108,7 @@
|
|||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
<th>Edit</th>
|
||||||
<th>Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -126,7 +127,10 @@
|
|||||||
<td> {{ ps.sessionvalue }} </td>
|
<td> {{ ps.sessionvalue }} </td>
|
||||||
<td> {{ ps.sessionunit }} </td>
|
<td> {{ ps.sessionunit }} </td>
|
||||||
<td>
|
<td>
|
||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/?next={{ request.path|urlencode }}">Delete</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@
|
|||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
<th>Edit</th>
|
||||||
<th>Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -132,6 +133,9 @@
|
|||||||
</td>
|
</td>
|
||||||
<td> {{ ps.sessionvalue }} </td>
|
<td> {{ ps.sessionvalue }} </td>
|
||||||
<td> {{ ps.sessionunit }} </td>
|
<td> {{ ps.sessionunit }} </td>
|
||||||
|
<td>
|
||||||
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
{% extends "newbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Update Template Session{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<h1>Edit Session Template</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="main-content">
|
||||||
|
<li class="grid_2">
|
||||||
|
<h2>{{ thesession.name }}</h2>
|
||||||
|
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||||
|
{% if form.errors %}
|
||||||
|
<p style="color: red;">
|
||||||
|
Please correct the error{{ form.errors|pluralize }} below.
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<p>
|
||||||
|
<table>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
{% csrf_token %}
|
||||||
|
<div id="id_guidance">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/sessions/{{ thesession.id }}/deleteconfirm">Delete</a>
|
||||||
|
</p>
|
||||||
|
<input class="button"
|
||||||
|
action="/rowers/sessions/{{ thesession.id }}/templateedit/" type="submit" value="Save">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li class="grid_2">
|
||||||
|
<h1>Templates</h1>
|
||||||
|
<p>
|
||||||
|
Click on session name to clone to current period
|
||||||
|
</p>
|
||||||
|
<table class="listtable shortpadded" width="80%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th> </th>
|
||||||
|
<th>Edit</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for ps in sessiontemplates %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if ps.name != '' %}
|
||||||
|
<a class="small"
|
||||||
|
href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}/?when={{ timeperiod }}">{{ ps.name }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="small"
|
||||||
|
href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}/?when={{ timeperiod }}">Unnamed Session</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td> {{ ps.sessionvalue }} </td>
|
||||||
|
<td> {{ ps.sessionunit }} </td>
|
||||||
|
<td>
|
||||||
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/templateedit/">Edit Template</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm/">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
{% include 'menu_plan.html' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
var o = $("td #id_sessiontype").find(":selected").val();
|
||||||
|
|
||||||
|
if (o != 'coursetest') {
|
||||||
|
$("td #id_course").hide();
|
||||||
|
$("th label[for='id_course']").hide();
|
||||||
|
} else {
|
||||||
|
$("td #id_course").show();
|
||||||
|
$("th label[for='id_course']").show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$("td #id_sessionmode").change(function() {
|
||||||
|
|
||||||
|
if (this.value == 'TRIMP') {
|
||||||
|
$("td #id_sessionunit").prop("value","None");
|
||||||
|
$('#id_guidance').html("<p>TRIMP has no unit</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'distance') {
|
||||||
|
$("td #id_sessionunit").prop("value","m");
|
||||||
|
$('#id_guidance').html("<p>Distance: Set value to meters</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'time') {
|
||||||
|
$("td #id_sessionunit").prop("value","min");
|
||||||
|
$('#id_guidance').html("<p>Time: Set value to minutes</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.value == 'rScore') {
|
||||||
|
$("td #id_sessionunit").prop("value","None");
|
||||||
|
$('#id_guidance').html("<p>rScore has no unit</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("td #id_sessiontype").change(function() {
|
||||||
|
|
||||||
|
if (this.value == 'session') {
|
||||||
|
$("td #id_criterium").prop("value","none");
|
||||||
|
$('#id_guidance').html("<p>For Training Sessions, the default criterium is 'Approximately'</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'test') {
|
||||||
|
$("td #id_criterium").prop("value","exact");
|
||||||
|
$("td #id_sessionmode").prop("value","distance");
|
||||||
|
$("td #id_sessionunit").prop("value","m");
|
||||||
|
$('#id_guidance').html("<p>Set mode to distance. For Mandatory Tests, only distance or time are allowed.</p><p>For Mandatory Tests, the only criterium is 'Exactly'</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.value == 'coursetest') {
|
||||||
|
$("th label[for='id_course']").show();
|
||||||
|
$("td #id_course").show();
|
||||||
|
$("td #id_criterium").prop("value","none");
|
||||||
|
$("td #id_sessionmode").prop("value","distance");
|
||||||
|
$("td #id_sessionunit").prop("value","m");
|
||||||
|
$('#id_guidance').html("<p>Set mode to distance. For OTW Tests, only distance is allowed.</p><p>The exact value is not relevant because it is calculated from the course.</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.value != 'coursetest') {
|
||||||
|
$("th label[for='id_course']").hide();
|
||||||
|
$("td #id_course").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (this.value == 'challenge') {
|
||||||
|
$("td #id_criterium").prop("value","minimum");
|
||||||
|
$('#id_guidance').html("<p>For Challenges, the default criterium is 'At Least'</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.value == 'cycletarget') {
|
||||||
|
$("td #id_criterium").prop("value","none");
|
||||||
|
$('#id_guidance').html("<p>For Cycle Targets, the default criterium is 'Approximately'</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
$("td #id_sessionunit").change(function() {
|
||||||
|
|
||||||
|
if (this.value == 'm') {
|
||||||
|
$("td #id_sessionmode").prop("value","distance");
|
||||||
|
$('#id_guidance').html("<p>Mode was set to distance</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'km') {
|
||||||
|
$("td #id_sessionmode").prop("value","distance");
|
||||||
|
$('#id_guidance').html("<p>Mode was set to distance</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'None') {
|
||||||
|
$("td #id_sessionmode").prop("value","rScore");
|
||||||
|
$('#id_guidance').html("<p>Mode was set to rScore</p>");
|
||||||
|
}
|
||||||
|
if (this.value == 'min') {
|
||||||
|
$("td #id_sessionmode").prop("value","time");
|
||||||
|
$('#id_guidance').html("<p>Mode was set to time</p>");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
<p>
|
<p>
|
||||||
<a href="/rowers/sessions/{{ psdict.id.1 }}/edit/user/{{ rower.user.id }}">
|
<a href="/rowers/sessions/{{ psdict.id.1 }}/edit/user/{{ rower.user.id }}">
|
||||||
Edit Session</a>
|
Edit Session</a>
|
||||||
|
/
|
||||||
|
<a href="/rowers/sessions/{{ psdict.id.1 }}/maketemplate/?next={{ request.path|urlencode }}">Save to template</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h1>Session {{ psdict.name.1 }}</h1>
|
<h1>Session {{ psdict.name.1 }}</h1>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from rowers.plannedsessions import (
|
|||||||
from rowers import c2stuff, runkeeperstuff
|
from rowers import c2stuff, runkeeperstuff
|
||||||
from rowers.c2stuff import c2_open
|
from rowers.c2stuff import c2_open
|
||||||
from rowers.runkeeperstuff import runkeeper_open
|
from rowers.runkeeperstuff import runkeeper_open
|
||||||
from rowers.models import checkaccessuser
|
from rowers.rower_rules import is_coach_user, is_workout_user, isplanmember,ispromember
|
||||||
from rowers.mytypes import otwtypes
|
from rowers.mytypes import otwtypes
|
||||||
from rowers.utils import NoTokenError
|
from rowers.utils import NoTokenError
|
||||||
|
|
||||||
@@ -385,14 +385,13 @@ def is_session_manager(id,user):
|
|||||||
|
|
||||||
return ps.manager == user
|
return ps.manager == user
|
||||||
|
|
||||||
from rowers.models import checkworkoutuser
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def may_edit(workout,request):
|
def may_edit(workout,request):
|
||||||
mayedit = 0
|
mayedit = 0
|
||||||
if request.user == workout.user.user:
|
if request.user == workout.user.user:
|
||||||
mayedit = True
|
mayedit = True
|
||||||
if checkworkoutuser(request.user,workout):
|
if is_workout_user(request.user,workout):
|
||||||
mayedit = True
|
mayedit = True
|
||||||
|
|
||||||
return mayedit
|
return mayedit
|
||||||
@@ -413,7 +412,7 @@ def mayeditplan(obj,request):
|
|||||||
return request.user == obj.manager.user
|
return request.user == obj.manager.user
|
||||||
|
|
||||||
rr = Rower.objects.get(user=request.user)
|
rr = Rower.objects.get(user=request.user)
|
||||||
if checkaccessuser(request.user,obj.rower) and rr.rowerplan not in ['basic','pro']:
|
if is_coach_user(request.user,obj.rower) and rr.rowerplan not in ['basic','pro']:
|
||||||
mayedit = True
|
mayedit = True
|
||||||
|
|
||||||
|
|
||||||
@@ -431,7 +430,7 @@ def get_field_id(id,s,form):
|
|||||||
|
|
||||||
from rowers.models import Rower,Team,TrainingPlan,TrainingTarget
|
from rowers.models import Rower,Team,TrainingPlan,TrainingTarget
|
||||||
|
|
||||||
from rowers.views import ispromember
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def is_promember(user):
|
def is_promember(user):
|
||||||
return ispromember(user)
|
return ispromember(user)
|
||||||
@@ -441,10 +440,10 @@ def is_manager(user):
|
|||||||
r = Rower.objects.get(user=user)
|
r = Rower.objects.get(user=user)
|
||||||
return 'coach' in r.rowerplan
|
return 'coach' in r.rowerplan
|
||||||
|
|
||||||
from rowers.views import hasplannedsessions
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def is_planmember(user):
|
def is_planmember(user):
|
||||||
return hasplannedsessions(user)
|
return isplanmember(user)
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def get_age(r):
|
def get_age(r):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from django.test import TestCase, Client,override_settings
|
|||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from rowers.views import checkworkoutuser,c2_open
|
from rowers.views import c2_open
|
||||||
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
|
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
|
||||||
from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
|
from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
|
||||||
import rowers.plots as plots
|
import rowers.plots as plots
|
||||||
@@ -69,6 +69,10 @@ def mocked_myqueue(*args, **kwargs):
|
|||||||
|
|
||||||
return Job()
|
return Job()
|
||||||
|
|
||||||
|
def mock_c2open(*args, **kwargs):
|
||||||
|
print('mock')
|
||||||
|
return('aap')
|
||||||
|
|
||||||
def mocked_sqlalchemy(*args, **kwargs):
|
def mocked_sqlalchemy(*args, **kwargs):
|
||||||
# return object with method
|
# return object with method
|
||||||
|
|
||||||
@@ -606,6 +610,7 @@ def mocked_requests(*args, **kwargs):
|
|||||||
def __init__(self, json_data, status_code):
|
def __init__(self, json_data, status_code):
|
||||||
self.json_data = json_data
|
self.json_data = json_data
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
|
self.ok = True
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
return self.json_data
|
return self.json_data
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from django.core.management import call_command
|
|||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from rowers.views import checkworkoutuser,c2_open, multi_compare_view
|
from rowers.views import c2_open, multi_compare_view
|
||||||
|
|
||||||
from rowers.forms import (
|
from rowers.forms import (
|
||||||
DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail,
|
DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail,
|
||||||
@@ -220,5 +220,3 @@ def cleanup(request):
|
|||||||
|
|
||||||
|
|
||||||
request.addfinalizer(remove_test_files)
|
request.addfinalizer(remove_test_files)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -242,9 +242,9 @@ class WorkoutViewTest(TestCase):
|
|||||||
|
|
||||||
@patch('rowers.dataprep.create_engine')
|
@patch('rowers.dataprep.create_engine')
|
||||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||||
# @patch('rowers.weather.requests.get', side_effect=mocked_requests)
|
@patch('rowers.weather.requests.get', side_effect=mocked_requests)
|
||||||
def test_waterworkout_view(self,
|
def test_waterworkout_view(self,
|
||||||
mocked_sqlalchemy, mocked_getsmallrowdata_db):
|
mocked_sqlalchemy, mocked_getsmallrowdata_db, mocked_requests):
|
||||||
login = self.c.login(username=self.u.username, password=self.password)
|
login = self.c.login(username=self.u.username, password=self.password)
|
||||||
self.assertTrue(login)
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ class SimpleViewTest(TestCase):
|
|||||||
birthdate=faker.profile()['birthdate'],
|
birthdate=faker.profile()['birthdate'],
|
||||||
gdproptin=True,surveydone=True,
|
gdproptin=True,surveydone=True,
|
||||||
gdproptindate=timezone.now(),
|
gdproptindate=timezone.now(),
|
||||||
|
protrialexpires=datetime.date(1970,1,1),
|
||||||
|
plantrialexpires=datetime.date(1970,1,1),
|
||||||
rowerplan='basic')
|
rowerplan='basic')
|
||||||
|
|
||||||
self.c = Client()
|
self.c = Client()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from .statements import *
|
|||||||
|
|
||||||
nu = datetime.datetime.now()
|
nu = datetime.datetime.now()
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
|
||||||
#@pytest.mark.django_db
|
#@pytest.mark.django_db
|
||||||
class WorkoutTests(TestCase):
|
class WorkoutTests(TestCase):
|
||||||
@@ -28,7 +28,7 @@ class WorkoutTests(TestCase):
|
|||||||
duration="0:55:00",distance=8000)
|
duration="0:55:00",distance=8000)
|
||||||
|
|
||||||
def test_checkworkoutuser(self):
|
def test_checkworkoutuser(self):
|
||||||
self.assertEqual(checkworkoutuser(self.u,self.w),True)
|
self.assertEqual(is_workout_user(self.u,self.w),True)
|
||||||
|
|
||||||
#@pytest.mark.django_db
|
#@pytest.mark.django_db
|
||||||
class C2Tests(TestCase):
|
class C2Tests(TestCase):
|
||||||
|
|||||||
@@ -13,6 +13,87 @@ from django.db import transaction
|
|||||||
|
|
||||||
import rowers.teams as teams
|
import rowers.teams as teams
|
||||||
import rowers.plannedsessions as plannedsessions
|
import rowers.plannedsessions as plannedsessions
|
||||||
|
from rowers.rower_rules import is_coach_user
|
||||||
|
|
||||||
|
@override_settings(TESTING=True)
|
||||||
|
class PlanningPermissionsCoach(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Client()
|
||||||
|
|
||||||
|
self.ucoach = UserFactory()
|
||||||
|
self.rcoach = Rower.objects.create(
|
||||||
|
user=self.ucoach,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach',
|
||||||
|
clubsize=10,
|
||||||
|
)
|
||||||
|
self.ucoachpassword = faker.word()
|
||||||
|
self.ucoach.set_password(self.ucoachpassword)
|
||||||
|
self.ucoach.save()
|
||||||
|
|
||||||
|
self.ucoachee = UserFactory()
|
||||||
|
self.rcoachee = Rower.objects.create(
|
||||||
|
user=self.ucoachee,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='basic'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.coachgroup = CoachingGroup.objects.create(name=self.ucoach.first_name)
|
||||||
|
self.rcoach.mycoachgroup = self.coachgroup
|
||||||
|
self.rcoach.save()
|
||||||
|
|
||||||
|
self.team = Team.objects.create(
|
||||||
|
name=faker.word()+'3',
|
||||||
|
notes=faker.text(),
|
||||||
|
manager=self.ucoach)
|
||||||
|
|
||||||
|
# coachee is in coach's team
|
||||||
|
self.rcoachee.team.add(self.team)
|
||||||
|
|
||||||
|
# coachee is coached by coach
|
||||||
|
self.rcoachee.coachinggroups.add(self.rcoach.mycoachgroup)
|
||||||
|
self.rcoachee.save()
|
||||||
|
|
||||||
|
self.ugroupmember = UserFactory()
|
||||||
|
self.rgroupmember = Rower.objects.create(
|
||||||
|
user=self.ugroupmember,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='basic'
|
||||||
|
)
|
||||||
|
|
||||||
|
# groupmember is in coach's team (but not coached)
|
||||||
|
self.rgroupmember.team.add(self.team)
|
||||||
|
|
||||||
|
|
||||||
|
# def test_target(self):
|
||||||
|
|
||||||
|
def test_trainingplan(self):
|
||||||
|
plan = TrainingPlan(
|
||||||
|
name='test plan',
|
||||||
|
manager=self.ucoach.rower,
|
||||||
|
)
|
||||||
|
plan.save()
|
||||||
|
|
||||||
|
# can add self and coachee
|
||||||
|
plan.rowers.add(self.ucoach.rower)
|
||||||
|
plan.rowers.add(self.ucoachee.rower)
|
||||||
|
|
||||||
|
# test 1
|
||||||
|
athletes = plan.rowers.all()
|
||||||
|
self.assertTrue(self.ucoach.rower in athletes)
|
||||||
|
self.assertTrue(self.ucoachee.rower in athletes)
|
||||||
|
|
||||||
|
# can add groupmember if not basic
|
||||||
|
plan.rowers.add(self.rgroupmember)
|
||||||
|
athletes = plan.rowers.all()
|
||||||
|
self.assertTrue(self.rgroupmember in athletes)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(TESTING=True)
|
@override_settings(TESTING=True)
|
||||||
class PermissionsFreeCoach(TestCase):
|
class PermissionsFreeCoach(TestCase):
|
||||||
@@ -528,6 +609,8 @@ class PermissionsViewTests(TestCase):
|
|||||||
rowerplan='basic')
|
rowerplan='basic')
|
||||||
|
|
||||||
self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic)
|
self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic)
|
||||||
|
self.ubasic_workouts[0].privacy == 'private'
|
||||||
|
|
||||||
self.factory = RequestFactory()
|
self.factory = RequestFactory()
|
||||||
self.ubasicpassword = faker.word()
|
self.ubasicpassword = faker.word()
|
||||||
self.ubasic.set_password(self.ubasicpassword)
|
self.ubasic.set_password(self.ubasicpassword)
|
||||||
@@ -553,6 +636,24 @@ class PermissionsViewTests(TestCase):
|
|||||||
manager=self.ucoach)
|
manager=self.ucoach)
|
||||||
|
|
||||||
|
|
||||||
|
## only ubasic can view ubasic_workouts[0] which is private
|
||||||
|
def test_view_workout(self):
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('workout_view',
|
||||||
|
kwargs={'id':self.ubasic_workouts[0].id})
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertTrue(response.status_code,403)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ubasic.username, password=self.ubasicpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('workout_view',
|
||||||
|
kwargs={'id':self.ubasic_workouts[0].id})
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertTrue(response.status_code,200)
|
||||||
|
|
||||||
## Coach can have any number of groups
|
## Coach can have any number of groups
|
||||||
def test_coach_groups_create(self):
|
def test_coach_groups_create(self):
|
||||||
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
@@ -644,7 +745,8 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
## Coach can edit on behalf of athlete if permitted
|
## Coach can edit on behalf of athlete if permitted
|
||||||
def test_coach_edit_athlete_settings(self):
|
# 1, Preferences
|
||||||
|
def test_coach_edit_athlete_prefs(self):
|
||||||
self.rbasic.team.add(self.teamcoach)
|
self.rbasic.team.add(self.teamcoach)
|
||||||
self.rbasic.coachinggroups.add(self.coachinggroup)
|
self.rbasic.coachinggroups.add(self.coachinggroup)
|
||||||
|
|
||||||
@@ -656,7 +758,7 @@ 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)
|
||||||
|
|
||||||
def test_coach_edit_athlete_settings_not(self):
|
def test_coach_edit_athlete_prefs_not(self):
|
||||||
self.rbasic.team.add(self.teamcoach)
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
@@ -667,6 +769,78 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url)
|
response = self.c.get(url)
|
||||||
self.assertEqual(response.status_code,403)
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
|
# 2, Favorite Charts
|
||||||
|
def test_coach_edit_athlete_settings(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
self.rbasic.coachinggroups.add(self.coachinggroup)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_favoritecharts_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
def test_coach_edit_athlete_settings_not(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_favoritecharts_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
|
# 3, Export Settings
|
||||||
|
def test_coach_edit_athlete_exportsettings(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
self.rbasic.coachinggroups.add(self.coachinggroup)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_exportsettings_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
def test_coach_edit_athlete_exportsettings_not(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_exportsettings_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
|
# 4, Account settings
|
||||||
|
def test_coach_edit_athlete_account(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
self.rbasic.coachinggroups.add(self.coachinggroup)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_edit_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
def test_coach_edit_athlete_account_not(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('rower_edit_view',kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
## Coach can run analytics for athlete
|
## Coach can run analytics for athlete
|
||||||
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
||||||
def test_coach_edit_athlete_analysis(self,mocked_df):
|
def test_coach_edit_athlete_analysis(self,mocked_df):
|
||||||
@@ -679,7 +853,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
url = reverse('cumstats',
|
url = reverse('cumstats',
|
||||||
kwargs={
|
kwargs={
|
||||||
'theuser':self.ubasic.id,
|
'userid':self.ubasic.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -687,6 +861,8 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
||||||
def test_coach_edit_athlete_analysis_not(self,mocked_df):
|
def test_coach_edit_athlete_analysis_not(self,mocked_df):
|
||||||
self.rbasic.team.add(self.teamcoach)
|
self.rbasic.team.add(self.teamcoach)
|
||||||
@@ -697,7 +873,25 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
url = reverse('cumstats',
|
url = reverse('cumstats',
|
||||||
kwargs={
|
kwargs={
|
||||||
'theuser':self.ubasic.id,
|
'userid':self.ubasic.id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
|
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
||||||
|
def test_coach_edit_athlete_analysis_not2(self,mocked_df):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
|
||||||
|
url = reverse('analysis_new',
|
||||||
|
kwargs={
|
||||||
|
'userid':self.ubasic.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -810,6 +1004,32 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url)
|
response = self.c.get(url)
|
||||||
self.assertEqual(response.status_code,403)
|
self.assertEqual(response.status_code,403)
|
||||||
|
|
||||||
|
## Coach can see list of workouts of athlete
|
||||||
|
def test_coach_athlete_workout_list(self):
|
||||||
|
self.rbasic.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
|
||||||
|
self.assertTrue(login)
|
||||||
|
|
||||||
|
url = reverse('workouts_view',
|
||||||
|
kwargs={'rowerid':self.rbasic.id})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
url = reverse('workouts_view',
|
||||||
|
kwargs={'userid':self.ubasic.id})
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
|
url = reverse('workouts_view')
|
||||||
|
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
## Self coach can create one group
|
## Self coach can create one group
|
||||||
## Self coach cannot create more than one group
|
## Self coach cannot create more than one group
|
||||||
def test_plan_groups_create(self):
|
def test_plan_groups_create(self):
|
||||||
@@ -857,7 +1077,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
|
|
||||||
expected_url = reverse('paidplans')
|
expected_url = reverse('paidplans_view')
|
||||||
|
|
||||||
response = self.c.post(url,form_data,follow=True)
|
response = self.c.post(url,form_data,follow=True)
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
@@ -924,7 +1144,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
url = reverse('cumstats',
|
url = reverse('cumstats',
|
||||||
kwargs={
|
kwargs={
|
||||||
'theuser':self.ubasic.id,
|
'userid':self.ubasic.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -994,7 +1214,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
|
|
||||||
expected_url = reverse('paidplans')
|
expected_url = reverse('paidplans_view')
|
||||||
|
|
||||||
response = self.c.post(url,form_data,follow=True)
|
response = self.c.post(url,form_data,follow=True)
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
@@ -1016,7 +1236,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url,follow=True)
|
response = self.c.get(url,follow=True)
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
expected_url = reverse('paidplans')
|
expected_url = reverse('paidplans_view')
|
||||||
|
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
expected_url=expected_url,
|
expected_url=expected_url,
|
||||||
@@ -1038,6 +1258,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
## Pro cannot run analytics on behalf of athlete
|
## Pro cannot run analytics on behalf of athlete
|
||||||
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
|
||||||
def test_pro_edit_athlete_analysis(self,mocked_df):
|
def test_pro_edit_athlete_analysis(self,mocked_df):
|
||||||
|
with transaction.atomic():
|
||||||
self.rpro.team.add(self.teampro)
|
self.rpro.team.add(self.teampro)
|
||||||
|
|
||||||
login = self.c.login(username=self.upro2.username, password=self.upro2password)
|
login = self.c.login(username=self.upro2.username, password=self.upro2password)
|
||||||
@@ -1046,7 +1267,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
|
|
||||||
url = reverse('cumstats',
|
url = reverse('cumstats',
|
||||||
kwargs={
|
kwargs={
|
||||||
'theuser':self.ubasic.id,
|
'userid':self.ubasic.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1068,7 +1289,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url,follow=True)
|
response = self.c.get(url,follow=True)
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
expected_url = reverse('paidplans')
|
expected_url = reverse('paidplans_view')
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
expected_url = expected_url,
|
expected_url = expected_url,
|
||||||
status_code=302,target_status_code=200)
|
status_code=302,target_status_code=200)
|
||||||
@@ -1180,7 +1401,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url,follow=True)
|
response = self.c.get(url,follow=True)
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
expected_url = reverse('team_view',kwargs={'id':self.teampro.id})
|
expected_url = reverse('team_view',kwargs={'team_id':self.teampro.id})
|
||||||
|
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
expected_url = expected_url,
|
expected_url = expected_url,
|
||||||
@@ -1200,7 +1421,7 @@ class PermissionsViewTests(TestCase):
|
|||||||
response = self.c.get(url,follow=True)
|
response = self.c.get(url,follow=True)
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
|
|
||||||
expected_url = reverse('paidplans')
|
expected_url = reverse('paidplans_view')
|
||||||
self.assertRedirects(response,
|
self.assertRedirects(response,
|
||||||
expected_url = expected_url,
|
expected_url = expected_url,
|
||||||
status_code=302,target_status_code=200)
|
status_code=302,target_status_code=200)
|
||||||
|
|||||||
@@ -0,0 +1,501 @@
|
|||||||
|
from .statements import *
|
||||||
|
|
||||||
|
viewstotest = [
|
||||||
|
('workout_view',
|
||||||
|
{
|
||||||
|
'anonymous': True,
|
||||||
|
'anonymous_response':200,
|
||||||
|
'own': 'basic',
|
||||||
|
'own_response': 200,
|
||||||
|
'own_nonperm': 302,
|
||||||
|
'member': 'basic',
|
||||||
|
'member_response': 200,
|
||||||
|
'member_nonperm': 404,
|
||||||
|
'coachee': 'coach',
|
||||||
|
'coachee_response': 200,
|
||||||
|
'coachee_nonperm': 404,
|
||||||
|
'is_staff': False,
|
||||||
|
'workoutid': True,
|
||||||
|
'userid': False,
|
||||||
|
'dotest': True,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
df = pd.read_csv('./rowers/tests/viewnames.csv')
|
||||||
|
|
||||||
|
for id, row in df.iterrows():
|
||||||
|
view = row['view']
|
||||||
|
tpl = (view,
|
||||||
|
{
|
||||||
|
'anonymous':row.anonymous,
|
||||||
|
'anonymous_response':row.anonymous_response,
|
||||||
|
'own': row.own,
|
||||||
|
'own_response':row.own_response,
|
||||||
|
'own_nonperm': row.own_nonperm,
|
||||||
|
'member': row.member,
|
||||||
|
'member_response':row.member_response,
|
||||||
|
'member_nonperm': row.member_nonperm,
|
||||||
|
'coachee': row.coachee,
|
||||||
|
'coachee_response':row.coachee_response,
|
||||||
|
'coachee_nonperm': row.coachee_nonperm,
|
||||||
|
'is_staff':row.is_staff,
|
||||||
|
'workoutid':row.workoutid,
|
||||||
|
'userid':row.userid,
|
||||||
|
'dotest':row.dotest,
|
||||||
|
})
|
||||||
|
if row.dotest:
|
||||||
|
viewstotest.append(tpl)
|
||||||
|
|
||||||
|
|
||||||
|
plans = ['basic','plan','coach','pro']
|
||||||
|
|
||||||
|
@override_settings(TESTING=True)
|
||||||
|
class PermissionsViewTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Client()
|
||||||
|
## Users - Pro, Basic, Coach & Self Coach
|
||||||
|
|
||||||
|
ucoach = UserFactory(username='coachuser')
|
||||||
|
rcoach = Rower.objects.create(user=ucoach,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach',clubsize=10)
|
||||||
|
|
||||||
|
ucoach_workouts = WorkoutFactory.create_batch(5, user=rcoach)
|
||||||
|
coachinggroup = CoachingGroup.objects.create()
|
||||||
|
rcoach.mycoachgroup = coachinggroup
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
ucoachpassword = faker.word()
|
||||||
|
ucoach.set_password(ucoachpassword)
|
||||||
|
ucoach.save()
|
||||||
|
|
||||||
|
self.ucoach = {
|
||||||
|
'user': ucoach,
|
||||||
|
'password': ucoachpassword,
|
||||||
|
'username': ucoach.username,
|
||||||
|
'workouts': ucoach_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
uplan = UserFactory(username='planuser')
|
||||||
|
rplan = Rower.objects.create(user=uplan,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='plan',clubsize=10)
|
||||||
|
|
||||||
|
uplan_workouts = WorkoutFactory.create_batch(5, user=rplan)
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
uplanpassword = faker.word()
|
||||||
|
uplan.set_password(uplanpassword)
|
||||||
|
uplan.save()
|
||||||
|
|
||||||
|
self.uplan = {
|
||||||
|
'user': uplan,
|
||||||
|
'password': uplanpassword,
|
||||||
|
'username': uplan.username,
|
||||||
|
'workouts': uplan_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
uplan2 = UserFactory(username='plan2user')
|
||||||
|
rplan2 = Rower.objects.create(user=uplan2,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='plan',clubsize=10)
|
||||||
|
|
||||||
|
uplan2_workouts = WorkoutFactory.create_batch(5, user=rplan2)
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
uplan2password = faker.word()
|
||||||
|
uplan2.set_password(uplan2password)
|
||||||
|
uplan2.save()
|
||||||
|
|
||||||
|
self.uplan2 = {
|
||||||
|
'user': uplan2,
|
||||||
|
'password': uplan2password,
|
||||||
|
'username': uplan2.username,
|
||||||
|
'workouts': uplan2_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
upro = UserFactory(username='prouser')
|
||||||
|
rpro = Rower.objects.create(user=upro,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='pro',clubsize=10)
|
||||||
|
|
||||||
|
upro_workouts = WorkoutFactory.create_batch(5, user=rpro)
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
upropassword = faker.word()
|
||||||
|
upro.set_password(upropassword)
|
||||||
|
upro.save()
|
||||||
|
|
||||||
|
self.upro = {
|
||||||
|
'user': upro,
|
||||||
|
'password': upropassword,
|
||||||
|
'username': upro.username,
|
||||||
|
'workouts': upro_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
ubasic = UserFactory(username='basicuser')
|
||||||
|
rbasic = Rower.objects.create(user=ubasic,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='basic',clubsize=10)
|
||||||
|
|
||||||
|
ubasic_workouts = WorkoutFactory.create_batch(5, user=rbasic)
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
ubasicpassword = faker.word()
|
||||||
|
ubasic.set_password(ubasicpassword)
|
||||||
|
ubasic.save()
|
||||||
|
|
||||||
|
self.ubasic = {
|
||||||
|
'user': ubasic,
|
||||||
|
'password': ubasicpassword,
|
||||||
|
'username': ubasic.username,
|
||||||
|
'workouts': ubasic_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
ustrange = UserFactory(username='strangeuser')
|
||||||
|
rstrange = Rower.objects.create(user=ustrange,
|
||||||
|
birthdate=faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,surveydone=True,gdproptindate=timezone.now(),
|
||||||
|
rowerplan='basic',clubsize=10)
|
||||||
|
|
||||||
|
ustrange_workouts = WorkoutFactory.create_batch(5, user=rstrange)
|
||||||
|
rcoach.save()
|
||||||
|
|
||||||
|
ustrangepassword = faker.word()
|
||||||
|
ustrange.set_password(ustrangepassword)
|
||||||
|
ustrange.save()
|
||||||
|
|
||||||
|
self.ustrange = {
|
||||||
|
'user': ustrange,
|
||||||
|
'password': ustrangepassword,
|
||||||
|
'username': ustrange.username,
|
||||||
|
'workouts': ustrange_workouts,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## TeamPro, TeamCoach, TeamSelfCoach
|
||||||
|
|
||||||
|
self.teampro = Team.objects.create(
|
||||||
|
name=faker.word(),
|
||||||
|
notes=faker.text(),
|
||||||
|
manager=self.upro['user'])
|
||||||
|
|
||||||
|
self.teamplan = Team.objects.create(
|
||||||
|
name=faker.word()+'2',
|
||||||
|
notes=faker.text(),
|
||||||
|
manager=self.uplan2['user'])
|
||||||
|
|
||||||
|
self.teamcoach = Team.objects.create(
|
||||||
|
name=faker.word()+'3',
|
||||||
|
notes=faker.text(),
|
||||||
|
manager=self.ucoach['user'])
|
||||||
|
|
||||||
|
self.uplan['user'].rower.team.add(self.teamcoach)
|
||||||
|
self.ubasic['user'].rower.team.add(self.teamcoach)
|
||||||
|
self.ucoach['user'].rower.team.add(self.teamcoach)
|
||||||
|
self.upro['user'].rower.team.add(self.teamcoach)
|
||||||
|
|
||||||
|
self.upro['user'].rower.team.add(self.teamplan)
|
||||||
|
self.uplan2['user'].rower.team.add(self.teamplan)
|
||||||
|
|
||||||
|
self.upro['user'].rower.team.add(self.teampro)
|
||||||
|
self.uplan['user'].rower.team.add(self.teampro)
|
||||||
|
|
||||||
|
self.uplan['user'].rower.coachinggroups.add(coachinggroup)
|
||||||
|
self.ubasic['user'].rower.coachinggroups.add(coachinggroup)
|
||||||
|
|
||||||
|
|
||||||
|
# Test access for anonymous users
|
||||||
|
@parameterized.expand(viewstotest)
|
||||||
|
@patch('rowers.c2stuff.Session', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.c2_open')
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.dataprep.read_df_sql')
|
||||||
|
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||||
|
@patch('requests.get',side_effect=mocked_requests)
|
||||||
|
@patch('requests.post',side_effect=mocked_requests)
|
||||||
|
@patch('rowers.dataprep.get_video_data',side_effect=mocked_get_video_data)
|
||||||
|
def test_permissions_anonymous(
|
||||||
|
self,view,permissions,
|
||||||
|
mock_Session,
|
||||||
|
mock_c2open,
|
||||||
|
mocked_sqlalchemy,
|
||||||
|
mocked_read_df_sql,
|
||||||
|
mocked_getsmallrowdata_db,
|
||||||
|
mock_get,
|
||||||
|
mock_post,
|
||||||
|
mocked_get_video_data,
|
||||||
|
):
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(view,'anonymous',permissions['anonymous'],permissions['is_staff'],permissions['dotest'])
|
||||||
|
print()
|
||||||
|
|
||||||
|
if permissions['anonymous'] and not permissions['is_staff'] and permissions['dotest']:
|
||||||
|
urlstotest = []
|
||||||
|
if permissions['workoutid']:
|
||||||
|
url = reverse(view,kwargs={'id':encoder.encode_hex(self.ucoach['workouts'][0].id)})
|
||||||
|
urlstotest.append(url)
|
||||||
|
else:
|
||||||
|
url = reverse(view)
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
print(view,'anonymous',urlstotest)
|
||||||
|
|
||||||
|
for url in urlstotest:
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code,permissions['anonymous_response'])
|
||||||
|
|
||||||
|
# Test access for logged in users - accessing own objects
|
||||||
|
@parameterized.expand(viewstotest)
|
||||||
|
@patch('rowers.c2stuff.Session', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.c2_open')
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.dataprep.read_df_sql')
|
||||||
|
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||||
|
@patch('requests.get',side_effect=mocked_requests)
|
||||||
|
@patch('requests.post',side_effect=mocked_requests)
|
||||||
|
@patch('rowers.dataprep.get_video_data',side_effect=mocked_get_video_data)
|
||||||
|
def test_permissions_own(
|
||||||
|
self,view,permissions,
|
||||||
|
mock_Session,
|
||||||
|
mock_c2open,
|
||||||
|
mocked_sqlalchemy,
|
||||||
|
mocked_read_df_sql,
|
||||||
|
mocked_getsmallrowdata_db,
|
||||||
|
mock_get,
|
||||||
|
mock_post,
|
||||||
|
mocked_get_video_data,
|
||||||
|
):
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(view,'own')
|
||||||
|
print()
|
||||||
|
|
||||||
|
if permissions['own'] in plans and not permissions['is_staff'] and permissions['dotest']:
|
||||||
|
urlstotest = []
|
||||||
|
falseurlstotest = []
|
||||||
|
otheruserurls = []
|
||||||
|
|
||||||
|
thisuser = self.ubasic
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = None
|
||||||
|
|
||||||
|
print(view,'own')
|
||||||
|
|
||||||
|
if permissions['own'] == 'basic':
|
||||||
|
thisuser = self.ubasic
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = None
|
||||||
|
elif permissions['own'] == 'pro':
|
||||||
|
thisuser = self.upro
|
||||||
|
notuser = self.ubasic
|
||||||
|
elif permissions['own'] == 'plan':
|
||||||
|
thisuser = self.uplan
|
||||||
|
notuser = self.upro
|
||||||
|
elif permissions['own'] == 'coach':
|
||||||
|
thisuser = self.ucoach
|
||||||
|
notuser = self.uplan
|
||||||
|
|
||||||
|
|
||||||
|
if permissions['workoutid']:
|
||||||
|
workouts = thisuser['workouts']
|
||||||
|
url = reverse(view,kwargs={'id':encoder.encode_hex(workouts[0].id)})
|
||||||
|
urlstotest.append(url)
|
||||||
|
if notuser:
|
||||||
|
workouts = notuser['workouts']
|
||||||
|
url = reverse(view,kwargs={'id':encoder.encode_hex(workouts[0].id)})
|
||||||
|
falseurlstotest.append(url)
|
||||||
|
elif permissions['userid']:
|
||||||
|
url = reverse(view,kwargs={'userid':thisuser['user'].id})
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
url = reverse(view,kwargs={'userid':self.ustrange['user'].id})
|
||||||
|
otheruserurls.append(url)
|
||||||
|
else:
|
||||||
|
url = reverse(view)
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
print(view,'own',urlstotest,falseurlstotest,otheruserurls)
|
||||||
|
|
||||||
|
# test logged in as user who has permissions
|
||||||
|
for url in urlstotest:
|
||||||
|
login = self.c.login(username = thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code, permissions['own_response'])
|
||||||
|
|
||||||
|
# test logged as user with no permissions (e.g. too low plan)
|
||||||
|
for url in falseurlstotest:
|
||||||
|
login = self.c.login(username = notuser['username'],password = notuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code, permissions['own_nonperm'])
|
||||||
|
|
||||||
|
# test as user with permissions, accessing object of non-related user
|
||||||
|
for url in otheruserurls:
|
||||||
|
login = self.c.login(username=thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code,403)
|
||||||
|
|
||||||
|
# Test access for logged in users - accessing team member objects
|
||||||
|
@parameterized.expand(viewstotest)
|
||||||
|
@patch('rowers.c2stuff.Session', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.c2_open')
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.dataprep.read_df_sql')
|
||||||
|
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||||
|
@patch('requests.get',side_effect=mocked_requests)
|
||||||
|
@patch('requests.post',side_effect=mocked_requests)
|
||||||
|
@patch('rowers.dataprep.get_video_data',side_effect=mocked_get_video_data)
|
||||||
|
def test_permissions_member(
|
||||||
|
self,view,permissions,
|
||||||
|
mock_Session,
|
||||||
|
mock_c2open,
|
||||||
|
mocked_sqlalchemy,
|
||||||
|
mocked_read_df_sql,
|
||||||
|
mocked_getsmallrowdata_db,
|
||||||
|
mock_get,
|
||||||
|
mock_post,
|
||||||
|
mocked_get_video_data,
|
||||||
|
):
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(view,'member')
|
||||||
|
print()
|
||||||
|
|
||||||
|
if permissions['member'] in plans and permissions['is_staff'] is False and permissions['dotest']:
|
||||||
|
urlstotest = []
|
||||||
|
falseurlstotest = []
|
||||||
|
otheruserurls = []
|
||||||
|
|
||||||
|
thisuser = self.ubasic
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = None
|
||||||
|
|
||||||
|
print(view,'member')
|
||||||
|
|
||||||
|
if permissions['member'] == 'basic':
|
||||||
|
thisuser = self.ubasic
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = None
|
||||||
|
elif permissions['member'] == 'pro':
|
||||||
|
thisuser = self.upro
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = self.ubasic
|
||||||
|
elif permissions['member'] == 'plan':
|
||||||
|
thisuser = self.uplan
|
||||||
|
memberuser = self.ubasic
|
||||||
|
notuser = self.upro
|
||||||
|
elif permissions['member'] == 'coach':
|
||||||
|
thisuser = self.ucoach
|
||||||
|
memberuser = self.uplan
|
||||||
|
notuser = self.uplan
|
||||||
|
|
||||||
|
|
||||||
|
if permissions['workoutid']:
|
||||||
|
workouts = memberuser['workouts']
|
||||||
|
url = reverse(view,kwargs={'id':encoder.encode_hex(workouts[0].id)})
|
||||||
|
urlstotest.append(url)
|
||||||
|
if notuser:
|
||||||
|
falseurlstotest.append(url)
|
||||||
|
elif permissions['userid']:
|
||||||
|
url = reverse(view,kwargs={'userid':memberuser['user'].id})
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
url = reverse(view,kwargs={'userid':self.ustrange['user'].id})
|
||||||
|
otheruserurls.append(url)
|
||||||
|
else:
|
||||||
|
url = reverse(view)
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
print('member',urlstotest,falseurlstotest,otheruserurls)
|
||||||
|
|
||||||
|
# test logged in as user who has permissions
|
||||||
|
for url in urlstotest:
|
||||||
|
login = self.c.login(username = thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code, permissions['member_response'])
|
||||||
|
|
||||||
|
# test logged as user with no permissions (e.g. too low plan)
|
||||||
|
for url in falseurlstotest:
|
||||||
|
login = self.c.login(username = notuser['username'],password = notuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code, permissions['member_nonperm'])
|
||||||
|
|
||||||
|
# test as user with permissions, accessing object of non-related user
|
||||||
|
for url in otheruserurls:
|
||||||
|
login = self.c.login(username=thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code,403)
|
||||||
|
|
||||||
|
# Test access for logged in users - accessing coachee
|
||||||
|
@parameterized.expand(viewstotest)
|
||||||
|
@patch('rowers.c2stuff.Session', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.c2_open')
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.dataprep.read_df_sql')
|
||||||
|
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||||
|
@patch('requests.get',side_effect=mocked_requests)
|
||||||
|
@patch('requests.post',side_effect=mocked_requests)
|
||||||
|
@patch('rowers.dataprep.get_video_data',side_effect=mocked_get_video_data)
|
||||||
|
def test_permissions_coachee(
|
||||||
|
self,view,permissions,
|
||||||
|
mock_Session,
|
||||||
|
mock_c2open,
|
||||||
|
mocked_sqlalchemy,
|
||||||
|
mocked_read_df_sql,
|
||||||
|
mocked_getsmallrowdata_db,
|
||||||
|
mock_get,
|
||||||
|
mock_post,
|
||||||
|
mocked_get_video_data,
|
||||||
|
):
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(view,'coachee')
|
||||||
|
print()
|
||||||
|
|
||||||
|
if permissions['coachee'] in plans and not permissions['is_staff'] and permissions['dotest']:
|
||||||
|
urlstotest = []
|
||||||
|
falseurlstotest = []
|
||||||
|
otheruserurls = []
|
||||||
|
|
||||||
|
thisuser = self.ucoach
|
||||||
|
coacheeuser = self.ubasic
|
||||||
|
notuser = self.uplan
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if permissions['workoutid']:
|
||||||
|
workouts = coacheeuser['workouts']
|
||||||
|
url = reverse(view,kwargs={'id':encoder.encode_hex(workouts[0].id)})
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
elif permissions['userid']:
|
||||||
|
url = reverse(view,kwargs={'userid':coacheeuser['user'].id})
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
url = reverse(view,kwargs={'userid':self.ustrange['user'].id})
|
||||||
|
otheruserurls.append(url)
|
||||||
|
else:
|
||||||
|
url = reverse(view)
|
||||||
|
urlstotest.append(url)
|
||||||
|
|
||||||
|
print('coachee',urlstotest,falseurlstotest,otheruserurls)
|
||||||
|
|
||||||
|
# test logged in as user who has permissions
|
||||||
|
for url in urlstotest:
|
||||||
|
login = self.c.login(username = thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code, permissions['coachee_response'])
|
||||||
|
|
||||||
|
# test as user with permissions, accessing object of non-related user
|
||||||
|
for url in otheruserurls:
|
||||||
|
login = self.c.login(username=thisuser['username'],password = thisuser['password'])
|
||||||
|
result = self.c.get(url)
|
||||||
|
self.assertEqual(result.status_code,403)
|
||||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||||||
#from __future__ import print_function
|
#from __future__ import print_function
|
||||||
from .statements import *
|
from .statements import *
|
||||||
nu = datetime.datetime.now()
|
nu = datetime.datetime.now()
|
||||||
|
|
||||||
from rowers.utils import allmonths,allsundays
|
from rowers.utils import allmonths,allsundays
|
||||||
|
|
||||||
import rowers.plannedsessions as plannedsessions
|
import rowers.plannedsessions as plannedsessions
|
||||||
@@ -125,7 +126,6 @@ class TrainingPlanTest(TestCase):
|
|||||||
|
|
||||||
for url in urls:
|
for url in urls:
|
||||||
if 'planbyweeks' in url and not tested:
|
if 'planbyweeks' in url and not tested:
|
||||||
print(url)
|
|
||||||
response = self.c.get(url,follow=True)
|
response = self.c.get(url,follow=True)
|
||||||
self.assertEqual(response.status_code,200)
|
self.assertEqual(response.status_code,200)
|
||||||
tested = True
|
tested = True
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ from __future__ import unicode_literals
|
|||||||
from .statements import *
|
from .statements import *
|
||||||
nu = datetime.datetime.now()
|
nu = datetime.datetime.now()
|
||||||
|
|
||||||
from rowers.views import hasplannedsessions,iscoachmember,ispromember
|
from rowers.views import isplanmember,iscoachmember,ispromember
|
||||||
|
from rowers.rower_rules import *
|
||||||
|
|
||||||
class TrialsTest(TestCase):
|
class TrialsTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -33,34 +34,35 @@ class TrialsTest(TestCase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def test_basictrial(self):
|
def test_basictrial(self):
|
||||||
self.assertEqual(hasplannedsessions(self.u),False)
|
self.assertEqual(isplanmember(self.u),False)
|
||||||
self.assertEqual(iscoachmember(self.u),False)
|
self.assertEqual(iscoachmember(self.u),False)
|
||||||
self.assertEqual(ispromember(self.u),False)
|
self.assertEqual(ispromember(self.u),False)
|
||||||
|
|
||||||
self.r.protrialexpires = (nu+datetime.timedelta(days=10)).date()
|
self.r.protrialexpires = (nu+datetime.timedelta(days=10)).date()
|
||||||
self.r.save()
|
self.r.save()
|
||||||
|
|
||||||
self.assertEqual(hasplannedsessions(self.u),False)
|
self.assertEqual(isplanmember(self.u),False)
|
||||||
self.assertEqual(iscoachmember(self.u),False)
|
self.assertEqual(iscoachmember(self.u),False)
|
||||||
self.assertEqual(ispromember(self.u),True)
|
self.assertEqual(ispromember(self.u),True)
|
||||||
|
|
||||||
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
|
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
|
||||||
self.r.save()
|
self.r.save()
|
||||||
|
|
||||||
self.assertEqual(hasplannedsessions(self.u),True)
|
self.assertEqual(isplanmember(self.u),True)
|
||||||
self.assertEqual(iscoachmember(self.u),False)
|
self.assertEqual(iscoachmember(self.u),False)
|
||||||
self.assertEqual(ispromember(self.u),True)
|
self.assertEqual(ispromember(self.u),True)
|
||||||
|
|
||||||
def test_protrial(self):
|
def test_protrial(self):
|
||||||
self.r.rowerplan = 'pro'
|
self.r.rowerplan = 'pro'
|
||||||
self.r.save()
|
self.r.save()
|
||||||
self.assertEqual(hasplannedsessions(self.u),False)
|
self.assertEqual(isplanmember(self.u),False)
|
||||||
self.assertEqual(iscoachmember(self.u),False)
|
self.assertEqual(iscoachmember(self.u),False)
|
||||||
self.assertEqual(ispromember(self.u),True)
|
self.assertEqual(ispromember(self.u),True)
|
||||||
|
|
||||||
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
|
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
|
||||||
self.r.save()
|
self.r.save()
|
||||||
|
|
||||||
self.assertEqual(hasplannedsessions(self.u),True)
|
self.assertEqual(is_plantrial(self.u),True)
|
||||||
|
self.assertEqual(isplanmember(self.u),True)
|
||||||
self.assertEqual(iscoachmember(self.u),False)
|
self.assertEqual(iscoachmember(self.u),False)
|
||||||
self.assertEqual(ispromember(self.u),True)
|
self.assertEqual(ispromember(self.u),True)
|
||||||
|
|||||||
@@ -209,7 +209,6 @@ class URLTests(TestCase):
|
|||||||
'/rowers/workout/'+encoded1+'/editintervals/',
|
'/rowers/workout/'+encoded1+'/editintervals/',
|
||||||
'/rowers/workout/'+encoded1+'/flexchart/',
|
'/rowers/workout/'+encoded1+'/flexchart/',
|
||||||
'/rowers/workout/'+encoded1+'/forcecurve/',
|
'/rowers/workout/'+encoded1+'/forcecurve/',
|
||||||
'/rowers/workout/'+encoded1+'/get-testscript/',
|
|
||||||
'/rowers/workout/'+encoded1+'/get-thumbnails/',
|
'/rowers/workout/'+encoded1+'/get-thumbnails/',
|
||||||
'/rowers/workout/'+encoded1+'/histo/',
|
'/rowers/workout/'+encoded1+'/histo/',
|
||||||
'/rowers/workout/'+encoded1+'/image/',
|
'/rowers/workout/'+encoded1+'/image/',
|
||||||
|
|||||||
@@ -0,0 +1,310 @@
|
|||||||
|
,id,view,function,anonymous,anonymous_response,own,own_response,own_nonperm,member,member_response,member_nonperm,coachee,coachee_response,coachee_nonperm,is_staff,userid,workoutid,dotest,realtest,kwargs
|
||||||
|
0,0,workouts_summaries_email_view,sends summary excel with workouts list and links to data to user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
1,1,rower_update_empower_view,updates old Empower Oarlock files (corrects Power bug),TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
2,2,agegroupcpview,needs age,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
3,4,ajax_agegrouprecords,gets age group records from C2 ,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
4,5,fitness_metric_view,updates a person's fitness metric,TRUE,302,basic,302,302,FALSE,403,302,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
5,6,agegrouprecordview,shows ergo age group records,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
6,7,workouts_view,workouts list,TRUE,302,basic,200,302,basic,200,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
7,8,virtualevents_view,virtual races list,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
8,9,virtualevent_create_view,create virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
9,10,indoorvirtualevent_create_view,create indoor virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
10,11,virtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
11,12,indoorvirtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
12,13,virtualevent_view,view virtual race,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
13,14,virtualevent_ranking_view,view ranking,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
14,15,virtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
15,16,indoorvirtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
16,17,virtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
17,18,indoorvirtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
18,19,virtualevent_addboat_view,add a new boat type,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
19,20,virtualevent_withdraw_view,withdraw,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
20,21,virtualevent_submit_result_view,submit a result,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
21,22,virtualevent_disqualify_view,disqualify a racer,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
22,24,courses_view,see race courses,TRUE,200,FALSE,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
23,25,course_upload_view,upload a new course,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
24,26,addmanual_view,upload a manual workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
25,27,team_comparison_select,compare with a team member workout,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,TRUE,TRUE,TRUE,TRUE,
|
||||||
|
26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
27,29,workouts_join_select,select workouts to join,TRUE,404,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
28,30,user_boxplot_select,select boxplots,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
29,31,analysis_new,analysis front page,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
30,32,user_multiflex_select,select multiflex data,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
31,33,session_jobs_view,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
32,34,session_jobs_status,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
33,35,kill_async_job,kill job,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
34,36,post_progress,post progress,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
35,37,graphs_view,view charts,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
36,38,fitnessmetric_view,view fitness metric,TRUE,302,plan,200,302,plan,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
37,39,rankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
38,40,rankings_view2,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
39,41,otwrankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
40,42,oterankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
41,43,cum_flex,flex all chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
42,44,analysis_view_data,redirects to analysis direct,TRUE,302,pro,302,302,pro,302,302,coach,302,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
43,47,cum_flex_data,flex all chart data (json),TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
44,48,histo,histogram view,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
45,49,histo_data,histogram data,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
46,51,cumstats,cumulative statistics,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
47,53,graph_show_view,show a chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
48,54,GraphDelete,delete a chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
49,55,get_thumbnails,get thumbnails,TRUE,403,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
50,56,otw_use_impeller,switch to impeller data,TRUE,403,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
51,57,otw_use_gps,switch to GPS data,TRUE,403,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
52,58,workout_toggle_ranking,toggle ranking,TRUE,302,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
53,59,team_workout_upload_view,upload workout for team member,TRUE,302,coach,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
54,60,workout_upload_view,upload a workout,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
55,61,workout_histo_view,histogram ,TRUE,302,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
56,62,workout_forcecurve_view,force curve,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
57,63,workout_unsubscribe_view,unsubscribe from comments,TRUE,302,basic,200,302,basic,200,302,basic,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
58,64,workout_comment_view,comment on workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
59,65,workout_tcxemail_view,download TCX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
60,66,workout_gpxemail_view,download GPX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
61,67,workout_csvemail_view,download CSV file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
62,68,workout_csvtoadmin_view,send CSV to admin,TRUE,403,basic,200,200,basic,200,200,coach,200,200,TRUE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
63,69,workout_edit_view,Edit Workout,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
64,70,workout_map_view,View workout Map,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
65,71,workout_update_cp_view,Update CP data based on new workout,TRUE,403,pro,302,302,pro,403,403,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
66,72,instroke_chart,View In-Stroke data chart,TRUE,302,pro,302,302,pro,403,403,coach,302,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
67,73,instroke_view,Create in stroke chart,TRUE,403,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
68,74,workout_stats_view,View Workout Stats,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
69,75,workout_data_view,shows the detailed data for a workout,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
70,76,workout_otwsetpower_view,set weight and start offline OTW power calculations,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
71,77,workout_otwpowerplot_view,generates OTW power chart,TRUE,200,basic,200,200,basic,200,200,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
72,78,workout_wind_view,set wind,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
73,79,workout_uploadimage_view,upload image,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
74,80,virtualevent_compare_view,compare workouts from a virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
75,81,virtualevent_uploadimage_view,upload image to virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
76,82,virtualevent_setlogo_view,set logo of virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
77,83,logo_delete_view,delete logo,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
78,84,workout_downloadwind_view,download Wind,TRUE,403,pro,302,302,pro,403,403,coach,302,403,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
79,85,workout_downloadmetar_view,download METAR,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
80,86,workout_stream_view,edit stream (redirects as no data in test suite),TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
81,87,workout_summary_edit_view,edit workout summary,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
82,88,workout_summary_restore_view,restore workout summary,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
83,89,workout_split_view,split workout,TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
84,90,workout_view,view workout ,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
85,91,workout_video_create_view,add video ,TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
86,92,VideoDelete,delete video,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
87,93,workout_video_view_mini,minimal view,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
88,94,workout_video_view,"video view (not tested, no video in test suite)",TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
89,95,list_videos,list my videos,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
90,96,video_selectworkout,select workout to create video,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
91,98,workout_fusion_view,needs to workouts,TRUE,403,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
92,99,workout_fusion_list,list workouts to fuse with,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
94,103,workout_add_chart_view,add chart,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
95,112,WorkoutDelete,delete workout,TRUE,403,basic,200,302,basic,403,403,coach,403,403,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
96,113,workout_smoothenpace_view,smoothen pace,TRUE,403,pro,302,302,pro,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
97,114,workout_undo_smoothenpace_view,unsmoothen pace,TRUE,403,pro,302,302,pro,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
98,115,workout_c2import_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
99,120,workout_stravaimport_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
100,122,workout_getc2workout_all,gets all C2 workouts (now redirects due to NoTokenError,TRUE,302,basic,302,302,FALSE,302,302,FALSE,302,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
101,124,workout_getimportview,imports a workout from third party,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
102,125,workout_getstravaworkout_all,gets all C2 workouts (now redirects due to NoTokenError,TRUE,302,basic,302,302,FALSE,302,302,FALSE,302,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
103,126,workout_getstravaworkout_next,gets all strava workouts,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
104,127,workout_sporttracksimport_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
105,129,workout_getsporttracksworkout_all,gets all C2 workouts (now redirects due to NoTokenError,TRUE,302,basic,302,302,FALSE,302,302,FALSE,302,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
106,130,workout_polarimport_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
107,132,workout_runkeeperimport_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
108,134,workout_underarmourimport_view,list workouts to be imported (test stops at notokenerror),TRUE,302,basic,302,302,basic,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
109,135,workout_c2_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
110,136,workout_strava_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
111,137,workout_recalcsummary_view,recalculates workout summary,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
112,138,workout_sporttracks_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
113,139,workout_runkeeper_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
114,140,workout_underarmour_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
115,141,workout_tp_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
116,142,multi_compare_view,compare workouts ,TRUE,302,basic,302,403,basic,302,403,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
117,145,alerts_view,view alerts,TRUE,302,basic,200,403,basic,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
118,147,AlertDelete,delete alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
119,148,alert_edit_view,edit alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
120,150,alert_create_view,create alert,TRUE,302,pro,200,403,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
121,152,alert_report_view,view alerts report,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
122,155,boxplot_view,View boxplot,TRUE,302,pro,302,403,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
123,157,boxplot_view_data,data for boxplot,TRUE,302,pro,200,403,pro,200,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
124,158,multiflex_view,view multiflex,TRUE,302,pro,302,403,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
125,160,multiflex_data,data for multiflex,TRUE,302,pro,200,403,pro,200,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
126,161,deactivate_user,deactivate a user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
127,162,remove_user,remove a user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
128,163,user_gdpr_confirm,GDPR confirmation,TRUE,302,basic,302,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
129,165,user_gdpr_optin,GDPR optin,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
130,167,rower_teams_view,view team,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
131,168,rower_calcdps_view,calculates distance per stroke,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
132,169,rower_exportsettings_view,Export settings,TRUE,302,basic,200,302,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
133,171,team_view,Team view,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
134,172,team_members_stats_view,Stats for team members,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
135,173,team_edit_view,View Team,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
136,174,team_leaveconfirm_view,Leave Team,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
137,175,team_leave_view,Leave Team,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
138,176,team_deleteconfirm_view,Delete Team,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
139,177,team_requestmembership_view,Request team membership,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
140,178,reject_revoke_coach_request,Reject request,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
141,179,coach_drop_athlete_confirm_view,Drop athlete,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
142,180,coach_drop_athlete_view,Drop athlete,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
143,181,athlete_drop_coach_confirm_view,Drop athlete,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
144,182,athlete_drop_coach_view,Drop coach,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
145,184,reject_revoke_coach_offer,Reject offer,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
146,186,request_coaching_view,Request coaching,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
147,187,offer_coaching_view,Offer Coaching,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE,
|
||||||
|
148,188,coach_accept_coachrequest_view,Accept Coach request,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
149,189,rower_accept_coachoffer_view,Accept Coach offer,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
150,190,team_delete_view,Delete Team,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
151,191,team_create_view,Create Team,TRUE,302,pro,302,302,FALSE,200,200,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
152,192,manager_member_drop_view,Drop member,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
153,193,invitation_reject_view,Reject invitation,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
154,194,invitation_revoke_view,redirects when no invitations,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
155,195,rower_invitations_view,See Invitations,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
156,196,raise_500,Test 500 error,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
157,198,request_revoke_view,redirects when no invitations,TRUE,302,basic,302,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
158,199,request_reject_view,rejects request,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
159,200,manager_requests_view,views requests,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
160,202,rower_edit_view,edit rower preferences,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
161,204,rower_prefs_view,edit more preferences,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
162,205,transactions_view,view transactions (staff only),TRUE,302,basic,200,302,basic,200,302,coach,200,302,TRUE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
163,208,rower_c2_authorize,redirects to C2 auth page,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
164,209,rower_polar_authorize,redirects to Polar,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
165,210,rower_revokeapp_view,revoke app,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
166,211,rower_strava_authorize,authorize on strava,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
167,212,rower_sporttracks_authorize,authorize on sporttracks,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
168,213,rower_underarmour_authorize,authorize on UA,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
169,214,rower_tp_authorize,authorize on TP,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
170,215,rower_runkeeper_authorize,authorize on RK,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
171,216,rower_sporttracks_token_refresh,refresh token,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
172,217,rower_underarmour_token_refresh,refresh token,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
173,218,rower_tp_token_refresh,refresh token,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
174,219,rower_c2_token_refresh,refresh token,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
175,220,rower_favoritecharts_view,See favorite charts,TRUE,302,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
176,222,workout_workflow_config2_view,configure workflow,TRUE,302,basic,200,302,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,FALSE,FALSE,
|
||||||
|
177,224,workflow_default_view,resets workflow to default,TRUE,302,basic,302,302,FALSE,403,403,FALSE,302,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
178,225,sendmail,feedback form,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
180,232,laboratory_view,lab,TRUE,302,basic,200,302,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
181,233,errormessage_view,not used,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
182,237,payment_confirm_view,confirm payment,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
183,238,upgrade_confirm_view,confirm upgrade,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
184,240,downgrade_confirm_view,confirm downgrade,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
185,241,billing_view,confirm billing,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
186,242,upgrade_view,confirm upgrade,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
187,243,downgrade_view,confirm downgrade,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
188,244,payment_completed_view,payment completed,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
189,245,downgrade_completed_view,downgrade completed,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
190,246,paidplans_view,paid plans,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
191,247,plan_stop_view,stop plan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
192,248,plan_tobasic_view,reset to basic,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
193,249,checkouts_view,checkout,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
194,250,upgrade_checkouts_view,upgrade checkout,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
195,251,downgrade_checkouts_view,downgrade checkout,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
196,252,planrequired_view,a plan is required,TRUE,302,basic,302,302,basic,302,302,coach,302,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
197,253,start_trial_view,payments,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
198,254,start_plantrial_view,paid plans,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
199,256,rower_register_view,register rower,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
200,257,freecoach_register_view,register coach,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
201,259,workout_workflow_view,workout workflow vieq,TRUE,302,basic,200,200,basic,200,200,coach,200,200,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
202,260,workout_flexchart3_view,flex chart,TRUE,302,basic,200,403,basic,200,200,coach,200,200,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||||
|
203,264,rower_process_testcallback,test callback,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
204,265,rower_create_trainingplan,create training plan,TRUE,302,plan,200,302,FALSE,403,403,FALSE,200,403,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
205,267,TrainingPlanDelete,delete training plan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
206,268,MicroCycleDelete,delete training plan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
207,269,MesoCycleDelete,delete training plan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
208,270,MacroCycleDelete,delete training plan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
209,271,rower_trainingplan_view,see training plan,TRUE,200,plan,200,302,plan,403,403,coach,200,403,FALSE,TRUE,FALSE,FALSE,FALSE,
|
||||||
|
210,279,rower_trainingplan_execution_view,see training plan execution,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
211,281,TrainingMacroCycleUpdate,update macro cycle,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
212,282,TrainingMesoCycleUpdate,update cycle,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
213,283,planmacrocyclebymonth,update cycle,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
214,285,planmesocyclebyweek,plan meso by week,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
215,287,TrainingMicroCycleUpdate,update cycle,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
216,288,rower_delete_trainingtarget,delete training target,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
217,289,TrainingPlanUpdate,update trainingplan,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
218,290,TrainingTargetUpdate,update training target,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
219,291,strokedataform,test strokedata,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
220,292,plannedsession_teamcreate_view,create planned session for team,TRUE,302,coach,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||||
|
221,296,plannedsession_teamedit_view,edit planned sesssion,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
222,298,plannedsession_create_view,create planned session ,TRUE,302,plan,200,302,FALSE,200,302,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
223,300,plannedsession_multiclone_view,clone multiple planned sessions,TRUE,302,plan,200,302,plan,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
224,302,plannedsession_multicreate_view,create multiple planned sessions,TRUE,302,plan,200,302,plan,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
225,305,plannedsession_edit_view,edit planned sesssion,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
226,306,plannedsession_totemplate_view,planned session to template,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
227,307,plannedsession_compare_view,compare workouts from planned session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
228,310,plannedsession_clone_view,clone planned session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
229,311,plannedsession_teamclone_view,clone team planned session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
230,313,plannedsession_detach_view,remove workout from session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
231,315,plannedsession_view,view session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
232,317,PlannedSessionDelete,delete session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
233,319,plannedsessions_manage_view,manage planned sesions,TRUE,302,plan,200,302,plan,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
234,323,plannedsessions_coach_view,team view,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
235,325,plannedsessions_coach_icsemail_view,team view,TRUE,302,coach,302,403,coach,302,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
236,326,plannedsessions_print_view,print view,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
237,327,plannedsession_comment_view,comment on planned session,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
238,330,plannedsessions_icsemail_view,send ICS email,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE,
|
||||||
|
239,332,plannedsessions_view,View planned sessions,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||||
|
240,334,course_edit_view,Edit course,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
241,335,course_delete_view,Delete course,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
242,336,course_kmldownload_view,Kmldownload course,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
243,337,course_replace_view,Replace course,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
244,338,course_view, view,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
245,339,course_map_view,Map course,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
246,341,c2listdebug_view,Debug view,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
247,343,rower_process_callback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
248,344,rower_process_stravacallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
249,345,rower_process_sporttrackscallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
250,346,rower_process_underarmourcallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
251,347,rower_process_polarcallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
252,348,rower_process_runkeepercallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
253,349,rower_process_tpcallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
254,350,rower_process_twittercallback,Tested in specific test suite,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
255,351,set_language,Set language,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
256,352,SetOffsetView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
257,353,stats,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
258,354,stats_json,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
259,355,jobs,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
260,356,workers,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
261,357,worker_details,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
262,358,finished_jobs,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
263,359,started_jobs,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
264,360,deferred_jobs,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
265,361,clear_queue,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
266,362,requeue_all,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
267,363,job_detail,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
268,364,delete_job,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
269,365,actions,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
270,366,requeue_job_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
271,367,enqueue_job,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
272,368,JavaScriptCatalog,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
273,369,serve,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
274,371,LoginView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
275,372,LogoutView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
276,373,PasswordChangeView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
277,374,PasswordChangeDoneView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
278,375,PasswordResetView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
279,376,PasswordResetDoneView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
280,377,PasswordResetConfirmView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
281,378,PasswordResetCompleteView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
282,386,index,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
283,387,login,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
284,388,logout,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
285,389,password_change,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
286,390,password_change_done,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
287,391,i18n_javascript,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
288,392,shortcut,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
289,393,changelist_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
290,394,add_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
291,395,autocomplete_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
292,396,history_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
293,397,delete_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
294,398,change_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
295,399,RedirectView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
296,568,app_index,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
297,571,landingview,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
298,573,get_blog_posts,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
299,576,AuthorizationView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
300,577,TokenView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
301,578,WorkoutViewSet,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
302,582,RowerViewSet,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
303,586,FavoriteChartViewSet,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
304,590,APIRootView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
305,592,SwaggerSchemaView,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
306,595,strokedatajson,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
307,596,error500_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
308,603,failed_queue_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
309,604,failed_queue_empty,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||||
|
310,605,failed_job_view,Other Apps views,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||||
|
+3
-1
@@ -42,6 +42,8 @@ oauth_data = {
|
|||||||
'scope':'write',
|
'scope':'write',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
|
||||||
|
|
||||||
# Checks if user has UnderArmour token, renews them if they are expired
|
# Checks if user has UnderArmour token, renews them if they are expired
|
||||||
def tp_open(user):
|
def tp_open(user):
|
||||||
@@ -171,7 +173,7 @@ def workout_tp_upload(user,w):
|
|||||||
# need some code if token doesn't refresh
|
# need some code if token doesn't refresh
|
||||||
|
|
||||||
|
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
tcxfile = createtpworkoutdata(w)
|
tcxfile = createtpworkoutdata(w)
|
||||||
if tcxfile:
|
if tcxfile:
|
||||||
res,reason,status_code,headers = uploadactivity(
|
res,reason,status_code,headers = uploadactivity(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from django.test import TestCase, Client,override_settings
|
|||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from .views import checkworkoutuser,c2_open
|
from .views import c2_open
|
||||||
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
|
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
|
||||||
from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
|
from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
|
||||||
import rowers.plots as plots
|
import rowers.plots as plots
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import numpy
|
|||||||
|
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
from rowers.mytypes import otwtypes
|
from rowers.mytypes import otwtypes
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
UNDERARMOUR_CLIENT_KEY,
|
UNDERARMOUR_CLIENT_KEY,
|
||||||
@@ -331,7 +332,7 @@ def workout_ua_upload(user,w):
|
|||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
|
|
||||||
if (checkworkoutuser(user,w)):
|
if (is_workout_user(user,w)):
|
||||||
data = createunderarmourworkoutdata(w)
|
data = createunderarmourworkoutdata(w)
|
||||||
# return HttpResponse(json.dumps(data))
|
# return HttpResponse(json.dumps(data))
|
||||||
if not data:
|
if not data:
|
||||||
|
|||||||
+10
-8
@@ -14,6 +14,8 @@ from rowers.tasks import (
|
|||||||
|
|
||||||
from rowers.models import GraphImage
|
from rowers.models import GraphImage
|
||||||
|
|
||||||
|
from rowers.rower_rules import ispromember
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -472,6 +474,8 @@ import rowers.runkeeperstuff as runkeeperstuff
|
|||||||
import rowers.underarmourstuff as underarmourstuff
|
import rowers.underarmourstuff as underarmourstuff
|
||||||
import rowers.tpstuff as tpstuff
|
import rowers.tpstuff as tpstuff
|
||||||
|
|
||||||
|
from rowers.rower_rules import is_promember
|
||||||
|
|
||||||
def set_workouttype(w,options):
|
def set_workouttype(w,options):
|
||||||
try:
|
try:
|
||||||
w.workouttype = options['workouttype']
|
w.workouttype = options['workouttype']
|
||||||
@@ -500,8 +504,6 @@ def make_private(w,options):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
from rowers.utils import isprorower
|
|
||||||
|
|
||||||
def do_sync(w,options):
|
def do_sync(w,options):
|
||||||
try:
|
try:
|
||||||
if options['stravaid'] != 0:
|
if options['stravaid'] != 0:
|
||||||
@@ -511,7 +513,7 @@ def do_sync(w,options):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if ('upload_to_C2' in options and options['upload_to_C2']) or (w.user.c2_auto_export and isprorower(w.user)):
|
if ('upload_to_C2' in options and options['upload_to_C2']) or (w.user.c2_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_C2' in options and not options['upload_to_C2']):
|
if ('upload_to_C2' in options and not options['upload_to_C2']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -521,7 +523,7 @@ def do_sync(w,options):
|
|||||||
id = 0
|
id = 0
|
||||||
message = "Something went wrong with the Concept2 sync"
|
message = "Something went wrong with the Concept2 sync"
|
||||||
|
|
||||||
if ('upload_to_Strava' in options and options['upload_to_Strava']) or (w.user.strava_auto_export and isprorower(w.user)):
|
if ('upload_to_Strava' in options and options['upload_to_Strava']) or (w.user.strava_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_Strava' in options and not options['upload_to_Strava']):
|
if ('upload_to_Strava' in options and not options['upload_to_Strava']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -534,7 +536,7 @@ def do_sync(w,options):
|
|||||||
message = "Please connect to Strava first"
|
message = "Please connect to Strava first"
|
||||||
|
|
||||||
|
|
||||||
if ('upload_to_SportTracks' in options and options['upload_to_SportTracks']) or (w.user.sporttracks_auto_export and isprorower(w.user)):
|
if ('upload_to_SportTracks' in options and options['upload_to_SportTracks']) or (w.user.sporttracks_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_SportTracks' in options and not options['upload_to_SportTracks']):
|
if ('upload_to_SportTracks' in options and not options['upload_to_SportTracks']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -548,7 +550,7 @@ def do_sync(w,options):
|
|||||||
id = 0
|
id = 0
|
||||||
|
|
||||||
|
|
||||||
if ('upload_to_RunKeeper' in options and options['upload_to_RunKeeper']) or (w.user.runkeeper_auto_export and isprorower(w.user)):
|
if ('upload_to_RunKeeper' in options and options['upload_to_RunKeeper']) or (w.user.runkeeper_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_RunKeeper' in options and not options['upload_to_RunKeeper']):
|
if ('upload_to_RunKeeper' in options and not options['upload_to_RunKeeper']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -561,7 +563,7 @@ def do_sync(w,options):
|
|||||||
message = "Please connect to Runkeeper first"
|
message = "Please connect to Runkeeper first"
|
||||||
id = 0
|
id = 0
|
||||||
|
|
||||||
if ('upload_to_MapMyFitness' in options and options['upload_to_MapMyFitness']) or (w.user.mapmyfitness_auto_export and isprorower(w.user)):
|
if ('upload_to_MapMyFitness' in options and options['upload_to_MapMyFitness']) or (w.user.mapmyfitness_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_MapMyFitness' in options and not options['upload_to_MapMyFitness']):
|
if ('upload_to_MapMyFitness' in options and not options['upload_to_MapMyFitness']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -574,7 +576,7 @@ def do_sync(w,options):
|
|||||||
id = 0
|
id = 0
|
||||||
|
|
||||||
|
|
||||||
if ('upload_to_TrainingPeaks' in options and options['upload_to_TrainingPeaks']) or (w.user.trainingpeaks_auto_export and isprorower(w.user)):
|
if ('upload_to_TrainingPeaks' in options and options['upload_to_TrainingPeaks']) or (w.user.trainingpeaks_auto_export and ispromember(w.user)):
|
||||||
if ('upload_to_TrainingPeaks' in options and not options['upload_to_TrainingPeaks']):
|
if ('upload_to_TrainingPeaks' in options and not options['upload_to_TrainingPeaks']):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|||||||
+30
-25
@@ -153,6 +153,8 @@ urlpatterns = [
|
|||||||
views.agegrouprecordview,name='agegrouprecordview'),
|
views.agegrouprecordview,name='agegrouprecordview'),
|
||||||
re_path(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/$',
|
re_path(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/$',
|
||||||
views.agegrouprecordview,name='agegrouprecordview'),
|
views.agegrouprecordview,name='agegrouprecordview'),
|
||||||
|
re_path(r'^agegrouprecords/$',
|
||||||
|
views.agegrouprecordview,name='agegrouprecordview'),
|
||||||
re_path(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True},
|
re_path(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True},
|
||||||
name='workouts_view'),
|
name='workouts_view'),
|
||||||
# re_path(r'^list-workouts/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
# re_path(r'^list-workouts/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
||||||
@@ -191,7 +193,7 @@ urlpatterns = [
|
|||||||
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
||||||
re_path(r'^virtualevent/(?P<id>\d+)/submit/(?P<workoutid>\b[0-9A-Fa-f]+\b)/$',
|
re_path(r'^virtualevent/(?P<id>\d+)/submit/(?P<workoutid>\b[0-9A-Fa-f]+\b)/$',
|
||||||
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
||||||
re_path(r'^virtualevent/(?P<raceid>\d+)/disqualify/(?P<recordid>\d+)/',
|
re_path(r'^virtualevent/(?P<id>\d+)/disqualify/(?P<recordid>\d+)/',
|
||||||
views.virtualevent_disqualify_view,name='virtualevent_disqualify_view'),
|
views.virtualevent_disqualify_view,name='virtualevent_disqualify_view'),
|
||||||
re_path(r'^list-workouts/$',views.workouts_view,name='workouts_view'),
|
re_path(r'^list-workouts/$',views.workouts_view,name='workouts_view'),
|
||||||
re_path(r'^list-courses/$',views.courses_view,name='courses_view'),
|
re_path(r'^list-courses/$',views.courses_view,name='courses_view'),
|
||||||
@@ -218,6 +220,7 @@ urlpatterns = [
|
|||||||
# re_path(r'^workouts-join-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,
|
# re_path(r'^workouts-join-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,
|
||||||
# name='workouts_join_select'),
|
# name='workouts_join_select'),
|
||||||
re_path(r'^workouts-join/$',views.workouts_join_view,name='workouts_join_view'),
|
re_path(r'^workouts-join/$',views.workouts_join_view,name='workouts_join_view'),
|
||||||
|
re_path(r'^workouts-join/user/(?P<userid>\d+)$',views.workouts_join_view,name='workouts_join_view'),
|
||||||
re_path(r'^workouts-join-select/team/(?P<teamid>\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
re_path(r'^workouts-join-select/team/(?P<teamid>\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||||
# re_path(r'^workouts-join-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
# re_path(r'^workouts-join-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||||
re_path(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'),
|
re_path(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'),
|
||||||
@@ -243,26 +246,27 @@ urlpatterns = [
|
|||||||
re_path(r'^record-progress/(?P<id>.*)/$',views.post_progress),
|
re_path(r'^record-progress/(?P<id>.*)/$',views.post_progress),
|
||||||
re_path(r'^record-progress/$',views.post_progress),
|
re_path(r'^record-progress/$',views.post_progress),
|
||||||
re_path(r'^list-graphs/$',views.graphs_view,name='graphs_view'),
|
re_path(r'^list-graphs/$',views.graphs_view,name='graphs_view'),
|
||||||
|
re_path(r'^list-graphs/user/(?P<userid>\d+)/$',views.graphs_view,name='graphs_view'),
|
||||||
re_path(r'^fitness-progress/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
re_path(r'^fitness-progress/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||||
re_path(r'^fitness-progress/user/(?P<id>\d+)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
re_path(r'^fitness-progress/user/(?P<userid>\d+)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||||
re_path(r'^fitness-progress/user/(?P<id>\d+)/(?P<mode>\w+.*)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
re_path(r'^fitness-progress/user/(?P<userid>\d+)/(?P<mode>\w+.*)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||||
# re_path(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
# re_path(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
||||||
re_path(r'^ote-bests/user/(?P<theuser>\d+)/$',views.rankings_view,name='rankings_view'),
|
re_path(r'^ote-bests/user/(?P<userid>\d+)/$',views.rankings_view,name='rankings_view'),
|
||||||
# re_path(r'^ote-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
# re_path(r'^ote-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
||||||
re_path(r'^ote-bests/$',views.rankings_view,name='rankings_view'),
|
re_path(r'^ote-bests/$',views.rankings_view,name='rankings_view'),
|
||||||
re_path(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view,name='rankings_view'),
|
re_path(r'^(?P<userid>\d+)/ote-bests/$',views.rankings_view,name='rankings_view'),
|
||||||
# re_path(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
# re_path(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||||
re_path(r'^ote-bests2/user/(?P<theuser>\d+)/$',views.rankings_view2,name='rankings_view2'),
|
re_path(r'^ote-bests2/user/(?P<userid>\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||||
# re_path(r'^ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
# re_path(r'^ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||||
re_path(r'^ote-bests2/$',views.rankings_view2,name='rankings_view2'),
|
re_path(r'^ote-bests2/$',views.rankings_view2,name='rankings_view2'),
|
||||||
# re_path(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
# re_path(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||||
# re_path(r'^otw-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
# re_path(r'^otw-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||||
re_path(r'^otw-bests/user/(?P<theuser>\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
re_path(r'^otw-bests/user/(?P<userid>\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||||
re_path(r'^otw-bests/$',views.otwrankings_view,name='otwrankings_view'),
|
re_path(r'^otw-bests/$',views.otwrankings_view,name='otwrankings_view'),
|
||||||
# re_path(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
# re_path(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||||
# re_path(r'^ote-ranking/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
# re_path(r'^ote-ranking/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||||
re_path(r'^ote-ranking/$',views.oterankings_view,name='oterankings_view'),
|
re_path(r'^ote-ranking/$',views.oterankings_view,name='oterankings_view'),
|
||||||
re_path(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view,name='oterankings_view'),
|
re_path(r'^ote-ranking/user/(?P<userid>\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||||
# re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
# re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
||||||
# re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cum_flex,name='cum_flex'),
|
# re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cum_flex,name='cum_flex'),
|
||||||
re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/$',views.cum_flex,name='cum_flex'),
|
re_path(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/$',views.cum_flex,name='cum_flex'),
|
||||||
@@ -270,11 +274,11 @@ urlpatterns = [
|
|||||||
re_path(r'^flexall/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
re_path(r'^flexall/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
||||||
re_path(r'^flexall/$',views.cum_flex,name='cum_flex'),
|
re_path(r'^flexall/$',views.cum_flex,name='cum_flex'),
|
||||||
re_path(r'^flexalldata/$',views.cum_flex_data,name='cum_flex_data'),
|
re_path(r'^flexalldata/$',views.cum_flex_data,name='cum_flex_data'),
|
||||||
re_path(r'^histo/user/(?P<theuser>\d+)/$',views.histo,name='histo'),
|
re_path(r'^histo/user/(?P<userid>\d+)/$',views.histo,name='histo'),
|
||||||
re_path(r'^histodata/$',views.histo_data,name='histo_data'),
|
re_path(r'^histodata/$',views.histo_data,name='histo_data'),
|
||||||
# re_path(r'^histo/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.histo,name='histo'),
|
# re_path(r'^histo/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.histo,name='histo'),
|
||||||
re_path(r'^histo/$',views.histo,name='histo'),
|
re_path(r'^histo/$',views.histo,name='histo'),
|
||||||
re_path(r'^cumstats/user/(?P<theuser>\d+)/$',views.cumstats,name='cumstats'),
|
re_path(r'^cumstats/user/(?P<userid>\d+)/$',views.cumstats,name='cumstats'),
|
||||||
# re_path(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
# re_path(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||||
# re_path(r'^cumstats/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
# re_path(r'^cumstats/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||||
# re_path(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
# re_path(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||||
@@ -289,8 +293,6 @@ urlpatterns = [
|
|||||||
name='otw_use_gps'),
|
name='otw_use_gps'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/toggle-ranking/$',views.workout_toggle_ranking,
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/toggle-ranking/$',views.workout_toggle_ranking,
|
||||||
name='workout_toggle_ranking'),
|
name='workout_toggle_ranking'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/get-testscript/$',views.get_testscript,
|
|
||||||
name='get_testscript'),
|
|
||||||
re_path(r'^workout/upload/team/$',views.team_workout_upload_view,name='team_workout_upload_view'),
|
re_path(r'^workout/upload/team/$',views.team_workout_upload_view,name='team_workout_upload_view'),
|
||||||
re_path(r'^workout/upload/$',views.workout_upload_view,name='workout_upload_view'),
|
re_path(r'^workout/upload/$',views.workout_upload_view,name='workout_upload_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/histo/$',views.workout_histo_view,
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/histo/$',views.workout_histo_view,
|
||||||
@@ -355,6 +357,7 @@ urlpatterns = [
|
|||||||
re_path(r'^video/(?P<id>\w.+)/$',views.workout_video_view,
|
re_path(r'^video/(?P<id>\w.+)/$',views.workout_video_view,
|
||||||
name='workout_video_view'),
|
name='workout_video_view'),
|
||||||
re_path(r'^videos/',views.list_videos,name='list_videos'),
|
re_path(r'^videos/',views.list_videos,name='list_videos'),
|
||||||
|
re_path(r'^add-video/user/(?P<userid>\d+)/$',views.video_selectworkout,name='video_selectworkout'),
|
||||||
re_path(r'^add-video/',views.video_selectworkout,name='video_selectworkout'),
|
re_path(r'^add-video/',views.video_selectworkout,name='video_selectworkout'),
|
||||||
# re_path(r'^workout/(?P<id>\d+)/$',views.workout_view,name='workout_view'),
|
# re_path(r'^workout/(?P<id>\d+)/$',views.workout_view,name='workout_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.workout_view,name='workout_view'),
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.workout_view,name='workout_view'),
|
||||||
@@ -418,6 +421,7 @@ urlpatterns = [
|
|||||||
re_path(r'^workout/polarimport/user/(?P<userid>\d+)/',views.workout_polarimport_view,name='workout_polarimport_view'),
|
re_path(r'^workout/polarimport/user/(?P<userid>\d+)/',views.workout_polarimport_view,name='workout_polarimport_view'),
|
||||||
re_path(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
re_path(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
||||||
re_path(r'^workout/runkeeperimport/user/(?P<userid>\d+)/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
re_path(r'^workout/runkeeperimport/user/(?P<userid>\d+)/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
||||||
|
re_path(r'^workout/underarmourimport/user/(?P<userid>\d+)/$',views.workout_underarmourimport_view,name='workout_underarmourimport_view'),
|
||||||
re_path(r'^workout/underarmourimport/$',views.workout_underarmourimport_view,name='workout_underarmourimport_view'),
|
re_path(r'^workout/underarmourimport/$',views.workout_underarmourimport_view,name='workout_underarmourimport_view'),
|
||||||
# re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/deleteconfirm/$',views.workout_delete_confirm_view),
|
# re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/deleteconfirm/$',views.workout_delete_confirm_view),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/c2uploadw/$',views.workout_c2_upload_view,name='workout_c2_upload_view'),
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/c2uploadw/$',views.workout_c2_upload_view,name='workout_c2_upload_view'),
|
||||||
@@ -458,12 +462,12 @@ urlpatterns = [
|
|||||||
re_path(r'^me/calcdps/$',views.rower_calcdps_view,name='rower_calcdps_view'),
|
re_path(r'^me/calcdps/$',views.rower_calcdps_view,name='rower_calcdps_view'),
|
||||||
re_path(r'^me/exportsettings/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
re_path(r'^me/exportsettings/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
||||||
re_path(r'^me/exportsettings/user/(?P<userid>\d+)/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
re_path(r'^me/exportsettings/user/(?P<userid>\d+)/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/$',views.team_view,name='team_view'),
|
re_path(r'^team/(?P<team_id>\d+)/$',views.team_view,name='team_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/memberstats/$',views.team_members_stats_view,name='team_members_stats_view'),
|
re_path(r'^team/(?P<team_id>\d+)/memberstats/$',views.team_members_stats_view,name='team_members_stats_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/edit/$',views.team_edit_view,name='team_edit_view'),
|
re_path(r'^team/(?P<team_id>\d+)/edit/$',views.team_edit_view,name='team_edit_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/leaveconfirm/$',views.team_leaveconfirm_view,name='team_leaveconfirm_view'),
|
re_path(r'^team/(?P<id>\d+)/leaveconfirm/$',views.team_leaveconfirm_view,name='team_leaveconfirm_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/leave/$',views.team_leave_view,name='team_leave_view'),
|
re_path(r'^team/(?P<id>\d+)/leave/$',views.team_leave_view,name='team_leave_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/deleteconfirm/$',views.team_deleteconfirm_view,name='team_deleteconfirm_view'),
|
re_path(r'^team/(?P<team_id>\d+)/deleteconfirm/$',views.team_deleteconfirm_view,name='team_deleteconfirm_view'),
|
||||||
re_path(r'^team/(?P<teamid>\d+)/requestmembership/(?P<userid>\d+)/$',views.team_requestmembership_view,name='team_requestmembership_view'),
|
re_path(r'^team/(?P<teamid>\d+)/requestmembership/(?P<userid>\d+)/$',views.team_requestmembership_view,name='team_requestmembership_view'),
|
||||||
re_path(r'^me/coachrequest/(?P<id>\d+)/reject/$',views.reject_revoke_coach_request,
|
re_path(r'^me/coachrequest/(?P<id>\d+)/reject/$',views.reject_revoke_coach_request,
|
||||||
name='reject_revoke_coach_request'),
|
name='reject_revoke_coach_request'),
|
||||||
@@ -489,7 +493,7 @@ urlpatterns = [
|
|||||||
name='coach_accept_coachrequest_view'),
|
name='coach_accept_coachrequest_view'),
|
||||||
re_path(r'^me/coachoffer/(?P<code>\w+.*)/accept/$',views.rower_accept_coachoffer_view,
|
re_path(r'^me/coachoffer/(?P<code>\w+.*)/accept/$',views.rower_accept_coachoffer_view,
|
||||||
name='rower_accept_coachoffer_view'),
|
name='rower_accept_coachoffer_view'),
|
||||||
re_path(r'^team/(?P<id>\d+)/delete/$',views.team_delete_view,name='team_delete_view'),
|
re_path(r'^team/(?P<team_id>\d+)/delete/$',views.team_delete_view,name='team_delete_view'),
|
||||||
re_path(r'^team/create/$',views.team_create_view,name='team_create_view'),
|
re_path(r'^team/create/$',views.team_create_view,name='team_create_view'),
|
||||||
re_path(r'^me/team/(?P<teamid>\d+)/drop/(?P<userid>\d+)/$',views.manager_member_drop_view,name='manager_member_drop_view'),
|
re_path(r'^me/team/(?P<teamid>\d+)/drop/(?P<userid>\d+)/$',views.manager_member_drop_view,name='manager_member_drop_view'),
|
||||||
re_path(r'^me/invitation/(?P<id>\d+)/reject/$',views.invitation_reject_view,name='invitation_reject_view'),
|
re_path(r'^me/invitation/(?P<id>\d+)/reject/$',views.invitation_reject_view,name='invitation_reject_view'),
|
||||||
@@ -535,10 +539,10 @@ urlpatterns = [
|
|||||||
# re_path(r'^compatibility', TemplateView.as_view(template_name='compatibility.html'),name='about'),
|
# re_path(r'^compatibility', TemplateView.as_view(template_name='compatibility.html'),name='about'),
|
||||||
# re_path(r'^videos', TemplateView.as_view(template_name='videos.html'),name='videos'),
|
# re_path(r'^videos', TemplateView.as_view(template_name='videos.html'),name='videos'),
|
||||||
re_path(r'^analysis/user/(?P<userid>\d+)/$', views.analysis_view,name='analysis'),
|
re_path(r'^analysis/user/(?P<userid>\d+)/$', views.analysis_view,name='analysis'),
|
||||||
re_path(r'^laboratory/user/(?P<userid>\d+)/$', views.laboratory_view,name='laboratory'),
|
re_path(r'^laboratory/$', views.laboratory_view,name='laboratory_view'),
|
||||||
|
re_path(r'^laboratory/user/(?P<userid>\d+)/$', views.laboratory_view,name='laboratory_view'),
|
||||||
re_path(r'^errormessage/(?P<errormessage>[\w\ ]+.*)/$',views.errormessage_view,name='errormessage_view'),
|
re_path(r'^errormessage/(?P<errormessage>[\w\ ]+.*)/$',views.errormessage_view,name='errormessage_view'),
|
||||||
re_path(r'^analysis/$', views.analysis_view,name='analysis'),
|
re_path(r'^analysis/$', views.analysis_view,name='analysis'),
|
||||||
re_path(r'^laboratory/$', views.laboratory_view,name='laboratory'),
|
|
||||||
re_path(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
|
re_path(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
|
||||||
re_path(r'^checkout/(?P<planid>\d+)/$',views.payment_confirm_view,name='payment_confirm_view'),
|
re_path(r'^checkout/(?P<planid>\d+)/$',views.payment_confirm_view,name='payment_confirm_view'),
|
||||||
re_path(r'^upgradecheckout/(?P<planid>\d+)/$',views.upgrade_confirm_view,name='upgrade_confirm_view'),
|
re_path(r'^upgradecheckout/(?P<planid>\d+)/$',views.upgrade_confirm_view,name='upgrade_confirm_view'),
|
||||||
@@ -549,7 +553,7 @@ urlpatterns = [
|
|||||||
re_path(r'^downgrade/$',views.downgrade_view,name='downgrade'),
|
re_path(r'^downgrade/$',views.downgrade_view,name='downgrade'),
|
||||||
re_path(r'^paymentcompleted/$',views.payment_completed_view,name='payment_completed_view'),
|
re_path(r'^paymentcompleted/$',views.payment_completed_view,name='payment_completed_view'),
|
||||||
re_path(r'^downgradecompleted/$',views.downgrade_completed_view,name='downgrade_completed_view'),
|
re_path(r'^downgradecompleted/$',views.downgrade_completed_view,name='downgrade_completed_view'),
|
||||||
re_path(r'^paidplans/$',views.paidplans_view,name='paidplans'),
|
re_path(r'^paidplans/$',views.paidplans_view,name='paidplans_view'),
|
||||||
re_path(r'^me/cancelsubscriptions/$',views.plan_stop_view,name='plan_stop_view'),
|
re_path(r'^me/cancelsubscriptions/$',views.plan_stop_view,name='plan_stop_view'),
|
||||||
re_path(r'^me/cancelsubscription/(?P<id>[\w\ ]+.*)/$',views.plan_tobasic_view,name='plan_tobasic_view'),
|
re_path(r'^me/cancelsubscription/(?P<id>[\w\ ]+.*)/$',views.plan_tobasic_view,name='plan_tobasic_view'),
|
||||||
re_path(r'^checkouts/$',views.checkouts_view,name='checkouts'),
|
re_path(r'^checkouts/$',views.checkouts_view,name='checkouts'),
|
||||||
@@ -574,7 +578,7 @@ urlpatterns = [
|
|||||||
# re_path(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
# re_path(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||||
re_path(r'^test\_callback',views.rower_process_testcallback,name='rower_process_testcallback'),
|
re_path(r'^test\_callback',views.rower_process_testcallback,name='rower_process_testcallback'),
|
||||||
re_path(r'^createplan/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
re_path(r'^createplan/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
||||||
re_path(r'^createplan/user/(?P<userid>\d+)/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
re_path(r'^createplan/user/(?P<id>\d+)/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
||||||
re_path(r'^deleteplan/(?P<pk>\d+)/$',login_required(
|
re_path(r'^deleteplan/(?P<pk>\d+)/$',login_required(
|
||||||
views.TrainingPlanDelete.as_view()),name='trainingplan_delete_view'),
|
views.TrainingPlanDelete.as_view()),name='trainingplan_delete_view'),
|
||||||
re_path(r'^deletemicrocycle/(?P<pk>\d+)/$',login_required(
|
re_path(r'^deletemicrocycle/(?P<pk>\d+)/$',login_required(
|
||||||
@@ -637,9 +641,9 @@ urlpatterns = [
|
|||||||
re_path(r'^sessions/teamcreate/team/$',
|
re_path(r'^sessions/teamcreate/team/$',
|
||||||
views.plannedsession_teamcreate_view,
|
views.plannedsession_teamcreate_view,
|
||||||
name='plannedsession_teamcreate_view'),
|
name='plannedsession_teamcreate_view'),
|
||||||
re_path(r'^sessions/teamedit/(?P<sessionid>\d+)/$',views.plannedsession_teamedit_view,
|
re_path(r'^sessions/teamedit/(?P<id>\d+)/$',views.plannedsession_teamedit_view,
|
||||||
name='plannedsession_teamedit_view'),
|
name='plannedsession_teamedit_view'),
|
||||||
re_path(r'^sessions/teamedit/(?P<sessionid>\d+)/user/(?P<userid>\d+)/$',
|
re_path(r'^sessions/teamedit/(?P<id>\d+)/user/(?P<userid>\d+)/$',
|
||||||
views.plannedsession_teamedit_view,
|
views.plannedsession_teamedit_view,
|
||||||
name='plannedsession_teamedit_view'),
|
name='plannedsession_teamedit_view'),
|
||||||
re_path(r'^sessions/create/$',views.plannedsession_create_view,
|
re_path(r'^sessions/create/$',views.plannedsession_create_view,
|
||||||
@@ -653,7 +657,7 @@ urlpatterns = [
|
|||||||
# re_path(r'^sessions/create/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',
|
# re_path(r'^sessions/create/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',
|
||||||
# views.plannedsession_create_view,
|
# views.plannedsession_create_view,
|
||||||
# name='plannedsession_create_view'),
|
# name='plannedsession_create_view'),
|
||||||
re_path(r'^sessions/multiclone/$',views.plannedsession_multiclone_view),
|
re_path(r'^sessions/multiclone/$',views.plannedsession_multiclone_view,name='plannedsession_multiclone_view'),
|
||||||
re_path(r'^sessions/multiclone/user/(?P<userid>\d+)/$',
|
re_path(r'^sessions/multiclone/user/(?P<userid>\d+)/$',
|
||||||
views.plannedsession_multiclone_view,
|
views.plannedsession_multiclone_view,
|
||||||
name='plannedsession_multiclone_view'),
|
name='plannedsession_multiclone_view'),
|
||||||
@@ -666,6 +670,7 @@ urlpatterns = [
|
|||||||
views.plannedsession_multicreate_view,
|
views.plannedsession_multicreate_view,
|
||||||
name='plannedsession_multicreate_view'),
|
name='plannedsession_multicreate_view'),
|
||||||
re_path(r'^sessions/(?P<id>\d+)/edit/$',views.plannedsession_edit_view),
|
re_path(r'^sessions/(?P<id>\d+)/edit/$',views.plannedsession_edit_view),
|
||||||
|
re_path(r'^sessions/(?P<id>\d+)/templateedit/',views.plannedsession_templateedit_view),
|
||||||
re_path(r'^sessions/(?P<id>\d+)/maketemplate/$',views.plannedsession_totemplate_view),
|
re_path(r'^sessions/(?P<id>\d+)/maketemplate/$',views.plannedsession_totemplate_view),
|
||||||
re_path(r'^sessions/(?P<id>\d+)/compare/$',
|
re_path(r'^sessions/(?P<id>\d+)/compare/$',
|
||||||
views.plannedsession_compare_view,
|
views.plannedsession_compare_view,
|
||||||
@@ -716,7 +721,7 @@ urlpatterns = [
|
|||||||
re_path(r'^sessions/print/user/(?P<userid>\d+)/$',views.plannedsessions_print_view,
|
re_path(r'^sessions/print/user/(?P<userid>\d+)/$',views.plannedsessions_print_view,
|
||||||
name='plannedsessions_print_view'),
|
name='plannedsessions_print_view'),
|
||||||
re_path(r'^sessions/sendcalendar/$',views.plannedsessions_icsemail_view,
|
re_path(r'^sessions/sendcalendar/$',views.plannedsessions_icsemail_view,
|
||||||
name='plannedsessions_icsemail_view'),
|
name='plannedsessions_coach_icsemail_view'),
|
||||||
re_path(r'^sessions/sendcalendar/user/(?P<userid>\d+)/$',views.plannedsessions_icsemail_view,
|
re_path(r'^sessions/sendcalendar/user/(?P<userid>\d+)/$',views.plannedsessions_icsemail_view,
|
||||||
name='plannedsessions_icsemail_view'),
|
name='plannedsessions_icsemail_view'),
|
||||||
re_path(r'^sessions/$',views.plannedsessions_view,
|
re_path(r'^sessions/$',views.plannedsessions_view,
|
||||||
|
|||||||
@@ -405,17 +405,6 @@ def totaltime_sec_to_string(totaltime):
|
|||||||
|
|
||||||
return duration
|
return duration
|
||||||
|
|
||||||
def isprorower(r):
|
|
||||||
result = False
|
|
||||||
result = r.rowerplan in ['pro','coach','plan']
|
|
||||||
|
|
||||||
if not result and r.protrialexpires:
|
|
||||||
result = r.rowerplan == 'basic' and r.protrialexpires >= datetime.date.today()
|
|
||||||
if not result and r.rowerplan == 'freecoach':
|
|
||||||
if r.mycoachgroup is not None:
|
|
||||||
result = len(r.mycoachgroup)>=4
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def iscoach(m,r):
|
def iscoach(m,r):
|
||||||
result = False
|
result = False
|
||||||
@@ -518,4 +507,3 @@ def allsundays(startdate,enddate):
|
|||||||
while d<=enddate:
|
while d<=enddate:
|
||||||
yield d
|
yield d
|
||||||
d += datetime.timedelta(days=7)
|
d += datetime.timedelta(days=7)
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ defaultoptions = {
|
|||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def analysis_new(request,userid=0,function='boxplot',teamid=0):
|
def analysis_new(request,userid=0,function='boxplot',teamid=0):
|
||||||
r = getrequestrower(request, userid=userid)
|
r = getrequestrower(request, userid=userid)
|
||||||
user = r.user
|
user = r.user
|
||||||
@@ -669,6 +670,7 @@ def boxplotdata(workouts,options):
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def analysis_view_data(request,userid=0):
|
def analysis_view_data(request,userid=0):
|
||||||
if not request.is_ajax():
|
if not request.is_ajax():
|
||||||
url = reverse('analysis_new')
|
url = reverse('analysis_new')
|
||||||
@@ -727,7 +729,8 @@ def analysis_view_data(request,userid=0):
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def histo(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def histo(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
deltadays=-1,
|
deltadays=-1,
|
||||||
@@ -741,7 +744,7 @@ def histo(request,theuser=0,
|
|||||||
'histoparam':'power'
|
'histoparam':'power'
|
||||||
}):
|
}):
|
||||||
|
|
||||||
r = getrequestrower(request,userid=theuser)
|
r = getrequestrower(request,userid=userid)
|
||||||
theuser = r.user
|
theuser = r.user
|
||||||
|
|
||||||
if 'histoparam' in request.session:
|
if 'histoparam' in request.session:
|
||||||
@@ -1327,17 +1330,18 @@ def cum_flex(request,theuser=0,
|
|||||||
def planrequired_view(request):
|
def planrequired_view(request):
|
||||||
messages.info(request,"This functionality requires Coach or Self-Coach membership")
|
messages.info(request,"This functionality requires Coach or Self-Coach membership")
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('paidplans'))
|
return HttpResponseRedirect(reverse('paidplans_view'))
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(isplanmember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def fitnessmetric_view(request,id=0,mode='rower',
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def fitnessmetric_view(request,userid=0,mode='rower',
|
||||||
startdate=timezone.now()-timezone.timedelta(days=365),
|
startdate=timezone.now()-timezone.timedelta(days=365),
|
||||||
enddate=timezone.now()):
|
enddate=timezone.now()):
|
||||||
|
|
||||||
|
|
||||||
therower = getrequestrower(request,userid=id)
|
therower = getrequestrower(request,userid=userid)
|
||||||
theuser = therower.user
|
theuser = therower.user
|
||||||
|
|
||||||
|
|
||||||
@@ -1387,7 +1391,8 @@ def fitnessmetric_view(request,id=0,mode='rower',
|
|||||||
|
|
||||||
# Show ranking distances including predicted paces
|
# Show ranking distances including predicted paces
|
||||||
@login_required()
|
@login_required()
|
||||||
def rankings_view(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def rankings_view(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
deltadays=-1,
|
deltadays=-1,
|
||||||
@@ -1408,15 +1413,15 @@ def rankings_view(request,theuser=0,
|
|||||||
enddate = startdate
|
enddate = startdate
|
||||||
startdate = s
|
startdate = s
|
||||||
|
|
||||||
if theuser == 0:
|
|
||||||
theuser = request.user.id
|
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
if not request.user.is_anonymous:
|
r = getrequestrower(request,userid=userid)
|
||||||
r = getrower(request.user)
|
theuser = r.user.id
|
||||||
|
|
||||||
if r.birthdate:
|
if r.birthdate:
|
||||||
age = calculate_age(r.birthdate)
|
age = calculate_age(r.birthdate)
|
||||||
worldclasspower = int(metrics.getagegrouprecord(
|
worldclasspower = int(c2stuff.getagegrouprecord(
|
||||||
age,
|
age,
|
||||||
sex=r.sex,
|
sex=r.sex,
|
||||||
weightcategory=r.weightcategory,
|
weightcategory=r.weightcategory,
|
||||||
@@ -1737,7 +1742,8 @@ def ajax_agegrouprecords(request,
|
|||||||
|
|
||||||
# Show ranking distances including predicted paces
|
# Show ranking distances including predicted paces
|
||||||
@login_required()
|
@login_required()
|
||||||
def rankings_view2(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def rankings_view2(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
deltadays=-1,
|
deltadays=-1,
|
||||||
@@ -1758,15 +1764,16 @@ def rankings_view2(request,theuser=0,
|
|||||||
enddate = startdate
|
enddate = startdate
|
||||||
startdate = s
|
startdate = s
|
||||||
|
|
||||||
if theuser == 0:
|
if userid == 0:
|
||||||
theuser = request.user.id
|
userid = request.user.id
|
||||||
else:
|
else:
|
||||||
lastupdated = "01-01-1900"
|
lastupdated = "01-01-1900"
|
||||||
|
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
if not request.user.is_anonymous:
|
r = getrequestrower(request,userid=userid)
|
||||||
r = getrower(request.user)
|
theuser = r.user
|
||||||
|
|
||||||
wcdurations = []
|
wcdurations = []
|
||||||
wcpower = []
|
wcpower = []
|
||||||
|
|
||||||
@@ -1800,7 +1807,7 @@ def rankings_view2(request,theuser=0,
|
|||||||
else:
|
else:
|
||||||
recalc = False
|
recalc = False
|
||||||
|
|
||||||
options['userid'] = theuser
|
options['userid'] = theuser.id
|
||||||
|
|
||||||
if r.birthdate:
|
if r.birthdate:
|
||||||
age = calculate_age(r.birthdate)
|
age = calculate_age(r.birthdate)
|
||||||
@@ -1827,7 +1834,7 @@ def rankings_view2(request,theuser=0,
|
|||||||
options['wcpower'] = wcpower
|
options['wcpower'] = wcpower
|
||||||
options['wcdurations'] = wcdurations
|
options['wcdurations'] = wcdurations
|
||||||
if theuser:
|
if theuser:
|
||||||
options['userid'] = theuser
|
options['userid'] = theuser.id
|
||||||
|
|
||||||
request.session['options'] = options
|
request.session['options'] = options
|
||||||
|
|
||||||
@@ -1883,10 +1890,7 @@ def rankings_view2(request,theuser=0,
|
|||||||
r=0
|
r=0
|
||||||
|
|
||||||
|
|
||||||
try:
|
uu = theuser
|
||||||
uu = User.objects.get(id=theuser)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
uu = ''
|
|
||||||
|
|
||||||
|
|
||||||
# test to fix bug
|
# test to fix bug
|
||||||
@@ -2150,7 +2154,8 @@ def rankings_view2(request,theuser=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def otwrankings_view(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def otwrankings_view(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
startdatestring="",
|
startdatestring="",
|
||||||
@@ -2173,22 +2178,10 @@ def otwrankings_view(request,theuser=0,
|
|||||||
enddate = startdate
|
enddate = startdate
|
||||||
startdate = s
|
startdate = s
|
||||||
|
|
||||||
if theuser == 0:
|
r = getrequestrower(request,userid=userid)
|
||||||
if 'rowerid' in request.session:
|
promember = True
|
||||||
try:
|
|
||||||
r = Rower.objects.get(id=request.session['rowerid'])
|
|
||||||
theuser = r.user.id
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
theuser = request.user.id
|
|
||||||
else:
|
|
||||||
theuser = request.user.id
|
|
||||||
|
|
||||||
promember=0
|
theuser = r.user
|
||||||
if not request.user.is_anonymous:
|
|
||||||
r = Rower.objects.get(user=request.user)
|
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
|
||||||
if result:
|
|
||||||
promember=1
|
|
||||||
|
|
||||||
# get all OTW rows in date range
|
# get all OTW rows in date range
|
||||||
|
|
||||||
@@ -2242,10 +2235,7 @@ def otwrankings_view(request,theuser=0,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
uu = theuser
|
||||||
uu = User.objects.get(id=theuser)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
uu = ''
|
|
||||||
|
|
||||||
|
|
||||||
# test to fix bug
|
# test to fix bug
|
||||||
@@ -2555,7 +2545,8 @@ def otwcp_toadmin_view(request,theuser=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def oterankings_view(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def oterankings_view(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
startdatestring="",
|
startdatestring="",
|
||||||
@@ -2578,23 +2569,11 @@ def oterankings_view(request,theuser=0,
|
|||||||
enddate = startdate
|
enddate = startdate
|
||||||
startdate = s
|
startdate = s
|
||||||
|
|
||||||
if theuser == 0:
|
r = getrequestrower(request,userid=userid)
|
||||||
if 'rowerid' in request.session:
|
theuser = r.user
|
||||||
try:
|
|
||||||
r = Rower.objects.get(id=request.session['rowerid'])
|
|
||||||
theuser = r.user.id
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
theuser = request.user.id
|
|
||||||
else:
|
|
||||||
theuser = request.user.id
|
|
||||||
|
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
if not request.user.is_anonymous:
|
|
||||||
r = Rower.objects.get(user=request.user)
|
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
|
||||||
if result:
|
|
||||||
promember=1
|
|
||||||
|
|
||||||
# get all OTW rows in date range
|
# get all OTW rows in date range
|
||||||
|
|
||||||
@@ -2668,10 +2647,8 @@ def oterankings_view(request,theuser=0,
|
|||||||
raise Http404("Rower doesn't exist")
|
raise Http404("Rower doesn't exist")
|
||||||
|
|
||||||
|
|
||||||
try:
|
uu = theuser
|
||||||
uu = User.objects.get(id=theuser)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
uu = ''
|
|
||||||
|
|
||||||
|
|
||||||
# test to fix bug
|
# test to fix bug
|
||||||
@@ -2906,6 +2883,7 @@ def oterankings_view(request,theuser=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def user_multiflex_select(request,
|
def user_multiflex_select(request,
|
||||||
startdatestring="",
|
startdatestring="",
|
||||||
enddatestring="",
|
enddatestring="",
|
||||||
@@ -3112,6 +3090,7 @@ def user_multiflex_select(request,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def multiflex_data(request,userid=0,
|
def multiflex_data(request,userid=0,
|
||||||
options={
|
options={
|
||||||
'includereststrokes':False,
|
'includereststrokes':False,
|
||||||
@@ -3365,6 +3344,7 @@ def multiflex_data(request,userid=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def multiflex_view(request,userid=0,
|
def multiflex_view(request,userid=0,
|
||||||
options={
|
options={
|
||||||
'includereststrokes':False,
|
'includereststrokes':False,
|
||||||
@@ -3532,6 +3512,7 @@ def multiflex_view(request,userid=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def user_boxplot_select(request,
|
def user_boxplot_select(request,
|
||||||
startdatestring="",
|
startdatestring="",
|
||||||
enddatestring="",
|
enddatestring="",
|
||||||
@@ -3740,6 +3721,7 @@ def user_boxplot_select(request,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def boxplot_view_data(request,userid=0,
|
def boxplot_view_data(request,userid=0,
|
||||||
options={
|
options={
|
||||||
'includereststrokes':False,
|
'includereststrokes':False,
|
||||||
@@ -3857,6 +3839,7 @@ def boxplot_view_data(request,userid=0,
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def boxplot_view(request,userid=0,
|
def boxplot_view(request,userid=0,
|
||||||
options={
|
options={
|
||||||
'includereststrokes':False,
|
'includereststrokes':False,
|
||||||
@@ -3975,7 +3958,8 @@ def boxplot_view(request,userid=0,
|
|||||||
|
|
||||||
# Cumulative stats page
|
# Cumulative stats page
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
||||||
def cumstats(request,theuser=0,
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def cumstats(request,userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=30),
|
startdate=timezone.now()-datetime.timedelta(days=30),
|
||||||
enddate=timezone.now(),
|
enddate=timezone.now(),
|
||||||
deltadays=-1,
|
deltadays=-1,
|
||||||
@@ -3988,7 +3972,7 @@ def cumstats(request,theuser=0,
|
|||||||
'rankingonly':False,
|
'rankingonly':False,
|
||||||
}):
|
}):
|
||||||
|
|
||||||
r = getrequestrower(request,userid=theuser)
|
r = getrequestrower(request,userid=userid)
|
||||||
theuser = r.user
|
theuser = r.user
|
||||||
|
|
||||||
if 'waterboattype' in request.session:
|
if 'waterboattype' in request.session:
|
||||||
@@ -4106,7 +4090,7 @@ def cumstats(request,theuser=0,
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
'modality': modality,
|
'modality': modality,
|
||||||
'theuser': theuser.id,
|
'userid': theuser.id,
|
||||||
'waterboattype':waterboattype,
|
'waterboattype':waterboattype,
|
||||||
'startdatestring':startdatestring,
|
'startdatestring':startdatestring,
|
||||||
'enddatestring':enddatestring,
|
'enddatestring':enddatestring,
|
||||||
@@ -4326,6 +4310,7 @@ def agegrouprecordview(request,sex='male',weightcategory='hwt',
|
|||||||
# message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
# message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
# redirect_field_name=None)
|
# redirect_field_name=None)
|
||||||
@login_required
|
@login_required
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def alerts_view(request,userid=0):
|
def alerts_view(request,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
@@ -4360,6 +4345,7 @@ def alerts_view(request,userid=0):
|
|||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def alert_create_view(request,userid=0):
|
def alert_create_view(request,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
FilterFormSet = formset_factory(ConditionEditForm, formset=BaseConditionFormSet,extra=1)
|
FilterFormSet = formset_factory(ConditionEditForm, formset=BaseConditionFormSet,extra=1)
|
||||||
@@ -4438,6 +4424,7 @@ def alert_create_view(request,userid=0):
|
|||||||
|
|
||||||
# alert report view
|
# alert report view
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def alert_report_view(request,id=0,userid=0,nperiod=0):
|
def alert_report_view(request,id=0,userid=0,nperiod=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
if userid == 0:
|
if userid == 0:
|
||||||
@@ -4495,6 +4482,7 @@ def alert_report_view(request,id=0,userid=0,nperiod=0):
|
|||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def alert_edit_view(request,id=0,userid=0):
|
def alert_edit_view(request,id=0,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ from rowers.views.statements import *
|
|||||||
|
|
||||||
|
|
||||||
# Export workout to TCX and send to user's email address
|
# Export workout to TCX and send to user's email address
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_tcxemail_view(request,id=0):
|
def workout_tcxemail_view(request,id=0):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if not checkworkoutuser(request.user,w):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
|
|
||||||
row = rdata(w.csvfilename)
|
row = rdata(w.csvfilename)
|
||||||
@@ -169,13 +168,12 @@ def course_kmldownload_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Export workout to GPX and send to user's email address
|
# Export workout to GPX and send to user's email address
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_gpxemail_view(request,id=0):
|
def workout_gpxemail_view(request,id=0):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if not checkworkoutuser(request.user,w):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
|
|
||||||
row = rdata(w.csvfilename)
|
row = rdata(w.csvfilename)
|
||||||
@@ -236,14 +234,13 @@ def workouts_summaries_email_view(request):
|
|||||||
|
|
||||||
|
|
||||||
# Get Workout CSV file and send it to user's email address
|
# Get Workout CSV file and send it to user's email address
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_csvemail_view(request,id=0):
|
def workout_csvemail_view(request,id=0):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if not checkworkoutuser(request.user,w):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
rowdata = rdata(w.csvfilename)
|
rowdata = rdata(w.csvfilename)
|
||||||
code = str(uuid4())
|
code = str(uuid4())
|
||||||
@@ -252,8 +249,11 @@ def workout_csvemail_view(request,id=0):
|
|||||||
rowdate = rowdata.rowdatetime
|
rowdate = rowdata.rowdatetime
|
||||||
starttimeunix = arrow.get(rowdate).timestamp
|
starttimeunix = arrow.get(rowdate).timestamp
|
||||||
df = rowdata.df
|
df = rowdata.df
|
||||||
|
try:
|
||||||
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
|
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
|
||||||
df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix
|
df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
response = HttpResponse(df.to_csv())
|
response = HttpResponse(df.to_csv())
|
||||||
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
@@ -264,6 +264,7 @@ def workout_csvemail_view(request,id=0):
|
|||||||
|
|
||||||
# Get Workout CSV file and send it to user's email address
|
# Get Workout CSV file and send it to user's email address
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_csvtoadmin_view(request,id=0):
|
def workout_csvtoadmin_view(request,id=0):
|
||||||
message = ""
|
message = ""
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|||||||
+22
-31
@@ -13,7 +13,7 @@ def default(o):
|
|||||||
|
|
||||||
|
|
||||||
# Send workout to TP
|
# Send workout to TP
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_tp_upload_view(request,id=0):
|
def workout_tp_upload_view(request,id=0):
|
||||||
|
|
||||||
message = ""
|
message = ""
|
||||||
@@ -25,10 +25,10 @@ def workout_tp_upload_view(request,id=0):
|
|||||||
return HttpResponseRedirect("/rowers/me/tpauthorize/")
|
return HttpResponseRedirect("/rowers/me/tpauthorize/")
|
||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
w = get_workout_permitted(request.user,id)
|
w = get_workout_by_opaqueid(request,id)
|
||||||
r = w.user
|
r = w.user
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)):
|
|
||||||
tcxfile = tpstuff.createtpworkoutdata(w)
|
tcxfile = tpstuff.createtpworkoutdata(w)
|
||||||
if tcxfile:
|
if tcxfile:
|
||||||
res,reason,status_code,headers = tpstuff.uploadactivity(
|
res,reason,status_code,headers = tpstuff.uploadactivity(
|
||||||
@@ -56,10 +56,6 @@ def workout_tp_upload_view(request,id=0):
|
|||||||
w.save()
|
w.save()
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
|
|
||||||
else: # not allowed to upload
|
|
||||||
message = "You are not allowed to export this workout to TP"
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
url = reverse(r.defaultlandingpage,
|
url = reverse(r.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'id':encoder.encode_hex(w.id),
|
'id':encoder.encode_hex(w.id),
|
||||||
@@ -70,7 +66,7 @@ def workout_tp_upload_view(request,id=0):
|
|||||||
|
|
||||||
# Send workout to Strava
|
# Send workout to Strava
|
||||||
# abundance of error logging here because there were/are some bugs
|
# abundance of error logging here because there were/are some bugs
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_strava_upload_view(request,id=0):
|
def workout_strava_upload_view(request,id=0):
|
||||||
message = ""
|
message = ""
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
@@ -88,7 +84,7 @@ def workout_strava_upload_view(request,id=0):
|
|||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
w = get_workout_permitted(request.user,id)
|
w = get_workout_permitted(request.user,id)
|
||||||
r = w.user
|
r = w.user
|
||||||
if (checkworkoutuser(request.user,w)):
|
|
||||||
try:
|
try:
|
||||||
tcxfile,tcxmessg = stravastuff.createstravaworkoutdata(w)
|
tcxfile,tcxmessg = stravastuff.createstravaworkoutdata(w)
|
||||||
if tcxfile:
|
if tcxfile:
|
||||||
@@ -206,7 +202,7 @@ def workout_c2_upload_view(request,id=0):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
# Upload workout to RunKeeper
|
# Upload workout to RunKeeper
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_runkeeper_upload_view(request,id=0):
|
def workout_runkeeper_upload_view(request,id=0):
|
||||||
message = ""
|
message = ""
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
@@ -219,7 +215,7 @@ def workout_runkeeper_upload_view(request,id=0):
|
|||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)):
|
|
||||||
data = runkeeperstuff.createrunkeeperworkoutdata(w)
|
data = runkeeperstuff.createrunkeeperworkoutdata(w)
|
||||||
if not data:
|
if not data:
|
||||||
message = "Data error"
|
message = "Data error"
|
||||||
@@ -258,9 +254,6 @@ def workout_runkeeper_upload_view(request,id=0):
|
|||||||
message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text)
|
message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text)
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
|
|
||||||
else:
|
|
||||||
message = "You are not authorized to upload this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
url = reverse(r.defaultlandingpage,
|
url = reverse(r.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@@ -270,7 +263,7 @@ def workout_runkeeper_upload_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
# Upload workout to Underarmour
|
# Upload workout to Underarmour
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_underarmour_upload_view(request,id=0):
|
def workout_underarmour_upload_view(request,id=0):
|
||||||
message = ""
|
message = ""
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
@@ -283,7 +276,7 @@ def workout_underarmour_upload_view(request,id=0):
|
|||||||
|
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)):
|
|
||||||
data = underarmourstuff.createunderarmourworkoutdata(w)
|
data = underarmourstuff.createunderarmourworkoutdata(w)
|
||||||
if not data:
|
if not data:
|
||||||
message = "Data error"
|
message = "Data error"
|
||||||
@@ -322,9 +315,6 @@ def workout_underarmour_upload_view(request,id=0):
|
|||||||
s = response
|
s = response
|
||||||
message = "Something went wrong in workout_underarmour_upload_view: %s " % s.reason
|
message = "Something went wrong in workout_underarmour_upload_view: %s " % s.reason
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
else:
|
|
||||||
message = "You are not authorized to upload this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
url = reverse(r.defaultlandingpage,
|
url = reverse(r.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@@ -334,7 +324,7 @@ def workout_underarmour_upload_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
# Upload workout to SportTracks
|
# Upload workout to SportTracks
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid)
|
||||||
def workout_sporttracks_upload_view(request,id=0):
|
def workout_sporttracks_upload_view(request,id=0):
|
||||||
message = ""
|
message = ""
|
||||||
# ready to upload. Hurray
|
# ready to upload. Hurray
|
||||||
@@ -347,7 +337,7 @@ def workout_sporttracks_upload_view(request,id=0):
|
|||||||
return HttpResponseRedirect("/rowers/me/sporttracksauthorize/")
|
return HttpResponseRedirect("/rowers/me/sporttracksauthorize/")
|
||||||
|
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)):
|
|
||||||
data = sporttracksstuff.createsporttracksworkoutdata(w)
|
data = sporttracksstuff.createsporttracksworkoutdata(w)
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
@@ -388,9 +378,6 @@ def workout_sporttracks_upload_view(request,id=0):
|
|||||||
s = response
|
s = response
|
||||||
message = "Something went wrong in workout_sporttracks_upload_view: %s" % s.reason
|
message = "Something went wrong in workout_sporttracks_upload_view: %s" % s.reason
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
else:
|
|
||||||
message = "You are not authorized to upload this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
url = reverse(r.defaultlandingpage,
|
url = reverse(r.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@@ -899,10 +886,11 @@ def rower_process_testcallback(request):
|
|||||||
|
|
||||||
# The page where you select which Strava workout to import
|
# The page where you select which Strava workout to import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_stravaimport_view(request,message="",userid=0):
|
def workout_stravaimport_view(request,message="",userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
if r.user != request.user:
|
#if r.user != request.user:
|
||||||
messages.info(request,"You cannot import other people's workouts from Strava")
|
# messages.info(request,"You cannot import other people's workouts from Strava")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
thetoken = strava_open(request.user)
|
thetoken = strava_open(request.user)
|
||||||
@@ -998,6 +986,7 @@ def workout_stravaimport_view(request,message="",userid=0):
|
|||||||
|
|
||||||
# The page where you select which RunKeeper workout to import
|
# The page where you select which RunKeeper workout to import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_runkeeperimport_view(request,message="",userid=0):
|
def workout_runkeeperimport_view(request,message="",userid=0):
|
||||||
res = runkeeperstuff.get_runkeeper_workout_list(request.user)
|
res = runkeeperstuff.get_runkeeper_workout_list(request.user)
|
||||||
if (res.status_code != 200):
|
if (res.status_code != 200):
|
||||||
@@ -1053,6 +1042,7 @@ def workout_runkeeperimport_view(request,message="",userid=0):
|
|||||||
|
|
||||||
# The page where you select which RunKeeper workout to import
|
# The page where you select which RunKeeper workout to import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_underarmourimport_view(request,message="",userid=0):
|
def workout_underarmourimport_view(request,message="",userid=0):
|
||||||
res = underarmourstuff.get_underarmour_workout_list(request.user)
|
res = underarmourstuff.get_underarmour_workout_list(request.user)
|
||||||
if (res.status_code != 200):
|
if (res.status_code != 200):
|
||||||
@@ -1103,6 +1093,7 @@ def workout_underarmourimport_view(request,message="",userid=0):
|
|||||||
|
|
||||||
# the page where you select which Polar workout to Import
|
# the page where you select which Polar workout to Import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_polarimport_view(request,userid=0):
|
def workout_polarimport_view(request,userid=0):
|
||||||
exercises = polarstuff.get_polar_workouts(request.user)
|
exercises = polarstuff.get_polar_workouts(request.user)
|
||||||
workouts = []
|
workouts = []
|
||||||
@@ -1160,6 +1151,7 @@ def workout_polarimport_view(request,userid=0):
|
|||||||
|
|
||||||
# The page where you select which SportTracks workout to import
|
# The page where you select which SportTracks workout to import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_sporttracksimport_view(request,message="",userid=0):
|
def workout_sporttracksimport_view(request,message="",userid=0):
|
||||||
|
|
||||||
|
|
||||||
@@ -1304,14 +1296,15 @@ def workout_getc2workout_all(request,page=1,message=""):
|
|||||||
|
|
||||||
# List of workouts available on Concept2 logbook - for import
|
# List of workouts available on Concept2 logbook - for import
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def workout_c2import_view(request,page=1,userid=0,message=""):
|
def workout_c2import_view(request,page=1,userid=0,message=""):
|
||||||
|
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
if r.user != request.user:
|
# if r.user != request.user:
|
||||||
messages.info(request,"You cannot import other people's workouts from Concept2")
|
# messages.info(request,"You cannot import other people's workouts from Concept2")
|
||||||
|
|
||||||
r = getrower(request.user)
|
# r = getrower(request.user)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
thetoken = c2_open(request.user)
|
thetoken = c2_open(request.user)
|
||||||
@@ -1613,5 +1606,3 @@ def workout_getstravaworkout_next(request):
|
|||||||
|
|
||||||
url = reverse('workouts_view')
|
url = reverse('workouts_view')
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-120
@@ -74,123 +74,10 @@ def errormessage_view(request,errormessage='aap'):
|
|||||||
"result":1,
|
"result":1,
|
||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
|
||||||
def deactivate_user(request):
|
|
||||||
pk = request.user.id
|
|
||||||
user = User.objects.get(pk=pk)
|
|
||||||
user_form = DeactivateUserForm(instance=user)
|
|
||||||
if request.user.is_authenticated and request.user.id == user.id:
|
|
||||||
if request.method == "POST":
|
|
||||||
user_form = DeactivateUserForm(request.POST, instance=user)
|
|
||||||
if user_form.is_valid():
|
|
||||||
if not user_form.cleaned_data['is_active']:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
|
||||||
try:
|
|
||||||
subscriptions = braintreestuff.find_subscriptions(r)
|
|
||||||
for subscription in subscriptions:
|
|
||||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
|
||||||
for message in themessages:
|
|
||||||
messages.info(request,message)
|
|
||||||
except ProcessorCustomerError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
r.paidplan = None
|
|
||||||
r.teamplanexpires = timezone.now()
|
|
||||||
r.planexpires = timezone.now()
|
|
||||||
r.clubsize = 0
|
|
||||||
r.rowerplan = 'basic'
|
|
||||||
r.save()
|
|
||||||
|
|
||||||
deactivate_user = user_form.save(commit=False)
|
|
||||||
user.is_active = False
|
|
||||||
user.save()
|
|
||||||
deactivate_user.save()
|
|
||||||
# url = reverse(auth_views.logout_then_login)
|
|
||||||
url = '/logout/?next=/login'
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
return render(request, "userprofile_deactivate.html", {
|
|
||||||
"user_form": user_form,
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
raise PermissionDenied
|
|
||||||
|
|
||||||
@login_required()
|
|
||||||
def user_gdpr_optin(request):
|
|
||||||
r = getrower(request.user)
|
|
||||||
r.gdproptin = False
|
|
||||||
r.gdproptindate = None
|
|
||||||
r.save()
|
|
||||||
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
|
||||||
if r.gdproptin:
|
|
||||||
return HttpResponseRedirect(nexturl)
|
|
||||||
|
|
||||||
return render(request,'gdpr_optin.html',{
|
|
||||||
"next": nexturl
|
|
||||||
})
|
|
||||||
|
|
||||||
@login_required()
|
|
||||||
def user_gdpr_confirm(request):
|
|
||||||
r = getrower(request.user)
|
|
||||||
r.gdproptin = True
|
|
||||||
r.gdproptindate = timezone.now()
|
|
||||||
r.save()
|
|
||||||
|
|
||||||
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(nexturl)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
|
||||||
def remove_user(request):
|
|
||||||
pk = request.user.id
|
|
||||||
user = User.objects.get(pk=pk)
|
|
||||||
user_form = DeleteUserForm(instance=user)
|
|
||||||
if request.user.is_authenticated and request.user.id == user.id:
|
|
||||||
if request.method == "POST":
|
|
||||||
user_form = DeleteUserForm(request.POST,instance=user)
|
|
||||||
if user_form.is_valid():
|
|
||||||
cd = user_form.cleaned_data
|
|
||||||
name = user.first_name+' '+user.last_name
|
|
||||||
email = user.email
|
|
||||||
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
|
||||||
try:
|
|
||||||
subscriptions = braintreestuff.find_subscriptions(r)
|
|
||||||
for subscription in subscriptions:
|
|
||||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
|
||||||
for message in themessages:
|
|
||||||
messages.info(request,message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if cd['delete_user']:
|
|
||||||
# delete workouts
|
|
||||||
Workout.objects.filter(user=user.rower).delete()
|
|
||||||
# delete planned sessions
|
|
||||||
PlannedSession.objects.filter(manager=user).delete()
|
|
||||||
|
|
||||||
user.delete()
|
|
||||||
res = myqueue(queuehigh,
|
|
||||||
handle_sendemail_userdeleted,
|
|
||||||
name, email)
|
|
||||||
|
|
||||||
url = '/logout/?next=/login'
|
|
||||||
# url = reverse(auth_views.logout_then_login)
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
return render(request, "userprofile_delete.html", {
|
|
||||||
"user_form": user_form,
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
raise PermissionDenied
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Shows analysis page
|
# Shows analysis page
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def analysis_view(request,userid=0):
|
def analysis_view(request,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
return render(request,
|
return render(request,
|
||||||
@@ -203,6 +90,7 @@ def analysis_view(request,userid=0):
|
|||||||
|
|
||||||
# Shows laboratory page
|
# Shows laboratory page
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def laboratory_view(request,userid=0):
|
def laboratory_view(request,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
return render(request,
|
return render(request,
|
||||||
@@ -212,9 +100,3 @@ def laboratory_view(request,userid=0):
|
|||||||
'rower':r,
|
'rower':r,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -647,6 +647,7 @@ def freecoach_register_view(request):
|
|||||||
'next':nextpage,})
|
'next':nextpage,})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True)
|
||||||
def transactions_view(request):
|
def transactions_view(request):
|
||||||
if not request.user.is_staff:
|
if not request.user.is_staff:
|
||||||
raise PermissionDenied("Not Allowed")
|
raise PermissionDenied("Not Allowed")
|
||||||
@@ -673,4 +674,3 @@ def transactions_view(request):
|
|||||||
{
|
{
|
||||||
'dateform':dateform
|
'dateform':dateform
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+202
-206
@@ -5,27 +5,11 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
|
|
||||||
@login_required()
|
@login_required
|
||||||
|
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
def plannedsession_comment_view(request,id=0,userid=0):
|
def plannedsession_comment_view(request,id=0,userid=0):
|
||||||
r = getrequestplanrower(request,userid=userid)
|
r = getrequestplanrower(request,userid=userid)
|
||||||
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
try:
|
|
||||||
ps = PlannedSession.objects.get(id=id)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
m = ps.manager
|
|
||||||
mm = Rower.objects.get(user=m)
|
|
||||||
|
|
||||||
if ps.manager != request.user and ps.sessiontype not in ['race','indoorrace']:
|
|
||||||
if r.rowerplan == 'coach' and r not in ps.rower.all():
|
|
||||||
teams = Team.objects.filter(manager=request.user)
|
|
||||||
members = Rower.objects.filter(team__in=teams).distinct()
|
|
||||||
teamusers = [m.user for m in members]
|
|
||||||
if ps.manager not in teamusers:
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
elif r not in ps.rower.all():
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
|
|
||||||
comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")
|
comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")
|
||||||
|
|
||||||
@@ -171,7 +155,7 @@ def plannedsession_comment_view(request,id=0,userid=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Cloning sessions
|
# Cloning sessions
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_multiclone_view(
|
def plannedsession_multiclone_view(
|
||||||
@@ -322,7 +306,7 @@ def plannedsession_multiclone_view(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Individual user creates training for himself
|
# Individual user creates training for himself
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_create_view(request,
|
def plannedsession_create_view(request,
|
||||||
@@ -332,9 +316,6 @@ def plannedsession_create_view(request,
|
|||||||
|
|
||||||
r = getrequestplanrower(request,userid=userid)
|
r = getrequestplanrower(request,userid=userid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
|
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
|
||||||
enddatestring=enddatestring)
|
enddatestring=enddatestring)
|
||||||
|
|
||||||
@@ -477,7 +458,7 @@ def plannedsession_create_view(request,
|
|||||||
'timeperiod':timeperiod,
|
'timeperiod':timeperiod,
|
||||||
})
|
})
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_multicreate_view(request,
|
def plannedsession_multicreate_view(request,
|
||||||
@@ -613,7 +594,7 @@ def plannedsession_multicreate_view(request,
|
|||||||
return render(request,'plannedsession_multicreate.html',context)
|
return render(request,'plannedsession_multicreate.html',context)
|
||||||
|
|
||||||
# Manager creates sessions for entire team
|
# Manager creates sessions for entire team
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_teamcreate_view(request,
|
def plannedsession_teamcreate_view(request,
|
||||||
@@ -704,7 +685,9 @@ def plannedsession_teamcreate_view(request,
|
|||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
url += '?when='+startdatestring+'/'+enddatestring
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
next = request.GET.get('next', url)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(next)
|
||||||
else:
|
else:
|
||||||
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
@@ -786,21 +769,16 @@ def plannedsession_teamcreate_view(request,
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Manager edits sessions for entire team
|
# Manager edits sessions for entire team
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
def plannedsession_teamedit_view(request,
|
def plannedsession_teamedit_view(request,
|
||||||
sessionid=0,userid=0):
|
id=0,userid=0):
|
||||||
|
|
||||||
r = getrequestplanrower(request,userid=userid)
|
r = getrequestplanrower(request,userid=userid)
|
||||||
|
|
||||||
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
try:
|
|
||||||
ps = PlannedSession.objects.get(id=sessionid)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("This session doesn't exist")
|
|
||||||
if not ps.manager == request.user:
|
|
||||||
raise PermissionDenied("You are not the manager of this session")
|
|
||||||
|
|
||||||
teams = Team.objects.filter(manager=request.user)
|
teams = Team.objects.filter(manager=request.user)
|
||||||
teamchoices = [(team.id, team.name) for team in teams]
|
teamchoices = [(team.id, team.name) for team in teams]
|
||||||
@@ -890,15 +868,15 @@ def plannedsession_teamedit_view(request,
|
|||||||
|
|
||||||
url = reverse(plannedsession_teamedit_view,
|
url = reverse(plannedsession_teamedit_view,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'sessionid':sessionid,
|
'id':id,
|
||||||
})
|
})
|
||||||
|
|
||||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
url += '?when='+startdatestring+'/'+enddatestring
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
|
||||||
|
next = request.GET.get('next', url)
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(next)
|
||||||
else:
|
else:
|
||||||
sessioncreateform = PlannedSessionForm(instance=ps)
|
sessioncreateform = PlannedSessionForm(instance=ps)
|
||||||
sessionteamselectform = PlannedSessionTeamForm(
|
sessionteamselectform = PlannedSessionTeamForm(
|
||||||
@@ -1238,6 +1216,7 @@ def plannedsessions_print_view(request,userid=0):
|
|||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def plannedsessions_manage_view(request,userid=0,
|
def plannedsessions_manage_view(request,userid=0,
|
||||||
initialsession=0):
|
initialsession=0):
|
||||||
|
|
||||||
@@ -1245,8 +1224,6 @@ def plannedsessions_manage_view(request,userid=0,
|
|||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
is_ajax = True
|
is_ajax = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
startdate,enddate = get_dates_timeperiod(request)
|
startdate,enddate = get_dates_timeperiod(request)
|
||||||
@@ -1402,7 +1379,8 @@ def plannedsessions_manage_view(request,userid=0,
|
|||||||
|
|
||||||
# Clone an existing planned session
|
# Clone an existing planned session
|
||||||
# need clarity on cloning behavior time shift
|
# need clarity on cloning behavior time shift
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_clone_view(request,id=0,userid=0):
|
def plannedsession_clone_view(request,id=0,userid=0):
|
||||||
@@ -1420,13 +1398,7 @@ def plannedsession_clone_view(request,id=0,userid=0):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
trainingplan = None
|
trainingplan = None
|
||||||
|
|
||||||
try:
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
ps = PlannedSession.objects.get(id=id)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
if ps.manager != request.user:
|
|
||||||
raise PermissionDenied("You are not allowed to clone this planned session")
|
|
||||||
|
|
||||||
rowers = ps.rower.all()
|
rowers = ps.rower.all()
|
||||||
teams = ps.team.all()
|
teams = ps.team.all()
|
||||||
@@ -1465,12 +1437,13 @@ def plannedsession_clone_view(request,id=0,userid=0):
|
|||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
url += '?when='+startdatestring+'/'+enddatestring
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
|
||||||
|
next = request.GET.get('next', url)
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(next)
|
||||||
|
|
||||||
# Clone an existing planned session
|
# Clone an existing planned session
|
||||||
# need clarity on cloning behavior time shift
|
# need clarity on cloning behavior time shift
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def plannedsession_teamclone_view(request,id=0):
|
def plannedsession_teamclone_view(request,id=0):
|
||||||
@@ -1497,13 +1470,7 @@ def plannedsession_teamclone_view(request,id=0):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
trainingplan = None
|
trainingplan = None
|
||||||
|
|
||||||
try:
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
ps = PlannedSession.objects.get(id=id)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
if ps.manager != request.user:
|
|
||||||
raise PermissionDenied("You are not allowed to clone this planned session")
|
|
||||||
|
|
||||||
|
|
||||||
ps.pk = None
|
ps.pk = None
|
||||||
@@ -1522,7 +1489,7 @@ def plannedsession_teamclone_view(request,id=0):
|
|||||||
|
|
||||||
url = reverse(plannedsession_teamedit_view,
|
url = reverse(plannedsession_teamedit_view,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'sessionid':ps.id,
|
'id':ps.id,
|
||||||
'userid':r.user.id,
|
'userid':r.user.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1531,54 +1498,16 @@ def plannedsession_teamclone_view(request,id=0):
|
|||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
url += '?when='+startdatestring+'/'+enddatestring
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
|
||||||
|
next = request.GET.get('next', url)
|
||||||
|
return HttpResponseRedirect(next)
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
|
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
|
||||||
@user_passes_test(hasplannedsessions, login_url="/rowers/paidplans/",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
redirect_field_name=None)
|
||||||
redirect_field_name=None)
|
def plannedsession_templateedit_view(request,id=0):
|
||||||
def plannedsession_totemplate_view(request,id=0):
|
r = getrequestrower(request)
|
||||||
|
|
||||||
r = getrequestplanrower(request)
|
|
||||||
|
|
||||||
startdate, enddate = get_dates_timeperiod(request)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ps = PlannedSession.objects.get(id=id)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
if ps.manager != request.user:
|
|
||||||
raise PermissionDenied("You can only store your own sessions as a template")
|
|
||||||
|
|
||||||
ps.pk = None
|
|
||||||
ps.id = None
|
|
||||||
ps.is_template = True
|
|
||||||
ps.startdate = datetime.date(1970,1,1)
|
|
||||||
ps.enddate = datetime.date(1970,1,1)
|
|
||||||
ps.save()
|
|
||||||
|
|
||||||
url = reverse(plannedsession_create_view,kwargs={'userid':r.user.id})
|
|
||||||
|
|
||||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
||||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
||||||
url += '?when='+startdatestring+'/'+enddatestring
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
# Edit an existing planned session
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
|
||||||
redirect_field_name=None)
|
|
||||||
def plannedsession_edit_view(request,id=0,userid=0):
|
|
||||||
|
|
||||||
r = getrequestplanrower(request,userid=userid)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
startdate,enddate = get_dates_timeperiod(request)
|
startdate,enddate = get_dates_timeperiod(request)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
trainingplan = TrainingPlan.objects.filter(
|
trainingplan = TrainingPlan.objects.filter(
|
||||||
startdate__lte = startdate,
|
startdate__lte = startdate,
|
||||||
@@ -1598,10 +1527,131 @@ def plannedsession_edit_view(request,id=0,userid=0):
|
|||||||
if ps.sessiontype in ['race','indoorrace']:
|
if ps.sessiontype in ['race','indoorrace']:
|
||||||
raise PermissionDenied("You are not allowed to edit this planned session because it is a race")
|
raise PermissionDenied("You are not allowed to edit this planned session because it is a race")
|
||||||
|
|
||||||
|
if not ps.is_template:
|
||||||
|
ps.pk = None
|
||||||
|
ps.id = None
|
||||||
|
ps.is_template = True
|
||||||
|
ps.startdate = datetime.date(1970,1,1)
|
||||||
|
ps.enddate = datetime.date(1970,1,1)
|
||||||
|
ps.team.clear()
|
||||||
|
ps.save()
|
||||||
|
|
||||||
|
sessioncreateform = PlannedSessionTemplateForm(instance=ps)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
sessioncreateform = PlannedSessionTemplateForm(request.POST,instance=ps)
|
||||||
|
if sessioncreateform.is_valid():
|
||||||
|
cd = sessioncreateform.cleaned_data
|
||||||
|
if cd['sessionunit'] == 'min':
|
||||||
|
cd['sessionmode'] = 'time'
|
||||||
|
elif cd['sessionunit'] in ['km','m']:
|
||||||
|
cd['sessionmode'] = 'distance'
|
||||||
|
|
||||||
|
res, message = update_plannedsession(ps,cd)
|
||||||
|
|
||||||
|
if res:
|
||||||
|
messages.info(request,message)
|
||||||
|
else:
|
||||||
|
messages.error(request,message)
|
||||||
|
|
||||||
|
url = reverse(plannedsession_templateedit_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':int(ps.id),
|
||||||
|
})
|
||||||
|
|
||||||
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||||
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
next = request.GET.get('next', url)
|
||||||
|
return HttpResponseRedirect(next)
|
||||||
|
|
||||||
|
breadcrumbs = [
|
||||||
|
{
|
||||||
|
'url': reverse(plannedsessions_view),
|
||||||
|
'name': 'Sessions'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url':reverse(plannedsession_templateedit_view,
|
||||||
|
kwargs={
|
||||||
|
'id':id,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'name': 'Edit'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)
|
||||||
|
|
||||||
|
return render(request,'plannedsessiontemplateedit.html',
|
||||||
|
{
|
||||||
|
'teams':get_my_teams(request.user),
|
||||||
|
'plan': trainingplan,
|
||||||
|
'breadcrumbs': breadcrumbs,
|
||||||
|
'form': sessioncreateform,
|
||||||
|
'active':'nav-plan',
|
||||||
|
'thesession': ps,
|
||||||
|
'sessiontemplates': sessiontemplates,
|
||||||
|
'rower': r,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
|
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
|
||||||
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
|
redirect_field_name=None)
|
||||||
|
def plannedsession_totemplate_view(request,id=0):
|
||||||
|
|
||||||
|
r = getrequestplanrower(request)
|
||||||
|
|
||||||
|
startdate, enddate = get_dates_timeperiod(request)
|
||||||
|
|
||||||
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
|
|
||||||
|
ps.pk = None
|
||||||
|
ps.id = None
|
||||||
|
ps.is_template = True
|
||||||
|
ps.startdate = datetime.date(1970,1,1)
|
||||||
|
ps.enddate = datetime.date(1970,1,1)
|
||||||
|
ps.save()
|
||||||
|
|
||||||
|
url = reverse(plannedsession_create_view,kwargs={'userid':r.user.id})
|
||||||
|
|
||||||
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||||
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||||
|
url += '?when='+startdatestring+'/'+enddatestring
|
||||||
|
|
||||||
|
next = request.GET.get('next', url)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(next)
|
||||||
|
|
||||||
|
# Edit an existing planned session
|
||||||
|
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
|
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
|
||||||
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
|
redirect_field_name=None)
|
||||||
|
def plannedsession_edit_view(request,id=0,userid=0):
|
||||||
|
|
||||||
|
r = getrequestplanrower(request,userid=userid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
startdate,enddate = get_dates_timeperiod(request)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
trainingplan = TrainingPlan.objects.filter(
|
||||||
|
startdate__lte = startdate,
|
||||||
|
rowers = r,
|
||||||
|
enddate__gte = enddate)[0]
|
||||||
|
except IndexError:
|
||||||
|
trainingplan = None
|
||||||
|
|
||||||
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
|
|
||||||
if ps.team.all() or ps.rower.all().count()>1:
|
if ps.team.all() or ps.rower.all().count()>1:
|
||||||
url = reverse(plannedsession_teamedit_view,
|
url = reverse(plannedsession_teamedit_view,
|
||||||
kwargs={
|
kwargs={
|
||||||
'sessionid':id,
|
'id':id,
|
||||||
})
|
})
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@@ -1697,38 +1747,29 @@ def plannedsession_edit_view(request,id=0,userid=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def plannedsession_detach_view(request,id=0,psid=0):
|
def plannedsession_detach_view(request,id=0,psid=0):
|
||||||
|
|
||||||
r = getrequestrower(request)
|
r = getrequestrower(request)
|
||||||
|
|
||||||
try:
|
|
||||||
ps = PlannedSession.objects.get(id=psid)
|
ps = get_object_or_404(PlannedSession,pk=psid)
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
return HttpResponseForbidden("Permission Error")
|
|
||||||
|
|
||||||
remove_workout_plannedsession(w,ps)
|
remove_workout_plannedsession(w,ps)
|
||||||
|
|
||||||
url = reverse(plannedsession_view,kwargs={'id':psid})
|
url = reverse(plannedsession_view,kwargs={'id':psid})
|
||||||
|
next = request.GET.get('next', url)
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(next)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
|
||||||
def plannedsession_view(request,id=0,userid=0):
|
def plannedsession_view(request,id=0,userid=0):
|
||||||
|
|
||||||
r = getrequestplanrower(request,userid=userid)
|
r = getrequestplanrower(request,userid=userid)
|
||||||
|
|
||||||
|
ps = get_object_or_404(PlannedSession,pk=id)
|
||||||
|
|
||||||
try:
|
|
||||||
ps = PlannedSession.objects.get(id=id)
|
|
||||||
except PlannedSession.DoesNotExist:
|
|
||||||
raise Http404("Planned Session does not exist")
|
|
||||||
|
|
||||||
if ps.sessiontype in ['race','indoorrace']:
|
if ps.sessiontype in ['race','indoorrace']:
|
||||||
url = reverse('virtualevent_view',
|
url = reverse('virtualevent_view',
|
||||||
@@ -1745,16 +1786,6 @@ def plannedsession_view(request,id=0,userid=0):
|
|||||||
m = ps.manager
|
m = ps.manager
|
||||||
mm = Rower.objects.get(user=m)
|
mm = Rower.objects.get(user=m)
|
||||||
|
|
||||||
if ps.manager != request.user:
|
|
||||||
if 'coach' in r.rowerplan and r not in ps.rower.all():
|
|
||||||
teams = Team.objects.filter(manager=request.user)
|
|
||||||
members = Rower.objects.filter(team__in=teams).distinct()
|
|
||||||
teamusers = [m.user for m in members]
|
|
||||||
if ps.manager not in teamusers:
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
elif r not in ps.rower.all():
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
|
|
||||||
resultsdict = get_session_metrics(ps)
|
resultsdict = get_session_metrics(ps)
|
||||||
resultsdict = pd.DataFrame(resultsdict).transpose().to_dict()
|
resultsdict = pd.DataFrame(resultsdict).transpose().to_dict()
|
||||||
|
|
||||||
@@ -1958,24 +1989,23 @@ class PlannedSessionDelete(DeleteView):
|
|||||||
w.save()
|
w.save()
|
||||||
|
|
||||||
url = reverse(plannedsessions_view)
|
url = reverse(plannedsessions_view)
|
||||||
|
next = self.request.GET.get('next',url)
|
||||||
|
|
||||||
return url
|
return next
|
||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs)
|
obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs)
|
||||||
m = Rower.objects.get(user=obj.manager)
|
if not can_delete_session(self.request.user,obj):
|
||||||
if not checkaccessuser(self.request.user,m):
|
|
||||||
raise PermissionDenied('You are not allowed to delete this planned session')
|
raise PermissionDenied('You are not allowed to delete this planned session')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def rower_create_trainingplan(request,userid=0):
|
def rower_create_trainingplan(request,id=0):
|
||||||
|
therower = getrequestrower(request,userid=id)
|
||||||
therower = getrequestrower(request,userid=userid)
|
|
||||||
theuser = therower.user
|
theuser = therower.user
|
||||||
themanager = getrower(request.user)
|
themanager = getrower(request.user)
|
||||||
|
|
||||||
@@ -2041,6 +2071,7 @@ def rower_create_trainingplan(request,userid=0):
|
|||||||
p.save()
|
p.save()
|
||||||
|
|
||||||
for athlete in athletes:
|
for athlete in athletes:
|
||||||
|
if can_plan_user(request.user,athlete):
|
||||||
p.rowers.add(athlete)
|
p.rowers.add(athlete)
|
||||||
|
|
||||||
|
|
||||||
@@ -2076,12 +2107,12 @@ def rower_create_trainingplan(request,userid=0):
|
|||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
'url':reverse(plannedsessions_view,
|
'url':reverse(plannedsessions_view,
|
||||||
kwargs={'userid':userid}),
|
kwargs={'userid':id}),
|
||||||
'name': 'Plan'
|
'name': 'Plan'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(rower_create_trainingplan,
|
'url':reverse(rower_create_trainingplan,
|
||||||
kwargs={'userid':userid}),
|
kwargs={'id':id}),
|
||||||
'name': 'Manage Plans and Targets'
|
'name': 'Manage Plans and Targets'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -2099,40 +2130,27 @@ def rower_create_trainingplan(request,userid=0):
|
|||||||
'old_targets':old_targets,
|
'old_targets':old_targets,
|
||||||
})
|
})
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('target.delete_target',fn=get_target_by_pk,raise_exception=True)
|
||||||
def rower_delete_trainingtarget(request,id=0):
|
def rower_delete_trainingtarget(request,id=0):
|
||||||
try:
|
|
||||||
target = TrainingTarget.objects.get(id=id)
|
|
||||||
except TrainingPlan.DoesNotExist:
|
|
||||||
raise Http404("Training Plan Does Not Exist")
|
|
||||||
|
|
||||||
if checkaccessuser(request.user,target.manager):
|
target = get_object_or_404(TrainingTarget,pk=id)
|
||||||
target.delete()
|
target.delete()
|
||||||
messages.info(request,"We have deleted the training target")
|
|
||||||
else:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
url = reverse(rower_create_trainingplan)
|
url = reverse(rower_create_trainingplan)
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('target.delete_plan',fn=get_plan_by_pk,raise_exception=True)
|
||||||
def rower_delete_trainingplan(request,id=0):
|
def rower_delete_trainingplan(request,id=0):
|
||||||
try:
|
plan = get_object_or_404(TrainingPlan,pk=id)
|
||||||
plan = TrainingPlan.objects.get(id=id)
|
|
||||||
except TrainingPlan.DoesNotExist:
|
|
||||||
raise Http404("Training Plan Does Not Exist")
|
|
||||||
|
|
||||||
if checkaccessuser(request.user,plan.manager):
|
|
||||||
plan.delete()
|
plan.delete()
|
||||||
messages.info(request,"We have deleted the training plan")
|
|
||||||
else:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
url = reverse(rower_create_trainingplan)
|
url = reverse(rower_create_trainingplan)
|
||||||
|
|
||||||
@@ -2145,7 +2163,7 @@ class TrainingPlanDelete(DeleteView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
|
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.manager):
|
if not can_delete_plan(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to delete this training plan')
|
raise PermissionDenied('You are not allowed to delete this training plan')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
@@ -2211,7 +2229,7 @@ class MicroCycleDelete(DeleteView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
|
obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.plan.plan.plan.manager):
|
if not can_delete_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@@ -2273,7 +2291,7 @@ class MesoCycleDelete(DeleteView):
|
|||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)
|
obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)
|
||||||
|
|
||||||
if not checkaccessuser(self.request.user,obj.plan.plan.manager):
|
if not can_delete_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
@@ -2327,13 +2345,13 @@ class MacroCycleDelete(DeleteView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
|
obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.plan.manager):
|
if not can_delete_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def rower_trainingplan_execution_view(request,
|
def rower_trainingplan_execution_view(request,
|
||||||
@@ -2350,7 +2368,7 @@ def rower_trainingplan_execution_view(request,
|
|||||||
plan = TrainingPlan.objects.get(id=id)
|
plan = TrainingPlan.objects.get(id=id)
|
||||||
except TrainingPlan.DoesNotExist:
|
except TrainingPlan.DoesNotExist:
|
||||||
raise Http404("Training Plan Does Not Exist")
|
raise Http404("Training Plan Does Not Exist")
|
||||||
if not checkaccessuser(request.user,plan.manager):
|
if not is_coach_user(request.user,plan.manager.user):
|
||||||
if request.user.rower not in plan.rowers.all():
|
if request.user.rower not in plan.rowers.all():
|
||||||
raise PermissionDenied("Access denied")
|
raise PermissionDenied("Access denied")
|
||||||
|
|
||||||
@@ -2423,9 +2441,11 @@ def rower_trainingplan_execution_view(request,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
#@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
# message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
# redirect_field_name=None)
|
||||||
|
@login_required()
|
||||||
|
@permission_required('plan.view_plan',fn=get_plan_by_pk,raise_exception=True)
|
||||||
def rower_trainingplan_view(request,
|
def rower_trainingplan_view(request,
|
||||||
id=0,
|
id=0,
|
||||||
userid=0,
|
userid=0,
|
||||||
@@ -2436,18 +2456,9 @@ def rower_trainingplan_view(request,
|
|||||||
|
|
||||||
startdate,enddate = get_dates_timeperiod(request)
|
startdate,enddate = get_dates_timeperiod(request)
|
||||||
|
|
||||||
|
plan = get_object_or_404(TrainingPlan,pk=id)
|
||||||
try:
|
|
||||||
plan = TrainingPlan.objects.get(id=id)
|
|
||||||
except TrainingPlan.DoesNotExist:
|
|
||||||
raise Http404("Training Plan Does Not Exist")
|
|
||||||
|
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
if not checkaccessuser(request.user,plan.manager):
|
|
||||||
if request.user.rower not in plan.rowers.all():
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
createmacrofillers(plan)
|
createmacrofillers(plan)
|
||||||
macrocycles = TrainingMacroCycle.objects.filter(
|
macrocycles = TrainingMacroCycle.objects.filter(
|
||||||
plan=plan,
|
plan=plan,
|
||||||
@@ -2570,10 +2581,7 @@ class TrainingMacroCycleUpdate(UpdateView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs)
|
obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs)
|
||||||
if obj.plan.manager is not None and self.request.user.rower != obj.plan.manager:
|
if not can_change_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
||||||
|
|
||||||
if not checkaccessuser(self.request.user,obj.plan.manager):
|
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||||
else:
|
else:
|
||||||
obj.type = 'userdefined'
|
obj.type = 'userdefined'
|
||||||
@@ -2644,7 +2652,7 @@ class TrainingMesoCycleUpdate(UpdateView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs)
|
obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs)
|
||||||
if obj.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.manager:
|
if not can_change_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -2722,7 +2730,7 @@ class TrainingMicroCycleUpdate(UpdateView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs)
|
obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs)
|
||||||
if obj.plan.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.plan.manager:
|
if not can_change_cycle(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||||
|
|
||||||
|
|
||||||
@@ -2787,10 +2795,8 @@ class TrainingPlanUpdate(UpdateView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs)
|
obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs)
|
||||||
if obj.manager is not None and self.request.user.rower != obj.manager:
|
if not can_change_plan(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||||
if obj.manager.rowerplan not in ['coach','freecoach','plan']:
|
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan')
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@@ -2839,24 +2845,19 @@ class TrainingTargetUpdate(UpdateView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs)
|
obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs)
|
||||||
if obj.manager is not None and self.request.user.rower != obj.manager:
|
if not can_change_target(self.request.user,obj):
|
||||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
from rowers.utils import allsundays
|
from rowers.utils import allsundays
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('cycle.change_cycle',fn=get_meso_by_pk,raise_exception=True)
|
||||||
def planmesocyclebyweek(request,id=0,userid=0):
|
def planmesocyclebyweek(request,id=0,userid=0):
|
||||||
try:
|
cycle = get_object_or_404(TrainingMesoCycle,pk=id)
|
||||||
cycle = TrainingMesoCycle.objects.get(id=id)
|
|
||||||
except TrainingMesoCycle.DoesNotExist:
|
|
||||||
raise Http404("Training Cycle does not exist")
|
|
||||||
|
|
||||||
if not checkaccessuser(request.user,cycle.plan.plan.manager):
|
|
||||||
raise PermissionDenied("You are not allowed to do this")
|
|
||||||
|
|
||||||
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
||||||
for m in micros:
|
for m in micros:
|
||||||
@@ -2901,17 +2902,12 @@ def planmesocyclebyweek(request,id=0,userid=0):
|
|||||||
|
|
||||||
from rowers.utils import allmonths
|
from rowers.utils import allmonths
|
||||||
|
|
||||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
@user_passes_test(can_plan,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Coach or Self-Coach plan",
|
message="This functionality requires a Coach or Self-Coach plan",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('cycle.change_cycle',fn=get_macro_by_pk,raise_exception=True)
|
||||||
def planmacrocyclebymonth(request,id=0,userid=0):
|
def planmacrocyclebymonth(request,id=0,userid=0):
|
||||||
try:
|
cycle = get_object_or_404(TrainingMacroCycle,pk=id)
|
||||||
cycle = TrainingMacroCycle.objects.get(id=id)
|
|
||||||
except TrainingMacroCycle.DoesNotExist:
|
|
||||||
raise Http404("Training Cycle does not exist")
|
|
||||||
|
|
||||||
if not checkaccessuser(request.user,cycle.plan.manager):
|
|
||||||
raise PermissionDenied("You are not allowed to do this")
|
|
||||||
|
|
||||||
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
||||||
for m in mesos:
|
for m in mesos:
|
||||||
|
|||||||
+21
-64
@@ -7,7 +7,6 @@ from rowers.views.statements import *
|
|||||||
|
|
||||||
|
|
||||||
# List Courses
|
# List Courses
|
||||||
@login_required()
|
|
||||||
def courses_view(request):
|
def courses_view(request):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
@@ -81,17 +80,12 @@ def course_map_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('course.change_course',fn=get_course_by_pk,raise_exception=True)
|
||||||
def course_replace_view(request,id=0):
|
def course_replace_view(request,id=0):
|
||||||
try:
|
course = get_object_or_404(GeoCourse,pk=id)
|
||||||
course = GeoCourse.objects.get(id=id)
|
|
||||||
except GeoCourse.DoesNotExist:
|
|
||||||
return Http404("Course doesn't exist")
|
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if course.manager != r:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
thecourses = GeoCourse.objects.filter(manager=r).exclude(id=id)
|
thecourses = GeoCourse.objects.filter(manager=r).exclude(id=id)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@@ -143,17 +137,12 @@ def course_replace_view(request,id=0):
|
|||||||
'form':form})
|
'form':form})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('course.delete_course',fn=get_course_by_pk,raise_exception=True)
|
||||||
def course_delete_view(request,id=0):
|
def course_delete_view(request,id=0):
|
||||||
try:
|
course = get_object_or_404(GeoCourse,pk=id)
|
||||||
course = GeoCourse.objects.get(id=id)
|
|
||||||
except GeoCourse.DoesNotExist:
|
|
||||||
return Http404("Course doesn't exist")
|
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if course.manager != r:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
ps = PlannedSession.objects.filter(course=course)
|
ps = PlannedSession.objects.filter(course=course)
|
||||||
nosessions = len(ps) == 0
|
nosessions = len(ps) == 0
|
||||||
|
|
||||||
@@ -165,17 +154,12 @@ def course_delete_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('course.change_course',fn=get_course_by_pk,raise_exception=True)
|
||||||
def course_edit_view(request,id=0):
|
def course_edit_view(request,id=0):
|
||||||
try:
|
course = get_object_or_404(GeoCourse,pk=id)
|
||||||
course = GeoCourse.objects.get(id=id)
|
|
||||||
except GeoCourse.DoesNotExist:
|
|
||||||
return Http404("Course doesn't exist")
|
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if course.manager != r:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
ps = PlannedSession.objects.filter(course=course)
|
ps = PlannedSession.objects.filter(course=course)
|
||||||
nosessions = len(ps) == 0
|
nosessions = len(ps) == 0
|
||||||
|
|
||||||
@@ -266,11 +250,10 @@ def course_view(request,id=0):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('racelogo.delete_logo',fn=get_logo_by_pk,raise_exception=True)
|
||||||
def logo_delete_view(request,id=0):
|
def logo_delete_view(request,id=0):
|
||||||
try:
|
logo = get_object_or_404(RaceLogo,pk=id)
|
||||||
logo = RaceLogo.objects.get(id=id)
|
|
||||||
except RaceLogo.DoesNotExist:
|
|
||||||
raise Http404("Logo doesn't exist")
|
|
||||||
|
|
||||||
if logo.user == request.user:
|
if logo.user == request.user:
|
||||||
logo.delete()
|
logo.delete()
|
||||||
@@ -281,18 +264,11 @@ def logo_delete_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('virtualevent.change_race',fn=get_virtualevent_by_pk,raise_exception=True)
|
||||||
def virtualevent_setlogo_view(request,id=0,logoid=0):
|
def virtualevent_setlogo_view(request,id=0,logoid=0):
|
||||||
try:
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
race = VirtualRace.objects.get(id=id)
|
logo = get_object_or_404(RaceLogo,pk=logoid)
|
||||||
except VirtualRace.DoesNotExist:
|
|
||||||
raise Http404("Race doesn't exist")
|
|
||||||
|
|
||||||
try:
|
|
||||||
logo = RaceLogo.objects.get(id=logoid)
|
|
||||||
except RaceLogo.DoesNotExist:
|
|
||||||
raise Http404("Logo doesn't exist")
|
|
||||||
|
|
||||||
if logo.user == request.user and race.manager == request.user:
|
|
||||||
otherlogos = race.logos.all()
|
otherlogos = race.logos.all()
|
||||||
for otherlogo in otherlogos:
|
for otherlogo in otherlogos:
|
||||||
otherlogo.race.remove(race)
|
otherlogo.race.remove(race)
|
||||||
@@ -300,9 +276,6 @@ def virtualevent_setlogo_view(request,id=0,logoid=0):
|
|||||||
|
|
||||||
logo.race.add(race)
|
logo.race.add(race)
|
||||||
logo.save()
|
logo.save()
|
||||||
else:
|
|
||||||
message = "You do not own this race or this image"
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
url = reverse('virtualevent_view',
|
url = reverse('virtualevent_view',
|
||||||
kwargs={'id':id})
|
kwargs={'id':id})
|
||||||
@@ -318,10 +291,7 @@ def virtualevent_uploadimage_view(request,id=0):
|
|||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
try:
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
race = VirtualRace.objects.get(id=id)
|
|
||||||
except VirtualRace.DoesNotExist:
|
|
||||||
raise Http404("Race doesn't exist")
|
|
||||||
|
|
||||||
logos = RaceLogo.objects.filter(user=request.user).order_by("-creationdatetime")
|
logos = RaceLogo.objects.filter(user=request.user).order_by("-creationdatetime")
|
||||||
|
|
||||||
@@ -576,17 +546,12 @@ def virtualevents_view(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def virtualevent_disqualify_view(request,raceid=0,recordid=0):
|
@permission_required('virtualevent.change_race',fn=get_virtualevent_by_pk,raise_exception=True)
|
||||||
|
def virtualevent_disqualify_view(request,id=0,recordid=0):
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
|
|
||||||
try:
|
|
||||||
race = VirtualRace.objects.get(id=raceid)
|
|
||||||
except VirtualRace.DoesNotExist:
|
|
||||||
raise Http404("Virtual Race does not exist")
|
|
||||||
|
|
||||||
if r.user != race.manager:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
if race.sessiontype == 'race':
|
if race.sessiontype == 'race':
|
||||||
recordobj = VirtualRaceResult
|
recordobj = VirtualRaceResult
|
||||||
@@ -1872,15 +1837,12 @@ def virtualevent_create_view(request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('virtualevent.change_race',fn=get_virtualevent_by_pk,raise_exception=True)
|
||||||
def virtualevent_edit_view(request,id=0):
|
def virtualevent_edit_view(request,id=0):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
race = VirtualRace.objects.get(id=id)
|
|
||||||
if race.manager != request.user:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
except VirtualRace.DoesNotExist:
|
|
||||||
raise Http404("Virtual Race does not exist")
|
|
||||||
|
|
||||||
start_time = race.start_time
|
start_time = race.start_time
|
||||||
start_date = race.startdate
|
start_date = race.startdate
|
||||||
@@ -1970,15 +1932,10 @@ def virtualevent_edit_view(request,id=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('virtualevent.change_race',fn=get_virtualevent_by_pk,raise_exception=True)
|
||||||
def indoorvirtualevent_edit_view(request,id=0):
|
def indoorvirtualevent_edit_view(request,id=0):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
try:
|
|
||||||
race = VirtualRace.objects.get(id=id)
|
|
||||||
if race.manager != request.user:
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
except VirtualRace.DoesNotExist:
|
|
||||||
raise Http404("Virtual Race does not exist")
|
|
||||||
|
|
||||||
start_time = race.start_time
|
start_time = race.start_time
|
||||||
start_date = race.startdate
|
start_date = race.startdate
|
||||||
|
|||||||
+107
-98
@@ -19,6 +19,7 @@ from django.db.models import Q
|
|||||||
from django import template
|
from django import template
|
||||||
from django.db import IntegrityError, transaction
|
from django.db import IntegrityError, transaction
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from matplotlib.backends.backend_agg import FigureCanvas
|
from matplotlib.backends.backend_agg import FigureCanvas
|
||||||
import gc
|
import gc
|
||||||
from pyparsing import ParseException
|
from pyparsing import ParseException
|
||||||
@@ -31,10 +32,22 @@ from icalendar import Calendar, Event
|
|||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
|
from rules.contrib.views import PermissionRequiredMixin
|
||||||
|
|
||||||
import rowers.braintreestuff as braintreestuff
|
import rowers.braintreestuff as braintreestuff
|
||||||
import rowers.payments as payments
|
import rowers.payments as payments
|
||||||
from rowers.opaque import encoder
|
from rowers.opaque import encoder
|
||||||
|
|
||||||
|
from rowers.rower_rules import (
|
||||||
|
ispromember,is_coach_user,is_team_member,is_rower_team_member,
|
||||||
|
is_workout_user,isplanmember,can_delete_session,
|
||||||
|
can_view_target,can_change_target,can_delete_target,
|
||||||
|
can_view_plan,can_change_plan,can_delete_plan,
|
||||||
|
can_view_cycle,can_change_cycle,can_delete_cycle,
|
||||||
|
can_add_workout_member,can_plan_user,is_paid_coach,
|
||||||
|
can_start_trial, can_start_plantrial,can_plan,is_workout_team
|
||||||
|
)
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
@@ -97,7 +110,7 @@ from rowers.models import (
|
|||||||
TrainingMesoCycleForm, TrainingMicroCycleForm,
|
TrainingMesoCycleForm, TrainingMicroCycleForm,
|
||||||
RaceLogo,RowerBillingAddressForm,PaidPlan,
|
RaceLogo,RowerBillingAddressForm,PaidPlan,
|
||||||
AlertEditForm, ConditionEditForm,
|
AlertEditForm, ConditionEditForm,
|
||||||
PlannedSessionComment,CoachRequest,CoachOffer,checkaccessplanuser,
|
PlannedSessionComment,CoachRequest,CoachOffer,
|
||||||
VideoAnalysis
|
VideoAnalysis
|
||||||
)
|
)
|
||||||
from rowers.models import (
|
from rowers.models import (
|
||||||
@@ -107,7 +120,7 @@ from rowers.models import (
|
|||||||
WorkoutComment,WorkoutCommentForm,RowerExportForm,
|
WorkoutComment,WorkoutCommentForm,RowerExportForm,
|
||||||
CalcAgePerformance,
|
CalcAgePerformance,
|
||||||
PowerTimeFitnessMetric,BlogPost,
|
PowerTimeFitnessMetric,BlogPost,
|
||||||
PlannedSessionForm,
|
PlannedSessionForm,PlannedSessionTemplateForm,
|
||||||
PlannedSessionFormSmall,GeoCourseEditForm,VirtualRace,
|
PlannedSessionFormSmall,GeoCourseEditForm,VirtualRace,
|
||||||
VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm,
|
VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm,
|
||||||
IndoorVirtualRaceResultForm,IndoorVirtualRaceResult,
|
IndoorVirtualRaceResultForm,IndoorVirtualRaceResult,
|
||||||
@@ -240,7 +253,7 @@ from rq import Queue,cancel_job
|
|||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django_mailbox.models import Message,Mailbox,MessageAttachment
|
from django_mailbox.models import Message,Mailbox,MessageAttachment
|
||||||
|
|
||||||
|
from rules.contrib.views import permission_required, objectgetter
|
||||||
|
|
||||||
# Utility to get stroke data in a JSON response
|
# Utility to get stroke data in a JSON response
|
||||||
class JSONResponse(HttpResponse):
|
class JSONResponse(HttpResponse):
|
||||||
@@ -274,6 +287,49 @@ def getfavorites(r,row):
|
|||||||
|
|
||||||
return favorites,maxfav
|
return favorites,maxfav
|
||||||
|
|
||||||
|
def get_logo_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(RaceLogo,pk=id)
|
||||||
|
|
||||||
|
def get_virtualevent_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(VirtualRace,pk=id)
|
||||||
|
|
||||||
|
def get_promember(request,*args,**kwargs):
|
||||||
|
return request.user
|
||||||
|
|
||||||
|
def get_course_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(GeoCourse,pk=id)
|
||||||
|
|
||||||
|
def get_workout_by_opaqueid(request,id,**kwargs):
|
||||||
|
pk = encoder.decode_hex(id)
|
||||||
|
return get_object_or_404(Workout,pk=pk)
|
||||||
|
|
||||||
|
def get_session_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(PlannedSession,pk=id)
|
||||||
|
|
||||||
|
def get_target_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(TrainingTarget,pk=id)
|
||||||
|
|
||||||
|
def get_plan_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(TrainingPlan,pk=id)
|
||||||
|
|
||||||
|
def get_macro_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(TrainingMacroCycle,pk=id)
|
||||||
|
|
||||||
|
def get_meso_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(TrainingMesoCycle,pk=id)
|
||||||
|
|
||||||
|
def get_micro_by_pk(request,*args,**kwargs):
|
||||||
|
id = kwargs['id']
|
||||||
|
return get_object_or_404(TrainingMicroCycle,pk=id)
|
||||||
|
|
||||||
def get_workout_default_page(request,id):
|
def get_workout_default_page(request,id):
|
||||||
if request.user.is_anonymous:
|
if request.user.is_anonymous:
|
||||||
return reverse('workout_view',kwargs={'id':id})
|
return reverse('workout_view',kwargs={'id':id})
|
||||||
@@ -284,11 +340,42 @@ def get_workout_default_page(request,id):
|
|||||||
else:
|
else:
|
||||||
return reverse('workout_workflow_view',kwargs={'id':id})
|
return reverse('workout_workflow_view',kwargs={'id':id})
|
||||||
|
|
||||||
def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
def get_user_by_userid(*args,**kwargs):
|
||||||
|
request = args[0]
|
||||||
|
try:
|
||||||
|
id = kwargs['userid']
|
||||||
|
except KeyError:
|
||||||
|
id = request.user.id
|
||||||
|
|
||||||
|
if id is not None and int(id) == 0:
|
||||||
|
id = request.user.id
|
||||||
|
|
||||||
|
u = get_object_or_404(User,pk=id)
|
||||||
|
return u
|
||||||
|
|
||||||
|
def get_user_by_id(*args,**kwargs):
|
||||||
|
request = args[0]
|
||||||
|
try:
|
||||||
|
id = args[1]
|
||||||
|
except IndexError:
|
||||||
|
try:
|
||||||
|
id = kwargs['id']
|
||||||
|
except KeyError:
|
||||||
|
id = request.user.id
|
||||||
|
|
||||||
|
return get_object_or_404(User,pk=id)
|
||||||
|
|
||||||
|
def get_rower_by_id(request,id):
|
||||||
|
u = User.objects.get(id=id)
|
||||||
|
return u.rower
|
||||||
|
|
||||||
|
def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
||||||
userid = int(userid)
|
userid = int(userid)
|
||||||
rowerid = int(rowerid)
|
rowerid = int(rowerid)
|
||||||
|
|
||||||
|
if userid == 0:
|
||||||
|
userid = request.user.id
|
||||||
|
|
||||||
if notpermanent == False:
|
if notpermanent == False:
|
||||||
if rowerid == 0 and 'rowerid' in request.session:
|
if rowerid == 0 and 'rowerid' in request.session:
|
||||||
rowerid = request.session['rowerid']
|
rowerid = request.session['rowerid']
|
||||||
@@ -300,16 +387,25 @@ def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
|||||||
|
|
||||||
if rowerid != 0:
|
if rowerid != 0:
|
||||||
r = Rower.objects.get(id=rowerid)
|
r = Rower.objects.get(id=rowerid)
|
||||||
|
u = r.user
|
||||||
elif userid != 0:
|
elif userid != 0:
|
||||||
u = User.objects.get(id=userid)
|
u = User.objects.get(id=userid)
|
||||||
r = getrower(u)
|
r = getrower(u)
|
||||||
|
elif request.user.is_anonymous:
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
u = r.user
|
||||||
|
|
||||||
|
|
||||||
except Rower.DoesNotExist:
|
except Rower.DoesNotExist:
|
||||||
raise Http404("Rower doesn't exist")
|
raise Http404("Rower doesn't exist")
|
||||||
|
|
||||||
if not checkaccessuser(request.user,r):
|
if r.user == request.user:
|
||||||
|
return r
|
||||||
|
|
||||||
|
if userid != 0 and not is_rower_team_member(request.user,u.rower):
|
||||||
|
request.session['rowerid'] = request.user.rower.id
|
||||||
raise PermissionDenied("You have no access to this user")
|
raise PermissionDenied("You have no access to this user")
|
||||||
|
|
||||||
if notpermanent == False:
|
if notpermanent == False:
|
||||||
@@ -342,7 +438,8 @@ def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False):
|
|||||||
except Rower.DoesNotExist:
|
except Rower.DoesNotExist:
|
||||||
raise Http404("Rower doesn't exist")
|
raise Http404("Rower doesn't exist")
|
||||||
|
|
||||||
if not checkaccessplanuser(request.user,r):
|
if r.user != request.user and not can_plan_user(request.user,r ):
|
||||||
|
request.session['rowerid'] = r.id
|
||||||
raise PermissionDenied("You have no access to this user")
|
raise PermissionDenied("You have no access to this user")
|
||||||
|
|
||||||
if notpermanent == False:
|
if notpermanent == False:
|
||||||
@@ -376,21 +473,6 @@ def get_workout(id):
|
|||||||
|
|
||||||
return w
|
return w
|
||||||
|
|
||||||
def get_workout_permitted(user,id):
|
|
||||||
w = get_workout(id)
|
|
||||||
|
|
||||||
if (checkworkoutuser(user,w)==False):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
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
|
||||||
@@ -432,7 +514,6 @@ class SessionTaskListener(threading.Thread):
|
|||||||
for item in self.pubsub.listen():
|
for item in self.pubsub.listen():
|
||||||
if item['data'] == "KILL":
|
if item['data'] == "KILL":
|
||||||
self.pubsub.unsubscribe()
|
self.pubsub.unsubscribe()
|
||||||
print(self, "unsubscribed and finished")
|
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.work(item)
|
self.work(item)
|
||||||
@@ -773,9 +854,9 @@ def get_stored_tasks_status(request):
|
|||||||
|
|
||||||
return taskstatus
|
return taskstatus
|
||||||
|
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def get_thumbnails(request,id):
|
def get_thumbnails(request,id):
|
||||||
row = get_workout_permitted(request.user,id)
|
row = get_workout_by_opaqueid(request,id)
|
||||||
|
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
@@ -860,27 +941,6 @@ def get_blog_posts_old(request):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
|
||||||
def get_testscript(request,id):
|
|
||||||
row = get_workout_permitted(request.user,id)
|
|
||||||
r = getrower(request.user)
|
|
||||||
|
|
||||||
object = {
|
|
||||||
"script":"""
|
|
||||||
<div id="id_script">
|
|
||||||
<script>alert("hi")</script>
|
|
||||||
</div>
|
|
||||||
""",
|
|
||||||
"div":"""
|
|
||||||
<div id="id_div">
|
|
||||||
Hoi
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return JSONResponse([object,object])
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def session_jobs_view(request):
|
def session_jobs_view(request):
|
||||||
taskstatus = get_stored_tasks_status(request)
|
taskstatus = get_stored_tasks_status(request)
|
||||||
@@ -923,10 +983,10 @@ def rowhascoordinates(row):
|
|||||||
def rdata(file,rower=rrower()):
|
def rdata(file,rower=rrower()):
|
||||||
try:
|
try:
|
||||||
res = rrdata(csvfile=file,rower=rower)
|
res = rrdata(csvfile=file,rower=rower)
|
||||||
except (IOError, IndexError, EOFError):
|
except (IOError, IndexError, EOFError,FileNotFoundError):
|
||||||
try:
|
try:
|
||||||
res = rrdata(csvfile=file+'.gz',rower=rower)
|
res = rrdata(csvfile=file+'.gz',rower=rower)
|
||||||
except (IOError, IndexError, EOFError):
|
except (IOError, IndexError, EOFError,FileNotFoundError):
|
||||||
res = 0
|
res = 0
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@@ -989,10 +1049,6 @@ from rowers.utils import (
|
|||||||
|
|
||||||
import rowers.datautils as datautils
|
import rowers.datautils as datautils
|
||||||
|
|
||||||
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):
|
||||||
if not user.is_anonymous:
|
if not user.is_anonymous:
|
||||||
@@ -1008,56 +1064,9 @@ def iscoachmember(user):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def cancreateteam(user):
|
|
||||||
if user.is_anonymous:
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
r = Rower(user=user)
|
|
||||||
r.save()
|
|
||||||
|
|
||||||
if user.is_authenticated and ('coach' in r.rowerplan):
|
|
||||||
return True
|
|
||||||
elif user.is_athenticated() and r.rowerplan in ['plan','pro']:
|
|
||||||
ts = Team.objects.filter(manager=user)
|
|
||||||
if len(otherteams) >= 1:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Check if a user can create planned sessions
|
|
||||||
def hasplannedsessions(user):
|
|
||||||
if not user.is_anonymous:
|
|
||||||
try:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
r = Rower(user=user)
|
|
||||||
r.save()
|
|
||||||
|
|
||||||
result = user.is_authenticated and (r.rowerplan=='coach' or r.rowerplan=='freecoach' or r.rowerplan=='plan')
|
|
||||||
if not result and r.plantrialexpires:
|
|
||||||
result = user.is_authenticated and r.plantrialexpires >= datetime.date.today()
|
|
||||||
else:
|
|
||||||
result = False
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
from rowers.utils import ProcessorCustomerError
|
from rowers.utils import ProcessorCustomerError
|
||||||
from rowers.utils import isprorower
|
|
||||||
|
|
||||||
# Check if a user is a Pro member
|
|
||||||
def ispromember(user):
|
|
||||||
if user and not user.is_anonymous:
|
|
||||||
try:
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
r = Rower(user=user)
|
|
||||||
r.save()
|
|
||||||
|
|
||||||
result = user.is_authenticated and isprorower(r)
|
|
||||||
else:
|
|
||||||
result = False
|
|
||||||
return result
|
|
||||||
|
|
||||||
# More User/Rower utils
|
# More User/Rower utils
|
||||||
def add_defaultfavorites(r):
|
def add_defaultfavorites(r):
|
||||||
|
|||||||
+41
-59
@@ -5,9 +5,16 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
|
|
||||||
|
from rowers.rower_rules import *
|
||||||
|
|
||||||
|
def get_team_by_pk(request,team_id):
|
||||||
|
return get_object_or_404(Team,pk=team_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def team_view(request,id=0,userid=0):
|
@permission_required('teams.view_team',fn=get_team_by_pk,raise_exception=True)
|
||||||
|
def team_view(request,team_id=0,userid=0):
|
||||||
ismember = 0
|
ismember = 0
|
||||||
hasrequested = 0
|
hasrequested = 0
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
@@ -15,15 +22,10 @@ def team_view(request,id=0,userid=0):
|
|||||||
myteams, memberteams, otherteams = get_teams(request)
|
myteams, memberteams, otherteams = get_teams(request)
|
||||||
teams.remove_expired_invites()
|
teams.remove_expired_invites()
|
||||||
|
|
||||||
|
t = get_object_or_404(Team,pk=team_id)
|
||||||
|
|
||||||
|
#if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
|
||||||
try:
|
# raise PermissionDenied("You need to be on a Paid Plan to see or join this team")
|
||||||
t = Team.objects.get(id=id)
|
|
||||||
except Team.DoesNotExist:
|
|
||||||
raise Http404("Team doesn't exist")
|
|
||||||
|
|
||||||
if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
|
|
||||||
raise PermissionDenied("You need to be on a Paid Plan to see or join this team")
|
|
||||||
|
|
||||||
|
|
||||||
q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
||||||
@@ -83,7 +85,7 @@ def team_view(request,id=0,userid=0):
|
|||||||
'name': 'Groups'
|
'name': 'Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_view,kwargs={'id':id}),
|
'url':reverse(team_view,kwargs={'team_id':team_id}),
|
||||||
'name': t.name
|
'name': t.name
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -119,7 +121,7 @@ def team_leaveconfirm_view(request,id=0):
|
|||||||
'name': 'Groups'
|
'name': 'Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_view,kwargs={'id':id}),
|
'url':reverse(team_view,kwargs={'team_id':id}),
|
||||||
'name': t.name
|
'name': t.name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -435,11 +437,12 @@ def team_requestmembership_view(request,teamid,userid):
|
|||||||
|
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
if t.manager.rower.rowerplan in ['plan','pro'] and r.rowerplan == 'basic':
|
#if t.manager.rower.rowerplan in ['plan','pro'] and r.rowerplan == 'basic':
|
||||||
|
if not can_join_team(r.user,t):
|
||||||
messages.error(request,
|
messages.error(request,
|
||||||
"You have to be on a paid plan (Pro or higher) to join this team. As a basic user you can only join teams managed by users on the Coach plan.")
|
"You have to be on a paid plan (Pro or higher) to join this team. As a basic user you can only join teams managed by users on the Coach plan.")
|
||||||
|
|
||||||
url = reverse('paidplans')
|
url = reverse('paidplans_view')
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
res,text = teams.create_request(t,userid)
|
res,text = teams.create_request(t,userid)
|
||||||
@@ -450,7 +453,7 @@ def team_requestmembership_view(request,teamid,userid):
|
|||||||
|
|
||||||
|
|
||||||
url = reverse('team_view',kwargs={
|
url = reverse('team_view',kwargs={
|
||||||
'id':int(teamid),
|
'team_id':int(teamid),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -571,7 +574,7 @@ def rower_invitations_view(request,code=None,message='',successmessage=''):
|
|||||||
messages.info(request,text)
|
messages.info(request,text)
|
||||||
teamid=res
|
teamid=res
|
||||||
url = reverse(team_view,kwargs={
|
url = reverse(team_view,kwargs={
|
||||||
'id':teamid,
|
'team_id':teamid,
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
messages.error(request,text)
|
messages.error(request,text)
|
||||||
@@ -585,11 +588,10 @@ def rower_invitations_view(request,code=None,message='',successmessage=''):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def team_edit_view(request,id=0):
|
@permission_required('teams.change_team',fn=get_team_by_pk,raise_exception=True)
|
||||||
try:
|
def team_edit_view(request, team_id=0):
|
||||||
t = Team.objects.get(id=id)
|
t = get_object_or_404(Team,pk=team_id)
|
||||||
except Team.DoesNotExist:
|
|
||||||
raise Http404("Team does not exist")
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
teamcreateform = TeamForm(request.POST,instance=t)
|
teamcreateform = TeamForm(request.POST,instance=t)
|
||||||
@@ -609,7 +611,7 @@ def team_edit_view(request,id=0):
|
|||||||
|
|
||||||
url = reverse(team_view,
|
url = reverse(team_view,
|
||||||
kwargs={
|
kwargs={
|
||||||
'id':int(id),
|
'team_id':int(team_id),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -627,11 +629,11 @@ def team_edit_view(request,id=0):
|
|||||||
'name': 'Groups'
|
'name': 'Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_view,kwargs={'id':id}),
|
'url':reverse(team_view,kwargs={'team_id':team_id}),
|
||||||
'name': t.name
|
'name': t.name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_edit_view,kwargs={'id':id}),
|
'url':reverse(team_edit_view,kwargs={'team_id':team_id}),
|
||||||
'name': 'Edit'
|
'name': 'Edit'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -648,19 +650,11 @@ def team_edit_view(request,id=0):
|
|||||||
'team':t,
|
'team':t,
|
||||||
})
|
})
|
||||||
|
|
||||||
#@user_passes_test(cancreateteam,login_url="/rowers/paidplans",redirect_field_name=None)
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@user_passes_test(can_add_team,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||||
def team_create_view(request):
|
def team_create_view(request):
|
||||||
r = getrequestrower(request)
|
r = getrequestrower(request)
|
||||||
|
|
||||||
if r.rowerplan == 'basic':
|
|
||||||
if r.protrialexpires < timezone.now().date() and r.plantrialexpires < timezone.now().date():
|
|
||||||
messages.error(request,"You must upgrade to Pro or higher to create teams/training groups")
|
|
||||||
url = reverse('paidplans')
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
teamcreateform = TeamForm(request.POST)
|
teamcreateform = TeamForm(request.POST)
|
||||||
if teamcreateform.is_valid():
|
if teamcreateform.is_valid():
|
||||||
@@ -675,7 +669,7 @@ def team_create_view(request):
|
|||||||
|
|
||||||
if not res:
|
if not res:
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
url = reverse('paidplans')
|
url = reverse('paidplans_view')
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
url = reverse('rower_teams_view')
|
url = reverse('rower_teams_view')
|
||||||
@@ -708,15 +702,11 @@ def team_create_view(request):
|
|||||||
'breadcrumbs':breadcrumbs,
|
'breadcrumbs':breadcrumbs,
|
||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
#@login_required()
|
||||||
def team_deleteconfirm_view(request,id):
|
@permission_required('teams.delete_team',fn=get_team_by_pk,raise_exception=True)
|
||||||
|
def team_deleteconfirm_view(request,team_id):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
try:
|
t = get_object_or_404(Team,pk=team_id)
|
||||||
t = Team.objects.get(id=id)
|
|
||||||
except Team.DoesNotExist:
|
|
||||||
raise Http404("This team doesn't exist")
|
|
||||||
if t.manager != request.user:
|
|
||||||
raise PermissionDenied("You are not allowed to delete this team")
|
|
||||||
|
|
||||||
myteams, memberteams, otherteams = get_teams(request)
|
myteams, memberteams, otherteams = get_teams(request)
|
||||||
|
|
||||||
@@ -726,11 +716,11 @@ def team_deleteconfirm_view(request,id):
|
|||||||
'name': 'Groups'
|
'name': 'Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_view,kwargs={'id':id}),
|
'url':reverse(team_view,kwargs={'team_id':team_id}),
|
||||||
'name': t.name
|
'name': t.name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_deleteconfirm_view,kwargs={'id':id}),
|
'url':reverse(team_deleteconfirm_view,kwargs={'team_id':team_id}),
|
||||||
'name': 'Leave'
|
'name': 'Leave'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -745,14 +735,10 @@ def team_deleteconfirm_view(request,id):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def team_delete_view(request,id):
|
@permission_required('teams.delete_team',fn=get_team_by_pk,raise_exception=True)
|
||||||
|
def team_delete_view(request,team_id):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
try:
|
t = get_object_or_404(Team,pk=team_id)
|
||||||
t = Team.objects.get(id=id)
|
|
||||||
except Team.DoesNotExist:
|
|
||||||
raise Http404("This team doesn't exist")
|
|
||||||
if t.manager != request.user:
|
|
||||||
raise PermissionDenied("You are not allowed to delete this team")
|
|
||||||
|
|
||||||
teams.remove_team(t.id)
|
teams.remove_team(t.id)
|
||||||
|
|
||||||
@@ -761,14 +747,10 @@ def team_delete_view(request,id):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def team_members_stats_view(request,id):
|
@permission_required('teams.change_team',fn=get_team_by_pk,raise_exception=True)
|
||||||
|
def team_members_stats_view(request,team_id):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
try:
|
t = get_object_or_404(Team,pk=team_id)
|
||||||
t = Team.objects.get(id=id)
|
|
||||||
except Team.DoesNotExist:
|
|
||||||
raise Http404("This team doesn't exist")
|
|
||||||
if t.manager != request.user:
|
|
||||||
raise PermissionDenied("You are not allowed to see this page")
|
|
||||||
|
|
||||||
members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
|
members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
|
||||||
|
|
||||||
@@ -782,11 +764,11 @@ def team_members_stats_view(request,id):
|
|||||||
'name': 'Groups'
|
'name': 'Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_view,kwargs={'id':id}),
|
'url':reverse(team_view,kwargs={'team_id':team_id}),
|
||||||
'name': t.name
|
'name': t.name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'url':reverse(team_members_stats_view,kwargs={'id':id}),
|
'url':reverse(team_members_stats_view,kwargs={'team_id':team_id}),
|
||||||
'name': 'Members Stats'
|
'name': 'Members Stats'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+120
-2
@@ -5,6 +5,120 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def deactivate_user(request):
|
||||||
|
pk = request.user.id
|
||||||
|
user = User.objects.get(pk=pk)
|
||||||
|
user_form = DeactivateUserForm(instance=user)
|
||||||
|
if request.user.is_authenticated and request.user.id == user.id:
|
||||||
|
if request.method == "POST":
|
||||||
|
user_form = DeactivateUserForm(request.POST, instance=user)
|
||||||
|
if user_form.is_valid():
|
||||||
|
if not user_form.cleaned_data['is_active']:
|
||||||
|
r = Rower.objects.get(user=user)
|
||||||
|
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||||
|
try:
|
||||||
|
subscriptions = braintreestuff.find_subscriptions(r)
|
||||||
|
for subscription in subscriptions:
|
||||||
|
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||||
|
for message in themessages:
|
||||||
|
messages.info(request,message)
|
||||||
|
except ProcessorCustomerError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
r.paidplan = None
|
||||||
|
r.teamplanexpires = timezone.now()
|
||||||
|
r.planexpires = timezone.now()
|
||||||
|
r.clubsize = 0
|
||||||
|
r.rowerplan = 'basic'
|
||||||
|
r.save()
|
||||||
|
|
||||||
|
deactivate_user = user_form.save(commit=False)
|
||||||
|
user.is_active = False
|
||||||
|
user.save()
|
||||||
|
deactivate_user.save()
|
||||||
|
# url = reverse(auth_views.logout_then_login)
|
||||||
|
url = '/logout/?next=/login'
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
return render(request, "userprofile_deactivate.html", {
|
||||||
|
"user_form": user_form,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def user_gdpr_optin(request):
|
||||||
|
r = getrower(request.user)
|
||||||
|
r.gdproptin = False
|
||||||
|
r.gdproptindate = None
|
||||||
|
r.save()
|
||||||
|
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
||||||
|
if r.gdproptin:
|
||||||
|
return HttpResponseRedirect(nexturl)
|
||||||
|
|
||||||
|
return render(request,'gdpr_optin.html',{
|
||||||
|
"next": nexturl
|
||||||
|
})
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def user_gdpr_confirm(request):
|
||||||
|
r = getrower(request.user)
|
||||||
|
r.gdproptin = True
|
||||||
|
r.gdproptindate = timezone.now()
|
||||||
|
r.save()
|
||||||
|
|
||||||
|
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
||||||
|
|
||||||
|
return HttpResponseRedirect(nexturl)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def remove_user(request):
|
||||||
|
pk = request.user.id
|
||||||
|
user = User.objects.get(pk=pk)
|
||||||
|
user_form = DeleteUserForm(instance=user)
|
||||||
|
if request.user.is_authenticated and request.user.id == user.id:
|
||||||
|
if request.method == "POST":
|
||||||
|
user_form = DeleteUserForm(request.POST,instance=user)
|
||||||
|
if user_form.is_valid():
|
||||||
|
cd = user_form.cleaned_data
|
||||||
|
name = user.first_name+' '+user.last_name
|
||||||
|
email = user.email
|
||||||
|
|
||||||
|
r = Rower.objects.get(user=user)
|
||||||
|
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||||
|
try:
|
||||||
|
subscriptions = braintreestuff.find_subscriptions(r)
|
||||||
|
for subscription in subscriptions:
|
||||||
|
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||||
|
for message in themessages:
|
||||||
|
messages.info(request,message)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if cd['delete_user']:
|
||||||
|
# delete workouts
|
||||||
|
Workout.objects.filter(user=user.rower).delete()
|
||||||
|
# delete planned sessions
|
||||||
|
PlannedSession.objects.filter(manager=user).delete()
|
||||||
|
|
||||||
|
user.delete()
|
||||||
|
res = myqueue(queuehigh,
|
||||||
|
handle_sendemail_userdeleted,
|
||||||
|
name, email)
|
||||||
|
|
||||||
|
url = '/logout/?next=/login'
|
||||||
|
# url = reverse(auth_views.logout_then_login)
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
return render(request, "userprofile_delete.html", {
|
||||||
|
"user_form": user_form,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def survey(request):
|
def survey(request):
|
||||||
|
|
||||||
@@ -34,7 +148,7 @@ def survey(request):
|
|||||||
def start_trial_view(request):
|
def start_trial_view(request):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if r.protrialexpires > datetime.date(1970,1,1):
|
if not can_start_trial(request.user):
|
||||||
messages.error(request,'You do not qualify for a trial')
|
messages.error(request,'You do not qualify for a trial')
|
||||||
url = '/rowers/paidplans'
|
url = '/rowers/paidplans'
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
@@ -68,7 +182,7 @@ def start_trial_view(request):
|
|||||||
def start_plantrial_view(request):
|
def start_plantrial_view(request):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if r.plantrialexpires > datetime.date(1970,1,1):
|
if not can_start_plantrial(request.user):
|
||||||
messages.error(request,'You do not qualify for a trial')
|
messages.error(request,'You do not qualify for a trial')
|
||||||
url = '/rowers/paidplans'
|
url = '/rowers/paidplans'
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
@@ -101,6 +215,7 @@ def start_plantrial_view(request):
|
|||||||
|
|
||||||
# Page where user can manage his favorite charts
|
# Page where user can manage his favorite charts
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def rower_favoritecharts_view(request,userid=0):
|
def rower_favoritecharts_view(request,userid=0):
|
||||||
message = ''
|
message = ''
|
||||||
successmessage = ''
|
successmessage = ''
|
||||||
@@ -168,6 +283,7 @@ def rower_favoritecharts_view(request,userid=0):
|
|||||||
|
|
||||||
# page where user sets his export settings
|
# page where user sets his export settings
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def rower_exportsettings_view(request,userid=0):
|
def rower_exportsettings_view(request,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@@ -204,6 +320,7 @@ def rower_exportsettings_view(request,userid=0):
|
|||||||
# Page where user can set his details
|
# Page where user can set his details
|
||||||
# Add email address to form so user can change his email address
|
# Add email address to form so user can change his email address
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def rower_edit_view(request,rowerid=0,userid=0,message=""):
|
def rower_edit_view(request,rowerid=0,userid=0,message=""):
|
||||||
r = getrequestrower(request,rowerid=rowerid,userid=userid,notpermanent=True)
|
r = getrequestrower(request,rowerid=rowerid,userid=userid,notpermanent=True)
|
||||||
|
|
||||||
@@ -299,6 +416,7 @@ def rower_edit_view(request,rowerid=0,userid=0,message=""):
|
|||||||
# Page where user can set his details
|
# Page where user can set his details
|
||||||
# Add email address to form so user can change his email address
|
# Add email address to form so user can change his email address
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def rower_prefs_view(request,userid=0,message=""):
|
def rower_prefs_view(request,userid=0,message=""):
|
||||||
r = getrequestrower(request,userid=userid,notpermanent=True)
|
r = getrequestrower(request,userid=userid,notpermanent=True)
|
||||||
|
|
||||||
|
|||||||
+131
-204
@@ -64,8 +64,10 @@ def workout_video_view_mini(request,id=''):
|
|||||||
else:
|
else:
|
||||||
mode = 'erg'
|
mode = 'erg'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
mayedit = checkworkoutuser(request.user,w) and isprorower(request.user.rower)
|
mayedit = is_workout_user(request.user,w) and is_promember(request.user)
|
||||||
rower = request.user.rower
|
rower = request.user.rower
|
||||||
else:
|
else:
|
||||||
mayedit = False
|
mayedit = False
|
||||||
@@ -176,7 +178,7 @@ def workout_video_view(request,id=''):
|
|||||||
mode = 'erg'
|
mode = 'erg'
|
||||||
|
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
mayedit = checkworkoutuser(request.user,w) and isprorower(request.user.rower)
|
mayedit = is_promember(request.user) and is_workout_user(request.user,w)
|
||||||
rower = request.user.rower
|
rower = request.user.rower
|
||||||
else:
|
else:
|
||||||
mayedit = False
|
mayedit = False
|
||||||
@@ -271,20 +273,18 @@ def workout_video_view(request,id=''):
|
|||||||
|
|
||||||
|
|
||||||
# Create a video compared with data
|
# Create a video compared with data
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans/",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Pro plan or higher",
|
message="This functionality requires a Pro plan or higher",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def workout_video_create_view(request,id=0):
|
def workout_video_create_view(request,id=0):
|
||||||
# get workout
|
# get workout
|
||||||
w = get_workout_permitted(request.user,id)
|
w = get_workout_by_opaqueid(request,id)
|
||||||
if w.workouttype in mytypes.otwtypes:
|
if w.workouttype in mytypes.otwtypes:
|
||||||
mode = 'water'
|
mode = 'water'
|
||||||
else:
|
else:
|
||||||
mode = 'erg'
|
mode = 'erg'
|
||||||
|
|
||||||
|
|
||||||
mayedit = checkworkoutuser(request.user,w) and isprorower(request.user.rower)
|
|
||||||
|
|
||||||
# get video ID and offset
|
# get video ID and offset
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = VideoAnalysisCreateForm(request.POST)
|
form = VideoAnalysisCreateForm(request.POST)
|
||||||
@@ -386,21 +386,18 @@ def workout_video_create_view(request,id=0):
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans/",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_forcecurve_view(request,id=0,workstrokesonly=False):
|
def workout_forcecurve_view(request,id=0,workstrokesonly=False):
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
mayedit=0
|
mayedit=0
|
||||||
if not request.user.is_anonymous:
|
|
||||||
r = getrower(request.user)
|
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
|
||||||
if result:
|
|
||||||
promember=1
|
|
||||||
if request.user == row.user.user:
|
|
||||||
mayedit=1
|
|
||||||
|
|
||||||
if not promember:
|
r = getrequestrower(request)
|
||||||
return HttpResponseRedirect("/rowers/about/")
|
promember = 1
|
||||||
|
|
||||||
|
if r == row.user:
|
||||||
|
mayedit = 1
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ForceCurveOptionsForm(request.POST)
|
form = ForceCurveOptionsForm(request.POST)
|
||||||
@@ -457,12 +454,10 @@ def workout_forcecurve_view(request,id=0,workstrokesonly=False):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Switch from GPS to Impeller (only for SpeedCoach 2, if impeller data)
|
# Switch from GPS to Impeller (only for SpeedCoach 2, if impeller data)
|
||||||
@login_required
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def otw_use_impeller(request,id=0):
|
def otw_use_impeller(request,id=0):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
row = rdata(w.csvfilename)
|
row = rdata(w.csvfilename)
|
||||||
success = row.use_impellerdata()
|
success = row.use_impellerdata()
|
||||||
@@ -481,12 +476,10 @@ def otw_use_impeller(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Switch from Impeller to GPS (only for SpeedCoach 2, if impeller data)
|
# Switch from Impeller to GPS (only for SpeedCoach 2, if impeller data)
|
||||||
@login_required
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def otw_use_gps(request,id=0):
|
def otw_use_gps(request,id=0):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
row = rdata(w.csvfilename)
|
row = rdata(w.csvfilename)
|
||||||
success = row.use_gpsdata()
|
success = row.use_gpsdata()
|
||||||
@@ -507,21 +500,15 @@ def otw_use_gps(request,id=0):
|
|||||||
|
|
||||||
# Show Stroke power histogram for a workout
|
# Show Stroke power histogram for a workout
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_histo_view(request,id=0):
|
def workout_histo_view(request,id=0):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
r = getrequestrower(request)
|
||||||
|
promember = 1
|
||||||
|
|
||||||
promember=0
|
|
||||||
mayedit=0
|
mayedit=0
|
||||||
if not request.user.is_anonymous:
|
if w.user == r:
|
||||||
r = getrower(request.user)
|
mayedit = 1
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
|
||||||
if result:
|
|
||||||
promember=1
|
|
||||||
if request.user == w.user.user:
|
|
||||||
mayedit=1
|
|
||||||
|
|
||||||
if not promember:
|
|
||||||
return HttpResponseRedirect("/rowers/about/")
|
|
||||||
|
|
||||||
res = interactive_histoall([w],'power',False)
|
res = interactive_histoall([w],'power',False)
|
||||||
script = res[0]
|
script = res[0]
|
||||||
@@ -748,20 +735,14 @@ def fitness_metric_view(request,mode='rower',days=42):
|
|||||||
return HttpResponse("job queued")
|
return HttpResponse("job queued")
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def workout_update_cp_view(request,id=0):
|
def workout_update_cp_view(request,id=0):
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
row.rankingpiece = True
|
row.rankingpiece = True
|
||||||
row.save()
|
row.save()
|
||||||
|
|
||||||
@@ -778,17 +759,10 @@ def workout_update_cp_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Reload the workout and calculate the summary from the stroke data (lapIDx)
|
# Reload the workout and calculate the summary from the stroke data (lapIDx)
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_recalcsummary_view(request,id=0):
|
def workout_recalcsummary_view(request,id=0):
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
filename = row.csvfilename
|
filename = row.csvfilename
|
||||||
rowdata = rdata(filename)
|
rowdata = rdata(filename)
|
||||||
if rowdata:
|
if rowdata:
|
||||||
@@ -815,8 +789,11 @@ def workout_recalcsummary_view(request,id=0):
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def workouts_join_view(request):
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
|
def workouts_join_view(request,userid=0):
|
||||||
promember=0
|
promember=0
|
||||||
|
|
||||||
|
r = getrequestrower(request,userid=userid)
|
||||||
if not request.user.is_anonymous:
|
if not request.user.is_anonymous:
|
||||||
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)
|
||||||
@@ -869,6 +846,7 @@ defaultoptions = {
|
|||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
@user_passes_test(ispromember, login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher",
|
message="This functionality requires a Pro plan or higher",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
def video_selectworkout(request,userid=0,teamid=0):
|
def video_selectworkout(request,userid=0,teamid=0):
|
||||||
r = getrequestrower(request, userid=userid)
|
r = getrequestrower(request, userid=userid)
|
||||||
user = r.user
|
user = r.user
|
||||||
@@ -1057,6 +1035,7 @@ def video_selectworkout(request,userid=0,teamid=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
@@ -1065,16 +1044,15 @@ def workouts_join_select(request,
|
|||||||
enddatestring="",
|
enddatestring="",
|
||||||
message='',
|
message='',
|
||||||
successmessage='',
|
successmessage='',
|
||||||
|
userid=0,
|
||||||
startdate=timezone.now()-datetime.timedelta(days=30),
|
startdate=timezone.now()-datetime.timedelta(days=30),
|
||||||
enddate=timezone.now()+datetime.timedelta(days=1),
|
enddate=timezone.now()+datetime.timedelta(days=1),
|
||||||
teamid=0):
|
teamid=0):
|
||||||
|
|
||||||
try:
|
|
||||||
r = getrower(request.user)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
raise Http404("Rower doesn't exist")
|
|
||||||
|
|
||||||
|
|
||||||
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
if 'waterboattype' in request.session:
|
if 'waterboattype' in request.session:
|
||||||
waterboattype = request.session['waterboattype']
|
waterboattype = request.session['waterboattype']
|
||||||
else:
|
else:
|
||||||
@@ -1147,9 +1125,6 @@ def workouts_join_select(request,
|
|||||||
except Team.DoesNotExist:
|
except Team.DoesNotExist:
|
||||||
theteam = 0
|
theteam = 0
|
||||||
|
|
||||||
if r.rowerplan == 'basic' and theteam==0:
|
|
||||||
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,
|
||||||
@@ -1232,6 +1207,7 @@ def team_comparison_select(request,
|
|||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
requestrower = getrower(request.user)
|
requestrower = getrower(request.user)
|
||||||
|
|
||||||
|
|
||||||
request.session.pop('ps',None)
|
request.session.pop('ps',None)
|
||||||
|
|
||||||
if 'waterboattype' in request.session:
|
if 'waterboattype' in request.session:
|
||||||
@@ -1359,7 +1335,8 @@ def team_comparison_select(request,
|
|||||||
|
|
||||||
if id:
|
if id:
|
||||||
firstworkout = get_workout(id)
|
firstworkout = get_workout(id)
|
||||||
if not checkworkoutuserview(request.user,firstworkout):
|
if not is_workout_team(request.user,firstworkout):
|
||||||
|
|
||||||
raise PermissionDenied("You are not allowed to use 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))
|
||||||
@@ -1582,7 +1559,8 @@ def virtualevent_compare_view(request,id=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@permission_required('plannedsession.view_session',
|
||||||
|
fn=get_session_by_pk,raise_exception=True)
|
||||||
def plannedsession_compare_view(request,id=0,userid=0):
|
def plannedsession_compare_view(request,id=0,userid=0):
|
||||||
r = getrequestrower(request,userid=userid)
|
r = getrequestrower(request,userid=userid)
|
||||||
|
|
||||||
@@ -1591,18 +1569,6 @@ def plannedsession_compare_view(request,id=0,userid=0):
|
|||||||
except PlannedSession.DoesNotExist:
|
except PlannedSession.DoesNotExist:
|
||||||
raise Http404("Planned session does not exist")
|
raise Http404("Planned session does not exist")
|
||||||
|
|
||||||
m = ps.manager
|
|
||||||
mm = m.rower
|
|
||||||
|
|
||||||
if ps.manager != request.user:
|
|
||||||
if r.rowerplan == 'coach':
|
|
||||||
teams = Team.objects.filter(manager=request.user)
|
|
||||||
members = Rower.objects.filter(team__in=teams).distinct()
|
|
||||||
teamusers = [m.user for m in members]
|
|
||||||
if ps.manager not in teamusers:
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
elif r not in ps.rower.all():
|
|
||||||
raise PermissionDenied("You do not have access to this session")
|
|
||||||
|
|
||||||
workouts = Workout.objects.filter(plannedsession=ps)
|
workouts = Workout.objects.filter(plannedsession=ps)
|
||||||
|
|
||||||
@@ -1789,9 +1755,10 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
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 is_rower_team_member(request.user,r):
|
||||||
|
request.session['rowerid'] = request.user.rower.id
|
||||||
|
|
||||||
raise PermissionDenied("Access denied")
|
raise PermissionDenied("Access denied")
|
||||||
|
|
||||||
|
|
||||||
@@ -2001,17 +1968,15 @@ def workouts_view(request,message='',successmessage='',
|
|||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
def workout_fusion_list(request,id=0,message='',successmessage='',
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
|
def workout_fusion_list(request,id=0,
|
||||||
startdatestring="",enddatestring="",
|
startdatestring="",enddatestring="",
|
||||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||||
enddate=timezone.now()):
|
enddate=timezone.now()):
|
||||||
|
|
||||||
try:
|
r = getrequestrower(request)
|
||||||
r = getrower(request.user)
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
raise Http404("User has no rower instance")
|
|
||||||
|
|
||||||
u = User.objects.get(id=r.user.id)
|
u = r.user
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
dateform = DateRangeForm(request.POST)
|
dateform = DateRangeForm(request.POST)
|
||||||
if dateform.is_valid():
|
if dateform.is_valid():
|
||||||
@@ -2039,6 +2004,8 @@ def workout_fusion_list(request,id=0,message='',successmessage='',
|
|||||||
|
|
||||||
if id:
|
if id:
|
||||||
theid = encoder.decode_hex(id)
|
theid = encoder.decode_hex(id)
|
||||||
|
w = get_workout(id)
|
||||||
|
r = w.user
|
||||||
|
|
||||||
workouts = Workout.objects.filter(user=r,
|
workouts = Workout.objects.filter(user=r,
|
||||||
startdatetime__gte=startdate,
|
startdatetime__gte=startdate,
|
||||||
@@ -2068,8 +2035,6 @@ def workout_fusion_list(request,id=0,message='',successmessage='',
|
|||||||
workouts = paginator.page(paginator.num_pages)
|
workouts = paginator.page(paginator.num_pages)
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
messages.info(request,successmessage)
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
@@ -2104,6 +2069,7 @@ def workout_fusion_list(request,id=0,message='',successmessage='',
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Basic view of workout
|
# Basic view of workout
|
||||||
|
@permission_required('workout.view_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_view(request,id=0):
|
def workout_view(request,id=0):
|
||||||
request.session['referer'] = absolute(request)['PATH']
|
request.session['referer'] = absolute(request)['PATH']
|
||||||
|
|
||||||
@@ -2112,19 +2078,13 @@ def workout_view(request,id=0):
|
|||||||
else:
|
else:
|
||||||
rower = None
|
rower = None
|
||||||
|
|
||||||
try:
|
row = get_workout_by_opaqueid(request,id)
|
||||||
row = Workout.objects.get(id=encoder.decode_hex(id))
|
|
||||||
except Workout.DoesNotExist:
|
|
||||||
raise Http404("Workout doesn't exist")
|
|
||||||
|
|
||||||
comments = WorkoutComment.objects.filter(workout=row)
|
comments = WorkoutComment.objects.filter(workout=row)
|
||||||
|
|
||||||
aantalcomments = len(comments)
|
aantalcomments = len(comments)
|
||||||
|
|
||||||
|
|
||||||
if row.privacy == 'private' and not checkworkoutuser(request.user,row):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
|
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
|
||||||
for i in g:
|
for i in g:
|
||||||
try:
|
try:
|
||||||
@@ -2204,6 +2164,7 @@ def workout_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Resets stroke data to raw data (pace)
|
# Resets stroke data to raw data (pace)
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
@@ -2213,13 +2174,6 @@ def workout_undo_smoothenpace_view(
|
|||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
filename = row.csvfilename
|
filename = row.csvfilename
|
||||||
row = rdata(filename)
|
row = rdata(filename)
|
||||||
if row == 0:
|
if row == 0:
|
||||||
@@ -2243,6 +2197,7 @@ def workout_undo_smoothenpace_view(
|
|||||||
|
|
||||||
|
|
||||||
# Data smoothing of pace data
|
# Data smoothing of pace data
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
@@ -2253,20 +2208,27 @@ def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
filename = row.csvfilename
|
filename = row.csvfilename
|
||||||
row = rdata(filename)
|
row = rdata(filename)
|
||||||
if row == 0:
|
if row == 0:
|
||||||
return HttpResponse("Error: CSV Data File Not Found")
|
return HttpResponse("Error: CSV Data File Not Found")
|
||||||
|
|
||||||
|
try:
|
||||||
pace = row.df[' Stroke500mPace (sec/500m)'].values
|
pace = row.df[' Stroke500mPace (sec/500m)'].values
|
||||||
velo = 500./pace
|
velo = 500./pace
|
||||||
|
except KeyError:
|
||||||
|
messages.error(request,'Unable to find the data')
|
||||||
|
if previousurl:
|
||||||
|
url = previousurl
|
||||||
|
else:
|
||||||
|
url = reverse(r.defaultlandingpage,
|
||||||
|
kwargs = {
|
||||||
|
'id':id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
if not 'originalvelo' in row.df:
|
if not 'originalvelo' in row.df:
|
||||||
row.df['originalvelo'] = velo
|
row.df['originalvelo'] = velo
|
||||||
@@ -2373,6 +2335,7 @@ def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
|
|||||||
'id':row.id})
|
'id':row.id})
|
||||||
|
|
||||||
# Get weather for given location and date/time
|
# Get weather for given location and date/time
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
@@ -2382,12 +2345,6 @@ def workout_downloadwind_view(request,id=0,
|
|||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
f1 = row.csvfilename
|
f1 = row.csvfilename
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
# create bearing
|
# create bearing
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(f1)
|
||||||
@@ -2448,6 +2405,7 @@ def workout_downloadwind_view(request,id=0,
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
# Get weather for given location and date/time
|
# Get weather for given location and date/time
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
||||||
def workout_downloadmetar_view(request,id=0,
|
def workout_downloadmetar_view(request,id=0,
|
||||||
airportcode=None,
|
airportcode=None,
|
||||||
@@ -2455,12 +2413,7 @@ def workout_downloadmetar_view(request,id=0,
|
|||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
f1 = row.csvfilename
|
f1 = row.csvfilename
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
# create bearing
|
# create bearing
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(f1)
|
||||||
@@ -2523,6 +2476,7 @@ def workout_downloadmetar_view(request,id=0,
|
|||||||
|
|
||||||
|
|
||||||
# Show form to update wind data
|
# Show form to update wind data
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
||||||
def workout_wind_view(request,id=0,message="",successmessage=""):
|
def workout_wind_view(request,id=0,message="",successmessage=""):
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
@@ -2543,13 +2497,6 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
|
|
||||||
# get data
|
# get data
|
||||||
f1 = row.csvfilename
|
f1 = row.csvfilename
|
||||||
@@ -2659,17 +2606,13 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
|
|
||||||
# Show form to update River stream data (for river dwellers)
|
# Show form to update River stream data (for river dwellers)
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None)
|
||||||
def workout_stream_view(request,id=0,message="",successmessage=""):
|
def workout_stream_view(request,id=0,message="",successmessage=""):
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
|
|
||||||
# create interactive plot
|
# create interactive plot
|
||||||
@@ -2679,7 +2622,9 @@ def workout_stream_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(f1)
|
||||||
if rowdata == 0:
|
if rowdata == 0:
|
||||||
return HttpResponse("Error: CSV Data File Not Found")
|
messages.info(request,"Error: CSV data file not found")
|
||||||
|
url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(row.id)})
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
# process form
|
# process form
|
||||||
@@ -2745,23 +2690,15 @@ def workout_stream_view(request,id=0,message="",successmessage=""):
|
|||||||
'the_div':div})
|
'the_div':div})
|
||||||
|
|
||||||
# Form to set average crew weight and boat type, then run power calcs
|
# Form to set average crew weight and boat type, then run power calcs
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans",redirect_field_name=None)
|
@user_passes_test(ispromember, login_url="/rowers/paidplans",redirect_field_name=None)
|
||||||
def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|
||||||
mayedit = 0
|
mayedit = 1
|
||||||
if request.user == w.user.user:
|
|
||||||
mayedit=1
|
|
||||||
if checkworkoutuser(request.user,w):
|
|
||||||
mayedit=1
|
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@@ -2879,15 +2816,11 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
|||||||
'form':form,
|
'form':form,
|
||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def instroke_view(request,id=0):
|
def instroke_view(request,id=0):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
mayedit = 0
|
mayedit = 1
|
||||||
if request.user == w.user.user:
|
|
||||||
mayedit=1
|
|
||||||
if checkworkoutuser(request.user,w):
|
|
||||||
mayedit=1
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
@@ -2909,12 +2842,7 @@ def instroke_view(request,id=0):
|
|||||||
g = GraphImage.objects.filter(workout=w).order_by("-creationdatetime")
|
g = GraphImage.objects.filter(workout=w).order_by("-creationdatetime")
|
||||||
# check if user is owner of this workout
|
# check if user is owner of this workout
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
rowdata = rrdata(csvfile=w.csvfilename)
|
rowdata = rrdata(csvfile=w.csvfilename)
|
||||||
try:
|
try:
|
||||||
@@ -2937,16 +2865,11 @@ def instroke_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# generate instroke chart
|
# generate instroke chart
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def instroke_chart(request,id=0,metric=''):
|
def instroke_chart(request,id=0,metric=''):
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
message = "You are not allowed to edit this workout"
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse('workouts_view')
|
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
|
|
||||||
rowdata = rrdata(csvfile=w.csvfilename)
|
rowdata = rrdata(csvfile=w.csvfilename)
|
||||||
instrokemetrics = rowdata.get_instroke_columns()
|
instrokemetrics = rowdata.get_instroke_columns()
|
||||||
@@ -2995,14 +2918,12 @@ def instroke_chart(request,id=0,metric=''):
|
|||||||
|
|
||||||
|
|
||||||
# data explorer
|
# data explorer
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_data_view(request, id=0):
|
def workout_data_view(request, id=0):
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
|
|
||||||
if not checkworkoutuser(request.user,w):
|
|
||||||
raise PermissionDenied('Access Denied')
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
@@ -3023,8 +2944,10 @@ def workout_data_view(request, id=0):
|
|||||||
|
|
||||||
datadf,row = dataprep.getrowdata_db(id=encoder.decode_hex(id))
|
datadf,row = dataprep.getrowdata_db(id=encoder.decode_hex(id))
|
||||||
|
|
||||||
|
try:
|
||||||
datadf.sort_values(['ftime'],inplace=True)
|
datadf.sort_values(['ftime'],inplace=True)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
columns = datadf.columns.values
|
columns = datadf.columns.values
|
||||||
|
|
||||||
@@ -3049,11 +2972,13 @@ def workout_data_view(request, id=0):
|
|||||||
tcols = ['ftime','cumdist','fpace','spm','hr','power']
|
tcols = ['ftime','cumdist','fpace','spm','hr','power']
|
||||||
|
|
||||||
datadf = datadf[cols]
|
datadf = datadf[cols]
|
||||||
|
try:
|
||||||
datadf.loc[:,'hr'] = datadf['hr'].astype('int')
|
datadf.loc[:,'hr'] = datadf['hr'].astype('int')
|
||||||
datadf.loc[:,'power'] = datadf['power'].astype('int')
|
datadf.loc[:,'power'] = datadf['power'].astype('int')
|
||||||
datadf.loc[:,'distance'] = datadf['distance'].astype('int')
|
datadf.loc[:,'distance'] = datadf['distance'].astype('int')
|
||||||
datadf.loc[:,'spm'] = 10*datadf['spm'].astype('int')/10.
|
datadf.loc[:,'spm'] = 10*datadf['spm'].astype('int')/10.
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = DataFrameColumnsForm(request.POST)
|
form = DataFrameColumnsForm(request.POST)
|
||||||
@@ -3066,9 +2991,12 @@ def workout_data_view(request, id=0):
|
|||||||
try:
|
try:
|
||||||
datadf = datadf[tcols]
|
datadf = datadf[tcols]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tcols = list(set(datadf.columns(tolist)+tcols))
|
# tcols = list(set(datadf.columns(tolist)+tcols))
|
||||||
|
try:
|
||||||
datadf = datadf[tcols]
|
datadf = datadf[tcols]
|
||||||
datadf = datadf.fillna(value=0)
|
datadf = datadf.fillna(value=0)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
for col in cols:
|
for col in cols:
|
||||||
try:
|
try:
|
||||||
@@ -3100,7 +3028,7 @@ def workout_data_view(request, id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Stats page
|
# Stats page
|
||||||
@login_required()
|
@permission_required('workout.view_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_stats_view(request,id=0,message="",successmessage=""):
|
def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
@@ -3109,7 +3037,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
mayedit = 0
|
mayedit = 0
|
||||||
if request.user == w.user.user:
|
if request.user == w.user.user:
|
||||||
mayedit=1
|
mayedit=1
|
||||||
if checkworkoutuser(request.user,w):
|
if is_workout_user(request.user,w):
|
||||||
mayedit=1
|
mayedit=1
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
@@ -3135,8 +3063,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 (checkworkoutuserview(request.user,row)==False):
|
|
||||||
raise PermissionDenied('Access Denied')
|
|
||||||
|
|
||||||
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly,
|
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly,
|
||||||
ignoreadvanced=False)
|
ignoreadvanced=False)
|
||||||
@@ -3377,11 +3304,12 @@ def workout_workflow_config2_view(request,userid=0):
|
|||||||
|
|
||||||
# Workflow View
|
# Workflow View
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('workout.view_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_workflow_view(request,id):
|
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_permittedview(request.user,id)
|
row = get_workout_by_opaqueid(request,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)
|
||||||
@@ -3464,6 +3392,7 @@ def workout_workflow_view(request,id):
|
|||||||
|
|
||||||
# The famous flex chart
|
# The famous flex chart
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@permission_required('workout.view_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_flexchart3_view(request,*args,**kwargs):
|
def workout_flexchart3_view(request,*args,**kwargs):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -3482,17 +3411,17 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
favoritenr = -1
|
favoritenr = -1
|
||||||
|
|
||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
r = getrequestrower(request)
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
mayedit=0
|
mayedit=0
|
||||||
if not request.user.is_anonymous:
|
if not request.user.is_anonymous:
|
||||||
r = getrower(request.user)
|
result = ispromember(request.user)
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
|
||||||
if result:
|
if result:
|
||||||
promember=1
|
promember=1
|
||||||
if request.user == row.user.user:
|
if request.user == row.user.user:
|
||||||
mayedit=1
|
mayedit=1
|
||||||
if checkworkoutuser(request.user,row):
|
if is_workout_user(request.user,row):
|
||||||
mayedit=1
|
mayedit=1
|
||||||
|
|
||||||
workouttype = 'ote'
|
workouttype = 'ote'
|
||||||
@@ -3795,9 +3724,7 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
|
|||||||
# r = getrower(u)
|
# r = getrower(u)
|
||||||
|
|
||||||
promember=0
|
promember=0
|
||||||
mayedit=0
|
mayedit = 0
|
||||||
if not request.user.is_anonymous:
|
|
||||||
r = getrower(request.user)
|
|
||||||
result = request.user.is_authenticated and ispromember(request.user)
|
result = request.user.is_authenticated and ispromember(request.user)
|
||||||
if result:
|
if result:
|
||||||
promember=1
|
promember=1
|
||||||
@@ -3977,7 +3904,7 @@ def workout_comment_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# The basic edit page
|
# The basic edit page
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_edit_view(request,id=0,message="",successmessage=""):
|
def workout_edit_view(request,id=0,message="",successmessage=""):
|
||||||
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
|
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
|
||||||
request.session['referer'] = absolute(request)['PATH']
|
request.session['referer'] = absolute(request)['PATH']
|
||||||
@@ -3986,14 +3913,13 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
row = get_workout(id)
|
row = get_workout(id)
|
||||||
|
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,row)==False):
|
|
||||||
raise PermissionDenied("Access denied")
|
|
||||||
|
|
||||||
if request.user.rower.rowerplan == 'basic' and 'speedcoach2' in row.workoutsource:
|
if request.user.rower.rowerplan == 'basic' and 'speedcoach2' in row.workoutsource:
|
||||||
data = getsmallrowdata_db(['wash'],ids=[encoder.decode_hex(id)])
|
data = getsmallrowdata_db(['wash'],ids=[encoder.decode_hex(id)])
|
||||||
try:
|
try:
|
||||||
if data['wash'].std() != 0:
|
if data['wash'].std() != 0:
|
||||||
url = reverse('paidplans')
|
url = reverse('paidplans_view')
|
||||||
messages.info(
|
messages.info(
|
||||||
request,
|
request,
|
||||||
'Some Empower Oarlock data are only available to users with a <a href="{u}">paid plan</a>'.format(u=url)
|
'Some Empower Oarlock data are only available to users with a <a href="{u}">paid plan</a>'.format(u=url)
|
||||||
@@ -4149,7 +4075,9 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
f1 = row.csvfilename
|
f1 = row.csvfilename
|
||||||
u = row.user.user
|
u = row.user.user
|
||||||
r = getrower(u)
|
r = getrower(u)
|
||||||
|
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(f1)
|
||||||
|
|
||||||
hascoordinates = 1
|
hascoordinates = 1
|
||||||
if rowdata != 0:
|
if rowdata != 0:
|
||||||
try:
|
try:
|
||||||
@@ -4293,7 +4221,7 @@ def workout_map_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
# Image upload
|
# Image upload
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_uploadimage_view(request,id):
|
def workout_uploadimage_view(request,id):
|
||||||
is_ajax = False
|
is_ajax = False
|
||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
@@ -4319,8 +4247,7 @@ def workout_uploadimage_view(request,id):
|
|||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if not checkworkoutuser(request.user,w):
|
|
||||||
raise PermissionDenied("You are not allowed to edit this workout")
|
|
||||||
|
|
||||||
images = GraphImage.objects.filter(workout=w)
|
images = GraphImage.objects.filter(workout=w)
|
||||||
|
|
||||||
@@ -4398,7 +4325,7 @@ def workout_uploadimage_view(request,id):
|
|||||||
|
|
||||||
|
|
||||||
# Generic chart creation
|
# Generic chart creation
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_add_chart_view(request,id,plotnr=1):
|
def workout_add_chart_view(request,id,plotnr=1):
|
||||||
|
|
||||||
w = get_workout(id)
|
w = get_workout(id)
|
||||||
@@ -4406,9 +4333,7 @@ def workout_add_chart_view(request,id,plotnr=1):
|
|||||||
|
|
||||||
plotnr = int(plotnr)
|
plotnr = int(plotnr)
|
||||||
|
|
||||||
if (checkworkoutuser(request.user,w)==False):
|
|
||||||
raise PermissionDenied("You are not allowed add plots to this workout")
|
|
||||||
else:
|
|
||||||
f1 = w.csvfilename[6:-4]
|
f1 = w.csvfilename[6:-4]
|
||||||
timestr = strftime("%Y%m%d-%H%M%S")
|
timestr = strftime("%Y%m%d-%H%M%S")
|
||||||
imagename = f1+timestr+'.png'
|
imagename = f1+timestr+'.png'
|
||||||
@@ -4437,12 +4362,13 @@ def workout_add_chart_view(request,id,plotnr=1):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_toggle_ranking(request,id=0):
|
def workout_toggle_ranking(request,id=0):
|
||||||
is_ajax = False
|
is_ajax = False
|
||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
is_ajax = True
|
is_ajax = True
|
||||||
|
|
||||||
row = get_workout_permitted(request.user,id)
|
row = get_workout_by_opaqueid(request,id)
|
||||||
|
|
||||||
row.rankingpiece = not row.rankingpiece
|
row.rankingpiece = not row.rankingpiece
|
||||||
row.save()
|
row.save()
|
||||||
@@ -4868,22 +4794,22 @@ def workout_upload_view(request,
|
|||||||
return response
|
return response
|
||||||
else:
|
else:
|
||||||
if not is_ajax:
|
if not is_ajax:
|
||||||
if r.c2_auto_export and isprorower(r):
|
if r.c2_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_C2'] = True
|
uploadoptions['upload_to_C2'] = True
|
||||||
|
|
||||||
if r.strava_auto_export and isprorower(r):
|
if r.strava_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_Strava'] = True
|
uploadoptions['upload_to_Strava'] = True
|
||||||
|
|
||||||
if r.sporttracks_auto_export and isprorower(r):
|
if r.sporttracks_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_SportTracks'] = True
|
uploadoptions['upload_to_SportTracks'] = True
|
||||||
|
|
||||||
if r.runkeeper_auto_export and isprorower(r):
|
if r.runkeeper_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_RunKeeper'] = True
|
uploadoptions['upload_to_RunKeeper'] = True
|
||||||
|
|
||||||
if r.trainingpeaks_auto_export and isprorower(r):
|
if r.trainingpeaks_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_TrainingPeaks'] = True
|
uploadoptions['upload_to_TrainingPeaks'] = True
|
||||||
|
|
||||||
if r.mapmyfitness_auto_export and isprorower(r):
|
if r.mapmyfitness_auto_export and ispromember(r.user):
|
||||||
uploadoptions['upload_to_MapMyFitness'] = True
|
uploadoptions['upload_to_MapMyFitness'] = True
|
||||||
|
|
||||||
form = DocumentsForm(initial=docformoptions)
|
form = DocumentsForm(initial=docformoptions)
|
||||||
@@ -4969,7 +4895,7 @@ def team_workout_upload_view(request,message="",
|
|||||||
workouttype = form.cleaned_data['workouttype']
|
workouttype = form.cleaned_data['workouttype']
|
||||||
if rowerform.is_valid():
|
if rowerform.is_valid():
|
||||||
u = rowerform.cleaned_data['user']
|
u = rowerform.cleaned_data['user']
|
||||||
if u and request.user.rower in teams.rower_get_coaches(u.rower):
|
if can_add_workout_member(request.user,u.rower):
|
||||||
r = getrower(u)
|
r = getrower(u)
|
||||||
else:
|
else:
|
||||||
message = 'Please select a rower'
|
message = 'Please select a rower'
|
||||||
@@ -5150,10 +5076,9 @@ def list_videos(request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def graphs_view(request):
|
def graphs_view(request,userid=0):
|
||||||
request.session['referer'] = reverse('graphs_view')
|
request.session['referer'] = reverse('graphs_view')
|
||||||
try:
|
r = getrequestrower(request,userid=userid)
|
||||||
r = getrower(request.user)
|
|
||||||
workouts = Workout.objects.filter(user=r).order_by("-date", "-starttime")
|
workouts = Workout.objects.filter(user=r).order_by("-date", "-starttime")
|
||||||
query = request.GET.get('q')
|
query = request.GET.get('q')
|
||||||
if query:
|
if query:
|
||||||
@@ -5186,10 +5111,10 @@ def graphs_view(request):
|
|||||||
'searchform':searchform,
|
'searchform':searchform,
|
||||||
'active':'nav-workouts',
|
'active':'nav-workouts',
|
||||||
'teams':get_my_teams(request.user),
|
'teams':get_my_teams(request.user),
|
||||||
|
'rower':r,
|
||||||
})
|
})
|
||||||
|
|
||||||
except Rower.DoesNotExist:
|
|
||||||
raise Http404("User has no rower instance")
|
|
||||||
|
|
||||||
# Show the chart (png image)
|
# Show the chart (png image)
|
||||||
def graph_show_view(request,id):
|
def graph_show_view(request,id):
|
||||||
@@ -5237,9 +5162,9 @@ def graph_show_view(request,id):
|
|||||||
raise Http404("This workout doesn't exist")
|
raise Http404("This workout doesn't exist")
|
||||||
|
|
||||||
# Restore original stroke data and summary
|
# Restore original stroke data and summary
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_summary_restore_view(request,id,message="",successmessage=""):
|
def workout_summary_restore_view(request,id,message="",successmessage=""):
|
||||||
row = get_workout_permitted(request.user,id)
|
row = get_workout_by_opaqueid(request,id)
|
||||||
|
|
||||||
s = ""
|
s = ""
|
||||||
# still here - this is a workout we may edit
|
# still here - this is a workout we may edit
|
||||||
@@ -5287,11 +5212,12 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
# Split a workout
|
# Split a workout
|
||||||
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
@user_passes_test(ispromember,login_url="/rowers/paidplans",
|
||||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||||
redirect_field_name=None)
|
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_by_opaqueid(request,id)
|
||||||
|
|
||||||
r = row.user
|
r = row.user
|
||||||
|
|
||||||
@@ -5398,8 +5324,8 @@ def workout_fusion_view(request,id1=0,id2=1):
|
|||||||
w1 = Workout.objects.get(id=id1)
|
w1 = Workout.objects.get(id=id1)
|
||||||
w2 = Workout.objects.get(id=id2)
|
w2 = Workout.objects.get(id=id2)
|
||||||
r = w1.user
|
r = w1.user
|
||||||
if (checkworkoutuser(request.user,w1)==False) or \
|
if (is_workout_user(request.user,w1)==False) or \
|
||||||
(checkworkoutuser(request.user,w2)==False):
|
(is_workout_user(request.user,w2)==False):
|
||||||
raise PermissionDenied("You are not allowed to use these workouts")
|
raise PermissionDenied("You are not allowed to use these workouts")
|
||||||
except Workout.DoesNotExist:
|
except Workout.DoesNotExist:
|
||||||
raise Http404("One of the workouts doesn't exist")
|
raise Http404("One of the workouts doesn't exist")
|
||||||
@@ -5475,10 +5401,10 @@ def workout_fusion_view(request,id1=0,id2=1):
|
|||||||
|
|
||||||
|
|
||||||
# Edit the splits/summary
|
# Edit the splits/summary
|
||||||
@login_required()
|
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
|
||||||
def workout_summary_edit_view(request,id,message="",successmessage=""
|
def workout_summary_edit_view(request,id,message="",successmessage=""
|
||||||
):
|
):
|
||||||
row = get_workout_permitted(request.user,id)
|
row = get_workout_by_opaqueid(request,id)
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
@@ -5955,7 +5881,7 @@ class VideoDelete(DeleteView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(VideoDelete, self).get_object(*args, **kwargs)
|
obj = super(VideoDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.workout.user):
|
if not is_coach_user(self.request.user,obj.workout.user):
|
||||||
raise PermissionDenied('You are not allowed to delete this analysis')
|
raise PermissionDenied('You are not allowed to delete this analysis')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
@@ -6008,7 +5934,8 @@ class GraphDelete(DeleteView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super(GraphDelete, self).get_object(*args, **kwargs)
|
obj = super(GraphDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.workout.user):
|
|
||||||
|
if not is_workout_user(self.request.user,obj.workout):
|
||||||
raise PermissionDenied('You are not allowed to delete this chart')
|
raise PermissionDenied('You are not allowed to delete this chart')
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
@@ -6024,10 +5951,11 @@ def workout_code_delete_view(request,id=0):
|
|||||||
|
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
class WorkoutDelete(DeleteView):
|
class WorkoutDelete(PermissionRequiredMixin,DeleteView):
|
||||||
login_required = True
|
login_required = True
|
||||||
model = Workout
|
model = Workout
|
||||||
template_name = 'workout_delete_confirm.html'
|
template_name = 'workout_delete_confirm.html'
|
||||||
|
permission_required = 'workout.change_workout'
|
||||||
|
|
||||||
# extra parameters
|
# extra parameters
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@@ -6082,7 +6010,6 @@ class WorkoutDelete(DeleteView):
|
|||||||
except Workout.DoesNotExist:
|
except Workout.DoesNotExist:
|
||||||
raise Http404("One of the workouts doesn't exist")
|
raise Http404("One of the workouts doesn't exist")
|
||||||
# obj = super(WorkoutDelete, self).get_object(*args, **kwargs)
|
# obj = super(WorkoutDelete, self).get_object(*args, **kwargs)
|
||||||
if not checkaccessuser(self.request.user,obj.user):
|
|
||||||
raise PermissionDenied('You are not allowed to delete this workout')
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from __future__ import print_function
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
import requests
|
import requests
|
||||||
|
from requests.exceptions import ConnectionError
|
||||||
import json
|
import json
|
||||||
from lxml import objectify,etree
|
from lxml import objectify,etree
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
@@ -32,7 +33,10 @@ def get_weather_data(long,lat,unixtime):
|
|||||||
url = "https://api.darksky.net/forecast/"+FORECAST_IO_KEY+"/"
|
url = "https://api.darksky.net/forecast/"+FORECAST_IO_KEY+"/"
|
||||||
url += str(long)+","+str(lat)+","+str(unixtime)
|
url += str(long)+","+str(lat)+","+str(unixtime)
|
||||||
|
|
||||||
|
try:
|
||||||
s = requests.get(url)
|
s = requests.get(url)
|
||||||
|
except ConnectionError:
|
||||||
|
return 0
|
||||||
|
|
||||||
if s.ok:
|
if s.ok:
|
||||||
return s.json()
|
return s.json()
|
||||||
@@ -58,7 +62,11 @@ def get_metar_data(airportcode,unixtime):
|
|||||||
|
|
||||||
|
|
||||||
if s.ok:
|
if s.ok:
|
||||||
|
try:
|
||||||
doc = etree.fromstring(s.content)
|
doc = etree.fromstring(s.content)
|
||||||
|
except AttributeError:
|
||||||
|
message = 'METAR data content error'
|
||||||
|
return [0,0,message,'',0]
|
||||||
lengte = len(doc.xpath('data/METAR/station_id'))
|
lengte = len(doc.xpath('data/METAR/station_id'))
|
||||||
idnr = int(lengte/2)
|
idnr = int(lengte/2)
|
||||||
try:
|
try:
|
||||||
@@ -98,6 +106,8 @@ def get_metar_data(airportcode,unixtime):
|
|||||||
# Get wind data (and translate from knots to m/s)
|
# Get wind data (and translate from knots to m/s)
|
||||||
def get_wind_data(lat,long,unixtime):
|
def get_wind_data(lat,long,unixtime):
|
||||||
data = get_weather_data(lat,long,unixtime)
|
data = get_weather_data(lat,long,unixtime)
|
||||||
|
summary = ''
|
||||||
|
temperature = 20
|
||||||
if data:
|
if data:
|
||||||
try:
|
try:
|
||||||
# we are getting wind in mph
|
# we are getting wind in mph
|
||||||
@@ -107,11 +117,13 @@ def get_wind_data(lat,long,unixtime):
|
|||||||
windspeed = 0
|
windspeed = 0
|
||||||
windbearing = 0
|
windbearing = 0
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
airports = data['flags']['madis-stations']
|
airports = data['flags']['madis-stations']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
airports = ['unknown']
|
airports = ['unknown']
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
temperature = data['currently']['temperature']
|
temperature = data['currently']['temperature']
|
||||||
# Temp is given in Fahrenheit, so convert to Celsius for Europeans
|
# Temp is given in Fahrenheit, so convert to Celsius for Europeans
|
||||||
@@ -121,6 +133,7 @@ def get_wind_data(lat,long,unixtime):
|
|||||||
temperature = 'unknown'
|
temperature = 'unknown'
|
||||||
temperaturec = 'unknown'
|
temperaturec = 'unknown'
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
summary = data['currently']['summary']
|
summary = data['currently']['summary']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -128,6 +141,10 @@ def get_wind_data(lat,long,unixtime):
|
|||||||
else:
|
else:
|
||||||
windspeed = 0
|
windspeed = 0
|
||||||
windbearing = 0
|
windbearing = 0
|
||||||
|
summary = 'unknown'
|
||||||
|
airports = ['unknown']
|
||||||
|
temparature = 'unknown'
|
||||||
|
temperaturec = 'unknown'
|
||||||
message = 'Not able to get weather data'
|
message = 'Not able to get weather data'
|
||||||
|
|
||||||
# apply Hellman's coefficient for neutral air above human
|
# apply Hellman's coefficient for neutral air above human
|
||||||
|
|||||||
@@ -73,11 +73,13 @@ INSTALLED_APPS = [
|
|||||||
'tz_detect',
|
'tz_detect',
|
||||||
'django_social_share',
|
'django_social_share',
|
||||||
'django_countries',
|
'django_countries',
|
||||||
|
'rules',
|
||||||
]
|
]
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
'oauth2_provider.backends.OAuth2Backend',
|
'oauth2_provider.backends.OAuth2Backend',
|
||||||
# Uncomment following if you want to access the admin
|
# Uncomment following if you want to access the admin
|
||||||
|
'rules.permissions.ObjectPermissionBackend',
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ urlpatterns += [
|
|||||||
{'next_page': '/'},
|
{'next_page': '/'},
|
||||||
name='logout',),
|
name='logout',),
|
||||||
re_path(r'^rowers/',include('rowers.urls')),
|
re_path(r'^rowers/',include('rowers.urls')),
|
||||||
re_path(r'^survey/',include('survey.urls')),
|
# re_path(r'^survey/',include('survey.urls')),
|
||||||
# re_path(r'^cvkbrno/',include('cvkbrno.urls')),
|
# re_path(r'^cvkbrno/',include('cvkbrno.urls')),
|
||||||
# re_path(r'^admin/rq/',include('django_rq_dashboard.urls')),
|
# re_path(r'^admin/rq/',include('django_rq_dashboard.urls')),
|
||||||
re_path(r'^call\_back',rowersviews.rower_process_callback),
|
re_path(r'^call\_back',rowersviews.rower_process_callback),
|
||||||
|
|||||||
@@ -246,7 +246,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.rower.protrialexpires and user.rower.protrialexpires|is_future_date %}
|
{% if user.rower.protrialexpires and user.rower.protrialexpires|is_future_date %}
|
||||||
{% if user.rower.plantrialexpires and user.rower.rowerplan != 'plan' %}
|
{% if user.rower.plantrialexpires and user.rower.plantrialexpires|is_future_date and user.rower.rowerplan != 'plan' %}
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<p class="successmessage">
|
<p class="successmessage">
|
||||||
{{ user.rower.protrialexpires|date_dif|ddays }} days left of your Self-Coach trial - Would you like to <a href="/rowers/paidplans/">upgrade now?</a>
|
{{ user.rower.protrialexpires|date_dif|ddays }} days left of your Self-Coach trial - Would you like to <a href="/rowers/paidplans/">upgrade now?</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user