diff --git a/rowers/tasks.py b/rowers/tasks.py
index 5cf8866b..01f5bc7b 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -106,6 +106,7 @@ NK_API_LOCATION = CFG["nk_api_location"]
TP_CLIENT_ID = CFG["tp_client_id"]
TP_CLIENT_SECRET = CFG["tp_client_secret"]
+
from requests_oauthlib import OAuth1, OAuth1Session
import pandas as pd
@@ -386,7 +387,7 @@ def instroke_static(w, metric, debug=False, **kwargs):
@app.task
def handle_request_post(url, data, debug=False, **kwargs): # pragma: no cover
if 'localhost' in url:
- url = 'http'+url[5:]
+ url = 'http'+url[4:]
response = requests.post(url, data, verify=False)
dologging('upload_api.log', data)
dologging('upload_api.log', response.status_code)
diff --git a/rowers/templates/analysis.html b/rowers/templates/analysis.html
index b1e8ea47..555f58bf 100644
--- a/rowers/templates/analysis.html
+++ b/rowers/templates/analysis.html
@@ -131,18 +131,6 @@
Need to monitor a metric? Set up automatic alerting and see the reports for your workouts.
-
-
- Ranking Pieces
-
-
-

-
-
-
- Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces.
-
Histogram
diff --git a/rowers/templates/instroke_analysis.html b/rowers/templates/instroke_analysis.html
index ff533b4a..3669a531 100644
--- a/rowers/templates/instroke_analysis.html
+++ b/rowers/templates/instroke_analysis.html
@@ -17,7 +17,7 @@
{{ analysis.name }}
-
diff --git a/rowers/templates/menu_analytics.html b/rowers/templates/menu_analytics.html
index 2ad76f72..03bde62e 100644
--- a/rowers/templates/menu_analytics.html
+++ b/rowers/templates/menu_analytics.html
@@ -51,11 +51,6 @@
Marker Workouts
-
-
-
- Ranking Pieces
-
diff --git a/rowers/urls.py b/rowers/urls.py
index a43558f1..9b64f117 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -252,6 +252,8 @@ urlpatterns = [
path('403/', TemplateView.as_view(template_name='403.html'), name='403'),
re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/instroke/interactive/$',
views.instroke_chart_interactive, name='instroke_chart_interactive'),
+ re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/instroke/interactive/(?P\d+)/$',
+ views.instroke_chart_interactive, name='instroke_chart_interactive'),
re_path(r'^exportallworkouts/?/$', views.workouts_summaries_email_view,
name='workouts_summaries_email_view'),
path('failedjobs/', views.failed_queue_view, name='failed_queue_view'),
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index 1e9f7cda..b869d391 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -2916,10 +2916,12 @@ def instroke_chart(request, id=0, metric=''): # pragma: no cover
return HttpResponseRedirect(url)
@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)
+ r = getrequestrower(request, userid=userid)
+
w = get_workoutuser(id, request)
rowdata = rrdata(csvfile=w.csvfilename)
@@ -2975,19 +2977,64 @@ def instroke_chart_interactive(request, id=0):
'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 = ''
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':
form = InstrokeForm(request.POST,choices=instrokemetrics)
@@ -3002,18 +3049,31 @@ def instroke_chart_interactive(request, id=0):
name = form.cleaned_data['name']
if "_save" in request.POST:
- instroke_analysis = InStrokeAnalysis(
- workout = w,
- metric = metric,
- name = name,
- date = timezone.now().date(),
- notes = notes,
- start_second = 60*activeminutesmin,
- end_second = 60*activeminutesmax,
- spm_min = spm_min,
- spm_max = spm_max,
- rower=w.user,
- )
+ if not analysis:
+ instroke_analysis = InStrokeAnalysis(
+ workout = w,
+ metric = metric,
+ name = name,
+ date = timezone.now().date(),
+ notes = notes,
+ start_second = 60*activeminutesmin,
+ end_second = 60*activeminutesmax,
+ spm_min = spm_min,
+ 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()
messages.info(request,'In-Stroke Analysis saved')