Private
Public Access
1
0

force curve comparison

This commit is contained in:
Sander Roosendaal
2022-10-26 23:49:28 +02:00
parent cb8aeb1cf6
commit 7ebdf21c25
10 changed files with 590 additions and 27 deletions

View File

@@ -1844,6 +1844,108 @@ def agegrouprecordview(request, sex='male', weightcategory='hwt',
'the_div': div,
})
@user_passes_test(ispromember, login_url="/rowers/paidplans",
message="This functionality requires a Pro plan or higher."
" If you are already a Pro user, please log in to access this functionality",
redirect_field_name=None)
@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True)
def forcecurveanalysis_view(request, userid=0):
r = getrequestrower(request, userid=userid)
analyses = ForceCurveAnalysis.objects.filter(rower=r).order_by("-date","-id")
selected = []
div = ""
script = ""
if request.method == 'POST':
form = ForceCurveMultipleCompareForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
selected = cd['analyses']
request.session['analyses'] = [a.id for a in selected]
# now should redirect to analysis
script, div = forcecurve_multi_interactive_chart(selected)
breadcrumbs = [
{
'url': '/rowers/analysis',
'name': 'Analysis'
},
{
'url': reverse('instrokeanalysis_view'),
'name': 'In-Stroke Analysis',
},
]
return render(request, 'forcecurve_analysis.html',
{
'breadcrumbs': breadcrumbs,
'analyses': analyses,
'rower': r,
'the_script': script,
'the_div': div,
'selected': selected,
})
#instroke analysis delete view
class ForceCurveAnalysisDelete(DeleteView):
login_required = True
model = ForceCurveAnalysis
template_name = 'forcecurveanalysis_delete_confirm.html'
# extra parameters
def get_context_data(self, **kwargs):
context = super(ForceCurveAnalysisDelete, self).get_context_data(**kwargs)
if 'userid' in kwargs: # pragma: no cover
userid = kwargs['userid']
else:
userid = 0
context['rower'] = getrequestrower(self.request, userid=userid)
context['alert'] = self.object
breadcrumbs = [
{
'url': '/rowers/analysis',
'name': 'Analysis'
},
{
'url': reverse('forcecurveanalysis_view'),
'name': 'Force Curve Analysis',
},
{
'url': reverse('workout_forcecurve_view',
kwargs={'userid': userid,
'id': encoder.encode_hex(self.object.workout.id),
'analysis': self.object.pk}),
'name': self.object.name,
},
{
'url': reverse('forcecurve_analysis_delete_view', kwargs={'pk': self.object.pk}),
'name': 'Delete'
}
]
context['breadcrumbs'] = breadcrumbs
return context
def get_success_url(self):
return reverse('forcecurveanalysis_view')
def get_object(self, *args, **kwargs):
obj = super(ForceCurveAnalysisDelete, self).get_object(*args, **kwargs)
if obj.rower != self.request.user.rower:
raise PermissionDenied("You are not allowed to delete this Analysis")
return obj
@user_passes_test(ispromember, login_url="/rowers/paidplans",
message="This functionality requires a Pro plan or higher."
@@ -1856,8 +1958,9 @@ def instrokeanalysis_view(request, userid=0):
analyses = InStrokeAnalysis.objects.filter(rower=r).order_by("-date","-id")
selected = []
script = ""
div = ""
script = ""
if request.method == 'POST':
form = InStrokeMultipleCompareForm(request.POST)

View File

@@ -111,7 +111,8 @@ from rowers.forms import (
VideoAnalysisMetricsForm, SurveyForm, HistorySelectForm,
StravaChartForm, FitnessFitForm, PerformanceManagerForm,
TrainingPlanBillingForm, InstantPlanSelectForm,
TrainingZonesForm, InstrokeForm, InStrokeMultipleCompareForm
TrainingZonesForm, InstrokeForm, InStrokeMultipleCompareForm,
ForceCurveMultipleCompareForm
)
from django.urls import reverse, reverse_lazy
@@ -153,7 +154,7 @@ from rowers.models import (
VideoAnalysis, ShareKey,
StandardCollection, CourseStandard,
VirtualRaceFollower, TombStone, InstantPlan,
PlannedSessionStep,InStrokeAnalysis,
PlannedSessionStep,InStrokeAnalysis, ForceCurveAnalysis
)
from rowers.models import (
RowerPowerForm, RowerHRZonesForm, RowerForm, RowerCPForm, GraphImage, AdvancedWorkoutForm,

View File

@@ -408,33 +408,138 @@ def workout_video_create_view(request, id=0):
" If you are already a Pro user, please log in to access this functionality",
redirect_field_name=None)
@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)
def workout_forcecurve_view(request, id=0, workstrokesonly=False):
def workout_forcecurve_view(request, id=0, analysis=0, userid=0, workstrokesonly=False):
row = get_workoutuser(id, request)
mayedit = 0
r = getrequestrower(request)
r = getrequestrower(request, userid=userid)
if r == row.user:
mayedit = 1
if analysis:
try:
forceanalysis = ForceCurveAnalysis.objects.get(id=analysis)
dist_min = forceanalysis.dist_min
dist_max = forceanalysis.dist_max
spm_min = forceanalysis.spm_min
spm_max = forceanalysis.spm_max
work_min = forceanalysis.work_min
work_max = forceanalysis.work_max
notes = forceanalysis.notes
name = forceanalysis.name
includereststrokes = forceanalysis.include_rest_strokes
except (ForceCurveAnalysis.DoesNotExist, ValueError):
pass
else:
dist_min = 0
dist_max = 0
spm_min = 15
spm_max = 55
work_min = 0
work_max = 1500
notes = ''
includereststrokes = False
name = ''
form = ForceCurveOptionsForm(initial={
'spm_min': spm_min,
'spm_max': spm_max,
'dist_min': dist_min,
'dist_max': dist_max,
'work_min': work_min,
'work_max': work_max,
'notes': notes,
'plottype': 'line',
'name': name,
})
plottype = 'line'
if request.method == 'POST':
form = ForceCurveOptionsForm(request.POST)
if form.is_valid():
spm_min = form.cleaned_data['spm_min']
spm_max = form.cleaned_data['spm_max']
dist_min = form.cleaned_data['dist_min']
dist_max = form.cleaned_data['dist_max']
work_min = form.cleaned_data['work_min']
work_max = form.cleaned_data['work_max']
notes = form.cleaned_data['notes']
name = form.cleaned_data['name']
if not name:
name = row.name
includereststrokes = form.cleaned_data['includereststrokes']
plottype = form.cleaned_data['plottype']
workstrokesonly = not includereststrokes
if "_save" in request.POST and "new" not in request.POST:
if not analysis:
forceanalysis = ForceCurveAnalysis(
workout = row,
name = name,
date = timezone.now().date(),
notes = notes,
dist_min = dist_min,
dist_max = dist_max,
work_min = work_min,
work_max = work_max,
spm_min = spm_min,
spm_max = spm_max,
rower=row.user,
include_rest_strokes = includereststrokes,
)
else:
forceanalysis.workout = row
forceanalysis.name = name
forceanalysis.date = timezone.now().date()
forceanalysis.notes = notes
forceanalysis.dist_min = dist_min
forceanalysis.dist_max = dist_max
forceanalysis.work_min = work_min
forceanalysis.work_max = work_max
forceanalysis.spm_min = spm_min
forceanalysis.spm_max = spm_max
forceanalysis.include_rest_strokes = includereststrokes
forceanalysis.save()
dosave = True
messages.info(request,'Force Curve analysis saved')
if "_save_as_new" in request.POST:
forceanalysis = ForceCurveAnalysis(
workout = row,
name = name,
date = timezone.now().date(),
notes = notes,
dist_min = dist_min,
dist_max = dist_max,
spm_min = spm_min,
spm_max = spm_max,
work_min = work_min,
work_max = work_max,
rower=row.user,
include_rest_strokes = includereststrokes,
)
forceanalysis.save()
dosave = True
messages.info(request,'Force Curve analysis saved')
else: # pragma: no cover
workstrokesonly = True
plottype = 'line'
else:
form = ForceCurveOptionsForm()
plottype = 'line'
script, div, js_resources, css_resources = interactive_forcecurve(
[row],
workstrokesonly=workstrokesonly,
plottype=plottype,
dist_min = dist_min,
dist_max = dist_max,
spm_min = spm_min,
spm_max = spm_max,
work_min = work_min,
work_max = work_max,
notes=notes,
)
breadcrumbs = [
@@ -455,6 +560,9 @@ def workout_forcecurve_view(request, id=0, workstrokesonly=False):
r = getrower(request.user)
if dist_max == 0:
dist_max = row.distance+100
return render(request,
'forcecurve_single.html',
{
@@ -464,6 +572,13 @@ def workout_forcecurve_view(request, id=0, workstrokesonly=False):
'workout': row,
'breadcrumbs': breadcrumbs,
'active': 'nav-workouts',
'spm_min': spm_min,
'spm_max': spm_max,
'dist_min': dist_min,
'dist_max': dist_max,
'work_min': work_min,
'work_max': work_max,
'annotation': notes,
'the_div': div,
'js_res': js_resources,
'css_res': css_resources,
@@ -3052,7 +3167,7 @@ def instroke_chart_interactive(request, id=0, analysis=0, userid=0):
notes = form.cleaned_data['notes']
name = form.cleaned_data['name']
if "_save" in request.POST:
if "_save" in request.POST and "new" not in request.POST:
if not analysis:
instroke_analysis = InStrokeAnalysis(
workout = w,