# Copyright (c) 2023-present Plane Software, Inc. and contributors # SPDX-License-Identifier: AGPL-3.0-only # See the LICENSE file for details. # Third party imports from rest_framework import status from rest_framework.response import Response from rest_framework.parsers import MultiPartParser, FormParser, JSONParser # Module imports from ..base import BaseAPIView, BaseViewSet from plane.db.models import FileAsset, Workspace from plane.app.serializers import FileAssetSerializer from plane.utils.file_dedup import UploadedObjectMissing, confirm_uploaded_file_asset, release_file_asset_blob class FileAssetEndpoint(BaseAPIView): parser_classes = (MultiPartParser, FormParser, JSONParser) """ A viewset for viewing and editing task instances. """ def get(self, request, workspace_id, asset_key): asset_key = str(workspace_id) + "/" + asset_key files = FileAsset.objects.filter(asset=asset_key) if files.exists(): serializer = FileAssetSerializer(files, context={"request": request}, many=True) return Response({"data": serializer.data, "status": True}, status=status.HTTP_200_OK) else: return Response( {"error": "Asset key does not exist", "status": False}, status=status.HTTP_200_OK, ) def post(self, request, slug): serializer = FileAssetSerializer(data=request.data) if serializer.is_valid(): # Get the workspace workspace = Workspace.objects.get(slug=slug) asset = serializer.save(workspace_id=workspace.id) try: confirm_uploaded_file_asset(asset, request=request) except UploadedObjectMissing: return Response( {"error": "The uploaded asset object was not found.", "status": False}, status=status.HTTP_400_BAD_REQUEST, ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, workspace_id, asset_key): asset_key = str(workspace_id) + "/" + asset_key file_asset = FileAsset.objects.get(asset=asset_key) if not file_asset.is_uploaded: release_file_asset_blob(file_asset, request=request, delete_untracked_object=True) file_asset.is_deleted = True file_asset.save(update_fields=["is_deleted", "updated_at"]) return Response(status=status.HTTP_204_NO_CONTENT) class FileAssetViewSet(BaseViewSet): def restore(self, request, workspace_id, asset_key): asset_key = str(workspace_id) + "/" + asset_key file_asset = FileAsset.objects.get(asset=asset_key) file_asset.is_deleted = False file_asset.save(update_fields=["is_deleted"]) return Response(status=status.HTTP_204_NO_CONTENT) class UserAssetsEndpoint(BaseAPIView): parser_classes = (MultiPartParser, FormParser) def get(self, request, asset_key): files = FileAsset.objects.filter(asset=asset_key, created_by=request.user) if files.exists(): serializer = FileAssetSerializer(files, context={"request": request}) return Response({"data": serializer.data, "status": True}, status=status.HTTP_200_OK) else: return Response( {"error": "Asset key does not exist", "status": False}, status=status.HTTP_200_OK, ) def post(self, request): serializer = FileAssetSerializer(data=request.data) if serializer.is_valid(): asset = serializer.save() try: confirm_uploaded_file_asset(asset, request=request) except UploadedObjectMissing: return Response( {"error": "The uploaded asset object was not found.", "status": False}, status=status.HTTP_400_BAD_REQUEST, ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, asset_key): file_asset = FileAsset.objects.get(asset=asset_key, created_by=request.user) if not file_asset.is_uploaded: release_file_asset_blob(file_asset, request=request, delete_untracked_object=True) file_asset.is_deleted = True file_asset.save(update_fields=["is_deleted", "updated_at"]) return Response(status=status.HTTP_204_NO_CONTENT)