toolshed/backend/files/media_urls.py
2026-08-01 16:03:35 +02:00

51 lines
2.1 KiB
Python

from django.http import HttpResponse
from django.urls import path
from django.db.models import Q
from django.conf import settings
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from authentication.signature_auth import SignatureAuthentication
from files.models import File
@swagger_auto_schema(method='GET', auto_schema=None)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
@authentication_classes([SignatureAuthentication])
def media_urls(request, hash_path):
# Note: CORS headers are NOT set here - django-cors-headers (CorsMiddleware,
# configured in settings.py) adds them to every Django response automatically, so
# setting them manually on these responses would just be redundant. The one exception
# is the SERVE_X_ACCEL_REDIRECT path: nginx replaces this response entirely when it
# follows the X-Accel-Redirect and serves the file itself, so the CORS header for that
# case has to be configured in nginx's `location /redirect_media/` block instead.
try:
file = File.objects.filter(
Q(connected_items__owner__in=request.user.friends_or_self()) |
Q(profile_picture_users__in=request.user.friends_or_self())
).distinct().get(
file=hash_path)
if settings.SERVE_X_ACCEL_REDIRECT:
return HttpResponse(status=status.HTTP_200_OK,
content_type=file.mime_type,
headers={
'X-Accel-Redirect': f'/redirect_media/{hash_path}',
}) # TODO Expires and Cache-Control
else:
return HttpResponse(status=status.HTTP_200_OK,
content_type=file.mime_type,
content=open(file.file.path, 'rb').read())
except File.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
urlpatterns = [
path('<path:hash_path>', media_urls),
]