diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 9dbfd80a..0864eec7 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1274,7 +1274,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', pass # recalculate power data - if workouttype == 'rower' or workouttype == 'dynamic' or workouttype == 'slides': + if workouttype in otetypes: try: if r.erg_recalculatepower: row.erg_recalculatepower() @@ -1282,6 +1282,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', except: pass + averagehr = row.df[' HRCur (bpm)'].mean() maxhr = row.df[' HRCur (bpm)'].max() @@ -1451,6 +1452,35 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', _ = update_wps(r, mytypes.otwtypes) _ = update_wps(r, mytypes.otetypes) + # set user running wps + if not duplicate and workouttype in otetypes: + cntr = Workout.objects.filter(user=r, workouttype__in=otetypes, + startdatetime__gt=tz.now()-tz.timedelta(days=42), + duplicate=False).count() + new_value = (cntr*r.running_wps_erg + row.df['driveenergy'].mean())/(cntr+1.0) + # if new_value is not zero or infinite or -inf, r.running_wps can be set to value + if not (math.isnan(new_value) or math.isinf(new_value) or new_value == 0): + r.running_wps_erg = new_value + elif not (math.isnan(r.running_wps_erg) or math.isinf(r.running_wps_erg) or r.running_wps_erg == 0): + pass + else: + r.running_wps_erg = 600. + r.save() + + if not duplicate and workouttype in otwtypes: + cntr = Workout.objects.filter(user=r, workouttype__in=otwtypes, + startdatetime__gt=tz.now()-tz.timedelta(days=42), + duplicate=False).count() + new_value = (cntr*r.running_wps_erg + row.df['driveenergy'].mean())/(cntr+1.0) + if not (math.isnan(new_value) or math.isinf(new_value) or new_value == 0): + r.running_wps = new_value + elif not (math.isnan(r.running_wps) or math.isinf(r.running_wps) or r.running_wps == 0): + pass + else: + r.running_wps = 400. + r.save() + + _ = myqueue(queuehigh, handle_calctrimp, w.id, f2, r.ftp, r.sex, r.hrftp, r.max, r.rest) diff --git a/rowers/forms.py b/rowers/forms.py index 44469278..2db9b8bf 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1226,6 +1226,10 @@ bulkactions = ( ('remove','remove'), ('export','export'), ('rower assign','rower assign'), + ('set commute','set commute'), + ('set private','set private'), + ('set public','set public'), + ('unset commute','unset commute'), ) destinations = ( ('c2','c2'), diff --git a/rowers/idoklad.py b/rowers/idoklad.py index cb6f2593..2119a662 100644 --- a/rowers/idoklad.py +++ b/rowers/idoklad.py @@ -147,7 +147,7 @@ def create_contact(rower): if res.status_code not in [200, 201]: dologging('idoklad.log','Contact Created - reason '+str(res.reason)+'\n') - _ = myqueue.enqueue( + _ = myqueue( queuehigh, handle_send_email_noinvoice, rower.user.email, rower.user.first_name, diff --git a/rowers/models.py b/rowers/models.py index edf851aa..dbaa5d34 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1257,6 +1257,7 @@ class Rower(models.Model): verbose_name='Receive email notifications') imports_are_private = models.BooleanField(default=False, verbose_name='Make imports private by default') + show_commutes = models.BooleanField(default=False, verbose_name='Show commutes in workout list') # Friends/Team friends = models.ManyToManyField("self", blank=True) @@ -1295,6 +1296,9 @@ class Rower(models.Model): fastpaceotw = models.DurationField( default=otwpacefast, verbose_name='Fastest OTW Pace') + running_wps = models.FloatField(default=400.0, verbose_name='Running Work per Stroke') + running_wps_erg = models.FloatField(default=500.0, verbose_name='Running Work per Stroke (ergometer)') + fav_analysis = models.CharField(default='compare', choices=favanalysischoices, max_length=100, verbose_name='Favorite Analysis') @@ -5177,6 +5181,7 @@ class AccountRowerForm(ModelForm): 'defaultlandingpage', 'defaultlandingpage2', 'defaultlandingpage3', + 'show_commutes', 'offercoaching', 'autojoin', 'emailalternatives'] widgets = { diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index 51e40308..cd31fc05 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -104,11 +104,15 @@ {% endif %} {% for workout in workouts %} + {% if not workout.is_commute %}
  • {% if request.GET.selectworkouts %} {% endif %} {{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }} + {% if workout.privacy == 'hidden' %} + + {% endif %} {% if workout.duplicate %} {% endif %} @@ -198,7 +202,52 @@
  • - + {% elif user.rower.show_commutes %} +
  • +
    +
    + +
    + +
    + Distance + {{ workout.distance|distanceprint }} +
    +
    + Time + {{ workout.duration |durationprint:"%H:%M:%S.%f" }} +
    +
    + {% if workout|may_edit:request %} + + + {% else %} +   + {% endif %} +
    +
    + {% if workout|may_edit:request %} + {% if rower.defaultlandingpage2 != 'workout_delete' %} + + + {% else %} + + + {% endif %} + {% else %} +   + {% endif %} +
    +
    +
  • + {% endif %} + {% endfor %} {% else %} diff --git a/rowers/templates/rower_simplepreferences.html b/rowers/templates/rower_simplepreferences.html index 7aa851fd..328b0d70 100644 --- a/rowers/templates/rower_simplepreferences.html +++ b/rowers/templates/rower_simplepreferences.html @@ -40,41 +40,58 @@ - + + + + + + - + + + + + + + + + + + + +
    ID Zone NameLower Boundary (Watt) Lower Boundary (Watt)ID Zone NameLower Boundary (Watt) Lower Boundary (Watt)Target SPMTarget SPM
    IndoorOTWIndoorOTWIndoorOTW
    1{{ user.rower.powerzones.0 }}
    2{{ user.rower.powerzones.1 }} {{ user.rower.pw_ut2 }} {{ user.rower.pw_ut2|otwslack:user }}<{{ user.rower.pw_ut1|target_spm_erg:user }}<{{ user.rower.pw_ut1|target_spm_otw:user }}
    3{{ user.rower.powerzones.2 }} {{ user.rower.pw_ut1 }} {{ user.rower.pw_ut1|otwslack:user }}{{ user.rower.pw_ut1|target_spm_erg:user }}-{{ user.rower.pw_at|target_spm_erg:user }}{{ user.rower.pw_ut1|target_spm_otw:user }}-{{ user.rower.pw_at|target_spm_otw:user }}
    4{{ user.rower.powerzones.3 }} {{ user.rower.pw_at }} {{ user.rower.pw_at|otwslack:user }}{{ user.rower.pw_at|target_spm_erg:user }}-{{ user.rower.pw_tr|target_spm_erg:user }}{{ user.rower.pw_at|target_spm_otw:user }}-{{ user.rower.pw_tr|target_spm_otw:user }}
    5{{ user.rower.powerzones.4 }} {{ user.rower.pw_tr }} {{ user.rower.pw_tr|otwslack:user }}{{ user.rower.pw_tr|target_spm_erg:user }}-{{ user.rower.pw_an|target_spm_erg:user }}{{ user.rower.pw_tr|target_spm_otw:user }}-{{ user.rower.pw_an|target_spm_otw:user }}
    6{{ user.rower.powerzones.5 }} {{ user.rower.pw_an }} {{ user.rower.pw_an|otwslack:user }}>{{ user.rower.pw_an|target_spm_erg:user }}>{{ user.rower.pw_an|target_spm_otw:user }}
    diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 60a97c29..d6fe9ff1 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -1065,3 +1065,15 @@ def previousworkout(workout, user): def otwslack(value, user): r = Rower.objects.get(user=user) return int(value*(100.-r.otwslack)/100.) + +@register.filter +def target_spm_erg(value, user): + r = Rower.objects.get(user=user) + value = 1.0*value + return int(value*60/r.running_wps_erg) + +@register.filter +def target_spm_otw(value, user): + r = Rower.objects.get(user=user) + value = value*(100.-r.otwslack)/100. + return int(value*60/r.running_wps) diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index b5c20fb0..b81e6990 100644 Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ diff --git a/rowers/views/apiviews.py b/rowers/views/apiviews.py index d055c979..2bef2928 100644 --- a/rowers/views/apiviews.py +++ b/rowers/views/apiviews.py @@ -605,13 +605,11 @@ def strokedata_fit(request): name=title, date=startdate, ) -# workouttype='water',) uploadoptions = { 'secret': UPLOAD_SERVICE_SECRET, 'user': request.user.id, 'file': fit_filename, - 'workouttype': 'water', 'boattype': '1x', 'title': title, 'rpe': 0, diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index 7df07582..90cb4480 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -429,12 +429,6 @@ def rower_exportsettings_view(request, userid=0): } if form.is_valid(): cd = form.cleaned_data - if r.rowerplan == 'basic': # pragma: no cover - messages.error( - request, 'This setting will only be effective if you are a user \ - on one of the paid plans \ - or part of a coaching group.') - for attr, value in cd.items(): doset = True try: diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 43b7af02..25106afa 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -2067,6 +2067,22 @@ def workouts_bulk_actions(request): for w in workouts: messages.info(request,'Removed workout '+str(encoder.encode_hex(w.id))) w.delete() + elif action == 'set private': + for w in workouts: + w.privacy = 'private' + w.save() + elif action == 'set commute': + for w in workouts: + w.is_commute = True + w.save() + elif action == 'unset commute': + for w in workouts: + w.is_commute = False + w.save() + elif action == 'set public': + for w in workouts: + w.privacy = 'public' + w.save() elif action == 'export': exportchoice = ExportChoices(request.POST) if exportchoice.is_valid():