diff --git a/rowers/models.py b/rowers/models.py index ac3fe85e..0424cbe0 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -427,89 +427,115 @@ class RowerPowerForm(ModelForm): # Form to set rower's Power zones, including test routines # to enable consistency class RowerPowerZonesForm(ModelForm): - ut2name = forms.CharField(initial='UT2') - ut1name = forms.CharField(initial='UT1') - atname = forms.CharField(initial='AT') - trname = forms.CharField(initial='TR') - anname = forms.CharField(initial='AN') + + powerzones = ['UT3','UT2','UT1','AT','TR','AN'] + ut3name = forms.CharField(initial=powerzones[0]) + ut2name = forms.CharField(initial=powerzones[1]) + ut1name = forms.CharField(initial=powerzones[2]) + atname = forms.CharField(initial=powerzones[3]) + trname = forms.CharField(initial=powerzones[4]) + anname = forms.CharField(initial=powerzones[5]) + def __init__(self, *args,**kwargs): + super(RowerPowerZonesForm, self).__init__(*args, **kwargs) + + if 'instance' in kwargs: + powerzones = kwargs['instance'].powerzones + else: + powerzones = ['UT3','UT2','UT1','AT','TR','AN'] + + self.fields['ut3name'].initial = powerzones[0] + self.fields['ut2name'].initial = powerzones[1] + self.fields['ut1name'].initial = powerzones[2] + self.fields['atname'].initial = powerzones[3] + self.fields['trname'].initial = powerzones[4] + self.fields['anname'].initial = powerzones[5] + class Meta: model = Rower fields = ['pw_ut2','pw_ut1','pw_at','pw_tr','pw_an'] - def clean(self): - try: - pw_ut2 = self.cleaned_data['pw_ut2'] - except: - pw_ut2 = int(self.data['pw_ut2']) - try: - pw_ut1 = self.cleaned_data['pw_ut1'] - except: - pw_ut1 = int(self.data['pw_ut1']) - try: - pw_at = self.cleaned_data['pw_at'] - except: - pw_at = int(self.data['pw_at']) - try: - pw_tr = self.cleaned_data['pw_tr'] - except: - pw_tr = int(self.data['pw_tr']) - try: - pw_an = self.cleaned_data['pw_an'] - except: - pw_an = int(self.data['pw_an']) + def clean(self): + cleaned_data = super(RowerPowerZonesForm, self).clean() + try: + pw_ut2 = cleaned_data['pw_ut2'] + except: + pw_ut2 = int(self.data['pw_ut2']) + try: + pw_ut1 = cleaned_data['pw_ut1'] + except: + pw_ut1 = int(self.data['pw_ut1']) + try: + pw_at = cleaned_data['pw_at'] + except: + pw_at = int(self.data['pw_at']) + try: + pw_tr = cleaned_data['pw_tr'] + except: + pw_tr = int(self.data['pw_tr']) + try: + pw_an = cleaned_data['pw_an'] + except: + pw_an = int(self.data['pw_an']) - try: - ut2name = self.cleaned_data['ut2name'] - except: - ut2name = 'UT2' - self.cleaned_data['ut2name'] = 'UT2' - try: - ut1name = self.cleaned_data['ut1name'] - except: - ut1name = 'UT1' - self.cleaned_data['ut1name'] = 'UT1' - try: - atname = self.cleaned_data['atname'] - except: - atname = 'AT' - self.cleaned_data['atname'] = 'AT' - try: - trname = self.cleaned_data['trname'] - except: - trname = 'TR' - self.cleaned_data['ut1name'] = 'TR' - try: - anname = self.cleaned_data['anname'] - except: - anname = 'AN' - self.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' - - if pw_ut1 <= pw_ut2: - e = "{ut1name} should be higher than {ut2name}".format( - ut1name = ut1name, - ut2name= ut2name, - ) - raise forms.ValidationError(e) - if pw_at <= pw_ut1: - e = "{atname} should be higher than {ut1name}".format( - atname = atname, - ut1name= ut1name, - ) - raise forms.ValidationError(e) - if pw_tr <= pw_at: - e = "{trname} should be higher than {atname}".format( - atname = atname, - trname= trname, - ) - raise forms.ValidationError(e) - if pw_an <= pw_tr: - e = "{anname} should be higher than {trname}".format( - anname = anname, - trname= trname, - ) - raise forms.ValidationError(e) + + if pw_ut1 <= pw_ut2: + e = "{ut1name} should be higher than {ut2name}".format( + ut1name = ut1name, + ut2name= ut2name, + ) + raise forms.ValidationError(e) + if pw_at <= pw_ut1: + e = "{atname} should be higher than {ut1name}".format( + atname = atname, + ut1name= ut1name, + ) + raise forms.ValidationError(e) + if pw_tr <= pw_at: + e = "{trname} should be higher than {atname}".format( + atname = atname, + trname= trname, + ) + raise forms.ValidationError(e) + if pw_an <= pw_tr: + e = "{anname} should be higher than {trname}".format( + anname = anname, + trname= trname, + ) + raise forms.ValidationError(e) + + return cleaned_data # Form to set rower's Heart Rate zones, including test routines # to enable consistency diff --git a/rowers/templates/rower_form.html b/rowers/templates/rower_form.html index bec8fde4..04e8c616 100644 --- a/rowers/templates/rower_form.html +++ b/rowers/templates/rower_form.html @@ -27,20 +27,42 @@
{% if powerzonesform.errors %}

- Please correct the error{{ form.errors|pluralize }} below. + Please correct the error{{ powerzonesform.errors|pluralize }} below. + {{ powerzonesform.non_field_errors }} +

{% endif %} - + - + + + + + + + + + + + + + + + + + + + + +
IDZone NameLower BoundaryIDZone NameLower Boundary (Watt)
1{{ powerzonesform.ut2name }}1{{ powerzonesform.ut3name }}
2{{ powerzonesform.ut2name }}{{ powerzonesform.pw_ut2 }}
3{{ powerzonesform.ut1name }}{{ powerzonesform.pw_ut1 }}
4{{ powerzonesform.atname }}{{ powerzonesform.pw_at }}
5{{ powerzonesform.trname }}{{ powerzonesform.pw_tr }}
6{{ powerzonesform.anname }}{{ powerzonesform.pw_an }}
{% csrf_token %} diff --git a/rowers/urls.py b/rowers/urls.py index a7eda7f8..13ba7bb3 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -193,6 +193,8 @@ urlpatterns = [ url(r'^workout/(\d+)/stravauploadw/$',views.workout_strava_upload_view), url(r'^workout/(\d+)/recalcsummary/$',views.workout_recalcsummary_view), url(r'^workout/(\d+)/sporttracksuploadw/$',views.workout_sporttracks_upload_view), + url(r'^me/edit/c/(?P\w+.*)$',views.rower_edit_view), + url(r'^me/edit/s/(?P\w+.*)$',views.rower_edit_view), url(r'^me/edit/$',views.rower_edit_view), url(r'^me/edit/(.+.*)/$',views.rower_edit_view), url(r'^me/c2authorize/$',views.rower_c2_authorize), diff --git a/rowers/views.py b/rowers/views.py index 4c24014a..1608a367 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -440,9 +440,17 @@ def add_workout_from_strokedata(user,importid,data,strokedata, # make workout + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc, + powerzones=r.powerzones, + ) row = rdata(csvfilename,rower=rr) averagehr = row.df[' HRCur (bpm)'].mean() @@ -679,9 +687,15 @@ def add_workout_from_stdata(user,importid,data): compression='gzip') # make workout + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc,powerzones=powerzones) row = rdata(csvfilename,rower=rr) averagehr = row.df[' HRCur (bpm)'].mean() @@ -3837,9 +3851,15 @@ def workout_upload_view(request,message=""): # make Workout object and put in database r = Rower.objects.get(user=request.user) + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc,powerzones=powerzones) row = rdata(f2,rower=rr) if row == 0: return HttpResponse("Error: CSV Data File Not Found") @@ -4176,9 +4196,15 @@ def workout_summary_restore_view(request,id,message="",successmessage=""): f1 = row.csvfilename u = request.user r = Rower.objects.get(user=u) + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc,powerzones=powerzones) rowdata = rdata(f1,rower=rr) if rowdata == 0: return HttpResponse("Error: CSV Data File Not Found") @@ -4225,9 +4251,15 @@ def workout_summary_edit_view(request,id,message="",successmessage="" f1 = row.csvfilename u = request.user r = Rower.objects.get(user=u) + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc,powerzones=powerzones) rowdata = rdata(f1,rower=rr) if rowdata == 0: return HttpResponse("Error: CSV Data File Not Found") @@ -4465,6 +4497,7 @@ def rower_favoritecharts_view(request): # Add email address to form so user can change his email address @login_required() def rower_edit_view(request,message=""): + r = Rower.objects.get(user=request.user) if request.method == 'POST' and "ut2" in request.POST: form = RowerForm(request.POST) if form.is_valid(): @@ -4489,17 +4522,30 @@ def rower_edit_view(request,message=""): r.rest = max(min(rest,250),10) r.weightcategory = weightcategory r.save() - message = "User data changed" - url = reverse(workouts_view,args=[str(message)]) - response = HttpResponseRedirect(url) + successmessage = "Your Heart Rate data were changed" + form = RowerForm(instance=r) + powerform = RowerPowerForm(instance=r) + powerzonesform = RowerPowerZonesForm(instance=r) + return render(request, 'rower_form.html', + {'form':form, + 'powerzonesform':powerzonesform, + 'powerform':powerform, + 'rower':r, + 'successmessage':successmessage, + }) except Rower.DoesNotExist: message = "Funny. This user doesn't exist." url = reverse(workouts_view,args=[str(message)]) response = HttpResponseRedirect(url) else: message = HttpResponse("invalid form") + #form = RowerForm(instance=r) + powerform = RowerPowerForm(instance=r) + powerzonesform = RowerPowerZonesForm(instance=r) return render(request, 'rower_form.html', {'form':form, + 'powerzonesform':powerzonesform, + 'powerform':powerform, 'rower':r, }) # url = reverse(rower_edit_view,args=[str(message)]) @@ -4508,15 +4554,18 @@ def rower_edit_view(request,message=""): return response elif request.method == 'POST' and "ftp" in request.POST: - form = RowerPowerForm(request.POST) - if form.is_valid(): - cd = form.cleaned_data + powerform = RowerPowerForm(request.POST) + if powerform.is_valid(): + cd = powerform.cleaned_data ftp = cd['ftp'] try: r = Rower.objects.get(user=request.user) + powerfrac = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp r.ftp = max(min(ftp,650),50) - powerperc = [55,75,90,105,120] - ut2,ut1,at,tr,an = (r.ftp*np.array(powerperc)/100.).astype(int) + ut2,ut1,at,tr,an = (r.ftp*powerfrac/100.).astype(int) r.pw_ut2 = ut2 r.pw_ut1 = ut1 r.pw_at = at @@ -4528,10 +4577,13 @@ def rower_edit_view(request,message=""): response = HttpResponseRedirect(url) except Rower.DoesNotExist: message = "Funny. This user doesn't exist." - url = reverse(workouts_view,args=[str(message)]) + url = reverse(rower_edit_view,args=[str(message)]) response = HttpResponseRedirect(url) else: message = HttpResponse("invalid form") + form = RowerForm(instance=r) + #powerform = RowerPowerForm(instance=r) + powerzonesform = RowerPowerZonesForm(instance=r) return render(request, 'rower_form.html', {'form':form, 'powerform':powerform, @@ -4540,20 +4592,62 @@ def rower_edit_view(request,message=""): return response + elif request.method == 'POST' and "ut3name" in request.POST: + powerzonesform = RowerPowerZonesForm(request.POST) + if powerzonesform.is_valid(): + cd = powerzonesform.cleaned_data + pw_ut2 = cd['pw_ut2'] + pw_ut1 = cd['pw_ut1'] + pw_at = cd['pw_at'] + pw_tr = cd['pw_tr'] + pw_an = cd['pw_an'] + ut3name = cd['ut3name'] + ut2name = cd['ut2name'] + ut1name = cd['ut1name'] + atname = cd['atname'] + trname = cd['trname'] + anname = cd['anname'] + powerzones = [ut3name,ut2name,ut1name,atname,trname,anname] + try: + r = Rower.objects.get(user=request.user) + r.pw_ut2 = pw_ut2 + r.pw_ut1 = pw_ut1 + r.pw_at = pw_at + r.pw_tr = pw_tr + r.pw_an = pw_an + r.powerzones = powerzones + r.save() + successmessage = "Your Power Zone data were changed" + form = RowerForm(instance=r) + powerform = RowerPowerForm(instance=r) + powerzonesform = RowerPowerZonesForm(instance=r) + return render(request, 'rower_form.html', + {'form':form, + 'powerzonesform':powerzonesform, + 'powerform':powerform, + 'rower':r, + 'successmessage':successmessage, + }) + except Rower.DoesNotExist: + message = "Funny. This user doesn't exist." + url = reverse(workouts_view,args=[str(message)]) + response = HttpResponseRedirect(url) + return response + else: + form = RowerForm(instance=r) + powerform = RowerPowerForm(instance=r) + #powerzonesform = RowerPowerZonesForm(instance=r) + message = HttpResponse("invalid form") + return render(request, 'rower_form.html', + {'form':form, + 'powerform':powerform, + 'powerzonesform':powerzonesform, + 'rower':r, + }) + else: try: r = Rower.objects.get(user=request.user) - - # Temporary code - powerperc = [55,75,90,105,120] - ut2,ut1,at,tr,an = (r.ftp*np.array(powerperc)/100.).astype(int) - r.pw_ut2 = ut2 - r.pw_ut1 = ut1 - r.pw_at = at - r.pw_tr = tr - r.pw_an = an - r.save() - # end temporary form = RowerForm(instance=r) powerform = RowerPowerForm(instance=r) @@ -4742,10 +4836,15 @@ def strokedatajson(request,id): row.save() r = Rower.objects.get(user=request.user) - + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, - hrtr=r.tr,hran=r.an,ftp=r.ftp) + hrtr=r.tr,hran=r.an,ftp=r.ftp, + powerperc=powerperc,powerzones=powerzones) rowdata = rdata(row.csvfilename,rower=rr).df datadf = dataprep.dataprep(rowdata,id=row.id,bands=True,barchart=True,otwpower=True,empower=True)