From ee32e199fd62d16aefd1c8f0e9d97fea9850a035 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 13 Mar 2026 11:39:47 +0100 Subject: [PATCH] restored lost changes --- .../templates/export_workouts_daterange.html | 24 +++++++++ rowers/templates/rower_exportsettings.html | 4 ++ rowers/templates/workouts_export_email.html | 11 +++++ rowers/urls.py | 4 ++ rowers/views/exportviews.py | 49 +++++++++++++++++++ rowers/views/statements.py | 1 + 6 files changed, 93 insertions(+) create mode 100644 rowers/templates/export_workouts_daterange.html create mode 100644 rowers/templates/workouts_export_email.html diff --git a/rowers/templates/export_workouts_daterange.html b/rowers/templates/export_workouts_daterange.html new file mode 100644 index 00000000..178c22a2 --- /dev/null +++ b/rowers/templates/export_workouts_daterange.html @@ -0,0 +1,24 @@ +{% extends "newbase.html" %} +{% load static %} +{% load rowerfilters %} + +{% block title %}Export Workouts{% endblock %} + +{% block main %} +
+
+
+

Export All Your Workouts

+

Select a date range to export your workouts as a ZIP file containing individual CSV files.

+ +
+ {% csrf_token %} + + {{ form.as_table }} +
+ +
+
+
+
+{% endblock %} diff --git a/rowers/templates/rower_exportsettings.html b/rowers/templates/rower_exportsettings.html index ea9f09b1..539199ef 100644 --- a/rowers/templates/rower_exportsettings.html +++ b/rowers/templates/rower_exportsettings.html @@ -7,6 +7,10 @@ {% block main %}

Import and Export Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}

+

+ Export all workouts +

+
{% csrf_token %}
    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,