from django.core.management.base import BaseCommand from django.db.models import Q from apps.library.models import MediaItem from apps.library.services import HASH_FIELDS, ensure_visual_hashes class Command(BaseCommand): help = "Compute perceptual hashes for library items missing them." def add_arguments(self, parser): parser.add_argument( "--force", action="store_true", help="Recompute hashes even when they already exist.", ) def handle(self, *args, **options): queryset = MediaItem.objects.prefetch_related("locations").order_by("id") if not options["force"]: missing = Q() for field in HASH_FIELDS: missing |= Q(**{field: ""}) queryset = queryset.filter(missing) total = queryset.count() if total == 0: self.stdout.write(self.style.SUCCESS("All items already have hashes.")) return self.stdout.write(f"Computing hashes for {total} item(s) ...") done = 0 for item in queryset.iterator(chunk_size=100): if options["force"]: item.ahash = item.dhash = item.phash = item.whash = "" ensure_visual_hashes(item) done += 1 if done % 100 == 0: self.stdout.write(f"Processed {done} ...") self.stdout.write( self.style.SUCCESS(f"Done. Processed {done} item(s).") )