diff --git a/rowers/templates/workouts_export_email.html b/rowers/templates/workouts_export_email.html new file mode 100644 index 00000000..42ced93d --- /dev/null +++ b/rowers/templates/workouts_export_email.html @@ -0,0 +1,11 @@ +{% extends "emailbase.html" %} +{% block body %} +

    + You can download the file {{ filename }} from the following link: {{ download_url }}. The file will be deleted after downloading, so please make sure to download it as soon as possible. +

    + + +

    + Best Regards, the Rowsandall Team +

    +{% endblock %} diff --git a/rowers/urls.py b/rowers/urls.py index b92ea953..19d499f9 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -434,6 +434,10 @@ urlpatterns = [ name='create_marker_workouts_view'), re_path(r'^createmarkerworkouts/$', views.create_marker_workouts_view, name='create_marker_workouts_view'), + re_path(r'^workouts/alluserworkouts/$', views.export_all_workouts_zip_view, + name='workout_export_all_workouts_zip_view'), + re_path(r'^workouts/download/$', views.download_zip_file_view, + name='download_zip_file_view'), re_path(r'^goldmedalscores/$', views.goldmedalscores_view, name='goldmedalscores_view'), re_path(r'^goldmedalscores/user/(?P\d+)/$', diff --git a/rowers/views/exportviews.py b/rowers/views/exportviews.py index 3504e59f..0b62bdc2 100644 --- a/rowers/views/exportviews.py +++ b/rowers/views/exportviews.py @@ -273,6 +273,53 @@ def workout_csvemail_view(request, id=0): return response +import io + +# Export all workouts as ZIP file with individual CSV files +@login_required() +def export_all_workouts_zip_view(request): + from datetime import datetime + r = getrower(request.user) + + if request.method == 'GET': + form = DateRangeForm() + elif request.method == 'POST': + form = DateRangeForm(request.POST) + if not form.is_valid(): + messages.error(request, "Invalid date range. Please try again.") + return render(request, "export_workouts_daterange.html", {'form': form}) + + startdate = form.cleaned_data['startdate'] + enddate = form.cleaned_data['enddate'] + + myqueue(queuehigh, email_all_user_workouts_zip, r, startdate, enddate) + + successmessage = "A download link will be sent to you per email" + messages.info(request, successmessage) + + # return to export settings view + return render(request, "export_workouts_daterange.html", {'form': form}) + +def download_zip_file_view(request): + # This view would be called when the user clicks the download link in the email + zip_file_path = request.GET.get('file') + print("Requested ZIP file path:", zip_file_path) # Debugging statement + # add media folder + zip_file_path = os.path.join(settings.MEDIA_ROOT, zip_file_path) + + if not zip_file_path or not os.path.exists(zip_file_path): + messages.error(request, "The requested file does not exist.") + return HttpResponseRedirect(reverse('workouts_view')) + + with open(zip_file_path, 'rb') as f: + response = HttpResponse(f.read(), content_type='application/zip') + response['Content-Disposition'] = f'attachment; filename="{os.path.basename(zip_file_path)}"' + + # remove the file after sending + os.remove(zip_file_path) + + return response + # Get Workout CSV file and send it to user's email address @login_required() @@ -297,3 +344,5 @@ def workout_csvtoadmin_view(request, id=0): # pragma: no cover response = HttpResponseRedirect(url) return response + + diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 84a62fdb..55988dae 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -254,6 +254,7 @@ from rowers.rows import handle_uploaded_file, handle_uploaded_image from rowers.plannedsessions import * from rowers.tasks import handle_makeplot, handle_otwsetpower, handle_sendemailtcx, handle_sendemailcsv from rowers.tasks import ( + email_all_user_workouts_zip, handle_intervals_updateworkout, handle_post_workout_api, handle_sendemail_newftp, From fbc802a65e7d40039b310a9e7588b808d0effb16 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 13 Mar 2026 11:50:36 +0100 Subject: [PATCH 3/3] export --- 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 a3ba1af581198d9007d1bb0452bee681985a3c3a..326f589b17bad76d0ee1794422a241415dcc4adf 100644 GIT binary patch delta 16 XcmbO#KUJPxzMF&N*UQZt+57kbFjxi^ delta 16 XcmbO#KUJPxzMF$1Z<5