chore: storing and streaming binary response

This commit is contained in:
NarayanBavisetti 2024-05-27 18:32:11 +05:30
parent 65fd124864
commit 1573db24c5
5 changed files with 124 additions and 5 deletions

View File

@ -4,6 +4,7 @@ from django.urls import path
from plane.app.views import ( from plane.app.views import (
InboxViewSet, InboxViewSet,
InboxIssueViewSet, InboxIssueViewSet,
InboxIssueDescriptionViewSet,
) )
@ -50,4 +51,14 @@ urlpatterns = [
), ),
name="inbox-issue", name="inbox-issue",
), ),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/inbox-issues/<uuid:issue_id>/description/",
InboxIssueDescriptionViewSet.as_view(
{
"get": "retrieve",
"patch": "partial_update",
}
),
name="inbox-issue-description",
),
] ]

View File

@ -19,6 +19,7 @@ from plane.app.views import (
IssueUserDisplayPropertyEndpoint, IssueUserDisplayPropertyEndpoint,
IssueViewSet, IssueViewSet,
LabelViewSet, LabelViewSet,
IssueDescriptionViewSet,
) )
urlpatterns = [ urlpatterns = [
@ -49,6 +50,16 @@ urlpatterns = [
), ),
name="project-issue", name="project-issue",
), ),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:pk>/description/",
IssueDescriptionViewSet.as_view(
{
"get": "retrieve",
"patch": "partial_update",
}
),
name="issue-description",
),
path( path(
"workspaces/<str:slug>/projects/<uuid:project_id>/issue-labels/", "workspaces/<str:slug>/projects/<uuid:project_id>/issue-labels/",
LabelViewSet.as_view( LabelViewSet.as_view(

View File

@ -106,6 +106,7 @@ from .issue.base import (
IssueListEndpoint, IssueListEndpoint,
IssueViewSet, IssueViewSet,
IssueUserDisplayPropertyEndpoint, IssueUserDisplayPropertyEndpoint,
IssueDescriptionViewSet,
BulkDeleteIssuesEndpoint, BulkDeleteIssuesEndpoint,
) )
@ -192,7 +193,11 @@ from .estimate.base import (
BulkEstimatePointEndpoint, BulkEstimatePointEndpoint,
) )
from .inbox.base import InboxViewSet, InboxIssueViewSet from .inbox.base import (
InboxViewSet,
InboxIssueViewSet,
InboxIssueDescriptionViewSet,
)
from .analytic.base import ( from .analytic.base import (
AnalyticsEndpoint, AnalyticsEndpoint,

View File

@ -1,5 +1,6 @@
# Python imports # Python imports
import json import json
import base64
# Django import # Django import
from django.utils import timezone from django.utils import timezone
@ -9,6 +10,7 @@ from django.contrib.postgres.aggregates import ArrayAgg
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.db.models import Value, UUIDField from django.db.models import Value, UUIDField
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.http import StreamingHttpResponse
# Third party imports # Third party imports
from rest_framework import status from rest_framework import status
@ -578,3 +580,48 @@ class InboxIssueViewSet(BaseViewSet):
inbox_issue.delete() inbox_issue.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
class InboxIssueDescriptionViewSet(BaseViewSet):
permission_classes = [
ProjectLitePermission,
]
def retrieve(self, request, slug, project_id, pk):
issue = Issue.objects.get(
pk=pk, workspace__slug=slug, project_id=project_id
)
binary_data = issue.description_binary
def stream_data():
if binary_data:
yield binary_data
else:
yield b""
response = StreamingHttpResponse(
stream_data(), content_type="application/octet-stream"
)
response["Content-Disposition"] = (
'attachment; filename="issue_description.bin"'
)
return response
def partial_update(self, request, slug, project_id, pk):
issue = Issue.objects.get(
pk=pk, workspace__slug=slug, project_id=project_id
)
base64_data = request.data.get("description_binary")
if base64_data:
# Decode the base64 data to bytes
new_binary_data = base64.b64decode(base64_data)
# Store the updated binary data
issue.description_binary = new_binary_data
issue.description_html = request.data.get("description_html")
issue.save()
return Response({"message": "Updated successfully"})
else:
return Response({"error": "No binary data provided"})

View File

@ -1,6 +1,8 @@
# Python imports # Python imports
import json import json
import base64
# Django imports
from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.aggregates import ArrayAgg
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
@ -19,16 +21,14 @@ from django.db.models import (
When, When,
) )
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.http import StreamingHttpResponse
# Django imports
from django.utils import timezone from django.utils import timezone
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page from django.views.decorators.gzip import gzip_page
from rest_framework import status
# Third Party imports # Third Party imports
from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from plane.app.permissions import ( from plane.app.permissions import (
ProjectEntityPermission, ProjectEntityPermission,
ProjectLitePermission, ProjectLitePermission,
@ -674,3 +674,48 @@ class BulkDeleteIssuesEndpoint(BaseAPIView):
{"message": f"{total_issues} issues were deleted"}, {"message": f"{total_issues} issues were deleted"},
status=status.HTTP_200_OK, status=status.HTTP_200_OK,
) )
class IssueDescriptionViewSet(BaseViewSet):
permission_classes = [
ProjectEntityPermission,
]
def retrieve(self, request, slug, project_id, pk):
issue = Issue.objects.get(
pk=pk, workspace__slug=slug, project_id=project_id
)
binary_data = issue.description_binary
def stream_data():
if binary_data:
yield binary_data
else:
yield b""
response = StreamingHttpResponse(
stream_data(), content_type="application/octet-stream"
)
response["Content-Disposition"] = (
'attachment; filename="issue_description.bin"'
)
return response
def partial_update(self, request, slug, project_id, pk):
issue = Issue.objects.get(
pk=pk, workspace__slug=slug, project_id=project_id
)
base64_data = request.data.get("description_binary")
if base64_data:
# Decode the base64 data to bytes
new_binary_data = base64.b64decode(base64_data)
# Store the updated binary data
issue.description_binary = new_binary_data
issue.description_html = request.data.get("description_html")
issue.save()
return Response({"message": "Updated successfully"})
else:
return Response({"error": "No binary data provided"})