Refactor: file api in to seperate api app & use drf api views
This commit is contained in:
parent
1f75b1bf17
commit
bd2791c155
6 changed files with 150 additions and 71 deletions
108
backend/api/files/views.py
Normal file
108
backend/api/files/views.py
Normal file
|
@ -0,0 +1,108 @@
|
|||
import os
|
||||
from django.conf import settings
|
||||
from django.http import FileResponse
|
||||
from rest_framework import status
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from sorl.thumbnail import get_thumbnail
|
||||
from apps.files.models import PostFileModel
|
||||
from .serializers import PostFileSerializer # You'll need to create this
|
||||
|
||||
THUMBNAIL_SIZES = {
|
||||
"sx": (64, ".thumb_64.jpg"),
|
||||
"sm": (256, ".thumb_256.jpg"),
|
||||
"md": (748, ".thumb_748.jpg"),
|
||||
"lg": (1024, ".thumb_1024.jpg"),
|
||||
"xl": (2048, ".thumb_2048.jpg"),
|
||||
}
|
||||
|
||||
|
||||
class FileServeView(APIView):
|
||||
"""
|
||||
API view to serve content files for download or inline viewing.
|
||||
"""
|
||||
|
||||
# Uncomment the following line if authentication is required
|
||||
# permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_thumbnail_file(self, source_path, size_key):
|
||||
"""Generates and retrieves the thumbnail file."""
|
||||
size, suffix = THUMBNAIL_SIZES.get(size_key, (None, ""))
|
||||
if size:
|
||||
thumbnail_file = get_thumbnail(source_path, str(size), upscale=False)
|
||||
return os.path.abspath(
|
||||
os.path.join(settings.MEDIA_ROOT, thumbnail_file.name)
|
||||
), suffix
|
||||
return None, ""
|
||||
|
||||
def get(self, request, file_hash):
|
||||
"""Handle GET requests for file serving."""
|
||||
download = request.query_params.get("d") == "0"
|
||||
thumbnail_key = request.query_params.get("t")
|
||||
|
||||
try:
|
||||
obj_file = PostFileModel.objects.filter(hash_blake3=file_hash).first()
|
||||
if not obj_file:
|
||||
return Response(
|
||||
{"error": "File not found"}, status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
file_name = obj_file.name.first().filename
|
||||
file_type = obj_file.file_type
|
||||
source_file = obj_file.file
|
||||
|
||||
# Use thumbnail if requested and file type is image
|
||||
if thumbnail_key and file_type != "image":
|
||||
source_file = obj_file.thumbnail
|
||||
|
||||
# Retrieve the requested thumbnail file if applicable
|
||||
if thumbnail_key in THUMBNAIL_SIZES:
|
||||
thumbnail_path, suffix = self.get_thumbnail_file(
|
||||
source_file.path, thumbnail_key
|
||||
)
|
||||
if thumbnail_path:
|
||||
file_name += suffix
|
||||
file = open(thumbnail_path, "rb")
|
||||
else:
|
||||
file = source_file.file
|
||||
else:
|
||||
file = source_file.file
|
||||
|
||||
response = FileResponse(file)
|
||||
disposition_type = "attachment" if download else "inline"
|
||||
response["Content-Disposition"] = (
|
||||
f'{disposition_type}; filename="{file_name}"'
|
||||
)
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
|
||||
class FileDetailView(APIView):
|
||||
"""
|
||||
API view to get file metadata without serving the actual file.
|
||||
"""
|
||||
|
||||
# Uncomment the following line if authentication is required
|
||||
# permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, file_hash):
|
||||
"""Return file metadata."""
|
||||
try:
|
||||
obj_file = PostFileModel.objects.filter(hash_blake3=file_hash).first()
|
||||
if not obj_file:
|
||||
return Response(
|
||||
{"error": "File not found"}, status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
serializer = PostFileSerializer(obj_file)
|
||||
return Response(serializer.data)
|
||||
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue