Merge branch 'release/v21.2.0'
This commit is contained in:
+11
-1
@@ -1,7 +1,8 @@
|
|||||||
from rowers.utils import rankingdistances, rankingdurations
|
from rowers.utils import rankingdistances, rankingdurations
|
||||||
from rowers.utils import (
|
from rowers.utils import (
|
||||||
workflowleftpanel, workflowmiddlepanel,
|
workflowleftpanel, workflowmiddlepanel,
|
||||||
defaultleft, defaultmiddle
|
defaultleft, defaultmiddle,
|
||||||
|
workout_name_element,
|
||||||
)
|
)
|
||||||
from rowers.utils import palettes
|
from rowers.utils import palettes
|
||||||
from time import strftime
|
from time import strftime
|
||||||
@@ -497,6 +498,15 @@ class WorkFlowMiddlePanelElement(forms.Form):
|
|||||||
initial='None',
|
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
|
# The form to indicate additional actions to be performed immediately
|
||||||
# after a successful upload
|
# after a successful upload
|
||||||
|
|||||||
+62
-26
@@ -231,6 +231,34 @@ class AlternativeEmails(models.TextField):
|
|||||||
value = self._get_val_from_obj(obj)
|
value = self._get_val_from_obj(obj)
|
||||||
return self.get_deb_prep_value(value)
|
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
|
# model for Planned Session Steps
|
||||||
|
|
||||||
|
|
||||||
@@ -1094,6 +1122,8 @@ class Rower(models.Model):
|
|||||||
choices=landingpages2,
|
choices=landingpages2,
|
||||||
verbose_name="Title link on workout list")
|
verbose_name="Title link on workout list")
|
||||||
|
|
||||||
|
workoutnametemplate = WorkoutNameTemplateField(default=['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype'])
|
||||||
|
|
||||||
# Access tokens
|
# Access tokens
|
||||||
c2token = models.CharField(
|
c2token = models.CharField(
|
||||||
default='', max_length=200, blank=True, null=True)
|
default='', max_length=200, blank=True, null=True)
|
||||||
@@ -3667,25 +3697,38 @@ class Workout(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
||||||
date = self.date
|
elements = dict(
|
||||||
name = self.name
|
date = self.date.strftime('%Y-%m-%d'),
|
||||||
distance = str(self.distance)
|
name = self.name,
|
||||||
ownerfirst = self.user.user.first_name
|
distance = str(self.distance),
|
||||||
ownerlast = self.user.user.last_name
|
ownerfirst = self.user.user.first_name,
|
||||||
duration = self.duration
|
ownerlast = self.user.user.last_name,
|
||||||
boattype = self.boattype
|
duration = self.duration.strftime("%H:%M:%S"),
|
||||||
workouttype = self.workouttype
|
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:
|
try:
|
||||||
stri = u'{d} {n} {dist}m {duration} {workouttype} {ownerfirst} {ownerlast}'.format(
|
stri = u''
|
||||||
d=date.strftime('%Y-%m-%d'),
|
for element in self.user.workoutnametemplate:
|
||||||
n=name,
|
stri += u'{'+u'{element}'.format(element=element)+u'} '
|
||||||
dist=distance,
|
stri = stri[:-1]
|
||||||
duration=duration.strftime("%H:%M:%S"),
|
return stri.format(**elements)
|
||||||
workouttype=workouttype,
|
except ValueError:
|
||||||
ownerfirst=ownerfirst,
|
return self.name
|
||||||
ownerlast=ownerlast,
|
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:
|
except ValueError:
|
||||||
stri = self.name
|
stri = self.name
|
||||||
@@ -3693,15 +3736,8 @@ class Workout(models.Model):
|
|||||||
return "No workout"
|
return "No workout"
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
stri = u'{d} {n} {dist}m {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format(
|
stri = u'{date} {name} {distance}m {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format(
|
||||||
d=date.strftime('%Y-%m-%d'),
|
**elements
|
||||||
n=name,
|
|
||||||
dist=distance,
|
|
||||||
duration=duration.strftime("%H:%M:%S"),
|
|
||||||
workouttype=workouttype,
|
|
||||||
boattype=boattype,
|
|
||||||
ownerfirst=ownerfirst,
|
|
||||||
ownerlast=ownerlast,
|
|
||||||
)
|
)
|
||||||
except (ValueError, AttributeError):
|
except (ValueError, AttributeError):
|
||||||
stri = self.name
|
stri = self.name
|
||||||
|
|||||||
@@ -41,6 +41,27 @@
|
|||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h1>Workout Name Settings of {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form enctype="multipart/form-data" action="" method="post">
|
||||||
|
{{ workoutnametemplate_formset.management_form }}
|
||||||
|
<table width=100%>
|
||||||
|
{{ workoutnametemplate_formset.as_table }}
|
||||||
|
</table>
|
||||||
|
{% csrf_token %}
|
||||||
|
<p>
|
||||||
|
<input class="grid_2 alpha button" type="submit" value="Save">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type="submit" value="Restore Defaults" name="defaults_workoutname" class="button"/>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<h1>Change Favorite Charts of {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
<h1>Change Favorite Charts of {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -57,6 +57,22 @@ landingpages2 = (
|
|||||||
('workout_delete', 'Remove Workout')
|
('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 = (
|
workflowmiddlepanel = (
|
||||||
('panel_statcharts.html', 'Static Charts'),
|
('panel_statcharts.html', 'Static Charts'),
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ from rowers.forms import (
|
|||||||
CourseConfirmForm, ResampleForm,
|
CourseConfirmForm, ResampleForm,
|
||||||
TeamUploadOptionsForm, WorkFlowLeftPanelForm, WorkFlowMiddlePanelForm,
|
TeamUploadOptionsForm, WorkFlowLeftPanelForm, WorkFlowMiddlePanelForm,
|
||||||
WorkFlowLeftPanelElement, WorkFlowMiddlePanelElement,
|
WorkFlowLeftPanelElement, WorkFlowMiddlePanelElement,
|
||||||
|
WorkoutNameTemplateElement,
|
||||||
LandingPageForm, PlannedSessionSelectForm, WorkoutSessionSelectForm,
|
LandingPageForm, PlannedSessionSelectForm, WorkoutSessionSelectForm,
|
||||||
PlannedSessionTeamForm, PlannedSessionTeamMemberForm,
|
PlannedSessionTeamForm, PlannedSessionTeamMemberForm,
|
||||||
VirtualRaceSelectForm, WorkoutRaceSelectForm, CourseSelectForm,
|
VirtualRaceSelectForm, WorkoutRaceSelectForm, CourseSelectForm,
|
||||||
|
|||||||
@@ -322,6 +322,35 @@ def rower_favoritecharts_view(request, userid=0):
|
|||||||
FavoriteChartFormSet = formset_factory(
|
FavoriteChartFormSet = formset_factory(
|
||||||
FavoriteForm, formset=BaseFavoriteFormSet, extra=1)
|
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
|
if request.method == 'POST' and 'staticgrids' in request.POST: # pragma: no cover
|
||||||
staticchartform = StaticChartRowerForm(request.POST, instance=r)
|
staticchartform = StaticChartRowerForm(request.POST, instance=r)
|
||||||
if staticchartform.is_valid():
|
if staticchartform.is_valid():
|
||||||
@@ -400,6 +429,7 @@ def rower_favoritecharts_view(request, userid=0):
|
|||||||
'rower': r,
|
'rower': r,
|
||||||
'staticchartform': staticchartform,
|
'staticchartform': staticchartform,
|
||||||
'datasettingsform': datasettingsform,
|
'datasettingsform': datasettingsform,
|
||||||
|
'workoutnametemplate_formset': workoutnametemplate_formset,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'favoritecharts.html', context)
|
return render(request, 'favoritecharts.html', context)
|
||||||
|
|||||||
Reference in New Issue
Block a user