diff --git a/requirements.txt b/requirements.txt
index de167e15..674068c8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -184,7 +184,7 @@ ratelim==0.1.6
redis==3.5.3
requests==2.23.0
requests-oauthlib==1.2.0
-rowingdata==3.1.8
+rowingdata==3.2.7
rowingphysics==0.5.0
rq==0.13.0
rules==2.1
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 16790573..243e79a7 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -30,6 +30,8 @@ import pandas as pd
from rowingdata import rowingdata as rrdata
from rowingdata import rower as rrower
+from rowers.opaque import encoder
+
def to_pace(pace):
minutes, seconds = divmod(pace,60)
seconds, rest = divmod(seconds, 1)
@@ -455,7 +457,7 @@ def add_workouts_plannedsession(ws,ps,r):
w.plannedsession = ps
w.save()
result += 1
- comments.append('Attached workout %i to session' % w.id)
+ comments.append('Attached workout %s to session' % encoder.encode_hex(w.id))
if ps.sessiontype == 'coursetest':
record = CourseTestResult(
userid=w.user.id,
diff --git a/rowers/templates/instantplans.html b/rowers/templates/instantplans.html
new file mode 100644
index 00000000..b421fd6b
--- /dev/null
+++ b/rowers/templates/instantplans.html
@@ -0,0 +1,24 @@
+{% extends "newbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block title %}Rowsandall Training Plans{% endblock %}
+
+
+{% block main %}
+
Training Plans
+
+
+ {% for plan in trainingdict %}
+ -
+
{{ plan.name }}
+ {{ plan.plan|lookup:"duration"}}
+
+ {% endfor %}
+
+
+{% endblock %}
+
+{% block sidebar %}
+{% include 'menu_plan.html' %}
+{% endblock %}
diff --git a/rowers/urls.py b/rowers/urls.py
index 2e7bcd48..9bb36e53 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -740,6 +740,7 @@ urlpatterns = [
re_path(r'^test\_callback',views.rower_process_testcallback,name='rower_process_testcallback'),
re_path(r'^createplan/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
re_path(r'^createplan/user/(?P\d+)/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
+ re_path(r'^plans/$', views.rower_select_instantplan, name='rower_select_instantplan'),
re_path(r'^deleteplan/(?P\d+)/$',login_required(
views.TrainingPlanDelete.as_view()),name='trainingplan_delete_view'),
re_path(r'^deletemicrocycle/(?P\d+)/$',login_required(
diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py
index a8de7582..3b2bc520 100644
--- a/rowers/views/planviews.py
+++ b/rowers/views/planviews.py
@@ -2425,6 +2425,54 @@ class PlannedSessionDelete(DeleteView):
return obj
+@user_passes_test(can_plan,login_url="/rowers/paidplans",
+ message="This functionality requires a Coach or Self-Coach plan",
+ redirect_field_name=None)
+def rower_select_instantplan(request,id=0):
+ r = getrequestrower(request,userid=id)
+ themanager = getrower(request.user)
+
+ # get and present available plans
+ authorizationstring = 'Bearer '+settings.WORKOUTS_FIT_TOKEN
+
+ url = settings.WORKOUTS_FIT_URL+"/trainingplan/"
+ headers = {'Authorization':authorizationstring}
+
+ trainingdict = {}
+ response = requests.get(url=url, headers=headers)
+ if response.status_code != 200:
+ messages.error(request,"Could not connect to the training plan server")
+ else:
+ trainingdict = response.json()['plans']
+
+ for plan in trainingdict:
+ print(plan['ID'],plan['name'],plan['plan']['duration'])
+
+ breadcrumbs = [
+ {
+ 'url':reverse('plannedsessions_view'),
+ 'name': 'Sessions'
+ },
+ {
+ 'url':reverse(rower_create_trainingplan,
+ kwargs={'id':id}),
+ 'name': 'Manage Plans and Targets'
+ },
+ {
+ 'url':reverse('rower_select_instantplan'),
+ 'name': 'Select Existing Plans'
+ }
+ ]
+
+
+ return render(request,
+ 'instantplans.html',
+ {
+ 'rower':r,
+ 'active':'nav-plan',
+ 'trainingdict':trainingdict,
+
+ })
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",