Files
JakeBreath 1c2cb8d468 Add an ephemeral similarity check page
- /similar (nav: Similar): drop a file to get the exact MD5 match, the
  perceptual matches against the library, and e621 IQDB candidates
  (auto-run for images when credentials are configured). Read-only —
  nothing enters the library.
- SimilarityCheck model + /api/similarity/ (create/list/retrieve/delete)
  with signed preview URLs and an expires_at timestamp.
- Temp files are wiped on startup (AppConfig.ready, file-only so no
  database access during initialization), lazily past
  SIMILARITY_TTL_MINUTES (default 30, env-overridable), on delete, and
  by manage.py cleanup_similarity.
- uploadFile() takes a target path; .env.example documents the TTL.
2026-09-17 18:22:11 -05:00

47 lines
1.5 KiB
Python

from datetime import timedelta
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils import timezone
from apps.library.similarity import purge_similarity_checks
class Command(BaseCommand):
help = (
"Delete ephemeral similarity-check files. By default removes checks "
"older than SIMILARITY_TTL_MINUTES; use --all to wipe every one."
)
def add_arguments(self, parser):
parser.add_argument(
"--minutes",
type=int,
default=None,
help="Delete checks older than N minutes "
"(default: the configured TTL, currently "
f"{getattr(settings, 'SIMILARITY_TTL_MINUTES', 30)}).",
)
parser.add_argument(
"--all",
action="store_true",
help="Delete every similarity check regardless of age.",
)
def handle(self, *args, **options):
if options["all"]:
deleted = purge_similarity_checks()
scope = "all"
else:
minutes = (
options["minutes"]
if options["minutes"] is not None
else getattr(settings, "SIMILARITY_TTL_MINUTES", 30)
)
cutoff = timezone.now() - timedelta(minutes=minutes)
deleted = purge_similarity_checks(cutoff)
scope = f"older than {minutes} minute(s)"
self.stdout.write(
self.style.SUCCESS(f"Deleted {deleted} similarity check(s) ({scope}).")
)