Upload pipeline: staging, MD5 auto-match, IQDB, three-column board
Backend: - TempUpload model: staged files (pending / visual_match / completed / error) with resolution, e621 payload, custom metadata and IQDB data - Files land in a temp folder and only move into the watched library folder once resolved; duplicates resolve immediately without a copy - Endpoints: stage (multipart), list, retrieve, temp file, IQDB save, resolve (link to post or custom metadata), discard/dismiss - cleanup_temp_uploads command for old staged files - Replaces the old direct-to-library upload endpoint Frontend: - Upload page is now a three-column board (Pending & Unmatched / Visual Similarity Detected / Auto-uploaded & Indexed) - After upload: MD5s are batch-checked against e621 and matches auto-complete with full post metadata; remaining files run through IQDB and move to the similarity column when candidates exist - Metadata modal with IQDB candidates, post-ID linking and custom tags/rating/notes; discard and dismiss actions - e621 client gains fetchPostsByMd5 and iqdbSearch helpers Roadmap updated with the completed upload items.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.library.models import TempUpload
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Delete staged uploads older than N hours (default 24)."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("--hours", type=int, default=24)
|
||||
parser.add_argument(
|
||||
"--include-completed",
|
||||
action="store_true",
|
||||
help="Also remove completed staging records.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
cutoff = timezone.now() - timedelta(hours=options["hours"])
|
||||
queryset = TempUpload.objects.filter(created_at__lt=cutoff)
|
||||
if not options["include_completed"]:
|
||||
queryset = queryset.exclude(status=TempUpload.STATUS_COMPLETED)
|
||||
|
||||
removed = 0
|
||||
for temp in queryset:
|
||||
if temp.file:
|
||||
temp.file.delete(save=False)
|
||||
temp.delete()
|
||||
removed += 1
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f"Removed {removed} staged upload(s).")
|
||||
)
|
||||
Reference in New Issue
Block a user