diff --git a/rowers/integrations/intervals.py b/rowers/integrations/intervals.py
index 5b168f5c..15a019f6 100644
--- a/rowers/integrations/intervals.py
+++ b/rowers/integrations/intervals.py
@@ -203,20 +203,32 @@ class IntervalsIntegration(SyncIntegration):
return 0
id = response.json()['id']
+ workout.uploadedtointervals = id
+ workout.save()
+
+ os.remove(filename)
+
# set workout type to workouttype
url = "https://intervals.icu/api/v1/activity/{activityid}".format(activityid=id)
thetype = mytypes.intervalsmapping[workout.workouttype]
- response = requests.put(url, headers=headers, json={'type': thetype})
+ jsondict = {'type': thetype}
+ subtype = w.sub_type
+ if subtype:
+ jsondict['sub_type'] = subtype
+
+ jsondict['icu_rpe'] = workout.rpe
+ jsondict['commute'] = workout.is_commute
+ if workout.plannedsession:
+ jsondict['paired_event_id'] = workout.plannedsession.intervals_icu_id
+
+
+ response = requests.put(url, headers=headers, json=jsondict)
if response.status_code not in [200, 201]:
return 0
- workout.uploadedtointervals = id
- workout.save()
-
- os.remove(filename)
dologging('intervals.icu.log', "Exported workout {id}".format(id=workout.id))
diff --git a/rowers/models.py b/rowers/models.py
index 0d13f520..a5c30698 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -1271,6 +1271,8 @@ class Rower(models.Model):
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')
small_commutes = models.BooleanField(default=False, verbose_name='Show commutes on a single line in workout list')
+ show_wups_cds = models.BooleanField(default=False, verbose_name='Show warmups and cooldowns in workout list')
+ small_wups_cds = models.BooleanField(default=False, verbose_name='Show warmups and cooldowns on a single line in workout list')
# Friends/Team
friends = models.ManyToManyField("self", blank=True)
@@ -3718,6 +3720,13 @@ rpechoices = (
(10, '10 Max Effort (You can barely remember your name, you would rather rip out your toenails than go through this)')
)
+subcategories = (
+ (None, "None"),
+ ("Race", "Race"),
+ ("Commute", "Commute"),
+ ("Warming Up", "Warming Up"),
+ ("Cooling Down", "Cooling Down")
+)
class Workout(models.Model):
workouttypes = mytypes.workouttypes
@@ -3770,6 +3779,8 @@ class Workout(models.Model):
verbose_name='Rate of Perceived Exertion')
is_commute = models.BooleanField(default=False)
+ is_race = models.BooleanField(default=False)
+ sub_type = models.CharField(default=None, null=True, blank=True, choices=subcategories, max_length=250)
weightcategory = models.CharField(
default="hwt",
@@ -4624,6 +4635,7 @@ class WorkoutForm(ModelForm):
'duration',
'distance',
'workouttype',
+ 'sub_type',
'boattype',
'boatname',
'seatnumber',
@@ -4636,6 +4648,7 @@ class WorkoutForm(ModelForm):
'rankingpiece',
'duplicate',
'is_commute',
+ 'is_race',
'plannedsession']
widgets = {
'date': AdminDateWidget(),
@@ -5206,6 +5219,8 @@ class AccountRowerForm(ModelForm):
'defaultlandingpage3',
'show_commutes',
'small_commutes',
+ 'show_wups_cds',
+ 'small_wups_cds',
'offercoaching', 'autojoin', 'emailalternatives']
widgets = {
diff --git a/rowers/tasks.py b/rowers/tasks.py
index fa10cdbf..d2ddb567 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -3599,6 +3599,7 @@ def handle_intervals_getworkout(rower, intervalstoken, workoutid, debug=False, *
return 0
data = response.json()
+
try:
title = data['name']
except KeyError:
@@ -3621,6 +3622,21 @@ def handle_intervals_getworkout(rower, intervalstoken, workoutid, debug=False, *
except KeyError:
is_commute = False
+
+ try:
+ subtype = data['sub_type']
+ if subtype is not None:
+ subtype = subtype.capitalize()
+ except KeyError:
+ subtype = None
+
+ try:
+ is_race = data['race']
+ if is_race is None:
+ is_race = False
+ except KeyError:
+ is_race = False
+
url = "https://intervals.icu/api/v1/activity/{workoutid}/fit-file".format(workoutid=workoutid)
response = requests.get(url, headers=headers)
@@ -3667,7 +3683,14 @@ def handle_intervals_getworkout(rower, intervalstoken, workoutid, debug=False, *
if is_commute:
for w in ws:
w.is_commute = True
+ w.sub_type = "Commute"
w.save()
+ for w in ws:
+ w.sub_type = subtype
+ w.save()
+ if is_race:
+ w.is_race = True
+ w.save()
if ws.count() > 0:
pss = PlannedSession.objects.filter(rower=rower,intervals_icu_id=paired_event_id)
if pss.count() > 0:
diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html
index e1e06146..252ebe2f 100644
--- a/rowers/templates/list_workouts.html
+++ b/rowers/templates/list_workouts.html
@@ -34,12 +34,18 @@
{% endif %}
-{% if nr_commutes %}
+{% if nr_commutes or nr_wups_cds %}
- Show {{ nr_commutes }} commutes
+ {% if nr_commutes %}
+ Show {{ nr_commutes }} commutes
+ {% endif %}
+ {% if nr_wups_cds %}
+ Show {{ nr_wups_cds }} warmups and cooldowns
+ {% endif %}
{% endif %}
+
@@ -109,7 +115,7 @@
{% endif %}
{% for workout in workouts %}
- {% if not workout.is_commute or not user.rower.small_commutes %}
+ {% if workout|show_normal %}
{% if request.GET.selectworkouts %}
@@ -124,6 +130,14 @@
{% if workout.rankingpiece %}
{% endif %}
+ {% if workout.is_commute %}
+ Commute
+ {% endif %}
+ {% if workout.sub_type == "Warming Up" %}
+ Warming Up
+ {% elif workout.sub_type == "Cooling Down" %}
+ Cooling Down
+ {% endif %}
{% if workout.rpe == 0 and not workout.duplicate %}
No RPE
@@ -207,7 +221,7 @@
- {% elif show_commutes and user.rower.small_commutes %}
+ {% elif workout|show_commute %}
+ {% elif workout|show_wup_cd %}
+
+
+
+ {% if workout.sub_type == "Warming Up" %}
+
+ {% else %}
+
+ {% endif %}
+
+
+
+ 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 %}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index d6fe9ff1..35f6542c 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -48,6 +48,25 @@ from six import string_types
register = template.Library()
+@register.filter
+def show_normal(workout):
+ # is commute
+ hide_commute = workout.is_commute and (workout.user.small_commutes or not workout.user.show_commutes)
+ hide_warmup = workout.sub_type in ["Warming Up", "Cooling Down"] and (workout.user.small_wups_cds or not workout.user.show_wups_cds)
+ return not hide_commute and not hide_warmup
+
+@register.filter
+def show_commute(workout):
+ return workout.is_commute and workout.user.small_commutes
+
+@register.filter
+def show_wup_cd(workout):
+ return workout.sub_type in ["Warming Up", "Cooling Down"] and workout.user.small_wups_cds
+
+@register.filter
+def is_wup_cd(workout):
+ return workout.sub_type in ["Warm Up", "Cooling Down"]
+
@register.filter
def getworkoutname(id):
try:
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz
index 0144addc..c4e640aa 100644
Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index 7069f591..b23fa352 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -2080,10 +2080,12 @@ def workouts_bulk_actions(request):
elif action == 'set commute':
for w in workouts:
w.is_commute = True
+ w.sub_type = "Commute"
w.save()
elif action == 'unset commute':
for w in workouts:
w.is_commute = False
+ w.sub_type = None
w.save()
elif action == 'set public':
for w in workouts:
@@ -2154,6 +2156,8 @@ def workouts_view(request, message='', successmessage='',
show_commutes = request.GET.get('show_commutes', False)
if show_commutes == 'true':
show_commutes = True
+
+ show_wups_cds = request.GET.get('show_wups_cds', False)
# check if access is allowed
@@ -2279,8 +2283,13 @@ def workouts_view(request, message='', successmessage='',
if not show_commutes:
nr_commutes = workouts.filter(is_commute=True).count()
workouts = workouts.exclude(is_commute=True)
-
-
+
+ nr_wups_cds = 0
+ show_wups_cds = show_wups_cds or r.show_wups_cds
+ if not show_wups_cds:
+ nr_wups_cds = workouts.filter(sub_type__in=['Warming Up', 'Cooling Down']).count()
+ workouts = workouts.exclude(sub_type='Warming Up').exclude(sub_type='Cooling Down')
+
workoutsnohr = workouts.exclude(averagehr__isnull=False)
for w in workoutsnohr: # pragma: no cover
_ = dataprep.workout_trimp(w)
@@ -2373,6 +2382,8 @@ def workouts_view(request, message='', successmessage='',
'totalhours': totalhours,
'nr_commutes': nr_commutes,
'show_commutes': show_commutes,
+ 'show_wups_cds': show_wups_cds,
+ 'nr_wups_cds': nr_wups_cds,
})
@@ -4503,6 +4514,8 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
newdragfactor = form.cleaned_data['dragfactor']
thetimezone = form.cleaned_data['timezone']
is_commute = form.cleaned_data['is_commute']
+ is_race = form.cleaned_data['is_race']
+ subtype = form.cleaned_data['sub_type']
try:
rpe = form.cleaned_data['rpe']
if not rpe: # pragma: no cover
@@ -4523,7 +4536,11 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
seatnumber = form.cleaned_data.get('seatnumber', 1)
boatname = form.cleaned_data.get('boatname', '')
empowerside = form.cleaned_data.get('empowerside','port')
-
+
+ if is_race and subtype is None:
+ subtype = "Race"
+ elif is_commute and subtype is None:
+ subtype = "Commute"
if private:
privacy = 'hidden'
@@ -4581,6 +4598,8 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
row.empowerside = empowerside
row.seatnumber = seatnumber
row.is_commute = is_commute
+ row.is_race = is_race
+ row.sub_type = subtype
dragchanged = False
if newdragfactor != row.dragfactor: # pragma: no cover