From 5a53e8f78a158c20a329794929bbb593a31cbaa5 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 20 Jan 2015 10:52:39 +0100 Subject: [PATCH] Refactoring project export --- taiga/export_import/api.py | 41 +++++++++++++------------- taiga/export_import/service.py | 1 + tests/integration/test_exporter_api.py | 2 +- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/taiga/export_import/api.py b/taiga/export_import/api.py index 15fda9ca..3e1cfbae 100644 --- a/taiga/export_import/api.py +++ b/taiga/export_import/api.py @@ -16,8 +16,8 @@ import json import codecs +import uuid -from rest_framework.exceptions import APIException from rest_framework.response import Response from rest_framework.decorators import throttle_classes from rest_framework import status @@ -27,6 +27,8 @@ from django.utils.translation import ugettext_lazy as _ from django.db.transaction import atomic from django.db.models import signals from django.conf import settings +from django.core.files.storage import default_storage +from django.core.files.base import ContentFile from taiga.base.api.mixins import CreateModelMixin from taiga.base.api.viewsets import GenericViewSet @@ -42,14 +44,11 @@ from . import permissions from . import tasks from . import dump_service from . import throttling +from .renderers import ExportRenderer from taiga.base.api.utils import get_object_or_404 -class Http400(APIException): - status_code = 400 - - class ProjectExporterViewSet(mixins.ImportThrottlingPolicyMixin, GenericViewSet): model = Project permission_classes = (permissions.ImportExportPermission, ) @@ -68,13 +67,15 @@ class ProjectExporterViewSet(mixins.ImportThrottlingPolicyMixin, GenericViewSet) tasks.delete_project_dump.apply_async((project.pk,), countdown=settings.EXPORTS_TTL) return Response({"export-id": task.id}, status=status.HTTP_202_ACCEPTED) - return Response( - service.project_to_dict(project), - status=status.HTTP_200_OK, - headers={ - "Content-Disposition": "attachment; filename={}.json".format(project.slug) - } - ) + path = "exports/{}/{}.json".format(project.pk, uuid.uuid4().hex) + content = ContentFile(ExportRenderer().render(service.project_to_dict(project), + renderer_context={"indent": 4}).decode('utf-8')) + + default_storage.save(path, content) + response_data = { + "url": default_storage.url(path) + } + return Response(response_data, status=status.HTTP_200_OK) class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixin, GenericViewSet): model = Project @@ -90,7 +91,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi project_serialized = service.store_project(data) if project_serialized is None: - raise Http400(service.get_errors()) + raise exc.BadRequest(service.get_errors()) if "points" in data: service.store_choices(project_serialized.object, data, @@ -144,7 +145,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) response_data = project_serialized.data response_data['id'] = project_serialized.object.id @@ -197,7 +198,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(issue.data) return Response(issue.data, status=status.HTTP_201_CREATED, headers=headers) @@ -212,7 +213,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(task.data) return Response(task.data, status=status.HTTP_201_CREATED, headers=headers) @@ -227,7 +228,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(us.data) return Response(us.data, status=status.HTTP_201_CREATED, headers=headers) @@ -242,7 +243,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(milestone.data) return Response(milestone.data, status=status.HTTP_201_CREATED, headers=headers) @@ -257,7 +258,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(wiki_page.data) return Response(wiki_page.data, status=status.HTTP_201_CREATED, headers=headers) @@ -272,7 +273,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi errors = service.get_errors() if errors: - raise Http400(errors) + raise exc.BadRequest(errors) headers = self.get_success_headers(wiki_link.data) return Response(wiki_link.data, status=status.HTTP_201_CREATED, headers=headers) diff --git a/taiga/export_import/service.py b/taiga/export_import/service.py index 253f8f9f..797ae81f 100644 --- a/taiga/export_import/service.py +++ b/taiga/export_import/service.py @@ -44,6 +44,7 @@ def add_errors(section, errors): else: _errors_log[section] = [errors] + def project_to_dict(project): return serializers.ProjectExportSerializer(project).data diff --git a/tests/integration/test_exporter_api.py b/tests/integration/test_exporter_api.py index edf333e4..9e25ccce 100644 --- a/tests/integration/test_exporter_api.py +++ b/tests/integration/test_exporter_api.py @@ -48,7 +48,7 @@ def test_valid_project_export_with_celery_disabled(client, settings): response = client.get(url, content_type="application/json") assert response.status_code == 200 response_data = json.loads(response.content.decode("utf-8")) - assert response_data["slug"] == project.slug + assert "url" in response_data def test_valid_project_export_with_celery_enabled(client, settings):