Merge branch 'release/v15.24'
This commit is contained in:
@@ -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
|
||||
|
||||
198
rowers/models.py
198
rowers/models.py
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user