Fix hidden library items not rendering in the browser

Items flagged hidden_from_guests (blacklisted tags) returned 404 for
<img> requests since tags cannot send the auth header. The API now
exposes signed raw_url/thumbnail_url fields (mirroring upload previews
and avatars), and the SPA uses them in the gallery, detail view,
duplicates and delete screens, and upload visual matches.
This commit is contained in:
2026-09-17 13:25:20 -05:00
parent 4df573da43
commit db74f7ab18
11 changed files with 88 additions and 24 deletions
+11 -5
View File
@@ -14,6 +14,7 @@ from rest_framework.views import APIView
from .models import TAG_CLOUD_CACHE_KEYS, MediaItem, MediaLocation
from .permissions import CanUpload
from .services import signed_media_url
logger = logging.getLogger(__name__)
@@ -85,9 +86,10 @@ def display_rating(item):
return rating if rating in {"s", "q", "e"} else ""
def item_brief(item):
def item_brief(item, request=None):
locations = list(item.locations.all())
location = locations[0] if locations else None
user = getattr(request, "user", None)
return {
"j_id": f"J-{item.id}",
"md5": item.md5,
@@ -97,6 +99,7 @@ def item_brief(item):
"location_count": len(locations),
"uploaded_by": item.uploaded_by.username if item.uploaded_by else None,
"e621_post_id": item.e621_post_id,
"thumbnail_url": signed_media_url(item, user, "thumbnail"),
}
@@ -128,7 +131,7 @@ class ExactDuplicatesView(APIView):
)
groups = []
for item in items:
brief = item_brief(item)
brief = item_brief(item, request)
brief["locations"] = [
{"id": location.id, "rel_path": location.rel_path}
for location in item.locations.all()
@@ -159,14 +162,14 @@ class VisualMatchesView(APIView):
similarity = similarity_between(target, item, algorithms, threshold)
if similarity is None:
continue
brief = item_brief(item)
brief = item_brief(item, request)
brief["similarity"] = round(similarity * 100, 1)
matches.append(brief)
matches.sort(key=lambda entry: entry["similarity"], reverse=True)
return Response(
{
"target": item_brief(target),
"target": item_brief(target, request),
"threshold": round(threshold * 100, 1),
"algorithms": algorithms,
"count": len(matches),
@@ -236,7 +239,10 @@ class VisualGroupsView(APIView):
"threshold": round(threshold * 100, 1),
"algorithms": algorithms,
"groups": [
{"size": len(members), "members": [item_brief(item) for item in members]}
{
"size": len(members),
"members": [item_brief(item, request) for item in members],
}
for members in page_groups
],
}