summaryrefslogtreecommitdiff
path: root/app/media/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/media/models.py')
-rw-r--r--app/media/models.py215
1 files changed, 130 insertions, 85 deletions
diff --git a/app/media/models.py b/app/media/models.py
index 190026f..dcf7ccc 100644
--- a/app/media/models.py
+++ b/app/media/models.py
@@ -1,28 +1,28 @@
import os.path
import io
import datetime
+from pathlib import Path
from PIL import Image
from django.core.exceptions import ValidationError
-from django.db import models
+from django.contrib.gis.db import models
from django.contrib.sitemaps import Sitemap
-from django.utils.encoding import force_text
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+from django.db.models.signals import m2m_changed
from django.utils.functional import cached_property
from django.urls import reverse
from django.apps import apps
from django.utils.html import format_html
-from django.utils.text import slugify
from django.conf import settings
from django import forms
-from taggit.managers import TaggableManager
-
from resizeimage.imageexceptions import ImageSizeError
+from taggit.managers import TaggableManager
+
+from .readexif import readexif
from .utils import resize_image
-from django.db.models.signals import post_save
-from django.dispatch import receiver
-from django.db.models.signals import m2m_changed
def get_upload_path(self, filename):
@@ -39,6 +39,7 @@ def get_audio_upload_path(self, filename):
class LuxImageSize(models.Model):
name = models.CharField(null=True, blank=True, max_length=30)
+ slug = models.SlugField(null=True, blank=True)
width = models.IntegerField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
quality = models.IntegerField()
@@ -63,10 +64,21 @@ class LuxImage(models.Model):
photo_credit_url = models.CharField(null=True, blank=True, max_length=300)
caption = models.TextField(blank=True, null=True)
pub_date = models.DateTimeField(default=datetime.datetime.now)
+ exif_raw = models.TextField(blank=True, null=True)
+ exif_aperture = models.CharField(max_length=50, blank=True, null=True)
+ exif_make = models.CharField(max_length=50, blank=True, null=True)
+ exif_model = models.CharField(max_length=50, blank=True, null=True)
+ exif_exposure = models.CharField(max_length=50, blank=True, null=True)
+ exif_iso = models.CharField(max_length=50, blank=True, null=True)
+ exif_focal_length = models.CharField(max_length=50, blank=True, null=True)
+ exif_lens = models.CharField(max_length=50, blank=True, null=True)
+ exif_date = models.DateTimeField(blank=True, null=True)
height = models.CharField(max_length=6, blank=True, null=True)
width = models.CharField(max_length=6, blank=True, null=True)
+ point = models.PointField(null=True, blank=True)
is_public = models.BooleanField(default=True)
- sizes = models.ManyToManyField(LuxImageSize, blank=True)
+ sizes = models.ManyToManyField(LuxImageSize, blank=True, related_name='sizes')
+ sizes_cache = models.CharField(null=True, blank=True, max_length=300)
class Meta:
ordering = ('-pub_date', 'id')
@@ -85,10 +97,7 @@ class LuxImage(models.Model):
def get_admin_image(self):
for size in self.sizes.all():
if size.width and size.width <= 820 or size.height and size.height <= 800:
- return self.get_image_by_size(size.name)
-
- def get_admin_insert(self):
- return "/media/images/%s/%s_tn.%s" % (self.pub_date.strftime("%Y"), self.get_image_name(), self.get_image_ext())
+ return self.get_image_url_by_size(size.name)
def get_largest_image(self):
t = []
@@ -98,74 +107,70 @@ class LuxImage(models.Model):
t.reverse()
return self.get_image_path_by_size(t[0])
- def get_image_name(self):
- return self.image.url.split("original/")[1][5:-4]
-
- def get_image_ext(self):
- return self.image.url[-3:]
-
@cached_property
- def get_featured_jrnl(self):
- ''' cached version of getting the primary image for archive page'''
- return "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.get_image_name(), 'featured_jrnl', self.get_image_ext())
+ def image_name(self):
+ return os.path.basename(self.image.path)[:-4]
@cached_property
- def get_picwide_sm(self):
- ''' cached version of getting the second image for archive page'''
- return "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.get_image_name(), 'picwide-sm', self.get_image_ext())
+ def image_ext(self):
+ return self.image.url[-3:]
@cached_property
+ def get_image_filename(self):
+ return os.path.basename(self.image.path)
+
+ @property
def get_srcset(self):
srcset = ""
length = len(self.sizes.all())
print(length)
loopnum = 1
for size in self.sizes.all():
- srcset += "%s%s/%s_%s.%s %sw" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.get_image_name(), size.name, self.get_image_ext(), size.width)
+ srcset += "%s%s/%s_%s.%s %sw" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.image_name, size.slug, self.image_ext, size.width)
if loopnum < length:
srcset += ", "
loopnum = loopnum+1
return srcset
- @cached_property
+ @property
def get_src(self):
src = ""
if self.sizes.all().count() > 1:
- src += "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.get_image_name(), 'picwide-med', self.get_image_ext())
+ src = self.get_image_url_by_size('picwide-med')
else:
- src += "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.get_image_name(), [size.name for size in self.sizes.all()], self.get_image_ext())
+ size = "".join(size.name for size in self.sizes.all())
+ src = self.get_image_url_by_size(size)
return src
- def get_image_by_size(self, size="original"):
- base = self.get_image_name()
- if size == "admin_insert":
- return "images/%s/%s.%s" % (self.pub_date.strftime("%Y"), base, self.get_image_ext())
+ def get_image_url_by_size(self, size="original"):
if size == "original":
- return "%soriginal/%s/%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, self.get_image_ext())
+ return "%soriginal/%s/%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.image_name, self.image_ext)
+ if size == "admin_insert":
+ return "images/%s/%s.%s" % (self.pub_date.strftime("%Y"), self.image_name, self.image_ext)
else:
- if size != 'tn':
- s = LuxImageSize.objects.get(name=size)
- if s not in self.sizes.all():
- print("new size is "+s.name)
- self.sizes.add(s)
- return "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, size, self.get_image_ext())
+ luximagesize = LuxImageSize.objects.get(slug=size)
+ #if luximagesize not in self.get_sizes:
+ #self.sizes.add(luximagesize)
+ return "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.image_name, luximagesize.slug, self.image_ext)
def get_image_path_by_size(self, size="original"):
- base = self.get_image_name()
if size == "original":
- return "%s/original/%s/%s.%s" % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), base, self.get_image_ext())
+ return self.image.path
else:
- return "%s/%s/%s_%s.%s" % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), base, size, self.get_image_ext())
+ luximagesize = LuxImageSize.objects.get(slug=size)
+ return "%s/%s/%s_%s.%s" % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), self.image_name, luximagesize.slug, self.image_ext)
+ @cached_property
def get_thumbnail_url(self):
- return self.get_image_by_size("tn")
+ return self.get_image_url_by_size("tn")
def admin_thumbnail(self):
- return format_html('<a href="%s"><img src="%s"></a>' % (self.get_image_by_size(), self.get_image_by_size("tn")))
+ return format_html('<a href="%s"><img src="%s"></a>' % (self.get_image_url_by_size(), self.get_image_url_by_size("tn")))
admin_thumbnail.short_description = 'Thumbnail'
+ @property
def get_sizes(self):
- return self.sizes.all()
+ return self.sizes_cache.split(",")
@property
def get_previous_published(self):
@@ -196,6 +201,9 @@ class LuxImage(models.Model):
return False
def save(self, *args, **kwargs):
+ created = self.pk is None
+ if not created:
+ self.sizes_cache = ",".join(s.slug for s in self.sizes.all())
super(LuxImage, self).save()
@@ -270,6 +278,7 @@ class LuxAudio(models.Model):
pub_date = models.DateTimeField(default=datetime.datetime.now)
mp3 = models.FileField(blank=True, null=True, upload_to=get_audio_upload_path)
ogg = models.FileField(blank=True, null=True, upload_to=get_audio_upload_path)
+ point = models.PointField(blank=True, null=True)
class Meta:
ordering = ('-pub_date',)
@@ -283,6 +292,9 @@ class LuxAudio(models.Model):
def get_absolute_url(self):
return reverse("prompt:detail", kwargs={"slug": self.slug})
+ def get_image_url_by_size(self, size="original"):
+ pass
+
@property
def get_previous_published(self):
return self.get_previous_by_pub_date(status__exact=1)
@@ -310,51 +322,84 @@ class LuxAudio(models.Model):
def save(self, *args, **kwargs):
md = render_images(self.body_markdown)
self.body_html = markdown_to_html(md)
+ if not self.point:
+ self.point = CheckIn.objects.latest().point
super(LuxAudio, self).save(*args, **kwargs)
@receiver(post_save, sender=LuxImage)
def post_save_events(sender, update_fields, created, instance, **kwargs):
- if instance.exif_raw == '':
- filename, file_extension = os.path.splitext(instance.image.path)
- if file_extension != ".mp4":
- img = Image.open(instance.image.path)
- instance.height = img.height
- instance.width = img.width
- post_save.disconnect(post_save_events, sender=LuxImage)
- instance.save()
- post_save.connect(post_save_events, sender=LuxImage)
+ if created:
+ if instance.exif_raw == '':
+ instance = readexif(instance)
+ instance.sizes.add(LuxImageSize.objects.get(slug="tn"))
+ img = Image.open(instance.image.path)
+ instance.height = img.height
+ instance.width = img.width
+ post_save.disconnect(post_save_events, sender=LuxImage)
+ instance.save()
+ post_save.connect(post_save_events, sender=LuxImage)
@receiver(m2m_changed, sender=LuxImage.sizes.through)
def update_photo_sizes(sender, instance, **kwargs):
- base_path = "%s/%s/" % (settings.IMAGES_ROOT, instance.pub_date.strftime("%Y"))
- filename, file_extension = os.path.splitext(instance.image.path)
- if file_extension != ".mp4":
- img = Image.open(instance.image.path)
- resize_image(img, 160, None, 78, base_path, "%s_tn.%s" % (instance.get_image_name(), instance.get_image_ext()))
- for size in instance.sizes.all():
- if size.width:
- print("Image width is:"+str(img.width))
- try:
- if size.width <= img.width:
- resize_image(img, size.width, None, size.quality, base_path, "%s_%s.%s" % (instance.get_image_name(), slugify(size.name), instance.get_image_ext()))
- else:
- raise ValidationError({'items': ["Size is larger than source image"]})
- except ImageSizeError:
- m2m_changed.disconnect(update_photo_sizes, sender=LuxImage.sizes.through)
- instance.sizes.remove(size)
- m2m_changed.connect(update_photo_sizes, sender=LuxImage.sizes.through)
- if size.height:
- try:
- if size.height <= img.height:
- resize_image(img, None, size.height, size.quality, base_path, "%s_%s.%s" % (instance.get_image_name(), slugify(size.name), instance.get_image_ext()))
-
- else:
- pass
- except ImageSizeError:
- m2m_changed.disconnect(update_photo_sizes, sender=LuxImage.sizes.through)
- instance.sizes.remove(size)
- m2m_changed.connect(update_photo_sizes, sender=LuxImage.sizes.through)
-
-
+ # update the local cache of sizes
+ sizes = instance.sizes.all()
+ if sizes:
+ instance.sizes_cache = ",".join(s.slug for s in sizes)
+ instance.save()
+ for size in instance.get_sizes:
+ print("SIZE is: %s" % size)
+ # check each size and see if there's an image there already
+ my_file = Path(instance.get_image_path_by_size(size))
+ if not my_file.is_file():
+ #file doesn't exist, so create it
+ new_size = LuxImageSize.objects.get(slug=size)
+ if new_size.width:
+ img = Image.open(instance.image.path)
+ try:
+ if new_size.width <= img.width:
+ resize_image(img, new_size.width, None, new_size.quality, instance.get_image_path_by_size(size))
+ else:
+ raise ValidationError({'items': ["Size is larger than source image"]})
+ except ImageSizeError:
+ m2m_changed.disconnect(update_photo_sizes, sender=LuxImage.sizes.through)
+ instance.sizes.remove(new_size)
+ m2m_changed.connect(update_photo_sizes, sender=LuxImage.sizes.through)
+ if new_size.height:
+ img = Image.open(instance.image.path)
+ try:
+ if new_size.height <= img.height:
+ resize_image(img, None, new_size.height, new_size.quality, instance.get_image_path_by_size(size))
+ else:
+ pass
+ except ImageSizeError:
+ m2m_changed.disconnect(update_photo_sizes, sender=LuxImage.sizes.through)
+ instance.sizes.remove(new_size)
+ m2m_changed.connect(update_photo_sizes, sender=LuxImage.sizes.through)
+ else:
+ # file exists, might add something here to force it to do the above when I want
+ print("file %s exists" % size)
+ pass
+
+
+def generate_image(luximage, size):
+ new_size = LuxImageSize.objects.get(slug=size)
+ if new_size.width:
+ img = Image.open(luximage.image.path)
+ try:
+ if new_size.width <= img.width:
+ resize_image(img, new_size.width, None, new_size.quality, luximage.get_image_path_by_size(size))
+ else:
+ raise ValidationError({'items': ["Size is larger than source image"]})
+ except ImageSizeError:
+ print("error creating size")
+ if new_size.height:
+ img = Image.open(luximage.image.path)
+ try:
+ if new_size.height <= img.height:
+ resize_image(img, None, new_size.height, new_size.quality, luximage.get_image_path_by_size(size))
+ else:
+ pass
+ except ImageSizeError:
+ print("error creating size")