From e409c564ab3e267874fab0a9ec8de48170d45c9e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 2 Jun 2025 20:24:46 +0200 Subject: [PATCH] analysis split --- rowers/fitness.py | 4 +++ rowers/models.py | 4 +-- rowers/mytypes.py | 3 +++ rowers/tasks.py | 37 ++++++++++++++++++++++++++ rowers/templates/summary_edit.html | 2 ++ rowers/tests/testdata/testdata.tcx.gz | Bin 3989 -> 3989 bytes rowers/urls.py | 2 ++ rowers/views/analysisviews.py | 1 + rowers/views/statements.py | 2 ++ rowers/views/workoutviews.py | 17 ++++++++++++ 10 files changed, 70 insertions(+), 2 deletions(-) diff --git a/rowers/fitness.py b/rowers/fitness.py index 2d2986cc..d67873ef 100644 --- a/rowers/fitness.py +++ b/rowers/fitness.py @@ -58,6 +58,7 @@ def getfatigues(df, fatigues, fitnesses, dates, impulses, startdate, kfatigue, k return fatigues, fitnesses, dates, impulses def calculate_fitness(rower, reset=False): + try: w_last = Workout.objects.get(id=rower.last_workout) datetime_last = w_last.startdatetime @@ -72,6 +73,9 @@ def calculate_fitness(rower, reset=False): rower.save() datetime_last = datetime.datetime.now() - datetime.timedelta(days=90) + if not datetime_last: + datetime_last = datetime.datetime.now() - datetime.timedelta(days=90) + workouts = Workout.objects.filter(user=rower, startdatetime__gt=datetime_last, duplicate=False).order_by('date').exclude(id=rower.last_workout) diff --git a/rowers/models.py b/rowers/models.py index 611574d4..5a6052c5 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -3854,9 +3854,9 @@ class Workout(models.Model): if self.timezone == 'tzutc()': self.timezone = 'UTC' # pragma: no cover - if self.workouttype in mytypes.otwtypes and self.boattype in mytypes.ergtypes: + if self.workouttype in mytypes.otwtypes and self.boattype in mytypes.ergtypes_check: self.boattype = '1x' - elif self.workouttype in mytypes.otetypes and self.boattype in mytypes.boattypes: + elif self.workouttype in mytypes.otetypes and self.boattype in mytypes.boattypes_check: self.boattype = 'static' records = VirtualRaceResult.objects.filter(workoutid=self.pk) diff --git a/rowers/mytypes.py b/rowers/mytypes.py index c46752f7..407329e8 100644 --- a/rowers/mytypes.py +++ b/rowers/mytypes.py @@ -513,6 +513,9 @@ ergtypes = ( ('other','Other Indoor Rower'), ) +boattypes_check = [i[0] for i in boattypes] +ergtypes_check = [i[0] for i in ergtypes] + adaptivetypes = ( diff --git a/rowers/tasks.py b/rowers/tasks.py index 395eb94b..4465de13 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -4073,6 +4073,43 @@ def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec, return workoutid +@app.task +def handle_split_workout_by_intervals(id, debug=False, **kwargs): + row = Workout.objects.get(id=id) + r = row.user + rowdata = rdata(csvfile=row.csvfilename) + if rowdata == 0: + messages.error(request,"No Data file found for this workout") + return HttpResponseRedirect(url) + + new_rowdata = rowdata.split_by_intervals() + interval_i = 1 + for data in new_rowdata: + filename = 'media/{code}.csv'.format( + code = uuid4() .hex[:16] + ) + + data.write_csv(filename) + + uploadoptions = { + 'secret': UPLOAD_SERVICE_SECRET, + 'user': r.user.id, + 'title': '{title} - interval {i}'.format(title=row.name, i=interval_i), + 'file': filename, + 'boattype': row.boattype, + 'workouttype': row.workouttype, + } + + session = requests.session() + newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plan'} + session.headers.update(newHeaders) + response = session.post(UPLOAD_SERVICE_URL, json=uploadoptions) + + interval_i = interval_i + 1 + + return 1 + + @app.task def fetch_rojabo_session(id,alldata,userid,rowerid,debug=False, **kwargs): # pragma: no cover try: diff --git a/rowers/templates/summary_edit.html b/rowers/templates/summary_edit.html index 886194e6..7d4989be 100644 --- a/rowers/templates/summary_edit.html +++ b/rowers/templates/summary_edit.html @@ -80,6 +80,8 @@ Reset to last saved   Restore Original data +   + Split Workout by Intervals

diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 48a5437446dab7f4cb3e27b3ac1bd766157d28ad..288068f65a4995866a0705175bc66459c4ed280c 100644 GIT binary patch delta 16 XcmbO#KUJPxzMF$%{Y%@8?0x(IEBysj delta 16 XcmbO#KUJPxzMF%Clih41dmldlA_N1) diff --git a/rowers/urls.py b/rowers/urls.py index 65db0431..3fca9aa8 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -538,6 +538,8 @@ urlpatterns = [ views.workout_downloadmetar_view, name='workout_downloadmetar_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/editintervals/$', views.workout_summary_edit_view, name='workout_summary_edit_view'), + re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/split_intervals/$', + views.workout_split_by_interval_view, name='workout_split_by_interval_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/restore/$', views.workout_summary_restore_view, name='workout_summary_restore_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/split/$', diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index acd13734..e511b070 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -221,6 +221,7 @@ def analysis_new(request, "-date", "-starttime" ).exclude(boattype__in=negtypes) + query = request.POST.get('q') if query: # pragma: no cover query_list = query.split() diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 2f40eb67..8da14d61 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -237,6 +237,7 @@ from rowsandall_app.settings import ( NK_REDIRECT_URI, NK_CLIENT_ID, NK_CLIENT_SECRET, ROJABO_REDIRECT_URI, ROJABO_CLIENT_ID, ROJABO_CLIENT_SECRET, IDOKLAD_REDIRECT_URI, IDOKLAD_CLIENT_ID, IDOKLAD_CLIENT_SECRET, + UPLOAD_SERVICE_URL, UPLOAD_SERVICE_SECRET, ) from django.contrib import messages @@ -282,6 +283,7 @@ from rowers.tasks import ( handle_nk_async_workout, check_tp_workout_id, handle_assignworkouts, + handle_split_workout_by_intervals, ) from scipy.signal import savgol_filter diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index fb8080fd..8f118934 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -6926,6 +6926,23 @@ def workout_summary_edit_view(request, id, message="", successmessage="" 'courseselectform': courseselectform, }) +@login_required() +@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True) +def workout_split_by_interval_view(request, id): + row = get_workout_by_opaqueid(request, id) + r = getrower(request.user) + url = reverse("workout_summary_edit_view", kwargs={"id": id}) + + _ = myqueue( + queuehigh, + handle_split_workout_by_intervals, + row.id, + ) + + messages.info(request,"New workouts are created in the background. They will show up in the workouts list soon.") + + return HttpResponseRedirect(url) + class VideoDelete(DeleteView): login_required = True