Private
Public Access
1
0

Merge branch 'release/v15.24'

This commit is contained in:
Sander Roosendaal
2021-01-26 14:32:19 +01:00
8 changed files with 227 additions and 46 deletions

View File

@@ -112,7 +112,7 @@ keyring==18.0.0
kiwisolver==1.0.1
kombu==4.5.0
llvmlite==0.33.0
lxml==4.3.2
lxml==4.6.2
Markdown==3.0.1
MarkupSafe==1.1.1
matplotlib==3.0.3
@@ -180,7 +180,7 @@ ratelim==0.1.6
redis==3.5.3
requests==2.23.0
requests-oauthlib==1.2.0
rowingdata==3.0.6
rowingdata==3.1.1
rowingphysics==0.5.0
rq==0.13.0
rules==2.1

View File

@@ -906,6 +906,14 @@ class Rower(models.Model):
'Pwr TR',
'Pwr AN'])
hrzones = PowerZonesField(default=['Rest',
'UT2',
'UT1',
'AT',
'TR',
'AN','max'])
emailalternatives = AlternativeEmails(default=[],null=True,blank=True,verbose_name='Alternative Email addresses (separate with ",")')
# Site Settings
@@ -3654,6 +3662,160 @@ class RowerCPForm(ModelForm):
model = Rower
fields = ['cprange','kfit','kfatigue']
# Form to set rower's Power zones, including test routines
# to enable consistency
class RowerHRZonesForm(ModelForm):
hrzones = ['Rest','UT2','UT1','AT','TR','AN','Max']
hrrestname = forms.CharField(initial=hrzones[0])
hrut2name = forms.CharField(initial=hrzones[1])
hrut1name = forms.CharField(initial=hrzones[2])
hratname = forms.CharField(initial=hrzones[3])
hrtrname = forms.CharField(initial=hrzones[4])
hranname = forms.CharField(initial=hrzones[5])
hrmaxname = forms.CharField(initial=hrzones[6])
def __init__(self, *args,**kwargs):
super(RowerHRZonesForm, self).__init__(*args, **kwargs)
if 'instance' in kwargs:
hrzones = kwargs['instance'].hrzones
else:
hrzones = ['Rest','UT2','UT1','AT','TR','AN','Max']
self.fields['hrrestname'].initial = hrzones[0]
self.fields['hrut2name'].initial = hrzones[1]
self.fields['hrut1name'].initial = hrzones[2]
self.fields['hratname'].initial = hrzones[3]
self.fields['hrtrname'].initial = hrzones[4]
self.fields['hranname'].initial = hrzones[5]
self.fields['hrmaxname'].initial = hrzones[6]
class Meta:
model = Rower
fields = ['rest','ut2','ut1','at','tr','an','max']
def clean(self):
cleaned_data = super(RowerHRZonesForm, self).clean()
try:
rest = cleaned_data['rest']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
rest = int(self.data['rest'])
try:
ut2 = cleaned_data['ut2']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
ut2 = int(self.data['ut2'])
try:
ut1 = cleaned_data['ut1']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
ut1 = int(self.data['ut1'])
try:
at = cleaned_data['at']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
at = int(self.data['at'])
try:
tr = cleaned_data['tr']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
tr = int(self.data['tr'])
try:
an = cleaned_data['an']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
an = int(self.data['an'])
try:
max = cleaned_data['max']
except KeyError:
raise ValidationError("Value cannot be empty")
except:
max = int(self.data['max'])
try:
hrrestname = cleaned_data['hrrestname']
except:
hrrestname = 'Rest'
cleaned_data['hrut3name'] = 'Rest'
try:
hrut2name = cleaned_data['hrut2name']
except:
hrut2name = 'UT2'
cleaned_data['hrut2name'] = 'UT2'
try:
hrut1name = cleaned_data['hrut1name']
except:
hrut1name = 'UT1'
cleaned_data['hrut1name'] = 'UT1'
try:
hratname = cleaned_data['hratname']
except:
hratname = 'AT'
cleaned_data['hratname'] = 'AT'
try:
hrtrname = cleaned_data['hrtrname']
except:
hrtrname = 'TR'
cleaned_data['hrtrname'] = 'TR'
try:
hranname = cleaned_data['hranname']
except:
hranname = 'AN'
cleaned_data['hranname'] = 'AN'
if rest >= ut2:
e = "{ut2name} should be higher than {restname}".format(
restname=hrrestname,
ut2name=hrut2name
)
raise forms.ValidationError(e)
if ut1 <= ut2:
e = "{ut1name} should be higher than {ut2name}".format(
ut1name = hrut1name,
ut2name= hrut2name,
)
raise forms.ValidationError(e)
if at <= ut1:
e = "{atname} should be higher than {ut1name}".format(
atname = hratname,
ut1name= hrut1name,
)
raise forms.ValidationError(e)
if tr <= at:
e = "{trname} should be higher than {atname}".format(
atname = hratname,
trname= hrtrname,
)
raise forms.ValidationError(e)
if an <= tr:
e = "{anname} should be higher than {trname}".format(
anname = hranname,
trname= hrtrname,
)
raise forms.ValidationError(e)
if max <= an:
e = "{anname} should be lower than {maxname}".format(
anname=hranname,
maxname=hrmaxname,
)
return cleaned_data
# Form to set rower's Power zones, including test routines
# to enable consistency
class RowerPowerZonesForm(ModelForm):
@@ -3743,44 +3905,12 @@ class RowerPowerZonesForm(ModelForm):
trname = cleaned_data['trname']
except:
trname = 'TR'
cleaned_data['ut1name'] = 'TR'
cleaned_data['trname'] = 'TR'
try:
anname = cleaned_data['anname']
except:
anname = 'AN'
cleaned_data['ut1name'] = 'AN'
try:
ut3name = cleaned_data['ut3name']
except:
ut2name = 'UT3'
cleaned_data['ut3name'] = 'UT3'
try:
ut2name = cleaned_data['ut2name']
except:
ut2name = 'UT2'
cleaned_data['ut2name'] = 'UT2'
try:
ut1name = cleaned_data['ut1name']
except:
ut1name = 'UT1'
cleaned_data['ut1name'] = 'UT1'
try:
atname = cleaned_data['atname']
except:
atname = 'AT'
cleaned_data['atname'] = 'AT'
try:
trname = cleaned_data['trname']
except:
trname = 'TR'
cleaned_data['ut1name'] = 'TR'
try:
anname = cleaned_data['anname']
except:
anname = 'AN'
cleaned_data['ut1name'] = 'AN'
cleaned_data['anname'] = 'AN'
if pw_ut1 <= pw_ut2:

View File

@@ -2123,13 +2123,15 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
hran = hrdata['hran']
ftp = hrdata['ftp']
powerzones = deserialize_list(hrdata['powerzones'])
hrzones = deserialize_list(hrdata['hrzones'])
powerperc = np.array(deserialize_list(hrdata['powerperc'])).astype(float)
rr = rowingdata.rower(hrmax=hrmax, hrut2=hrut2,
hrut1=hrut1, hrat=hrat,
hrtr=hrtr, hran=hran,
ftp=ftp, powerperc=powerperc,
powerzones=powerzones)
powerzones=powerzones,
hrzones=hrzones)
try:
row = rdata(csvfile=f2, rower=rr)
except IOError:

View File

@@ -14,15 +14,49 @@
<p>
<h2>Heart Rate Zones</h2>
<p>Set your heart rate zones with this form.</p>
<form enctype="multipart/form-data" action="" method="post">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
{{ form.non_field_errors }}
</p>
{% endif %}
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ form.as_table }}
<thead>
<tr>
<th>ID</th><th>Zone Name</th><th>Lower Boundary (BPM)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>{{ form.hrrestname }}</td>
<td>{{ form.rest }}</td>
</tr>
<tr>
<td>2</td><td>{{ form.hrut2name }}</td>
<td>{{ form.ut2 }}</td>
</tr>
<tr>
<td>3</td><td>{{ form.hrut1name }}</td>
<td>{{ form.ut1 }}</td>
</tr>
<tr>
<td>4</td><td>{{ form.hratname }}</td>
<td>{{ form.at }}</td>
</tr>
<tr>
<td>5</td><td>{{ form.hrtrname }}</td>
<td>{{ form.tr }}</td>
</tr>
<tr>
<td>6</td><td>{{ form.hranname }}</td>
<td>{{ form.an }}</td>
</tr>
<tr>
<td>7</td><td>{{ form.hrmaxname }}</td>
<td>{{ form.max }}</td>
</tr>
</tbody>
</table>
{% csrf_token %}
<input type="submit" value="Update Heart Rate Zones">

View File

@@ -433,6 +433,7 @@ def make_plot(r,w,f1,f2,plottype,title,imagename='',plotnr=0):
'ftp':ftp,
'powerperc':serialize_list(powerperc),
'powerzones':serialize_list(r.powerzones),
'hrzones':serialize_list(r.hrzones),
}
# make plot - asynchronous task

View File

@@ -121,7 +121,7 @@ from rowers.models import (
VirtualRaceFollower,
)
from rowers.models import (
RowerPowerForm,RowerForm,RowerCPForm,GraphImage,AdvancedWorkoutForm,
RowerPowerForm,RowerHRZonesForm,RowerForm,RowerCPForm,GraphImage,AdvancedWorkoutForm,
RowerPowerZonesForm,AccountRowerForm,UserForm,
Team,TeamForm,TeamInviteForm,TeamInvite,TeamRequest,
WorkoutComment,WorkoutCommentForm,RowerExportForm,

View File

@@ -489,13 +489,13 @@ def rower_prefs_view(request,userid=0,message=""):
}
]
form = RowerForm(instance=r)
form = RowerHRZonesForm(instance=r)
powerform = RowerPowerForm(instance=r)
powerzonesform = RowerPowerZonesForm(instance=r)
cpform = RowerCPForm(instance=r)
if request.method == 'POST' and "ut2" in request.POST:
form = RowerForm(request.POST)
form = RowerHRZonesForm(request.POST)
if form.is_valid():
# something
cd = form.cleaned_data
@@ -507,6 +507,16 @@ def rower_prefs_view(request,userid=0,message=""):
an = cd['an']
rest = cd['rest']
hrrestname = cd['hrrestname']
hrut2name = cd['hrut2name']
hrut1name = cd['hrut1name']
hratname = cd['hratname']
hrtrname = cd['hrtrname']
hranname = cd['hranname']
hrmaxname = cd['hrmaxname']
hrzones = [hrrestname,hrut2name,hrut1name,hratname,hrtrname,hranname,hrmaxname]
r.max = max(min(hrmax,250),10)
r.ut2 = max(min(ut2,250),10)
r.ut1 = max(min(ut1,250),10)
@@ -514,6 +524,7 @@ def rower_prefs_view(request,userid=0,message=""):
r.tr = max(min(tr,250),10)
r.an = max(min(an,250),10)
r.rest = max(min(rest,250),10)
r.hrzones = hrzones
r.save()
successmessage = "Your Heart Rate data were changed"
messages.info(request,successmessage)

View File

@@ -1290,7 +1290,8 @@ def remove_power_view(request,id=0):
rr = rrower(hrmax=r.max, hrut2=r.ut2,
hrut1=r.ut1, hrat=r.at,
hrtr=r.tr, hran=r.an, ftp=r.ftp,
powerperc=powerperc, powerzones=r.powerzones)
powerperc=powerperc, powerzones=r.powerzones,
hrzones=r.hrzones)
row = rdata(f,rower=rr)
row.df[' Power (watts)'] = 0
row.write_csv(f)
@@ -5837,7 +5838,8 @@ def workout_summary_restore_view(request,id,message="",successmessage=""):
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an,ftp=ftp,
powerperc=powerperc,powerzones=r.powerzones)
powerperc=powerperc,powerzones=r.powerzones,
hrzones=r.hrzones)
rowdata = rdata(f1,rower=rr)
if rowdata == 0:
raise Http404("Error: CSV Data File Not Found")
@@ -6094,7 +6096,8 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an,ftp=ftp,
powerperc=powerperc,powerzones=r.powerzones)
powerperc=powerperc,powerzones=r.powerzones,
hrzones=r.hrzones)
rowdata = rdata(f1,rower=rr)
if rowdata == 0:
return HttpResponse("Error: CSV Data File Not Found")