diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py
index e5646ac9..5f5979bc 100644
--- a/rowers/c2stuff.py
+++ b/rowers/c2stuff.py
@@ -7,7 +7,7 @@ from rowers.imports import *
import datetime
from requests import Request, Session
-from rowers.types import otwtypes
+from rowers.mytypes import otwtypes
from iso8601 import ParseError
from rowsandall_app.settings import (
diff --git a/rowers/dataprep.py b/rowers/dataprep.py
index a23f3eda..70537eeb 100644
--- a/rowers/dataprep.py
+++ b/rowers/dataprep.py
@@ -74,7 +74,7 @@ queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('default')
from rowsandall_app.settings import SITE_URL
-from rowers.types import otwtypes
+from rowers.mytypes import otwtypes
from rowers.database import *
diff --git a/rowers/decorators.py b/rowers/decorators.py
new file mode 100644
index 00000000..3d356dd2
--- /dev/null
+++ b/rowers/decorators.py
@@ -0,0 +1,46 @@
+from django.contrib.auth.decorators import login_required,user_passes_test
+
+from django.http import HttpResponseRedirect
+from django.core.exceptions import PermissionDenied
+from django.utils.decorators import available_attrs
+from django.contrib import messages
+
+try:
+ from functools import wraps
+except ImportError:
+ from django.utils.functional import wraps
+
+
+REDIRECT_FIELD_NAME = None
+
+default_message = "Please log in, in order to see the requested page."
+
+def user_passes_test(test_func, message=default_message,login_url=None,redirect_field_name=None):
+ """
+ Decorator for views that checks that the user passes the given test,
+ setting a message in case of no success. The test should be a callable
+ that takes the user object and returns True if the user passes.
+ """
+ def decorator(view_func):
+ @wraps(view_func, assigned=available_attrs(view_func))
+ def _wrapped_view(request, *args, **kwargs):
+ if not test_func(request.user):
+ messages.error(request, message)
+ return HttpResponseRedirect(login_url)
+ return view_func(request, *args, **kwargs)
+ return _wrapped_view
+ return decorator
+
+def login_required_message(function=None, message=default_message):
+ """
+ Decorator for views that checks that the user is logged in, redirecting
+ to the log-in page if necessary.
+ """
+ actual_decorator = user_passes_test(
+ lambda u: u.is_authenticated(),
+ message=message,
+ )
+ if function:
+ return actual_decorator(function)
+ return actual_decorator
+
diff --git a/rowers/forms.py b/rowers/forms.py
index 834494fb..d9d6e39b 100644
--- a/rowers/forms.py
+++ b/rowers/forms.py
@@ -9,7 +9,7 @@ from django.forms.extras.widgets import SelectDateWidget
from django.utils import timezone,translation
from django.forms import ModelForm, Select
import dataprep
-import types
+import mytypes
import datetime
from django.forms import formset_factory
from utils import landingpages
@@ -83,7 +83,7 @@ class DocumentsForm(forms.Form):
choices=Workout.workouttypes)
boattype = forms.ChoiceField(required=True,
- choices=types.boattypes,
+ choices=mytypes.boattypes,
label = "Boat Type")
@@ -589,8 +589,8 @@ class IntervalUpdateForm(forms.Form):
self.fields['type_%s' % i].widget.attrs['style'] = 'width:156px; height: 22px;'
self.fields['intervald_%s' % i].widget = forms.TimeInput(format='%H:%M:%S.%f')
-boattypes = types.boattypes
-workouttypes = types.workouttypes
+boattypes = mytypes.boattypes
+workouttypes = mytypes.workouttypes
ww = list(workouttypes)
ww.append(tuple(('all','All')))
workouttypes = tuple(ww)
@@ -616,7 +616,7 @@ class TrendFlexModalForm(forms.Form):
initial='all')
waterboattype = forms.MultipleChoiceField(choices=boattypes,
label='Water Boat Type',
- initial = types.waterboattype)
+ initial = mytypes.waterboattype)
rankingonly = forms.BooleanField(initial=False,
label='Only Ranking Pieces',
required=False)
@@ -631,14 +631,14 @@ class StatsOptionsForm(forms.Form):
waterboattype = forms.MultipleChoiceField(choices=boattypes,
label='Water Boat Type',
widget=forms.CheckboxSelectMultiple(),
- initial = types.waterboattype)
+ initial = mytypes.waterboattype)
def __init__(self, *args, **kwargs):
super(StatsOptionsForm, self).__init__(*args,**kwargs)
- for type in types.checktypes:
+ for type in mytypes.checktypes:
self.fields[type] = forms.BooleanField(initial=True,required=False)
@@ -807,8 +807,8 @@ class WorkoutSessionSelectForm(forms.Form):
class RaceResultFilterForm(forms.Form):
- boatclasses = (type for type in types.workouttypes if type[0] in types.otwtypes)
- boatclassinitial = [t for t in types.otwtypes]
+ boatclasses = (type for type in mytypes.workouttypes if type[0] in mytypes.otwtypes)
+ boatclassinitial = [t for t in mytypes.otwtypes]
sexchoices = (
('female','Female'),
('male','Male'),
@@ -836,7 +836,7 @@ class RaceResultFilterForm(forms.Form):
boattype = forms.MultipleChoiceField(
choices=boattypes,
label='Boat Type',
- initial=types.waterboattype,
+ initial=mytypes.waterboattype,
widget=forms.CheckboxSelectMultiple())
age_min = forms.IntegerField(label='Min Age',initial=16)
diff --git a/rowers/imports.py b/rowers/imports.py
index c1e150cc..70f765c0 100644
--- a/rowers/imports.py
+++ b/rowers/imports.py
@@ -38,7 +38,7 @@ from django.contrib.auth.decorators import login_required
from rowingdata import rowingdata, make_cumvalues
import pandas as pd
from rowers.models import Rower,Workout,checkworkoutuser
-from rowers import types
+from rowers import mytypes
from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI,
diff --git a/rowers/middleware.py b/rowers/middleware.py
index 495ad436..9a44b7fe 100644
--- a/rowers/middleware.py
+++ b/rowers/middleware.py
@@ -5,7 +5,7 @@ from utils import myqueue
import django_rq
queue = django_rq.get_queue('default')
from rowers.tasks import handle_updatefitnessmetric
-from rowers.types import otwtypes
+from rowers.mytypes import otwtypes
def getrower(user):
try:
diff --git a/rowers/models.py b/rowers/models.py
index ffdb668e..4d968e96 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -34,7 +34,7 @@ from rowers.rows import validate_file_extension
from collections import OrderedDict
from timezonefinder import TimezoneFinder
-import types
+import mytypes
from matplotlib import path
from rowsandall_app.settings import (
@@ -1990,13 +1990,13 @@ class PlannedSessionFormSmall(ModelForm):
'manager': forms.HiddenInput(),
}
-boattypes = types.boattypes
+boattypes = mytypes.boattypes
# Workout
class Workout(models.Model):
- workouttypes = types.workouttypes
- workoutsources = types.workoutsources
- privacychoices = types.privacychoices
+ workouttypes = mytypes.workouttypes
+ workoutsources = mytypes.workoutsources
+ privacychoices = mytypes.privacychoices
user = models.ForeignKey(Rower)
team = models.ManyToManyField(Team,blank=True)
@@ -2121,7 +2121,7 @@ def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
# Virtual Race results (for keeping results when workouts are deleted)
class VirtualRaceResult(models.Model):
- boatclasses = (type for type in types.workouttypes if type[0] in types.otwtypes)
+ boatclasses = (type for type in mytypes.workouttypes if type[0] in mytypes.otwtypes)
userid = models.IntegerField(default=0)
teamname = models.CharField(max_length=80,verbose_name = 'Team Name',
blank=True,null=True)
diff --git a/rowers/types.py b/rowers/mytypes.py
similarity index 100%
rename from rowers/types.py
rename to rowers/mytypes.py
diff --git a/rowers/templates/analysis.html b/rowers/templates/analysis.html
index 121e38ef..8fd8ef83 100644
--- a/rowers/templates/analysis.html
+++ b/rowers/templates/analysis.html
@@ -37,11 +37,7 @@
Power Histogram
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -52,11 +48,7 @@
Statistics
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -67,11 +59,7 @@
Box Chart
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -83,11 +71,7 @@
OTW Critical Power
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -98,11 +82,7 @@
OTE Critical Power
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -114,11 +94,7 @@
Trend Flex
- {% if user|is_promember %}
- {% else %}
-
- {% endif %}
@@ -130,11 +106,7 @@
Power Progress
- {% if user|is_planmember %}
- {% else %}
-
- {% endif %}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 38cfc83d..9456bded 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -20,7 +20,7 @@ from rowers import c2stuff, runkeeperstuff
from rowers.c2stuff import c2_open
from rowers.runkeeperstuff import runkeeper_open
-from rowers.types import otwtypes
+from rowers.mytypes import otwtypes
from rowers.utils import NoTokenError
def strfdelta(tdelta):
diff --git a/rowers/uploads.py b/rowers/uploads.py
index d871d870..676e481c 100644
--- a/rowers/uploads.py
+++ b/rowers/uploads.py
@@ -26,7 +26,7 @@ queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
-from types import workouttypes,boattypes,otwtypes
+from mytypes import workouttypes,boattypes,otwtypes
try:
from cStringIO import StringIO
diff --git a/rowers/urls.py b/rowers/urls.py
index 59b9f769..cf4ff1fd 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -397,6 +397,7 @@ urlpatterns = [
url(r'^analysis/$', views.analysis_view,name='analysis'),
url(r'^laboratory/$', views.laboratory_view,name='laboratory'),
url(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
+ url(r'^planrequired',views.planrequired_view),
url(r'^starttrial$',views.start_trial_view),
url(r'^startplantrial$',views.start_plantrial_view),
# url(r'^planmembership', TemplateView.as_view(template_name='planmembership.html'),name='planmembership'),
diff --git a/rowers/views.py b/rowers/views.py
index de0a49d6..846ff465 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -98,7 +98,8 @@ import rowers.uploads as uploads
from django.forms.formsets import formset_factory
from django.forms import modelformset_factory
import StringIO
-from django.contrib.auth.decorators import login_required,user_passes_test
+from django.contrib.auth.decorators import login_required #,user_passes_test
+from rowers.decorators import user_passes_test
from time import strftime,strptime,mktime,time,daylight
import os,sys
import datetime
@@ -161,7 +162,7 @@ from scipy.signal import savgol_filter
from django.shortcuts import render_to_response
from Cookie import SimpleCookie
from shutil import copyfile,move
-import types
+import mytypes
from rowingdata import rower as rrower
from rowingdata import main as rmain
from rowingdata import rowingdata as rrdata
@@ -630,7 +631,7 @@ def get_thumbnails(request,id):
aantalcomments = len(comments)
workouttype = 'ote'
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
workouttype = 'otw'
try:
@@ -2475,7 +2476,7 @@ def cum_flex_data(
'includereststrokes':False,
'rankingonly':False,
'modality':'all',
- 'waterboattype':types.waterboattype,
+ 'waterboattype':mytypes.waterboattype,
'theuser':0,
'xparam':'spm',
'yparam1':'power',
@@ -2504,7 +2505,7 @@ def cum_flex_data(
enddatestring = keyvalue_get_default('enddatestring',options,def_options)
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
@@ -2579,7 +2580,7 @@ def histo_data(
'includereststrokes':False,
'rankingonly':False,
'modality':'all',
- 'waterboattype':types.waterboattype,
+ 'waterboattype':mytypes.waterboattype,
'theuser':0,
'enddatestring':'',
'startdatestring':'',
@@ -2602,7 +2603,7 @@ def histo_data(
enddatestring = keyvalue_get_default('enddatestring',options,def_options)
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
@@ -2679,8 +2680,8 @@ def cum_flex(request,theuser=0,
enddatestring="",
options={
'includereststrokes':False,
- 'workouttypes':[i[0] for i in types.workouttypes],
- 'waterboattype':types.waterboattype,
+ 'workouttypes':[i[0] for i in mytypes.workouttypes],
+ 'waterboattype':mytypes.waterboattype,
'rankingonly':False,
}):
@@ -2691,7 +2692,7 @@ def cum_flex(request,theuser=0,
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'rankingonly' in request.session:
@@ -2706,7 +2707,7 @@ def cum_flex(request,theuser=0,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
@@ -2723,7 +2724,7 @@ def cum_flex(request,theuser=0,
workstrokesonly = not includereststrokes
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if startdatestring != "":
@@ -2757,12 +2758,12 @@ def cum_flex(request,theuser=0,
waterboattype = modalityform.cleaned_data['waterboattype']
rankingonly = modalityform.cleaned_data['rankingonly']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
request.session['modalities'] = modalities
@@ -2799,7 +2800,7 @@ def cum_flex(request,theuser=0,
flexaxesform = FlexAxesForm(request,initial=initial)
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -2861,7 +2862,13 @@ def cum_flex(request,theuser=0,
})
-@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+def planrequired_view(request):
+ messages.info(request,"This functionality requires Coach or Self-Coach membership")
+
+ return render(request,'promembership.html')
+
+@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def fitnessmetric_view(request,id=0,mode='rower',
startdate=timezone.now()-timezone.timedelta(days=365),
@@ -2904,6 +2911,7 @@ def fitnessmetric_view(request,id=0,mode='rower',
# Show the EMpower Oarlock generated Stroke Profile
@user_passes_test(ispromember,login_url="/rowers/promembership/",
+ message="This functionality requires a Pro plan or higher",
redirect_field_name=None)
def workout_forcecurve_view(request,id=0,workstrokesonly=False):
row = get_workout(id)
@@ -3034,7 +3042,9 @@ def workout_histo_view(request,id=0):
# Histogram for a date/time range
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def histo(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=365),
enddate=timezone.now(),
@@ -3043,8 +3053,8 @@ def histo(request,theuser=0,
enddatestring="",
options={
'includereststrokes':False,
- 'workouttypes':[i[0] for i in types.workouttypes],
- 'waterboattype':types.waterboattype,
+ 'workouttypes':[i[0] for i in mytypes.workouttypes],
+ 'waterboattype':mytypes.waterboattype,
'rankingonly': False,
}):
@@ -3054,7 +3064,7 @@ def histo(request,theuser=0,
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'rankingonly' in request.session:
@@ -3069,7 +3079,7 @@ def histo(request,theuser=0,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
@@ -3086,7 +3096,7 @@ def histo(request,theuser=0,
workstrokesonly = not includereststrokes
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if startdatestring != "":
@@ -3119,12 +3129,12 @@ def histo(request,theuser=0,
waterboattype = modalityform.cleaned_data['waterboattype']
rankingonly = modalityform.cleaned_data['rankingonly']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
request.session['modalities'] = modalities
@@ -3151,7 +3161,7 @@ def histo(request,theuser=0,
)
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -4090,7 +4100,9 @@ def rankings_view2(request,theuser=0,
'teams':get_my_teams(request.user),
})
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_update_cp_view(request,id=0):
row = get_workout(id)
@@ -4108,7 +4120,7 @@ def workout_update_cp_view(request,id=0):
dataprep.runcpupdate(r)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
url = reverse(otwrankings_view)
else:
url = reverse(oterankings_view)
@@ -4116,7 +4128,9 @@ def workout_update_cp_view(request,id=0):
return HttpResponseRedirect(url)
# Show ranking distances including predicted paces
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def otwrankings_view(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=365),
enddate=timezone.now(),
@@ -4519,7 +4533,9 @@ def otwcp_toadmin_view(request,theuser=0,
return response
# Show ranking distances including predicted paces
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def oterankings_view(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=365),
enddate=timezone.now(),
@@ -4950,7 +4966,9 @@ def workout_setprivate_view(request,id,
return HttpResponseRedirect(url)
# Joining workout
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workouts_join_view(request):
promember=0
if not request.user.is_anonymous():
@@ -4994,7 +5012,9 @@ def workouts_join_view(request):
url = reverse(workouts_join_select)
return HttpResponseRedirect(url)
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workouts_join_select(request,
startdatestring="",
enddatestring="",
@@ -5013,7 +5033,7 @@ def workouts_join_select(request,
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'modalities' in request.session:
@@ -5023,7 +5043,7 @@ def workouts_join_select(request,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
if request.method == 'POST' and 'daterange' in request.POST:
@@ -5048,19 +5068,19 @@ def workouts_join_select(request,
modality = modalityform.cleaned_data['modality']
waterboattype = modalityform.cleaned_data['waterboattype']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
request.session['modalities'] = modalities
request.session['waterboattype'] = waterboattype
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -5166,7 +5186,7 @@ def team_comparison_select(request,
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'rankingonly' in request.session:
rankingonly = request.session['rankingonly']
@@ -5180,7 +5200,7 @@ def team_comparison_select(request,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
if request.method == 'POST':
@@ -5198,12 +5218,12 @@ def team_comparison_select(request,
modality = modalityform.cleaned_data['modality']
waterboattype = modalityform.cleaned_data['waterboattype']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
if 'rankingonly' in modalityform.cleaned_data:
@@ -5228,7 +5248,7 @@ def team_comparison_select(request,
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -5451,7 +5471,9 @@ def multi_compare_view(request):
return HttpResponseRedirect(url)
# Multi Flex Chart with Grouping
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def user_multiflex_select(request,
startdatestring="",
enddatestring="",
@@ -5494,7 +5516,7 @@ def user_multiflex_select(request,
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'rankingonly' in request.session:
rankingonly = request.session['rankingonly']
@@ -5509,7 +5531,7 @@ def user_multiflex_select(request,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
if request.method == 'POST':
@@ -5527,12 +5549,12 @@ def user_multiflex_select(request,
waterboattype = modalityform.cleaned_data['waterboattype']
rankingonly = modalityform.cleaned_data['rankingonly']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
request.session['modalities'] = modalities
@@ -5561,7 +5583,7 @@ def user_multiflex_select(request,
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -5649,7 +5671,9 @@ def user_multiflex_select(request,
'teams':get_my_teams(request.user),
})
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def multiflex_data(request,userid=0,
options={
'includereststrokes':False,
@@ -5880,7 +5904,9 @@ def multiflex_data(request,userid=0,
})
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def multiflex_view(request,userid=0,
options={
'includereststrokes':False,
@@ -6045,7 +6071,9 @@ def multiflex_view(request,userid=0,
# Box plots
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def user_boxplot_select(request,
startdatestring="",
enddatestring="",
@@ -6056,7 +6084,7 @@ def user_boxplot_select(request,
options={
'includereststrokes':False,
'workouttypes':['rower','dynamic','slides'],
- 'waterboattype':types.waterboattype,
+ 'waterboattype':mytypes.waterboattype,
'rankingonly':False,
},
userid=0):
@@ -6093,7 +6121,7 @@ def user_boxplot_select(request,
workstrokesonly = not includereststrokes
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if startdatestring != "":
@@ -6122,11 +6150,11 @@ def user_boxplot_select(request,
modality = optionsform.cleaned_data['modality']
waterboattype = optionsform.cleaned_data['waterboattype']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
if 'rankingonly' in optionsform.cleaned_data:
@@ -6149,14 +6177,14 @@ def user_boxplot_select(request,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -6176,7 +6204,7 @@ def user_boxplot_select(request,
startdate = s
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -6188,7 +6216,7 @@ def user_boxplot_select(request,
).order_by(
"-date", "-starttime"
).exclude(boattype__in=negtypes)
- # workouttypes = [w for w in workouttypes if w not in types.otwtypes]
+ # workouttypes = [w for w in workouttypes if w not in mytypes.otwtypes]
if rankingonly:
workouts = [w for w in workouts if w.rankingpiece]
@@ -6247,7 +6275,9 @@ def user_boxplot_select(request,
'teams':get_my_teams(request.user),
})
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def boxplot_view_data(request,userid=0,
options={
'includereststrokes':False,
@@ -6344,7 +6374,9 @@ def boxplot_view_data(request,userid=0,
"div":div,
})
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def boxplot_view(request,userid=0,
options={
'includereststrokes':False,
@@ -6645,7 +6677,9 @@ def workouts_view(request,message='',successmessage='',
# List of workouts to compare a selected workout to
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_comparison_list(request,id=0,message='',successmessage='',
startdatestring="",enddatestring="",
startdate=timezone.now()-datetime.timedelta(days=365),
@@ -6725,7 +6759,9 @@ def workout_comparison_list(request,id=0,message='',successmessage='',
# List of workouts to compare a selected workout to
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_fusion_list(request,id=0,message='',successmessage='',
startdatestring="",enddatestring="",
startdate=timezone.now()-datetime.timedelta(days=365),
@@ -6917,7 +6953,9 @@ def workout_view(request,id=0):
# Resets stroke data to raw data (pace)
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_undo_smoothenpace_view(
request,id=0,message="",successmessage=""
):
@@ -6954,7 +6992,9 @@ def workout_undo_smoothenpace_view(
# Data smoothing of pace data
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
@@ -7003,7 +7043,9 @@ def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
return HttpResponseRedirect(url)
# Process CrewNerd Summary CSV and update summary
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
r = getrower(request.user)
@@ -7078,7 +7120,9 @@ def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
'id':row.id})
# Get weather for given location and date/time
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",
+ message="This functionality requires a Pro plan or higher",
+ redirect_field_name=None)
def workout_downloadwind_view(request,id=0,
airportcode=None,
message="",successmessage=""):
@@ -7144,7 +7188,7 @@ def workout_downloadwind_view(request,id=0,
return response
# Get weather for given location and date/time
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def workout_downloadmetar_view(request,id=0,
airportcode=None,
message="",successmessage=""):
@@ -7211,7 +7255,7 @@ def workout_downloadmetar_view(request,id=0,
# Show form to update wind data
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def workout_wind_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
r = getrower(request.user)
@@ -7347,7 +7391,7 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
# Show form to update River stream data (for river dwellers)
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def workout_stream_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
r = getrower(request.user)
@@ -7668,7 +7712,7 @@ def workout_geeky_view(request,id=0,message="",successmessage=""):
messages.error(request,message)
messages.info(request,successmessage)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
return render(request,
'otwgeeky.html',
{'workout':row,
@@ -7742,7 +7786,7 @@ def instroke_chart(request,id=0,metric=''):
return HttpResponseRedirect(url)
# Cumulative stats page
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def cumstats(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=30),
enddate=timezone.now(),
@@ -7752,7 +7796,7 @@ def cumstats(request,theuser=0,
options={
'includereststrokes':False,
'workouttypes':['rower','dynamic','slides'],
- 'waterboattype':types.waterboattype,
+ 'waterboattype':mytypes.waterboattype,
'rankingonly':False,
}):
@@ -7762,7 +7806,7 @@ def cumstats(request,theuser=0,
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if 'rankingonly' in request.session:
@@ -7777,7 +7821,7 @@ def cumstats(request,theuser=0,
else:
modality = modalities[0]
else:
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
modality = 'all'
@@ -7794,7 +7838,7 @@ def cumstats(request,theuser=0,
workstrokesonly = not includereststrokes
- waterboattype = types.waterboattype
+ waterboattype = mytypes.waterboattype
if startdatestring != "":
@@ -7829,12 +7873,12 @@ def cumstats(request,theuser=0,
waterboattype = modalityform.cleaned_data['waterboattype']
rankingonly = modalityform.cleaned_data['rankingonly']
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
if modality != 'water':
- waterboattype = [b[0] for b in types.boattypes]
+ waterboattype = [b[0] for b in mytypes.boattypes]
request.session['modalities'] = modalities
@@ -7861,7 +7905,7 @@ def cumstats(request,theuser=0,
)
negtypes = []
- for b in types.boattypes:
+ for b in mytypes.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
@@ -7887,7 +7931,7 @@ def cumstats(request,theuser=0,
if modality == 'all':
- modalities = [m[0] for m in types.workouttypes]
+ modalities = [m[0] for m in mytypes.workouttypes]
else:
modalities = [modality]
@@ -8347,7 +8391,7 @@ def workout_advanced_view(request,id=0,message="",successmessage=""):
messages.info(request,successmessage)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
return render(request,
'advancedotw.html',
{'workout':row,
@@ -8620,7 +8664,7 @@ def workout_workflow_view(request,id):
aantalcomments = len(comments)
workouttype = 'ote'
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
workouttype = 'otw'
try:
@@ -8730,7 +8774,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
mayedit=1
workouttype = 'ote'
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
workouttype = 'otw'
try:
@@ -8904,7 +8948,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
for name,d in rowingmetrics:
if d['mode'] == 'erg':
axchoicespro.pop(name)
@@ -11507,7 +11551,7 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
r.pw_tr,r.pw_an])/r.ftp
ftp = float(r.ftp)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
ftp = ftp*(100.-r.otwslack)/100.
rr = rrower(hrmax=r.max,hrut2=r.ut2,
@@ -11542,7 +11586,7 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
return HttpResponseRedirect(url)
# Split a workout
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def workout_split_view(request,id=id):
row = get_workout_permitted(request.user,id)
@@ -11633,7 +11677,7 @@ def workout_split_view(request,id=id):
# Fuse two workouts
-@user_passes_test(ispromember,login_url="/rowers/promembership",redirect_field_name=None)
+@user_passes_test(ispromember,login_url="/rowers/promembership",message="This functionality requires a Pro plan or higher",redirect_field_name=None)
def workout_fusion_view(request,id1=0,id2=1):
r = getrower(request.user)
@@ -11746,7 +11790,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
r.pw_tr,r.pw_an])/r.ftp
ftp = float(r.ftp)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
ftp = ftp*(100.-r.otwslack)/100.
rr = rrower(hrmax=r.max,hrut2=r.ut2,
@@ -13038,7 +13082,7 @@ def strokedatajson(request,id):
r.pw_tr,r.pw_an])/r.ftp
ftp = float(r.ftp)
- if row.workouttype in types.otwtypes:
+ if row.workouttype in mytypes.otwtypes:
ftp = ftp*(100.-r.otwslack)/100.
rr = rrower(hrmax=r.max,hrut2=r.ut2,
@@ -13755,6 +13799,7 @@ def agegrouprecordview(request,sex='male',weightcategory='hwt',
# Cloning sessions
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_multiclone_view(
request,
@@ -13867,6 +13912,7 @@ def plannedsession_multiclone_view(
# Individual user creates training for himself
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_create_view(request,
userid=0):
@@ -14000,6 +14046,7 @@ def plannedsession_create_view(request,
})
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_multicreate_view(request,
teamid=0,userid=0,extrasessions=0):
@@ -14709,6 +14756,7 @@ def plannedsessions_manage_view(request,userid=0,
# Clone an existing planned session
# need clarity on cloning behavior time shift
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_clone_view(request,id=0,userid=0):
@@ -14772,6 +14820,7 @@ def plannedsession_clone_view(request,id=0,userid=0):
# Edit an existing planned session
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership/",
+ message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_edit_view(request,id=0,userid=0):
@@ -15281,12 +15330,12 @@ def virtualevent_view(request,id=0):
try:
boattype = cd['boattype']
except KeyError:
- boattype = types.waterboattype
+ boattype = mytypes.waterboattype
try:
boatclass = cd['boatclass']
except KeyError:
- boatclass = [t for t in types.otwtypes]
+ boatclass = [t for t in mytypes.otwtypes]
age_min = cd['age_min']
age_max = cd['age_max']
@@ -15403,7 +15452,7 @@ def virtualevent_addboat_view(request,id=0):
boattypes = [record.boattype for record in records]
boatclasses = [record.boatclass for record in records]
- allowedboats = tuple([ type for type in types.boattypes if type[0] not in boattypes] )
+ allowedboats = tuple([ type for type in mytypes.boattypes if type[0] not in boattypes] )
# we're still here
@@ -15908,7 +15957,9 @@ def virtualevent_submit_result_view(request,id=0):
'w_form':w_form,
})
-@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", redirect_field_name=None)
+@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
def rower_create_trainingplan(request,userid=0):
therower = getrequestrower(request,userid=userid)
@@ -15979,7 +16030,9 @@ def rower_create_trainingplan(request,userid=0):
'targetform':targetform,
})
-@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", redirect_field_name=None)
+@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
def rower_delete_trainingtarget(request,id=0):
try:
target = TrainingTarget.objects.get(id=id)
@@ -15997,7 +16050,9 @@ def rower_delete_trainingtarget(request,id=0):
return HttpResponseRedirect(url)
-@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", redirect_field_name=None)
+@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
def rower_delete_trainingplan(request,id=0):
try:
plan = TrainingPlan.objects.get(id=id)
@@ -16224,6 +16279,7 @@ class WorkoutDelete(DeleteView):
]
mayedit=0
+ promember=0
if not self.request.user.is_anonymous():
r = getrower(self.request.user)
result = self.request.user.is_authenticated() and ispromember(self.request.user)
@@ -16306,7 +16362,9 @@ class MacroCycleDelete(DeleteView):
return obj
-@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", redirect_field_name=None)
+@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
def rower_trainingplan_view(request,
id=0,
userid=0,