From b83d97cd3a46f8b9128e20824108c9ca12063244 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 2 Jun 2025 21:36:02 +0200
Subject: [PATCH 1/5] making stack chart setting
---
rowers/models.py | 28 +++++++++++++++++++++-
rowers/templates/favoritecharts.html | 13 ++++++++++
rowers/templates/flexchartstacked.html | 7 ++++++
rowers/views/userviews.py | 33 ++++++++++++++++++++++++++
rowers/views/workoutviews.py | 11 +++++++++
5 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/rowers/models.py b/rowers/models.py
index 5a6052c5..24a5f5be 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -266,7 +266,29 @@ class WorkoutNameTemplateField(models.TextField):
value = self._get_val_from_obj(obj)
return self.get_deb_prep_value(value)
-
+
+class WorkoutChartStackFavoriteField(models.TextField):
+ def __init__(self, *args, **kwargs):
+ super(WorkoutChartStackFavoriteField, 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
@@ -1177,6 +1199,10 @@ class Rower(models.Model):
verbose_name="Title link on workout list")
workoutnametemplate = WorkoutNameTemplateField(default=['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype'])
+ chartstacktemplate_x = models.CharField(default='time',verbose_name='X-Axis for Chart Stacked View',max_length=200,
+ choices=(('time', 'Time'),('distance', 'Distance')),)
+ chartstacktemplate_y = WorkoutChartStackFavoriteField(default=['pace','power','hr','spm'],
+ verbose_name='Y-Axis for Chart Stacked View',)
# Access tokens
training_plan_code = models.CharField(default='', max_length=200, blank=True, null=True)
diff --git a/rowers/templates/favoritecharts.html b/rowers/templates/favoritecharts.html
index 77f2d3f7..e577454e 100644
--- a/rowers/templates/favoritecharts.html
+++ b/rowers/templates/favoritecharts.html
@@ -41,6 +41,19 @@
+
+ Use this form to change the default axes for the stacked workout chart.
+
+
+
+
+
Workout Name Settings of {{ rower.user.first_name }} {{ rower.user.last_name }}
diff --git a/rowers/templates/flexchartstacked.html b/rowers/templates/flexchartstacked.html
index 58aa7ffb..458ef850 100644
--- a/rowers/templates/flexchartstacked.html
+++ b/rowers/templates/flexchartstacked.html
@@ -47,6 +47,13 @@
+
+
+
+
+ (This saves your preferred X and Y axes for all workouts.)
+
diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py
index 9f72a107..991a5c21 100644
--- a/rowers/views/userviews.py
+++ b/rowers/views/userviews.py
@@ -250,6 +250,27 @@ def rower_favoritecharts_view(request, userid=0):
staticchartform = StaticChartRowerForm(instance=r)
datasettingsform = DataRowerForm(instance=r)
+ xparam = 'time'
+ yparam1 = 'pace'
+ yparam2 = 'power'
+ yparam3 = 'hr'
+ yparam4 = 'spm'
+
+ xparam = r.chartstacktemplate_x
+ yparam1 = r.chartstacktemplate_y[0]
+ yparam2 = r.chartstacktemplate_y[1]
+ yparam3 = r.chartstacktemplate_y[2]
+ yparam4 = r.chartstacktemplate_y[3]
+
+ initial = {
+ 'xaxis': xparam,
+ 'yaxis1': yparam1,
+ 'yaxis2': yparam2,
+ 'yaxis3': yparam3,
+ 'yaxis4': yparam4,
+ }
+ stackedchartform = StravaChartForm(request, initial=initial)
+
favorites = FavoriteChart.objects.filter(user=r).order_by('id')
aantal = len(favorites)
favorites_data = [{'yparam1': f.yparam1,
@@ -272,6 +293,17 @@ def rower_favoritecharts_view(request, userid=0):
workoutnametemplate_data = [{'element': element} for element in r.workoutnametemplate]
workoutnametemplate_formset = WorkoutNameTemplateFormSet(initial=workoutnametemplate_data, prefix='workoutname')
+ if request.method == 'POST' and 'yaxis4' in request.POST:
+ stackedchartform = StravaChartForm(request, request.POST)
+ if stackedchartform.is_valid():
+ r.chartstacktemplate_x = stackedchartform.cleaned_data.get('xaxis')
+ r.chartstacktemplate_y = [stackedchartform.cleaned_data.get('yaxis1'),
+ stackedchartform.cleaned_data.get('yaxis2'),
+ stackedchartform.cleaned_data.get('yaxis3'),
+ stackedchartform.cleaned_data.get('yaxis4')]
+ r.save()
+ messages.info(request, "We have updated your stacked chart settings")
+
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']
@@ -371,6 +403,7 @@ def rower_favoritecharts_view(request, userid=0):
'favorites_formset': favorites_formset,
'teams': get_my_teams(request.user),
'rower': r,
+ 'stackedchartform': stackedchartform,
'staticchartform': staticchartform,
'datasettingsform': datasettingsform,
'workoutnametemplate_formset': workoutnametemplate_formset,
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index 8f118934..312c0742 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -4240,6 +4240,12 @@ def workout_flexchart_stacked_view(request, *args, **kwargs):
yparam3 = 'hr'
yparam4 = 'spm'
+ xparam = r.chartstacktemplate_x
+ yparam1 = r.chartstacktemplate_y[0]
+ yparam2 = r.chartstacktemplate_y[1]
+ yparam3 = r.chartstacktemplate_y[2]
+ yparam4 = r.chartstacktemplate_y[3]
+
if request.method == 'POST':
flexaxesform = StravaChartForm(request, request.POST)
if flexaxesform.is_valid():
@@ -4250,6 +4256,11 @@ def workout_flexchart_stacked_view(request, *args, **kwargs):
yparam3 = cd['yaxis3']
yparam4 = cd['yaxis4']
+ if 'save' in request.POST:
+ r.chartstacktemplate_x = xparam
+ r.chartstacktemplate_y = [yparam1, yparam2, yparam3, yparam4]
+ r.save()
+
(
script, div
) = interactive_flexchart_stacked(
From a802035d8ce3640c63b729fa89a532f106b320fd Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 2 Jun 2025 21:48:49 +0200
Subject: [PATCH 2/5] favoritechartstack tested
---
rowers/tests/testdata/testdata.tcx.gz | Bin 3989 -> 3989 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz
index 288068f65a4995866a0705175bc66459c4ed280c..a180a61bbbc8bdfa2fd37a9facdad6651c96790d 100644
GIT binary patch
delta 15
WcmbO#KUJPhzMF$%
Date: Mon, 16 Jun 2025 18:54:49 +0200
Subject: [PATCH 3/5] fixds
---
rowers/plannedsessions.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 5b0513f9..d0223417 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -1128,7 +1128,7 @@ def create_next_week_from_json(plansteps, rower, planbyrscore=False, plan=None,
startdate=timezone.now()-timezone.timedelta(days=timezone.now().weekday())+timezone.timedelta(days=7)):
trainingdays = plansteps['cycles']
# start date is the first day of the following week
-
+
ndays = 0
for day in trainingdays:
try:
From ba0b86a79d28efb020b73f2fa48df4f0c997cafc Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Thu, 19 Jun 2025 07:59:00 +0200
Subject: [PATCH 4/5] fixing NK import summary error
---
rowers/nkimportutils.py | 5 ++++-
rowers/tests/testdata/testdata.tcx.gz | Bin 3989 -> 3989 bytes
rowers/views/paymentviews.py | 7 ++++++-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/rowers/nkimportutils.py b/rowers/nkimportutils.py
index 2b398e75..1778fe38 100644
--- a/rowers/nkimportutils.py
+++ b/rowers/nkimportutils.py
@@ -64,7 +64,10 @@ def add_workout_from_data(userid, nkid, data, strokedata, source='nk', splitdata
totalDistance = totalDistanceImp
useImpeller = True
- summary = get_nk_allstats(data, strokedata)
+ try:
+ summary = get_nk_allstats(data, strokedata)
+ except Exception: # pragma: no cover
+ summary = "error generating summary\n"
speedInput = data['speedInput'] # 0 = GPS; 1 = Impeller
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz
index a180a61bbbc8bdfa2fd37a9facdad6651c96790d..8be32d41843def2351fa629ff0930631e6d0623f 100644
GIT binary patch
delta 16
XcmbO#KUJPxzMF$%*RtS^?0x(ID<%ap
delta 16
XcmbO#KUJPxzMF$%<6qm2?0x(IEQ1AV
diff --git a/rowers/views/paymentviews.py b/rowers/views/paymentviews.py
index 4d378e01..40831540 100644
--- a/rowers/views/paymentviews.py
+++ b/rowers/views/paymentviews.py
@@ -960,7 +960,12 @@ def rower_register_view(request):
email = EmailMessage(
mail_subject, message, to=[to_email]
)
- email.send()
+ try:
+ email.send()
+ except Exception as e:
+ # send through alternative email server
+ pass
+
return render(request, 'confirmemailpage.html', {'address': to_email})
# login(request,theuser)
From 3bcad6ac99cf6fa212cf3223b31fc0c01683f065 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Thu, 19 Jun 2025 08:07:33 +0200
Subject: [PATCH 5/5] fixing nk import
---
.#config.yaml | 1 +
1 file changed, 1 insertion(+)
create mode 120000 .#config.yaml
diff --git a/.#config.yaml b/.#config.yaml
new file mode 120000
index 00000000..b90ba2a6
--- /dev/null
+++ b/.#config.yaml
@@ -0,0 +1 @@
+sander@rowsandall-2.14384:1749892836
\ No newline at end of file