passing tests
This commit is contained in:
@@ -106,6 +106,7 @@ NK_API_LOCATION = CFG["nk_api_location"]
|
|||||||
TP_CLIENT_ID = CFG["tp_client_id"]
|
TP_CLIENT_ID = CFG["tp_client_id"]
|
||||||
TP_CLIENT_SECRET = CFG["tp_client_secret"]
|
TP_CLIENT_SECRET = CFG["tp_client_secret"]
|
||||||
|
|
||||||
|
|
||||||
from requests_oauthlib import OAuth1, OAuth1Session
|
from requests_oauthlib import OAuth1, OAuth1Session
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@@ -386,7 +387,7 @@ def instroke_static(w, metric, debug=False, **kwargs):
|
|||||||
@app.task
|
@app.task
|
||||||
def handle_request_post(url, data, debug=False, **kwargs): # pragma: no cover
|
def handle_request_post(url, data, debug=False, **kwargs): # pragma: no cover
|
||||||
if 'localhost' in url:
|
if 'localhost' in url:
|
||||||
url = 'http'+url[5:]
|
url = 'http'+url[4:]
|
||||||
response = requests.post(url, data, verify=False)
|
response = requests.post(url, data, verify=False)
|
||||||
dologging('upload_api.log', data)
|
dologging('upload_api.log', data)
|
||||||
dologging('upload_api.log', response.status_code)
|
dologging('upload_api.log', response.status_code)
|
||||||
|
|||||||
@@ -131,18 +131,6 @@
|
|||||||
<p>
|
<p>
|
||||||
Need to monitor a metric? Set up automatic alerting and see the reports for your workouts.
|
Need to monitor a metric? Set up automatic alerting and see the reports for your workouts.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
|
||||||
<li class="rounder">
|
|
||||||
<h2>Ranking Pieces</h2>
|
|
||||||
<a href="/rowers/ote-bests2/">
|
|
||||||
<div class="vignet">
|
|
||||||
<img src="/static/img/rankingpiece.png"
|
|
||||||
alt="Ranking Piece">
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<p>
|
|
||||||
Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces.
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="rounder">
|
<li class="rounder">
|
||||||
<h2>Histogram</h2>
|
<h2>Histogram</h2>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div><h3>{{ analysis.name }}</h3></div>
|
<div><h3>{{ analysis.name }}</h3></div>
|
||||||
<div class="analysiscontainer">
|
<div class="analysiscontainer">
|
||||||
<div class="workoutelement">
|
<div class="workoutelement">
|
||||||
<a class="small" href="/rowers/instrokeanalysis/{{ analysis.id }}/edit/"
|
<a class="small" href="/rowers/workout/{{ analysis.workout.id|encode }}/instroke/interactive/{{ analysis.id }}/"
|
||||||
title="Edit">
|
title="Edit">
|
||||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -51,11 +51,6 @@
|
|||||||
<a href="/rowers/goldmedalscores/">
|
<a href="/rowers/goldmedalscores/">
|
||||||
<i class="far fa-medal fa-fw"></i> Marker Workouts
|
<i class="far fa-medal fa-fw"></i> Marker Workouts
|
||||||
</a>
|
</a>
|
||||||
</li>
|
|
||||||
<li id="fitness-ranking">
|
|
||||||
<a href="/rowers/ote-bests2/">
|
|
||||||
<i class="fas fa-star fa-fw"></i> Ranking Pieces
|
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li id="fitness-zones">
|
<li id="fitness-zones">
|
||||||
<a href="/rowers/trainingzones/">
|
<a href="/rowers/trainingzones/">
|
||||||
|
|||||||
@@ -252,6 +252,8 @@ urlpatterns = [
|
|||||||
path('403/', TemplateView.as_view(template_name='403.html'), name='403'),
|
path('403/', TemplateView.as_view(template_name='403.html'), name='403'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/instroke/interactive/$',
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/instroke/interactive/$',
|
||||||
views.instroke_chart_interactive, name='instroke_chart_interactive'),
|
views.instroke_chart_interactive, name='instroke_chart_interactive'),
|
||||||
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/instroke/interactive/(?P<analysis>\d+)/$',
|
||||||
|
views.instroke_chart_interactive, name='instroke_chart_interactive'),
|
||||||
re_path(r'^exportallworkouts/?/$', views.workouts_summaries_email_view,
|
re_path(r'^exportallworkouts/?/$', views.workouts_summaries_email_view,
|
||||||
name='workouts_summaries_email_view'),
|
name='workouts_summaries_email_view'),
|
||||||
path('failedjobs/', views.failed_queue_view, name='failed_queue_view'),
|
path('failedjobs/', views.failed_queue_view, name='failed_queue_view'),
|
||||||
|
|||||||
@@ -2916,10 +2916,12 @@ def instroke_chart(request, id=0, metric=''): # pragma: no cover
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)
|
@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)
|
||||||
def instroke_chart_interactive(request, id=0):
|
def instroke_chart_interactive(request, id=0, analysis=0, userid=0):
|
||||||
|
|
||||||
is_ajax = request_is_ajax(request)
|
is_ajax = request_is_ajax(request)
|
||||||
|
|
||||||
|
r = getrequestrower(request, userid=userid)
|
||||||
|
|
||||||
w = get_workoutuser(id, request)
|
w = get_workoutuser(id, request)
|
||||||
|
|
||||||
rowdata = rrdata(csvfile=w.csvfilename)
|
rowdata = rrdata(csvfile=w.csvfilename)
|
||||||
@@ -2975,19 +2977,64 @@ def instroke_chart_interactive(request, id=0):
|
|||||||
'maxminutes': maxminutes,
|
'maxminutes': maxminutes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if analysis:
|
||||||
|
try:
|
||||||
|
instroke_analysis = InStrokeAnalysis.objects.get(id=analysis)
|
||||||
|
if instroke_analysis.rower != r:
|
||||||
|
analysis = 0
|
||||||
|
messages.error(request,'Access to this saved analysis denied')
|
||||||
|
raise ValueError
|
||||||
|
if instroke_analysis.workout != w:
|
||||||
|
messages.error(request,'This saved analysis belongs to a different workout')
|
||||||
|
form = InstrokeForm(
|
||||||
|
choices=instrokemetrics,
|
||||||
|
initial={
|
||||||
|
'metric':instroke_analysis.metric,
|
||||||
|
'name': instroke_analysis.name,
|
||||||
|
'notes': instroke_analysis.notes,
|
||||||
|
'activeminutesmin':int(instroke_analysis.start_second/60.),
|
||||||
|
'activeminutesmax':int(instroke_analysis.end_second/60.),
|
||||||
|
'spm_min': instroke_analysis.spm_min,
|
||||||
|
'spm_max': instroke_analysis.spm_max,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
metric = instroke_analysis.metric
|
||||||
|
name = instroke_analysis.name
|
||||||
|
notes = instroke_analysis.notes
|
||||||
|
activeminutesmin = int(instroke_analysis.start_second/60.)
|
||||||
|
activeminutesmax = int(instroke_analysis.end_second/60.)
|
||||||
|
spm_min = instroke_analysis.spm_min
|
||||||
|
spm_max = instroke_analysis.spm_max
|
||||||
|
except (InStrokeAnalysis.DoesNotExist, ValueError):
|
||||||
|
metric = instrokemetrics[0]
|
||||||
|
spm_min = 15
|
||||||
|
spm_max = 45
|
||||||
|
name = ''
|
||||||
|
notes = ''
|
||||||
|
activeminutesmax = int(rowdata.duration/60.)
|
||||||
|
activeminutesmin = 0
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
metric = instrokemetrics[0]
|
||||||
|
|
||||||
|
spm_min = 15
|
||||||
|
spm_max = 45
|
||||||
|
name = ''
|
||||||
|
notes = ''
|
||||||
|
|
||||||
|
activeminutesmax = int(rowdata.duration/60.)
|
||||||
|
activeminutesmin = 0
|
||||||
|
|
||||||
|
maxminutes = int(rowdata.duration/60.)
|
||||||
|
individual_curves = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
div = get_call()
|
div = get_call()
|
||||||
|
|
||||||
metric = instrokemetrics[0]
|
|
||||||
spm_min = 15
|
|
||||||
spm_max = 45
|
|
||||||
name = ''
|
|
||||||
notes = ''
|
|
||||||
|
|
||||||
activeminutesmax = int(rowdata.duration/60.)
|
|
||||||
activeminutesmin = 0
|
|
||||||
maxminutes = activeminutesmax
|
|
||||||
individual_curves = False
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = InstrokeForm(request.POST,choices=instrokemetrics)
|
form = InstrokeForm(request.POST,choices=instrokemetrics)
|
||||||
@@ -3002,18 +3049,31 @@ def instroke_chart_interactive(request, id=0):
|
|||||||
name = form.cleaned_data['name']
|
name = form.cleaned_data['name']
|
||||||
|
|
||||||
if "_save" in request.POST:
|
if "_save" in request.POST:
|
||||||
instroke_analysis = InStrokeAnalysis(
|
if not analysis:
|
||||||
workout = w,
|
instroke_analysis = InStrokeAnalysis(
|
||||||
metric = metric,
|
workout = w,
|
||||||
name = name,
|
metric = metric,
|
||||||
date = timezone.now().date(),
|
name = name,
|
||||||
notes = notes,
|
date = timezone.now().date(),
|
||||||
start_second = 60*activeminutesmin,
|
notes = notes,
|
||||||
end_second = 60*activeminutesmax,
|
start_second = 60*activeminutesmin,
|
||||||
spm_min = spm_min,
|
end_second = 60*activeminutesmax,
|
||||||
spm_max = spm_max,
|
spm_min = spm_min,
|
||||||
rower=w.user,
|
spm_max = spm_max,
|
||||||
)
|
rower=w.user,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
instroke_analysis.workout = w
|
||||||
|
instroke_analysis.metric = metric
|
||||||
|
instroke_analysis.name = name
|
||||||
|
instroke_analysis.date = timezone.now().date()
|
||||||
|
instroke_analysis.notes = notes
|
||||||
|
instroke_analysis.start_second = 60*activeminutesmin
|
||||||
|
instroke_analysis.end_second = 60*activeminutesmax
|
||||||
|
instroke_analysis.spm_min = spm_min
|
||||||
|
instroke_analysis.spm_max = spm_max
|
||||||
|
instroke_analysis.rower=w.user
|
||||||
|
|
||||||
instroke_analysis.save()
|
instroke_analysis.save()
|
||||||
messages.info(request,'In-Stroke Analysis saved')
|
messages.info(request,'In-Stroke Analysis saved')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user