# Path: apps/photos/models/db.py
# class Photo(models.Model):
#     user = models.ForeignKey(
#         settings.AUTH_USER_MODEL,
#         related_name="photos",
#         on_delete=models.CASCADE,
#     )
#     # title = models.CharField(_("title"), max_length=255)
#     description = models.TextField(blank=True, default="")
# 
#     category = models.ForeignKey(
#         "Category", on_delete=models.SET_NULL, null=True, blank=True
#     )
# 
#     file = models.ImageField(upload_to=hexdigest_filename)
#     width = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
#     height = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
#     size = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
# 
#     uploaded_at = models.DateTimeField(
#         default=timezone.now, db_index=True, editable=False
#     )
# 
#     class Meta:
#         ordering = ["-exif__shot_time"]
# 
#     def __str__(self):
#         return f"{self.file.name} - {self.uploaded_at}"
# 
#     @property
#     def shape(self):
#         return self.width, self.height
# 
#     @cached_property
#     def thumb(self):
#         return self.resize_image()
# 
#     @property
#     def camera(self):
#         return self.exif.camera
# 
#     @property
#     def lens(self):
#         return self.exif.lens
# 
#     def resize_image(self, size=128):
#         _img_url = f"/upload/{size}/{self.file.name}"
#         if not debug:
#             _img_url = f"https://image.jiaxin.im{_img_url}"
#         return _img_url
# 
#     def gallery_image(self):
#         return self.resize_image(1280)
# 
#     def thumbnail_image(self):
#         return self.resize_image(600)
# 
# class Exif(models.Model):
#     photo = models.OneToOneField(
#         "Photo", related_name="exif", on_delete=models.CASCADE
#     )
#     info = JSONField(encoder=json.JSONEncoder)
# 
#     shot_time = models.DateTimeField(default=timezone.now, db_index=True)
# 
#     def __str__(self):
#         return f"{self.camera} - {self.lens}"
# 
#     @property
#     def camera(self):
#         _make = self.info.get("Make")
#         _model = self.info.get("Model")
#         return f"{_make} - {_model}"
# 
#     @property
#     def lens(self):
#         return self.info.get("LensModel")
# 
# Path: apps/photos/utils.py
# def get_exif(fp) -> dict:
#     ret = OrderedDict()
#     im = Image.open(fp)
#     info = im._getexif()
#     for tag, value in info.items():
#         decode = TAGS.get(tag, tag)
#         if decode in ["GPSInfo", "CFAPattern"]:
#             continue
#         elif decode == "ComponentsConfiguration":
#             value = process_components_configuration(value)
#         if isinstance(value, bytes):
#             _value = smart_str(value)
#         else:
#             _value = value
#         ret[decode] = _value
#     return ret


import logging
from datetime import datetime
from hashlib import md5
from django.core.cache import cache
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from .models import Photo, Exif
from .utils import get_exif



logger = logging.getLogger("django")


@receiver(pre_save, sender=Photo)
def get_photo_exif(sender, instance: Photo, raw, **kwargs):
    if isinstance(instance, sender):
        _exif = get_exif(instance.file)
        key_str = f"{instance.user_id} - {instance.uploaded_at.timestamp()}"
        key = md5(key_str.encode("utf-8")).hexdigest()
        logger.info(_exif)
        setattr(instance, "width", instance.file.width)

# Path: apps/photos/models/db.py
# class Photo(models.Model):
#     user = models.ForeignKey(
#         settings.AUTH_USER_MODEL,
#         related_name="photos",
#         on_delete=models.CASCADE,
#     )
#     # title = models.CharField(_("title"), max_length=255)
#     description = models.TextField(blank=True, default="")
# 
#     category = models.ForeignKey(
#         "Category", on_delete=models.SET_NULL, null=True, blank=True
#     )
# 
#     file = models.ImageField(upload_to=hexdigest_filename)
#     width = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
#     height = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
#     size = models.PositiveIntegerField(
#         default=0, editable=False, db_index=True
#     )
# 
#     uploaded_at = models.DateTimeField(
#         default=timezone.now, db_index=True, editable=False
#     )
# 
#     class Meta:
#         ordering = ["-exif__shot_time"]
# 
#     def __str__(self):
#         return f"{self.file.name} - {self.uploaded_at}"
# 
#     @property
#     def shape(self):
#         return self.width, self.height
# 
#     @cached_property
#     def thumb(self):
#         return self.resize_image()
# 
#     @property
#     def camera(self):
#         return self.exif.camera
# 
#     @property
#     def lens(self):
#         return self.exif.lens
# 
#     def resize_image(self, size=128):
#         _img_url = f"/upload/{size}/{self.file.name}"
#         if not debug:
#             _img_url = f"https://image.jiaxin.im{_img_url}"
#         return _img_url
# 
#     def gallery_image(self):
#         return self.resize_image(1280)
# 
#     def thumbnail_image(self):
#         return self.resize_image(600)
# 
# class Exif(models.Model):
#     photo = models.OneToOneField(
#         "Photo", related_name="exif", on_delete=models.CASCADE
#     )
#     info = JSONField(encoder=json.JSONEncoder)
# 
#     shot_time = models.DateTimeField(default=timezone.now, db_index=True)
# 
#     def __str__(self):
#         return f"{self.camera} - {self.lens}"
# 
#     @property
#     def camera(self):
#         _make = self.info.get("Make")
#         _model = self.info.get("Model")
#         return f"{_make} - {_model}"
# 
#     @property
#     def lens(self):
#         return self.info.get("LensModel")
# 
# Path: apps/photos/utils.py
# def get_exif(fp) -> dict:
#     ret = OrderedDict()
#     im = Image.open(fp)
#     info = im._getexif()
#     for tag, value in info.items():
#         decode = TAGS.get(tag, tag)
#         if decode in ["GPSInfo", "CFAPattern"]:
#             continue
#         elif decode == "ComponentsConfiguration":
#             value = process_components_configuration(value)
#         if isinstance(value, bytes):
#             _value = smart_str(value)
#         else:
#             _value = value
#         ret[decode] = _value
#     return ret


# Path: apps/photos/signals.py
import logging
from datetime import datetime
from hashlib import md5
from django.core.cache import cache
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from .models import Photo, Exif
from .utils import get_exif




logger = logging.getLogger("django")


@receiver(pre_save, sender=Photo)
def get_photo_exif(sender, instance: Photo, raw, **kwargs):
    if isinstance(instance, sender):
        _exif = get_exif(instance.file)
        key_str = f"{instance.user_id} - {instance.uploaded_at.timestamp()}"
        key = md5(key_str.encode("utf-8")).hexdigest()
        logger.info(_exif)
        setattr(instance, "width", instance.file.width)

        setattr(instance, "height", instance.file.height)