|
1 | 1 | import io |
2 | | -import urllib.parse |
3 | 2 |
|
4 | 3 | from django.contrib.auth import get_user_model |
5 | 4 | from django.db import IntegrityError, transaction |
6 | 5 | from django.db.models import Exists, OuterRef, Prefetch |
7 | | -from django.http import FileResponse, HttpResponse |
8 | 6 | from django.shortcuts import get_object_or_404 |
9 | 7 | from django.utils import timezone |
10 | 8 | from django.utils.timezone import now |
|
20 | 18 |
|
21 | 19 | from core.serializers import EmptySerializer, SetLikedSerializer, SetViewedSerializer |
22 | 20 | from core.services import add_view, set_like |
23 | | -from core.utils import XlsxFileToExport, ascii_filename, sanitize_filename |
| 21 | +from core.utils import ( |
| 22 | + XlsxFileToExport, |
| 23 | + build_xlsx_download_response, |
| 24 | + sanitize_excel_value, |
| 25 | +) |
24 | 26 | from partner_programs.helpers import date_to_iso |
25 | 27 | from partner_programs.models import ( |
26 | 28 | PartnerProgram, |
|
50 | 52 | build_program_field_columns, |
51 | 53 | prepare_project_scores_export_data, |
52 | 54 | row_dict_for_link, |
53 | | - sanitize_excel_value, |
54 | 55 | ) |
55 | 56 | from partner_programs.utils import filter_program_projects_by_field_name |
56 | 57 | from projects.models import Collaborator, Project |
@@ -655,20 +656,7 @@ def get(self, request, pk: int): |
655 | 656 |
|
656 | 657 | date_suffix = timezone.now().strftime("%d.%m.%y") |
657 | 658 | base_name = f"scores - {program.name or 'program'} - {date_suffix}" |
658 | | - safe_name = sanitize_filename(base_name) |
659 | | - filename = f"{safe_name}.xlsx" |
660 | | - encoded_file_name: str = urllib.parse.quote(filename) |
661 | | - fallback_filename = f"{ascii_filename(base_name)}.xlsx" |
662 | | - response = HttpResponse( |
663 | | - binary_data_to_export, |
664 | | - content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
665 | | - ) |
666 | | - response["Content-Disposition"] = ( |
667 | | - "attachment; " |
668 | | - f"filename=\"{fallback_filename}\"; " |
669 | | - f"filename*=UTF-8''{encoded_file_name}" |
670 | | - ) |
671 | | - return response |
| 659 | + return build_xlsx_download_response(binary_data_to_export, base_name=base_name) |
672 | 660 |
|
673 | 661 |
|
674 | 662 | class PartnerProgramExportProjectsAPIView(APIView): |
@@ -732,23 +720,7 @@ def _export(self, program: PartnerProgram, only_submitted: bool): |
732 | 720 | label = "projects_review" if only_submitted else "projects" |
733 | 721 | date_suffix = timezone.now().strftime("%d.%m.%y") |
734 | 722 | base_name = f"{label} - {program.name or 'program'} - {date_suffix}" |
735 | | - fname_base = sanitize_filename(base_name) |
736 | | - filename = f"{fname_base}.xlsx" |
737 | | - encoded_file_name: str = urllib.parse.quote(filename) |
738 | | - fallback_filename = f"{ascii_filename(base_name)}.xlsx" |
739 | | - |
740 | | - response = FileResponse( |
741 | | - bio, |
742 | | - as_attachment=True, |
743 | | - filename=filename, |
744 | | - content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
745 | | - ) |
746 | | - response["Content-Disposition"] = ( |
747 | | - "attachment; " |
748 | | - f"filename=\"{fallback_filename}\"; " |
749 | | - f"filename*=UTF-8''{encoded_file_name}" |
750 | | - ) |
751 | | - return response |
| 723 | + return build_xlsx_download_response(bio.getvalue(), base_name=base_name) |
752 | 724 |
|
753 | 725 | def get(self, request, pk: int): |
754 | 726 | program = self._get_program(pk) |
|
0 commit comments