Online browser + post detail: SPA talks to e621 directly
Backend:
- POST /api/files/lookup/ reports which MD5s are already in the library
Frontend:
- e621 client extended with post/tag/favorite types and helpers: post
search, post detail, batch posts by id, tag autocomplete, toggle
favorite
- /online: tag search with autocomplete, post grid with rating colors
and in-library badges, numbered pagination, page tag cloud, blacklist
panel and filtered counts from /users/me.json, anonymous hint
- /online/view/🆔 media viewer (sample or original, video support),
taxonomy-colored tags by category, specs sheet, favorite/unfavorite,
description, sources, pools and parent/children thumbnails
- Shared CollapsibleSidebar extracted from the library page; Online
added to the nav, command palette and sidebar toggle
This commit is contained in:
@@ -5,7 +5,7 @@ from django.db.models import Min
|
||||
from rest_framework import mixins, status, viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.parsers import FormParser, MultiPartParser
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
@@ -24,7 +24,7 @@ class MediaItemViewSet(
|
||||
):
|
||||
serializer_class = MediaItemSerializer
|
||||
lookup_field = "md5"
|
||||
http_method_names = ["get", "patch", "head", "options"]
|
||||
http_method_names = ["get", "post", "patch", "head", "options"]
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = MediaItem.objects.prefetch_related("locations").annotate(
|
||||
@@ -79,6 +79,19 @@ class MediaItemViewSet(
|
||||
return services.serve_file(request, thumbnail)
|
||||
return services.serve_file(request, path)
|
||||
|
||||
@action(detail=False, methods=["post"], permission_classes=[AllowAny])
|
||||
def lookup(self, request):
|
||||
"""Return which of the given MD5s already exist in the library."""
|
||||
md5s = request.data.get("md5s")
|
||||
if not isinstance(md5s, list):
|
||||
return Response(
|
||||
{"detail": "md5s must be a list."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
wanted = {str(value).strip().lower()[:32] for value in md5s if value}
|
||||
found = MediaItem.objects.filter(md5__in=wanted).values_list("md5", flat=True)
|
||||
return Response({"found": sorted(found)})
|
||||
|
||||
@action(detail=True, methods=["get"])
|
||||
def neighbors(self, request, md5=None):
|
||||
"""Previous/next items in the ordered list, for keyboard navigation."""
|
||||
|
||||
Reference in New Issue
Block a user