diff --git a/rowers/forms.py b/rowers/forms.py index 8985cf2b..3d9e3e86 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1,7 +1,8 @@ from rowers.utils import rankingdistances, rankingdurations from rowers.utils import ( workflowleftpanel, workflowmiddlepanel, - defaultleft, defaultmiddle + defaultleft, defaultmiddle, + workout_name_element, ) from rowers.utils import palettes from time import strftime @@ -497,6 +498,15 @@ class WorkFlowMiddlePanelElement(forms.Form): initial='None', ) +class WorkoutNameTemplateElement(forms.Form): + templatechoices = tuple(list(workout_name_element)+[('None', 'None')]) + + element = forms.ChoiceField( + label='', + choices=templatechoices, + initial='None' + ) + # The form to indicate additional actions to be performed immediately # after a successful upload diff --git a/rowers/models.py b/rowers/models.py index bfa22a1c..6edc4c92 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -231,6 +231,34 @@ class AlternativeEmails(models.TextField): value = self._get_val_from_obj(obj) return self.get_deb_prep_value(value) + +# model for Workout Name template list + +class WorkoutNameTemplateField(models.TextField): + def __init__(self, *args, **kwargs): + super(WorkoutNameTemplateField, self).__init__(*args, **kwargs) + + def to_python(self, value): # pragma: no cover + if not value: + return + return json.loads(value) + + def from_db_value(self, value, expression, connection): + if not value: + return + return json.loads(value) + + def get_db_prep_value(self, value, connection, prepared=False): + if not value: + return + return json.dumps(value) + + def value_to_string(self, obj): # pragma: no cover + value = self._get_val_from_obj(obj) + return self.get_deb_prep_value(value) + + + # model for Planned Session Steps @@ -1094,6 +1122,8 @@ class Rower(models.Model): choices=landingpages2, verbose_name="Title link on workout list") + workoutnametemplate = WorkoutNameTemplateField(default=['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype']) + # Access tokens c2token = models.CharField( default='', max_length=200, blank=True, null=True) @@ -3667,25 +3697,38 @@ class Workout(models.Model): def __str__(self): - date = self.date - name = self.name - distance = str(self.distance) - ownerfirst = self.user.user.first_name - ownerlast = self.user.user.last_name - duration = self.duration - boattype = self.boattype - workouttype = self.workouttype + elements = dict( + date = self.date.strftime('%Y-%m-%d'), + name = self.name, + distance = str(self.distance), + ownerfirst = self.user.user.first_name, + ownerlast = self.user.user.last_name, + duration = self.duration.strftime("%H:%M:%S"), + boattype = self.boattype, + workouttype = self.workouttype, + seatnumber = 'seat '+str(self.seatnumber), + boatname = 'boat '+str(self.boatname), + empowerside = self.empowerside, + inboard = self.inboard, + oarlength = self.oarlength + ) - if workouttype not in ['water','rower']: + if len(self.user.workoutnametemplate): try: - stri = u'{d} {n} {dist}m {duration} {workouttype} {ownerfirst} {ownerlast}'.format( - d=date.strftime('%Y-%m-%d'), - n=name, - dist=distance, - duration=duration.strftime("%H:%M:%S"), - workouttype=workouttype, - ownerfirst=ownerfirst, - ownerlast=ownerlast, + stri = u'' + for element in self.user.workoutnametemplate: + stri += u'{'+u'{element}'.format(element=element)+u'} ' + stri = stri[:-1] + return stri.format(**elements) + except ValueError: + return self.name + except AttributeError: + return "No workout" + + if self.workouttype not in ['water','rower']: + try: + stri = u'{date} {name} {distance}m {duration} {workouttype} {ownerfirst} {ownerlast}'.format( + **elements ) except ValueError: stri = self.name @@ -3693,15 +3736,8 @@ class Workout(models.Model): return "No workout" else: try: - stri = u'{d} {n} {dist}m {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format( - d=date.strftime('%Y-%m-%d'), - n=name, - dist=distance, - duration=duration.strftime("%H:%M:%S"), - workouttype=workouttype, - boattype=boattype, - ownerfirst=ownerfirst, - ownerlast=ownerlast, + stri = u'{date} {name} {distance}m {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format( + **elements ) except (ValueError, AttributeError): stri = self.name diff --git a/rowers/templates/favoritecharts.html b/rowers/templates/favoritecharts.html index c34c1973..77f2d3f7 100644 --- a/rowers/templates/favoritecharts.html +++ b/rowers/templates/favoritecharts.html @@ -41,6 +41,27 @@

+

Workout Name Settings of {{ rower.user.first_name }} {{ rower.user.last_name }}

+ +

+ Use this form to change how the workout is named in charts. Our recommendation is name, date, rower first name, rower last name, workout type + as a minimum. +

+ +
+ {{ workoutnametemplate_formset.management_form }} + + {{ workoutnametemplate_formset.as_table }} +
+ {% csrf_token %} +

+ +

+

+ +

+
+

Change Favorite Charts of {{ rower.user.first_name }} {{ rower.user.last_name }}

diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index cbfec837..0fc0e3fd 100644 Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ diff --git a/rowers/utils.py b/rowers/utils.py index 49443593..9e7d5054 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -57,6 +57,22 @@ landingpages2 = ( ('workout_delete', 'Remove Workout') ) +workout_name_element = ( + ('date', 'Date'), + ('name', 'Name'), + ('distance', 'Distance'), + ('ownerfirst', 'Rower first name'), + ('ownerlast', 'Rower last name'), + ('duration', 'Duration'), + ('boattype','Boat type'), + ('workouttype', 'Workout type'), + ('seatnumber','Seat number'), + ('boatname', 'Boat name'), + ('empowerside', 'Empower side'), + ('inboard', 'Inboard'), + ('oarlength', 'Oar length'), +) + workflowmiddlepanel = ( ('panel_statcharts.html', 'Static Charts'), diff --git a/rowers/views/statements.py b/rowers/views/statements.py index ac88517b..351ca027 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -103,6 +103,7 @@ from rowers.forms import ( CourseConfirmForm, ResampleForm, TeamUploadOptionsForm, WorkFlowLeftPanelForm, WorkFlowMiddlePanelForm, WorkFlowLeftPanelElement, WorkFlowMiddlePanelElement, + WorkoutNameTemplateElement, LandingPageForm, PlannedSessionSelectForm, WorkoutSessionSelectForm, PlannedSessionTeamForm, PlannedSessionTeamMemberForm, VirtualRaceSelectForm, WorkoutRaceSelectForm, CourseSelectForm, diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index b03e5eb7..cd42ad56 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -322,6 +322,35 @@ def rower_favoritecharts_view(request, userid=0): FavoriteChartFormSet = formset_factory( FavoriteForm, formset=BaseFavoriteFormSet, extra=1) + workoutnametemplate = r.workoutnametemplate + WorkoutNameTemplateFormSet = formset_factory(WorkoutNameTemplateElement, extra=1) + + workoutnametemplate_data = [{'element': element} for element in r.workoutnametemplate] + workoutnametemplate_formset = WorkoutNameTemplateFormSet(initial=workoutnametemplate_data, prefix='workoutname') + + if request.method == 'POST' and 'workoutname-TOTAL_FORMS' in request.POST: + if 'defaults_workoutname' in request.POST: + r.workoutnametemplate = ['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype'] + r.save() + else: + workoutnametemplate_formset = WorkoutNameTemplateFormSet(request.POST, prefix='workoutname') + newworkoutnametemplate = [] + if workoutnametemplate_formset.is_valid(): + for form in workoutnametemplate_formset: + element = form.cleaned_data.get('element') + if element != 'None': + newworkoutnametemplate.append(element) + + newworkoutnametemplate = [i for i in newworkoutnametemplate if i is not None] + r.workoutnametemplate = newworkoutnametemplate + try: + r.save() + except IntegrityError: + messages.error("Something went wrong") + workoutnametemplate_data = [{'element': element} for element in r.workoutnametemplate] + workoutnametemplate_formset = WorkoutNameTemplateFormSet(initial=workoutnametemplate_data, prefix='workoutname') + + if request.method == 'POST' and 'staticgrids' in request.POST: # pragma: no cover staticchartform = StaticChartRowerForm(request.POST, instance=r) if staticchartform.is_valid(): @@ -400,6 +429,7 @@ def rower_favoritecharts_view(request, userid=0): 'rower': r, 'staticchartform': staticchartform, 'datasettingsform': datasettingsform, + 'workoutnametemplate_formset': workoutnametemplate_formset, } return render(request, 'favoritecharts.html', context)