import hashlib import os import uuid from os.path import isfile, join from django.db import models from django.urls import reverse from django.core.files import File from django.utils.translation import gettext_lazy as _ from django.db.models import Q from django.utils import timezone from imagebot import settings def get_hash(filepath): with open(filepath, 'rb') as file: # read contents of the file data = file.read() sha256 = hashlib.sha256(data).hexdigest() return sha256 class Image(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, verbose_name=_('ID')) title = models.CharField(max_length=200, help_text=_("Image title that will be posted"), blank=True, null=True) alt_text = models.TextField(help_text=_("Describe the image"), blank=True, null=True) file_path = models.CharField(max_length=1500) image = models.ImageField() file_hash = models.CharField(verbose_name=_('File hash'), max_length=64, blank=True, null=True, unique=True) last_posted = models.DateTimeField(blank=True, null=True) number_times_posted = models.IntegerField(default=0) def __str__(self): if self.title: return self.title else: return f"{self.file_hash}" def get_absolute_url(self): return reverse("image-update", args=[self.id]) def set_image_posted(self): self.number_times_posted += 1 self.last_posted = timezone.now() self.save() @staticmethod def consume(): files = [f for f in settings.MEDIA_CONSUME_DIR.iterdir() if f.is_file()] for path in files: file_hash = get_hash(path) with open(path, 'rb') as f: django_file = File(f, name=settings.MEDIA_PROCESSED_DIR_RELATIVE / path.name) img = Image.objects.create( file_path=str(path), image=django_file, file_hash=file_hash ) os.remove(path) @staticmethod def get_image_for_descriptor(): image = Image.objects.filter(Q(alt_text=None) | Q(title=None)).first() return image @staticmethod def get_image_to_post(): image = Image.objects.filter(Q(alt_text__isnull=False) & Q(title__isnull=False)).order_by('last_posted').first() return image