Merge branch 'release/v5.29'
This commit is contained in:
+6
-1
@@ -32,7 +32,7 @@ from rowingdata import (
|
|||||||
MysteryParser, BoatCoachOTWParser,QuiskeParser,
|
MysteryParser, BoatCoachOTWParser,QuiskeParser,
|
||||||
painsledDesktopParser, speedcoachParser, ErgStickParser,
|
painsledDesktopParser, speedcoachParser, ErgStickParser,
|
||||||
SpeedCoach2Parser, FITParser, fitsummarydata,
|
SpeedCoach2Parser, FITParser, fitsummarydata,
|
||||||
make_cumvalues,cumcpdata,
|
make_cumvalues,cumcpdata,ExcelTemplate,
|
||||||
summarydata, get_file_type,
|
summarydata, get_file_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -996,6 +996,11 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
|
|
||||||
def parsenonpainsled(fileformat,f2,summary):
|
def parsenonpainsled(fileformat,f2,summary):
|
||||||
# handle RowPro:
|
# handle RowPro:
|
||||||
|
if (fileformat == 'xls'):
|
||||||
|
row = ExcelTemplate(f2)
|
||||||
|
hasrecognized = True
|
||||||
|
|
||||||
|
|
||||||
if (fileformat == 'rp'):
|
if (fileformat == 'rp'):
|
||||||
row = RowProParser(f2)
|
row = RowProParser(f2)
|
||||||
hasrecognized = True
|
hasrecognized = True
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ class RegistrationFormTermsOfService(RegistrationForm):
|
|||||||
tos = forms.BooleanField(widget=forms.CheckboxInput,
|
tos = forms.BooleanField(widget=forms.CheckboxInput,
|
||||||
label='I have read and agree to the Terms of Service',
|
label='I have read and agree to the Terms of Service',
|
||||||
error_messages={'required': "You must agree to the terms to register"})
|
error_messages={'required': "You must agree to the terms to register"})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
|
class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
|
||||||
@@ -370,6 +371,35 @@ class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
|
|||||||
raise forms.ValidationError("This email address is already in use. Please supply a different email address.")
|
raise forms.ValidationError("This email address is already in use. Please supply a different email address.")
|
||||||
return self.cleaned_data['email']
|
return self.cleaned_data['email']
|
||||||
|
|
||||||
|
class RegistrationFormSex(RegistrationFormUniqueEmail):
|
||||||
|
sexcategories = (
|
||||||
|
('female','female'),
|
||||||
|
('male','male'),
|
||||||
|
('not specified','not specified'),
|
||||||
|
)
|
||||||
|
|
||||||
|
weightcategories = (
|
||||||
|
('hwt','heavy-weight'),
|
||||||
|
('lwt','light-weight'),
|
||||||
|
)
|
||||||
|
|
||||||
|
birthdate = forms.DateTimeField(widget=SelectDateWidget(
|
||||||
|
years=range(timezone.now().year-100,timezone.now().year-10)),
|
||||||
|
initial = datetime.date(year=1970,
|
||||||
|
month=4,
|
||||||
|
day=15))
|
||||||
|
|
||||||
|
sex = forms.ChoiceField(required=True,
|
||||||
|
choices=sexcategories,
|
||||||
|
initial='not specified',
|
||||||
|
label='Sex')
|
||||||
|
|
||||||
|
weightcategory = forms.ChoiceField(label='Weight Category',
|
||||||
|
choices=weightcategories)
|
||||||
|
|
||||||
|
# def __init__(self, *args, **kwargs):
|
||||||
|
# self.fields['sex'].initial = 'not specified'
|
||||||
|
|
||||||
# Time field supporting microseconds. Not used, I believe.
|
# Time field supporting microseconds. Not used, I believe.
|
||||||
class MyTimeField(forms.TimeField):
|
class MyTimeField(forms.TimeField):
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from utils import lbstoN
|
from utils import lbstoN
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
rowingmetrics = (
|
rowingmetrics = (
|
||||||
('time',{
|
('time',{
|
||||||
@@ -301,3 +302,17 @@ dropping to 8m for race pace in the single.""",
|
|||||||
This value should be fairly constant across all stroke rates.""",
|
This value should be fairly constant across all stroke rates.""",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def calc_trimp(df,sex,hrmax,hrmin):
|
||||||
|
if sex == 'male':
|
||||||
|
f = 1.92
|
||||||
|
else:
|
||||||
|
f = 1.67
|
||||||
|
|
||||||
|
dt = df['time'].diff()/6.e4
|
||||||
|
|
||||||
|
hrr = (df['hr']-hrmin)/(hrmax-hrmin)
|
||||||
|
trimpdata = dt*hrr*0.64*np.exp(f*hrr)
|
||||||
|
trimp = trimpdata.sum()
|
||||||
|
|
||||||
|
return trimp
|
||||||
|
|||||||
+20
-1
@@ -8,6 +8,7 @@ from django import forms
|
|||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.forms.widgets import SplitDateTimeWidget
|
from django.forms.widgets import SplitDateTimeWidget
|
||||||
|
from django.forms.extras.widgets import SelectDateWidget
|
||||||
from django.forms.formsets import BaseFormSet
|
from django.forms.formsets import BaseFormSet
|
||||||
from datetimewidget.widgets import DateTimeWidget
|
from datetimewidget.widgets import DateTimeWidget
|
||||||
from django.core.validators import validate_email
|
from django.core.validators import validate_email
|
||||||
@@ -210,6 +211,12 @@ class Rower(models.Model):
|
|||||||
('lwt','light-weight'),
|
('lwt','light-weight'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sexcategories = (
|
||||||
|
('male','male'),
|
||||||
|
('female','female'),
|
||||||
|
('not specified','not specified'),
|
||||||
|
)
|
||||||
|
|
||||||
stravatypes = (
|
stravatypes = (
|
||||||
('Ride','Ride'),
|
('Ride','Ride'),
|
||||||
('Kitesurf','Kitesurf'),
|
('Kitesurf','Kitesurf'),
|
||||||
@@ -257,6 +264,11 @@ class Rower(models.Model):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
choices=weightcategories)
|
choices=weightcategories)
|
||||||
|
|
||||||
|
sex = models.CharField(default="not specified",
|
||||||
|
max_length=30,
|
||||||
|
choices=sexcategories)
|
||||||
|
|
||||||
|
birthdate = models.DateField(null=True,blank=True)
|
||||||
# Power Zone Data
|
# Power Zone Data
|
||||||
ftp = models.IntegerField(default=226,verbose_name="Functional Threshold Power")
|
ftp = models.IntegerField(default=226,verbose_name="Functional Threshold Power")
|
||||||
|
|
||||||
@@ -939,10 +951,17 @@ class RowerPowerZonesForm(ModelForm):
|
|||||||
class AccountRowerForm(ModelForm):
|
class AccountRowerForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Rower
|
model = Rower
|
||||||
fields = ['weightcategory','getemailnotifications',
|
fields = ['sex','birthdate','weightcategory','getemailnotifications',
|
||||||
'defaulttimezone','showfavoritechartnotes',
|
'defaulttimezone','showfavoritechartnotes',
|
||||||
'defaultlandingpage']
|
'defaultlandingpage']
|
||||||
|
|
||||||
|
widgets = {
|
||||||
|
'birthdate': SelectDateWidget(
|
||||||
|
years=range(
|
||||||
|
timezone.now().year-100,timezone.now().year-10)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
email = self.cleaned_data.get('email')
|
email = self.cleaned_data.get('email')
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ def validate_file_extension(value):
|
|||||||
ext = os.path.splitext(value.name)[1]
|
ext = os.path.splitext(value.name)[1]
|
||||||
valid_extensions = ['.tcx','.csv','.TCX',
|
valid_extensions = ['.tcx','.csv','.TCX',
|
||||||
'.CSV','.fit','.FIT','.zip','.ZIP',
|
'.CSV','.fit','.FIT','.zip','.ZIP',
|
||||||
'.gz','.GZ']
|
'.gz','.GZ','.xls']
|
||||||
if not ext in valid_extensions:
|
if not ext in valid_extensions:
|
||||||
raise ValidationError(u'File not supported!')
|
raise ValidationError(u'File not supported!')
|
||||||
|
|
||||||
|
|||||||
@@ -307,6 +307,9 @@ class NewUserRegistrationTest(TestCase):
|
|||||||
'password1':'aapindewei2',
|
'password1':'aapindewei2',
|
||||||
'password2':'aapindewei2',
|
'password2':'aapindewei2',
|
||||||
'tos':True,
|
'tos':True,
|
||||||
|
'weightcategory':'hwt',
|
||||||
|
'sex':'male',
|
||||||
|
'birthdate':datetime.datetime(year=1970,month=4,day=2)
|
||||||
}
|
}
|
||||||
|
|
||||||
form = RegistrationFormUniqueEmail(form_data)
|
form = RegistrationFormUniqueEmail(form_data)
|
||||||
|
|||||||
+32
-6
@@ -44,7 +44,8 @@ from rowers.forms import (
|
|||||||
SummaryStringForm,IntervalUpdateForm,StrokeDataForm,
|
SummaryStringForm,IntervalUpdateForm,StrokeDataForm,
|
||||||
StatsOptionsForm,PredictedPieceForm,DateRangeForm,DeltaDaysForm,
|
StatsOptionsForm,PredictedPieceForm,DateRangeForm,DeltaDaysForm,
|
||||||
EmailForm, RegistrationForm, RegistrationFormTermsOfService,
|
EmailForm, RegistrationForm, RegistrationFormTermsOfService,
|
||||||
RegistrationFormUniqueEmail,CNsummaryForm,UpdateWindForm,
|
RegistrationFormUniqueEmail,RegistrationFormSex,
|
||||||
|
CNsummaryForm,UpdateWindForm,
|
||||||
UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm,
|
UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm,
|
||||||
FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm,
|
FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm,
|
||||||
TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm,
|
TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm,
|
||||||
@@ -58,6 +59,7 @@ from rowers.models import (
|
|||||||
)
|
)
|
||||||
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
|
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
|
||||||
from rowers.metrics import rowingmetrics,defaultfavoritecharts
|
from rowers.metrics import rowingmetrics,defaultfavoritecharts
|
||||||
|
from rowers import metrics
|
||||||
import rowers.uploads as uploads
|
import rowers.uploads as uploads
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
import StringIO
|
import StringIO
|
||||||
@@ -772,20 +774,25 @@ def add_defaultfavorites(r):
|
|||||||
# User registration
|
# User registration
|
||||||
def rower_register_view(request):
|
def rower_register_view(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = RegistrationFormUniqueEmail(request.POST)
|
#form = RegistrationFormUniqueEmail(request.POST)
|
||||||
|
form = RegistrationFormSex(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
first_name = form.cleaned_data['first_name']
|
first_name = form.cleaned_data['first_name']
|
||||||
last_name = form.cleaned_data['last_name']
|
last_name = form.cleaned_data['last_name']
|
||||||
email = form.cleaned_data['email']
|
email = form.cleaned_data['email']
|
||||||
password = form.cleaned_data['password1']
|
password = form.cleaned_data['password1']
|
||||||
username = form.cleaned_data['username']
|
username = form.cleaned_data['username']
|
||||||
|
sex = form.cleaned_data['sex']
|
||||||
|
birthdate = form.cleaned_data['birthdate']
|
||||||
|
weightcategory = form.cleaned_data['weightcategory']
|
||||||
theuser = User.objects.create_user(username,password=password)
|
theuser = User.objects.create_user(username,password=password)
|
||||||
theuser.first_name = first_name
|
theuser.first_name = first_name
|
||||||
theuser.last_name = last_name
|
theuser.last_name = last_name
|
||||||
theuser.email = email
|
theuser.email = email
|
||||||
theuser.save()
|
theuser.save()
|
||||||
|
|
||||||
therower = Rower(user=theuser)
|
therower = Rower(user=theuser,sex=sex,birthdate=birthdate,
|
||||||
|
weightcategory=weightcategory)
|
||||||
|
|
||||||
therower.save()
|
therower.save()
|
||||||
|
|
||||||
@@ -843,7 +850,7 @@ Oh, one more thing. The site is currently in beta and is developing fast. Bear w
|
|||||||
"registration_form.html",
|
"registration_form.html",
|
||||||
{'form':form})
|
{'form':form})
|
||||||
else:
|
else:
|
||||||
form = RegistrationFormUniqueEmail()
|
form = RegistrationFormSex()
|
||||||
return render(request,
|
return render(request,
|
||||||
"registration_form.html",
|
"registration_form.html",
|
||||||
{'form':form,})
|
{'form':form,})
|
||||||
@@ -6879,8 +6886,14 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
|
|
||||||
|
|
||||||
if datadf.empty:
|
if datadf.empty:
|
||||||
return HttpResponse("CSV data file not found")
|
datadf,row = dataprep.getrowdata_db(id=id)
|
||||||
|
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=False)
|
||||||
|
workstrokesonly=False
|
||||||
|
if datadf.empty:
|
||||||
|
return HttpResponse("CSV data file not found")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
workoutstateswork = [1,4,5,8,9,6,7]
|
workoutstateswork = [1,4,5,8,9,6,7]
|
||||||
workoutstatesrest = [3]
|
workoutstatesrest = [3]
|
||||||
workoutstatetransition = [0,2,10,11,12,13]
|
workoutstatetransition = [0,2,10,11,12,13]
|
||||||
@@ -6977,6 +6990,15 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
except ZeroDivisionError,ValueError:
|
except ZeroDivisionError,ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# TRIMP
|
||||||
|
if datadf['hr'].mean() > 0 and r.sex != 'not specified':
|
||||||
|
trimp = metrics.calc_trimp(datadf,r.sex,r.max,r.rest)
|
||||||
|
trimp = int(trimp)
|
||||||
|
otherstats['trimp'] = {
|
||||||
|
'verbose_name': 'TRIMP',
|
||||||
|
'value': trimp,
|
||||||
|
'unit': 'minutes'
|
||||||
|
}
|
||||||
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'workoutstats.html',
|
'workoutstats.html',
|
||||||
@@ -7802,7 +7824,7 @@ def workout_comment_view(request,id=0):
|
|||||||
url = url,
|
url = url,
|
||||||
)
|
)
|
||||||
if request.user != r.user:
|
if request.user != r.user:
|
||||||
a_messages.info(r.user,message)
|
a_messages.info(r.user,message.encode('ascii','ignore'))
|
||||||
|
|
||||||
res = myqueue(queuehigh,
|
res = myqueue(queuehigh,
|
||||||
handle_sendemailnewcomment,r.user.first_name,
|
handle_sendemailnewcomment,r.user.first_name,
|
||||||
@@ -10222,8 +10244,10 @@ def rower_edit_view(request,message=""):
|
|||||||
first_name = ucd['first_name']
|
first_name = ucd['first_name']
|
||||||
last_name = ucd['last_name']
|
last_name = ucd['last_name']
|
||||||
email = ucd['email']
|
email = ucd['email']
|
||||||
|
sex = cd['sex']
|
||||||
defaultlandingpage = cd['defaultlandingpage']
|
defaultlandingpage = cd['defaultlandingpage']
|
||||||
weightcategory = cd['weightcategory']
|
weightcategory = cd['weightcategory']
|
||||||
|
birthdate = cd['birthdate']
|
||||||
showfavoritechartnotes = cd['showfavoritechartnotes']
|
showfavoritechartnotes = cd['showfavoritechartnotes']
|
||||||
getemailnotifications = cd['getemailnotifications']
|
getemailnotifications = cd['getemailnotifications']
|
||||||
defaulttimezone=cd['defaulttimezone']
|
defaulttimezone=cd['defaulttimezone']
|
||||||
@@ -10242,6 +10266,8 @@ def rower_edit_view(request,message=""):
|
|||||||
r.getemailnotifications = getemailnotifications
|
r.getemailnotifications = getemailnotifications
|
||||||
r.defaultlandingpage = defaultlandingpage
|
r.defaultlandingpage = defaultlandingpage
|
||||||
r.showfavoritechartnotes = showfavoritechartnotes
|
r.showfavoritechartnotes = showfavoritechartnotes
|
||||||
|
r.sex = sex
|
||||||
|
r.birthdate = birthdate
|
||||||
r.save()
|
r.save()
|
||||||
form = RowerForm(instance=r)
|
form = RowerForm(instance=r)
|
||||||
powerform = RowerPowerForm(instance=r)
|
powerform = RowerPowerForm(instance=r)
|
||||||
|
|||||||
Reference in New Issue
Block a user