From d0b0c3767450dbcd627bd9606aa11395ae640132 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 22 Sep 2019 12:56:53 +0200 Subject: [PATCH 1/5] first changes for template planned sessions --- rowers/models.py | 2 + rowers/plannedsessions.py | 5 +- rowers/templates/plannedsessioncreate.html | 40 ++++++++++++++++ .../plannedsessiondeleteconfirm.html | 2 + rowers/templates/plannedsessionedit.html | 36 ++++++++++++++ rowers/tests/testdata/testdata.csv.gz | Bin 12642 -> 12642 bytes rowers/urls.py | 1 + rowers/views/planviews.py | 45 +++++++++++++++++- 8 files changed, 129 insertions(+), 2 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index 7d4cc3e9..e3e23ada 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2128,6 +2128,8 @@ class PlannedSession(models.Model): hasranking = models.BooleanField(default=False) + is_template = models.BooleanField(default=False) + def __str__(self): name = self.name diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 8682aaa7..f3c33b4e 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -600,6 +600,7 @@ def get_sessions_manager(m,teamid=0,startdate=date.today(), manager=m, startdate__lte=enddate, enddate__gte=startdate, + is_template=False, ).order_by("preferreddate","startdate","enddate").exclude( sessiontype='race').exclude(sessiontype='indoorrace') else: @@ -607,7 +608,8 @@ def get_sessions_manager(m,teamid=0,startdate=date.today(), manager=m, startdate__lte=enddate, enddate__gte=startdate, - ).order_by("preferreddate","startdate","enddate").exclude( + is_template=False, + ).order_by("preferreddate","startdate","enddate").exclude( sessiontype='race').exclude(sessiontype='indoorrace') return sps @@ -619,6 +621,7 @@ def get_sessions(r,startdate=date.today(), rower__in=[r], startdate__lte=enddate, enddate__gte=startdate, + is_template=False, ).order_by("preferreddate","startdate","enddate").exclude( sessiontype='race').exclude(sessiontype='indoorrace') diff --git a/rowers/templates/plannedsessioncreate.html b/rowers/templates/plannedsessioncreate.html index 7daf599b..b2056844 100644 --- a/rowers/templates/plannedsessioncreate.html +++ b/rowers/templates/plannedsessioncreate.html @@ -60,6 +60,7 @@ Edit Clone Delete + Template @@ -88,11 +89,50 @@ Delete + + Save + {% endfor %} +
  • +

    Templates

    +

    + Click on session name to clone to current period +

    + + + + + + + + + + + {% for ps in sessiontemplates %} + + + + + + + {% endfor %} + +
    NameValue Delete
    + {% if ps.name != '' %} + {{ ps.name }} + {% else %} + Unnamed Session + {% endif %} + {{ ps.sessionvalue }} {{ ps.sessionunit }} + Delete +
    +
  • {% endblock %} diff --git a/rowers/templates/plannedsessiondeleteconfirm.html b/rowers/templates/plannedsessiondeleteconfirm.html index a299e6b0..f196304f 100644 --- a/rowers/templates/plannedsessiondeleteconfirm.html +++ b/rowers/templates/plannedsessiondeleteconfirm.html @@ -18,6 +18,7 @@

    + {% if not object.is_template %}
  • Session {{ psdict.name.1 }}

    @@ -32,6 +33,7 @@ {% endfor %}
  • + {% endif %} diff --git a/rowers/templates/plannedsessionedit.html b/rowers/templates/plannedsessionedit.html index 7c8e13aa..9e1cf82d 100644 --- a/rowers/templates/plannedsessionedit.html +++ b/rowers/templates/plannedsessionedit.html @@ -110,6 +110,42 @@ +
  • +

    Templates

    +

    + Click on session name to clone to current period +

    + + + + + + + + + + + {% for ps in sessiontemplates %} + + + + + + + {% endfor %} + +
    NameValue Delete
    + {% if ps.name != '' %} + {{ ps.name }} + {% else %} + Unnamed Session + {% endif %} + {{ ps.sessionvalue }} {{ ps.sessionunit }} + Delete +
    +
  • {% endblock %} diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index fea10cad8250560ff1462282122ff3fc71ef0542..118da389aefa1feb99b5b506deb4a5720abd8cee 100644 GIT binary patch delta 15 WcmaEq^eBl\d+)/edit/$',views.plannedsession_edit_view), + re_path(r'^sessions/(?P\d+)/maketemplate/$',views.plannedsession_totemplate_view), re_path(r'^sessions/(?P\d+)/compare/$', views.plannedsession_compare_view, name='plannedsession_compare_view'), diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index e29d6e1d..ba6af2b6 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -240,6 +240,7 @@ def plannedsession_multiclone_view( sps = PlannedSession.objects.filter( manager=request.user, rower__in=[r], + is_template=False, startdate__lte=enddate, enddate__gte=startdate).order_by( "startdate","preferreddate","enddate").exclude( @@ -435,6 +436,10 @@ def plannedsession_create_view(request, sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude( sessiontype='race') + + + sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True) + try: trainingplan = TrainingPlan.objects.filter( startdate__lte = startdate, @@ -458,6 +463,7 @@ def plannedsession_create_view(request, 'form':sessioncreateform, 'active':'nav-plan', 'plannedsessions':sps, + 'sessiontemplates':sessiontemplates, 'rower':r, 'timeperiod':timeperiod, }) @@ -1412,13 +1418,16 @@ def plannedsession_clone_view(request,id=0,userid=0): teams = ps.team.all() ps.pk = None + ps.id = None + if not ps.is_template: + ps.name += ' (copy)' + ps.is_template = False deltadays = ps.enddate-ps.startdate ps.startdate = timezone.now().date() ps.enddate = (timezone.now()+deltadays).date() ps.preferreddate = ps.preferreddate+deltadays - ps.name += ' (copy)' ps.save() @@ -1441,6 +1450,37 @@ def plannedsession_clone_view(request,id=0,userid=0): return HttpResponseRedirect(url) +@user_passes_test(hasplannedsessions, login_url="/rowers/paidplans/", + message="This functionality requires a Coach or Self-Coach plan", + redirect_field_name=None) +def plannedsession_totemplate_view(request,id=0): + + r = getrequestplanrower(request) + + startdate, enddate = get_dates_timeperiod(request) + + try: + ps = PlannedSession.objects.get(id=id) + except PlannedSession.DoesNotExist: + raise Http404("Planned Session does not exist") + + if ps.manager != request.user: + raise PermissionDenied("You can only store your own sessions as a template") + + ps.pk = None + ps.id = None + ps.is_template = True + ps.startdate = datetime.date(1970,1,1) + ps.enddate = datetime.date(1970,1,1) + ps.save() + + url = reverse(plannedsession_create_view,kwargs={'userid':request.user.id}) + + startdatestring = startdate.strftime('%Y-%m-%d') + enddatestring = enddate.strftime('%Y-%m-%d') + url += '?when='+startdatestring+'/'+enddatestring + + return HttpResponseRedirect(url) # Edit an existing planned session @user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/", @@ -1547,6 +1587,8 @@ def plannedsession_edit_view(request,id=0,userid=0): ] + sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True) + dateform = DateRangeForm(initial={ 'startdate':startdate, 'enddate':enddate, @@ -1564,6 +1606,7 @@ def plannedsession_edit_view(request,id=0,userid=0): 'plannedsessions':sps, 'thesession':ps, 'dateform':dateform, + 'sessiontemplates':sessiontemplates, 'rower':r, 'timeperiod':timeperiod, }) From d2d0e6c076661e367df2d9af9896b8ea89b092ec Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 22 Sep 2019 17:26:23 +0200 Subject: [PATCH 2/5] adding templates to team create session --- .../templates/plannedsessionteamcreate.html | 36 ++++++++++ rowers/urls.py | 1 + rowers/views/planviews.py | 70 +++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/rowers/templates/plannedsessionteamcreate.html b/rowers/templates/plannedsessionteamcreate.html index 6958c5c7..0c674ef1 100644 --- a/rowers/templates/plannedsessionteamcreate.html +++ b/rowers/templates/plannedsessionteamcreate.html @@ -101,6 +101,42 @@

    {% endif %} +
  • +

    Templates

    +

    + Click on session name to clone to current period +

    + + + + + + + + + + + {% for ps in sessiontemplates %} + + + + + + + {% endfor %} + +
    NameValue Delete
    + {% if ps.name != '' %} + {{ ps.name }} + {% else %} + Unnamed Session + {% endif %} + {{ ps.sessionvalue }} {{ ps.sessionunit }} + Delete +
    +
  • diff --git a/rowers/urls.py b/rowers/urls.py index 2e40901c..599dbac8 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -658,6 +658,7 @@ urlpatterns = [ name='plannedsession_compare_view'), re_path(r'^sessions/(?P\d+)/edit/user/(?P\d+)/$',views.plannedsession_edit_view), re_path(r'^sessions/(?P\d+)/clone/user/(?P\d+)/$',views.plannedsession_clone_view), + re_path(r'^sessions/(?P\d+)/clone/team/$',views.plannedsession_teamclone_view), re_path(r'^sessions/(?P\d+)/clone/$',views.plannedsession_clone_view), re_path(r'^sessions/(?P\d+)/detach/(?P\b[0-9A-Fa-f]+\b)/user/(?P\d+)/$',views.plannedsession_detach_view), re_path(r'^sessions/(?P\d+)/detach/(?P\b[0-9A-Fa-f]+\b)/$',views.plannedsession_detach_view), diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index ba6af2b6..97e15a18 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -637,6 +637,8 @@ def plannedsession_teamcreate_view(request, sps = PlannedSession.objects.filter(id__in=ids).order_by( "preferreddate","startdate","enddate") + sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True) + if request.method == 'POST': sessioncreateform = PlannedSessionForm(request.POST) sessionteamselectform = PlannedSessionTeamForm( @@ -713,6 +715,7 @@ def plannedsession_teamcreate_view(request, 'plan':trainingplan, 'breadcrumbs':breadcrumbs, 'form':sessioncreateform, + 'sessiontemplates':sessiontemplates, 'teamform':sessionteamselectform, 'timeperiod':timeperiod, 'plannedsessions':sps, @@ -765,6 +768,7 @@ def plannedsession_teamcreate_view(request, 'dateform':dateform, 'breadcrumbs':breadcrumbs, 'form':sessioncreateform, + 'sessiontemplates':sessiontemplates, 'teamform':sessionteamselectform, 'timeperiod':timeperiod, 'plannedsessions':sps, @@ -1448,6 +1452,72 @@ def plannedsession_clone_view(request,id=0,userid=0): url += '?when='+startdatestring+'/'+enddatestring + return HttpResponseRedirect(url) + +# Clone an existing planned session +# need clarity on cloning behavior time shift +@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/", + message="This functionality requires a Coach or Self-Coach plan", + redirect_field_name=None) +def plannedsession_teamclone_view(request,id=0): + + r = getrequestplanrower(request) + + teams = Team.objects.filter(manager=request.user) + if len(teams)>0: + teamchoices = [(team.id, team.name) for team in teams] + teaminitial = [str(teams[0].id)] + else: + messages.info(request,"You have no teams established yet. We are redirecting you to the Team Management page.") + url = reverse('rower_teams_view') + return HttpResponseRedirect(url) + + + startdate,enddate = get_dates_timeperiod(request) + + try: + trainingplan = TrainingPlan.objects.filter( + startdate__lte = startdate, + rowers = r, + enddate__gte = enddate)[0] + except IndexError: + trainingplan = None + + try: + ps = PlannedSession.objects.get(id=id) + except PlannedSession.DoesNotExist: + raise Http404("Planned Session does not exist") + + if ps.manager != request.user: + raise PermissionDenied("You are not allowed to clone this planned session") + + + ps.pk = None + ps.id = None + if not ps.is_template: + ps.name += ' (copy)' + ps.is_template = False + + deltadays = ps.enddate-ps.startdate + + ps.startdate = timezone.now().date() + ps.enddate = (timezone.now()+deltadays).date() + ps.preferreddate = ps.preferreddate+deltadays + + ps.save() + + url = reverse(plannedsession_teamedit_view, + kwargs = { + 'sessionid':ps.id, + 'userid':r.user.id, + } + ) + + startdatestring = startdate.strftime('%Y-%m-%d') + enddatestring = enddate.strftime('%Y-%m-%d') + url += '?when='+startdatestring+'/'+enddatestring + + return HttpResponseRedirect(url) @user_passes_test(hasplannedsessions, login_url="/rowers/paidplans/", From efaa0377ce4bddd7ec48746b0c46c8ab5c1e2cf4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 22 Sep 2019 17:45:39 +0200 Subject: [PATCH 3/5] adding template to teamcreate --- rowers/tests/testdata/testdata.csv.gz | Bin 12642 -> 12642 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index 118da389aefa1feb99b5b506deb4a5720abd8cee..22120638e5890c172282de8545be0511d16edd9e 100644 GIT binary patch delta 15 WcmaEq^eBl Date: Mon, 23 Sep 2019 15:51:16 +0200 Subject: [PATCH 4/5] fixed incorrect raise of NoTokenError --- rowers/c2stuff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py index 3c514742..4d034e6a 100644 --- a/rowers/c2stuff.py +++ b/rowers/c2stuff.py @@ -755,7 +755,7 @@ def workout_c2_upload(user,w): if (checkworkoutuser(user,w)): c2userid = get_userid(r.c2token) if not c2userid: - raise NoTokenError + raise NoTokenError("User has no token") data = createc2workoutdata(w) From 2c1951ac9f057f1322ec24ee67ccaf7952f893cb Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 23 Sep 2019 21:51:45 +0200 Subject: [PATCH 5/5] small bug fixes, new ranges for peak force angle --- rowers/metrics.py | 4 ++-- rowers/tests/testdata/testdata.csv.gz | Bin 12642 -> 12642 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rowers/metrics.py b/rowers/metrics.py index 0cc0fdc4..dd1852b2 100644 --- a/rowers/metrics.py +++ b/rowers/metrics.py @@ -230,8 +230,8 @@ rowingmetrics = ( 'numtype':'float', 'null':True, 'verbose_name': 'Peak Force Angle', - 'ax_min': -20, - 'ax_max': 20, + 'ax_min': -50, + 'ax_max': 50, 'default': 0, 'mode':'water', 'type': 'pro'}), diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index 22120638e5890c172282de8545be0511d16edd9e..38a2dead25f26c9f31b11359e8e765971b642e12 100644 GIT binary patch delta 16 XcmaEq^eBm4zMF$%mSX2d_Gm)@I7|i7 delta 16 XcmaEq^eBm4zMF$XYI^%d_Gm)@H--hq