From bad96133a5b03267bb34cca4ee00ec6a1c3b9828 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 28 Mar 2018 08:17:23 -0700 Subject: [PATCH 1/8] fixed team session coach view --- rowers/plannedsessions.py | 41 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 1ba59a54..ed98c9f5 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -42,8 +42,8 @@ def add_workouts_plannedsession(ws,ps,r): errors.append('For tests, you can only attach one workout') return result,comments,errors - - + + wold = Workout.objects.filter(plannedsession=ps,user=r) ids = [w.id for w in wold] + [w.id for w in ws] ids = list(set(ids)) @@ -51,7 +51,7 @@ def add_workouts_plannedsession(ws,ps,r): if len(ids)>1 and ps.sessiontype in ['test','coursetest']: errors.append('For tests, you can only attach one workout') return result,comments,errors - + # start adding sessions for w in ws: if w.date>=ps.startdate and w.date<=ps.enddate: @@ -63,7 +63,7 @@ def add_workouts_plannedsession(ws,ps,r): errors.append('Workout %i did not match session dates' % w.id) return result,comments,errors - + def remove_workout_plannedsession(w,ps): if w.plannedsession == ps: @@ -98,7 +98,7 @@ def get_session_metrics(ps): status = [] for r in rowers: - rscorev = 0 + rscorev = 0 trimpv = 0 durationv = 0 distancev = 0 @@ -113,7 +113,7 @@ def get_session_metrics(ps): durationv += timefield_to_seconds_duration(w.duration) trimpv += dataprep.workout_trimp(w) rscorev += dataprep.workout_rscore(w)[0] - + ratio,statusv,completiondate = is_session_complete_ws(ws,ps) try: completedatev = completiondate.strftime('%Y-%m-%d') @@ -139,7 +139,7 @@ def get_session_metrics(ps): 'rscore':rscore, 'trimp':trimp, 'completedate':completedate, - 'status':status, + 'status':status, } return thedict @@ -154,7 +154,7 @@ def is_session_complete_ws(ws,ps): return ratio,status,None else: return 0,'not done',None - + value = ps.sessionvalue if ps.sessionunit == 'min': value *= 60. @@ -171,7 +171,7 @@ def is_session_complete_ws(ws,ps): cratiomin = 0.9167 cratiomax = 1.0833 - + score = 0 completiondate = None for w in ws: @@ -236,7 +236,7 @@ def is_session_complete_ws(ws,ps): else: if not completiondate: completiondate = ws.reverse()[0].date - return ratio,'partial',completiondate + return ratio,'partial',completiondate elif ps.sessiontype == 'coursetest': if ps.course: ( @@ -274,19 +274,19 @@ def is_session_complete_ws(ws,ps): if not completiondate: completiondate = ws.reverse()[0].date return ratio,status,completiondate - + def is_session_complete(r,ps): status = 'not done' if r not in ps.rower.all(): return 0,'not assigned',None - + ws = Workout.objects.filter(user=r,plannedsession=ps) return is_session_complete_ws(ws,ps) - - + + def rank_results(ps): return 1 @@ -299,7 +299,7 @@ def add_team_session(t,ps): def add_rower_session(r,ps): ps.rower.add(r) ps.save() - + return 1 def remove_team_session(t,ps): @@ -364,8 +364,11 @@ def get_sessions_manager(m,teamid=0,startdate=date.today(), enddate=date.today()+timezone.timedelta(+1000)): if teamid: t = Team.objects.get(id=teamid) + rs = Rower.objects.filter( + team__in=[t] + ).distinct() sps = PlannedSession.objects.filter( - team__in=[t], + rower__in=rs, manager=m, startdate__lte=enddate, enddate__gte=startdate, @@ -376,9 +379,9 @@ def get_sessions_manager(m,teamid=0,startdate=date.today(), startdate__lte=enddate, enddate__gte=startdate, ).order_by("preferreddate","startdate","enddate") - + return sps - + def get_sessions(r,startdate=date.today(), enddate=date.today()+timezone.timedelta(+1000)): @@ -387,7 +390,7 @@ def get_sessions(r,startdate=date.today(), startdate__lte=enddate, enddate__gte=startdate, ).order_by("preferreddate","startdate","enddate") - + return sps def get_workouts_session(r,ps): From cf3a3e227d7afc735a7ae533777327005df5fe4b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 29 Mar 2018 11:22:05 -0700 Subject: [PATCH 2/8] debugging oauth --- rowers/dataprep.py | 9 +++++---- rowers/serializers.py | 23 ++++++++++++++++++++++- rowers/templates/strokedata_form.html | 2 +- rowers/views.py | 9 ++++++--- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 6885e341..56ce5fc4 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1586,9 +1586,9 @@ def rdata(file, rower=rrower()): try: res = rrdata(csvfile=file + '.gz', rower=rower) except IOError, IndexError: - res = 0 + res = rrdata() except: - res = 0 + res = rrdata() return res @@ -1637,7 +1637,7 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True): if data.empty: rowdata, row = getrowdata(id=id) - if rowdata: + if not rowdata.empty: data = dataprep(rowdata.df, id=id, bands=True, barchart=True, otwpower=True) else: @@ -1645,7 +1645,8 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True): else: row = Workout.objects.get(id=id) - if data['efficiency'].mean() == 0 and data['power'].mean() != 0: + + if not data.empty and data['efficiency'].mean() == 0 and data['power'].mean() != 0: data = add_efficiency(id=id) if doclean: diff --git a/rowers/serializers.py b/rowers/serializers.py index c552e2ed..3e94f954 100644 --- a/rowers/serializers.py +++ b/rowers/serializers.py @@ -21,6 +21,7 @@ class RowerSerializer(serializers.HyperlinkedModelSerializer): 'tr', 'an', 'ftp', + 'sex', ) class FavoriteChartSerializer(serializers.ModelSerializer): @@ -52,6 +53,13 @@ class WorkoutSerializer(serializers.ModelSerializer): 'maxhr', 'notes', 'summary', + 'boattype', + 'timezone', + 'forceunit', + 'inboard', + 'oarlength', + 'privacy', + 'rankingpiece' ) def create(self, validated_data): @@ -78,7 +86,13 @@ class WorkoutSerializer(serializers.ModelSerializer): summary=validated_data['summary'], averagehr=validated_data['averagehr'], maxhr=validated_data['maxhr'], - startdatetime=rowdatetime) + startdatetime=rowdatetime, + timezone=validated_data['timezone'], + forceunit=validated_data['forceunit'], + inboard=validated_data['inboard'], + oarlength=validated_data['oarlength'], + privacy=validated_data['privacy'], + rankingpiece=validated_data['rankingpiece'],) w.save() return w @@ -104,6 +118,13 @@ class WorkoutSerializer(serializers.ModelSerializer): instance.averagehr=validated_data['averagehr'] instance.maxhr=validated_data['maxhr'] instance.startdatetime=rowdatetime + instance.timezone=validated_data['timezone'] + instance.forceunit=validated_data['forceunit'] + instance.inboard=validated_data['inboard'] + instance.oarlength=validated_data['oarlength'] + instance.privacy=validated_data['privacy'] + instance.rankingpiece=validated_data['rankingpiece'] + instance.save() return instance diff --git a/rowers/templates/strokedata_form.html b/rowers/templates/strokedata_form.html index 34cabb57..c7ad8d3a 100644 --- a/rowers/templates/strokedata_form.html +++ b/rowers/templates/strokedata_form.html @@ -11,7 +11,7 @@

Stroke Data for workout {{ id }}

-
+ {{ form.as_table }}
diff --git a/rowers/views.py b/rowers/views.py index 07be1758..e9913488 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -11480,7 +11480,10 @@ def strokedatajson(request,id): df.index = df.index.astype(int) df.sort_index(inplace=True) # time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx - time = df['time']/1.e3 + try: + time = df['time']/1.e3 + except KeyError: + return HttpResponse("There must be time values",status=400) aantal = len(time) pace = df['pace']/1.e3 if len(pace) != aantal: @@ -11508,11 +11511,11 @@ def strokedatajson(request,id): lapidx = trydf(df,aantal,'lapidx') hr = trydf(df,aantal,'hr') - starttime = totimestamp(row.startdatetime)+time + starttime = totimestamp(row.startdatetime)+time[0] unixtime = starttime+time with open('media/apilog.log','a') as logfile: - logfile.write(starttime+": ") + logfile.write(str(starttime)+": ") logfile.write(request.user.username+"(POST) \r\n") data = pd.DataFrame({'TimeStamp (sec)':unixtime, From f711bd82149bf44a270d6879b9ef04d663f32879 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 29 Mar 2018 18:24:13 -0700 Subject: [PATCH 3/8] added NK EMpower parameters to api strokedata --- rowers/views.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rowers/views.py b/rowers/views.py index e9913488..c5a82a68 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -11508,6 +11508,12 @@ def strokedatajson(request,id): strokerecoverytime = trydf(df,aantal,'strokerecoverytime') averagedriveforce = trydf(df,aantal,'averagedriveforce') peakdriveforce = trydf(df,aantal,'peakdriveforce') + wash = trydf(df,aantal,'wash') + catch = trydf(df,aantal,'catch') + finish = trydf(df,aantal,'finish') + peakforceangle = trydf(df,aantal,'peakforceangle') + driveenergy = trydf(df,aantal,'driveenergy') + slip = trydf(df,aantal,'slip') lapidx = trydf(df,aantal,'lapidx') hr = trydf(df,aantal,'hr') @@ -11532,6 +11538,12 @@ def strokedatajson(request,id): ' PeakDriveForce (lbs)':peakdriveforce, ' lapIdx':lapidx, ' ElapsedTime (sec)':time, + 'catch':catch, + 'slip':slip, + 'finish':finish, + 'wash':wash, + 'driveenergy':driveenergy, + 'peakforceangle':peakforceangle, }) # Following part should be replaced with dataprep.new_workout_from_df From ff15f6e2f7886d94a4df77c44b1f449ed60e95a6 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 30 Mar 2018 16:03:42 -0700 Subject: [PATCH 4/8] small change --- rowers/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rowers/views.py b/rowers/views.py index c5a82a68..6d2da7c3 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -11547,7 +11547,9 @@ def strokedatajson(request,id): }) # Following part should be replaced with dataprep.new_workout_from_df - + + r = getrower(request.user) + timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S") csvfilename ='media/Import_'+timestr+'.csv' @@ -11556,7 +11558,6 @@ def strokedatajson(request,id): row.csvfilename = csvfilename row.save() - r = getrower(request.user) powerperc = 100*np.array([r.pw_ut2, r.pw_ut1, r.pw_at, From 8c4b4cce730ba5be1cfd54e077ecc4010b896fa6 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 30 Mar 2018 16:09:36 -0700 Subject: [PATCH 5/8] updated developers.html --- rowers/templates/developers.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rowers/templates/developers.html b/rowers/templates/developers.html index 32c6ee98..f5c61712 100644 --- a/rowers/templates/developers.html +++ b/rowers/templates/developers.html @@ -203,6 +203,12 @@
  • peakdriveforce: Peak handle force (lbs)
  • lapidx: Lap identifier
  • hr: Heart rate (beats per minute)
  • +
  • wash: Wash as defined per Empower oarlock (degrees)
  • +
  • catch: Catch angle per Empower oarlock (degrees)
  • +
  • finish: Finish angle per Empower oarlock (degrees)
  • +
  • peakforceangle: Peak Force Angle per Empower oarlock (degrees)
  • +
  • slip: Wash as defined per Empower oarlock (degrees)
  • +

    Consistency checks will be done and the stroke data will be From bfe6fc311162bdd4343084f6922956fb265621ca Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 31 Mar 2018 06:54:26 -0700 Subject: [PATCH 6/8] slight update of developers.html --- rowers/templates/developers.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rowers/templates/developers.html b/rowers/templates/developers.html index f5c61712..aefc5453 100644 --- a/rowers/templates/developers.html +++ b/rowers/templates/developers.html @@ -132,12 +132,6 @@ Developers of iOS or Android apps should contact me directly if this doesn't work for them. I can add exceptions.

    -

    The POST call must have content-type: x-www-form-urlencoded. - I set it this way to support the handy testing utility mentioned - belower. However, - I really would like to support application/json but with the - current framework I cannot support both at the same time. Expect - changes. Write to me if you want to be notified of changes.

    • Authorization URL: https://rowsandall.com/rowers/o/authorize
    • From 692883b8e0078cff70e39a9ea5e77438235cbad0 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 31 Mar 2018 07:01:45 -0700 Subject: [PATCH 7/8] host names on developers.html --- rowers/templates/developers.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rowers/templates/developers.html b/rowers/templates/developers.html index aefc5453..8ee6a523 100644 --- a/rowers/templates/developers.html +++ b/rowers/templates/developers.html @@ -134,9 +134,9 @@
        -
      • Authorization URL: https://rowsandall.com/rowers/o/authorize
      • -
      • Access Token request: https://rowsandall.com/rowers/o/token/
      • -
      • Access Token refresh: https://rowsandall.com/rowers/o/token/
      • +
      • Authorization URL: https://{{ request.get_host }}/rowers/o/authorize
      • +
      • Access Token request: https://{{ request.get_host }}/rowers/o/token/
      • +
      • Access Token refresh: https://{{ request.get_host }}/rowers/o/token/
      • Handy utility for testing: http://django-oauth-toolkit.herokuapp.com/consumer/
      @@ -163,7 +163,7 @@ posted to:

        -
      • https://rowsandall.com/rowers/api/workouts/{id}/strokedata
      • +
      • https://{{ request.get_host }}/rowers/api/workouts/{id}/strokedata

      The payload is application/json data and looks as follows:

      From d6c471d0e03b6e18e0e3a0fd44631ac349cfa4fe Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 1 Apr 2018 20:15:52 +0200 Subject: [PATCH 8/8] change rower replaced with name --- rowers/templates/cum_flex.html | 2 +- rowers/templates/cumstats.html | 2 +- rowers/templates/histo.html | 2 +- rowers/templates/list_workouts.html | 2 +- rowers/templates/oterankings.html | 2 +- rowers/templates/otwrankings.html | 2 +- rowers/templates/plannedsession_multicreate.html | 2 +- rowers/templates/plannedsessioncreate.html | 2 +- rowers/templates/plannedsessions.html | 2 +- rowers/templates/plannedsessions_print.html | 2 +- rowers/templates/plannedsessionsmanage.html | 2 +- rowers/templates/rankings.html | 2 +- rowers/templates/rower_form.html | 2 +- rowers/templates/strokedata_form.html | 2 -- rowers/templates/user_boxplot_select.html | 2 +- rowers/templates/user_multiflex_select.html | 2 +- 16 files changed, 15 insertions(+), 17 deletions(-) diff --git a/rowers/templates/cum_flex.html b/rowers/templates/cum_flex.html index ea74a7ae..4071a3fb 100644 --- a/rowers/templates/cum_flex.html +++ b/rowers/templates/cum_flex.html @@ -92,7 +92,7 @@ {% if user.is_authenticated and user|is_manager %}