views.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from rest_framework import exceptions, mixins, viewsets
  2. from rest_framework.decorators import action
  3. from rest_framework.response import Response
  4. from apps.files.tasks import assemble_artifacts_task
  5. from apps.organizations_ext.models import Organization
  6. from .models import Release, ReleaseFile
  7. from .permissions import ReleaseFilePermission, ReleasePermission
  8. from .serializers import (
  9. AssembleSerializer,
  10. ReleaseFileSerializer,
  11. ReleaseSerializer,
  12. )
  13. class ReleaseViewSet(viewsets.ModelViewSet):
  14. """
  15. /organizations/<org-slug>/releases/
  16. Sentry includes only project name and slug in nested list. This view uses ProjectReferenceSerializer,
  17. which also includes id and platform, for consistency.
  18. """
  19. queryset = Release.objects.all()
  20. serializer_class = ReleaseSerializer
  21. permission_classes = [ReleasePermission]
  22. lookup_field = "version"
  23. lookup_value_regex = "[^/]+"
  24. def get_organization(self):
  25. try:
  26. return Organization.objects.get(
  27. slug=self.kwargs.get("organization_slug"),
  28. users=self.request.user,
  29. )
  30. except Organization.DoesNotExist:
  31. raise exceptions.ValidationError("Organization does not exist")
  32. @action(detail=True, methods=["post"])
  33. def assemble(self, request, organization_slug: str, version: str):
  34. organization = self.get_organization()
  35. # release = self.get_object()
  36. serializer = AssembleSerializer(data=request.data)
  37. serializer.is_valid(raise_exception=True)
  38. checksum = serializer.validated_data.get("checksum", None)
  39. chunks = serializer.validated_data.get("chunks", [])
  40. assemble_artifacts_task.delay(
  41. org_id=organization.id,
  42. version=version,
  43. checksum=checksum,
  44. chunks=chunks,
  45. )
  46. # TODO should return more state's
  47. return Response({"state": "ok", "missingChunks": []})
  48. class ReleaseFileViewSet(
  49. mixins.CreateModelMixin,
  50. mixins.DestroyModelMixin,
  51. mixins.RetrieveModelMixin,
  52. viewsets.GenericViewSet,
  53. ):
  54. queryset = ReleaseFile.objects.all()
  55. serializer_class = ReleaseFileSerializer
  56. permission_classes = [ReleaseFilePermission]
  57. def get_queryset(self):
  58. queryset = self.queryset
  59. if not self.request.user.is_authenticated:
  60. return queryset.none()
  61. queryset = queryset.filter(
  62. release__organization__users=self.request.user,
  63. release__organization__slug=self.kwargs.get("organization_slug"),
  64. release__version=self.kwargs.get("release_version"),
  65. )
  66. if self.kwargs.get("project_slug"):
  67. queryset = queryset.filter(
  68. release__projects__slug=self.kwargs.get("project_slug")
  69. )
  70. queryset = queryset.select_related("file")
  71. return queryset
  72. def perform_create(self, serializer):
  73. try:
  74. release = Release.objects.get(
  75. version=self.kwargs.get("release_version"),
  76. organization__slug=self.kwargs.get("organization_slug"),
  77. )
  78. except Release.DoesNotExist:
  79. raise exceptions.ValidationError("Release does not exist")
  80. serializer.save(release=release)