Make media URLs stable and cacheable, add real image thumbnails
Signed media URLs embedded the current second (TimestampSigner), so every API response re-minted every raw/thumbnail/staged URL and the browser re-downloaded each file on every poll or navigation. Responses also carried no cache headers at all. - sign with a plain Signer plus a bucket-quantized exp (7d TTL, 24h bucket), so a URL is byte-identical across responses and rotates once a day; legacy TimestampSigner URLs stay accepted for one release - add a v=<md5> version parameter to library media URLs so replacing a file under the same J-ID (the optimize flow) busts caches exactly when needed - serve_file now sends ETag/Last-Modified and a private Cache-Control and answers conditional requests with 304; library media gets max-age 6d + immutable, staged/similarity files 1h - build cached 480px JPEG thumbnails for images (Pillow, keyed by MD5 under MEDIA_ROOT/thumbs) instead of serving full-size originals through the thumbnail endpoint; the library grid uses thumbnail_url for images too
This commit is contained in:
@@ -11,7 +11,6 @@ from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import signing
|
||||
from django.utils import timezone
|
||||
from rest_framework import mixins, status, viewsets
|
||||
from rest_framework.decorators import action
|
||||
@@ -22,6 +21,7 @@ from rest_framework.response import Response
|
||||
from . import services
|
||||
from .models import MediaItem, SimilarityCheck
|
||||
from .serializers import SimilarityCheckSerializer
|
||||
from .signing_urls import load_payload
|
||||
from .tools import item_brief
|
||||
from .uploads import find_library_matches
|
||||
|
||||
@@ -149,14 +149,7 @@ class SimilarityCheckViewSet(
|
||||
check = self.get_queryset().filter(pk=pk).first()
|
||||
else:
|
||||
signature = request.query_params.get("sig")
|
||||
payload = None
|
||||
if signature:
|
||||
try:
|
||||
payload = signing.loads(
|
||||
signature, salt=services.UPLOAD_FILE_SALT, max_age=86400
|
||||
)
|
||||
except signing.BadSignature:
|
||||
payload = None
|
||||
payload = load_payload(signature, services.UPLOAD_FILE_SALT) if signature else None
|
||||
if payload and payload.get("check") == str(pk):
|
||||
check = SimilarityCheck.objects.filter(pk=pk).first()
|
||||
if check is None or not check.file:
|
||||
|
||||
Reference in New Issue
Block a user