diff options
Diffstat (limited to 'app/photos/models.py')
-rw-r--r-- | app/photos/models.py | 555 |
1 files changed, 0 insertions, 555 deletions
diff --git a/app/photos/models.py b/app/photos/models.py deleted file mode 100644 index 24a218f..0000000 --- a/app/photos/models.py +++ /dev/null @@ -1,555 +0,0 @@ -import os.path -import io -import datetime -from PIL import Image - -from django.core.exceptions import ValidationError -from django.contrib.gis.db import models -from django.contrib.sitemaps import Sitemap -from django.utils.encoding import force_text -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 .utils import resize_image -from .readexif import readexif -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): - return "images/original/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename) - -def get_vid_upload_path(self, filename): - return "images/videos/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename) - -class LuxImageSize(models.Model): - name = models.CharField(null=True, blank=True, max_length=30) - width = models.IntegerField(null=True, blank=True) - height = models.IntegerField(null=True, blank=True) - quality = models.IntegerField() - - class Meta: - ordering = ('-name', 'id') - verbose_name_plural = 'Image Sizes' - - def __str__(self): - if self.width: - size = self.width - if self.height: - size = self.height - return "%s - %s" %(self.name, str(size)) - - -class LuxImage(models.Model): - image = models.FileField(blank=True, null=True, upload_to=get_upload_path) - title = models.CharField(null=True, blank=True, max_length=300) - alt = models.CharField(null=True, blank=True, max_length=300) - photo_credit_source = models.CharField(null=True, blank=True, max_length=300) - 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) - location = models.ForeignKey("locations.Location", on_delete=models.CASCADE, null=True, blank=True, related_name="+") - is_public = models.BooleanField(default=True) - sizes = models.ManyToManyField(LuxImageSize, blank=True, related_name="+") - flickr_id = models.CharField(null=True, blank=True, max_length=80) - twitter_link = models.CharField(null=True, blank=True, max_length=300) - facebook_link = models.CharField(null=True, blank=True, max_length=300) - - class Meta: - ordering = ('-pub_date', 'id') - verbose_name_plural = 'Images' - get_latest_by = 'pub_date' - - def __str__(self): - if self.title: - return "%s" % self.title - else: - return "%s" % self.pk - - def get_type(self): - return str(self.__class__.__name__) - - 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()) - - def get_largest_image(self): - t = [] - for size in self.sizes.all(): - t.append(size.width) - t.sort(key=float) - 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_name_new(self): - return os.path.basename(self.image.path)[:-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()) - - @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()) - - @cached_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) - if loopnum < length: - srcset += ", " - loopnum = loopnum+1 - return srcset - - @cached_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()) - 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()) - 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()) - if size == "original": - return "%soriginal/%s/%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, self.get_image_ext()) - else: - if size != 'tn': - try: - self.sizes.filter(name=size) - except DoesNotExist: - 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()) - - 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()) - else: - return "%s/%s/%s_%s.%s" % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), base, size, self.get_image_ext()) - - def get_thumbnail_url(self): - return self.get_image_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"))) - admin_thumbnail.short_description = 'Thumbnail' - - def get_sizes(self): - return self.sizes.all() - - @property - def latitude(self): - return self.point.y - - @property - def longitude(self): - return self.point.x - - @property - def get_previous_published(self): - return self.get_previous_by_pub_date() - - @property - def get_next_published(self): - return self.get_next_by_pub_date() - - @property - def get_previous_admin_url(self): - n = self.get_previous_by_pub_date() - return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] ) - - @property - def get_next_admin_url(self): - model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name) - try: - return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] ) - except model.DoesNotExist: - return '' - - @property - def is_portait(self): - if int(self.height) > int(self.width): - return True - else: - return False - - def save(self, *args, **kwargs): - if not self.point: - self.point = LuxImage.objects.latest().point - try: - self.location = apps.get_model('locations', 'Location').objects.filter( - geometry__contains=self.point - ).get() - except apps.get_model('locations', 'Location').DoesNotExist: - raise forms.ValidationError("There is no location associated with that point, add it: %sadmin/locations/location/add/" % (settings.BASE_URL)) - super(LuxImage, self).save() - - -@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 - instance = readexif(instance) - 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) - - -class LuxGallery(models.Model): - title = models.CharField(blank=True, max_length=300) - description = models.TextField(blank=True, null=True) - slug = models.CharField(blank=True, max_length=300) - thumb = models.ForeignKey(LuxImage, on_delete=models.CASCADE, related_name="gallery_thumb", null=True, blank=True) - images = models.ManyToManyField(LuxImage) - pub_date = models.DateTimeField(null=True) - point = models.PointField(null=True, blank=True) - location = models.ForeignKey("locations.Location", on_delete=models.CASCADE, null=True, blank=True) - is_public = models.BooleanField(default=True) - caption_style = models.CharField(blank=True, null=True, max_length=400) - - class Meta: - ordering = ('-pub_date', 'id') - verbose_name_plural = 'Galleries' - get_latest_by = 'pub_date' - - def __str__(self): - return self.title - - def get_main_image(self): - return "%sgallery_thumbs/%s.jpg" % (settings.IMAGES_URL, self.id) - - def get_absolute_url(self): - if self.is_public: - return "/photos/galleries/%s" % (self.slug) - else: - return "/photos/galleries/private/%s" % (self.slug) - - def latitude(self): - if self.point: - return self.point.y - - def longitude(self): - if self.point: - return self.point.x - - def thumbs(self): - lst = [x.image.name for x in self.images.all()] - lst = ["<a href='/media/%s'>%s</a>" % (x, x.split('/')[-1]) for x in lst] - return ', '.join(item for item in lst if item) - thumbs.allow_tags = True - - -class LuxVideo(models.Model): - video_mp4 = models.FileField(blank=True, null=True, upload_to=get_vid_upload_path) - video_webm = models.FileField(blank=True, null=True, upload_to=get_vid_upload_path) - video_poster = models.FileField(blank=True, null=True, upload_to=get_vid_upload_path) - title = models.CharField(null=True, blank=True, max_length=300) - pub_date = models.DateTimeField(default=datetime.datetime.now) - youtube_url = models.CharField(null=True, blank=True, max_length=80) - vimeo_url = models.CharField(null=True, blank=True, max_length=300) - - def __str__(self): - if self.title: - return self.title - else: - return str(self.pk) - - def get_type(self): - return str(self.__class__.__name__) - - class Meta: - ordering = ('-pub_date', 'id') - verbose_name_plural = 'Videos' - get_latest_by = 'pub_date' - -class Photo(models.Model): - description = models.TextField(blank=True, null=True) - title = models.CharField(blank=True, max_length=300) - pub_date = models.DateTimeField() - tags = TaggableManager(blank=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() - """Flickr Specific Stuff""" - # Vlickr id is varchar since Flickr ids are larger than than integerfield can handle and BigIntegerField gets weird in Postgres. - flickr_id = models.CharField(max_length=300) - flickr_owner = models.CharField(max_length=20) - flickr_server = models.IntegerField() - flickr_farm = models.IntegerField() - flickr_secret = models.CharField(max_length=50) - flickr_originalsecret = models.CharField(max_length=50) - lon = models.FloatField('Longitude', help_text="Longitude of centerpoint", null=True) - lat = models.FloatField('Latitude', help_text="Latitude of centerpoint", null=True) - location = models.ForeignKey("locations.Location", on_delete=models.CASCADE, null=True) - region = models.ForeignKey("locations.Region", on_delete=models.CASCADE, null=True) - slideshowimage_width = models.CharField(max_length=4, blank=True, null=True) - slideshowimage_height = models.CharField(max_length=4, blank=True, null=True) - slideshowimage_margintop = models.CharField(max_length=4, blank=True, null=True) - slideshowimage_marginleft = models.CharField(max_length=4, blank=True, null=True) - is_public = models.BooleanField(default=True) - - class Meta: - ordering = ('-pub_date',) - - def admin_thumbnail(self): - return force_text('<a href="%s"><img src="%s"></a>' % (self.get_absolute_url(), self.get_small_square_url())) - admin_thumbnail.allow_tags = True - admin_thumbnail.short_description = 'Thumbnail' - - def get_local_medium_url(self): - return '%sflickr/med/%s/%s.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id) - - def get_local_orig_url(self): - return '%s/flickr/full/%s/%s.jpg' % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), self.flickr_id) - - def get_local_slideshow_url(self): - return '%sslideshow/%s/%s.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id) - - def __str__(self): - return self.title - - def get_absolute_url(self): - return "/photo/%s/" % (self.id) - - def get_model_name(self): - return 'photo' - - def get_small_square_url(self): - return self.get_pic_url(size="small_square") - - def get_large_url(self): - return self.get_pic_url(size="large") - - def get_small_url(self): - return self.get_pic_url(size="small") - - def get_medium_url(self): - return self.get_pic_url(size="medium") - - def get_original_url(self): - # return self.get_pic_url(size="original") - return "http://farm%s.static.flickr.com/%s/%s_%s_o.jpg" % (self.flickr_farm, self.flickr_server, self.flickr_id, self.flickr_originalsecret) - - def get_retina_slideshow_url(self): - return '%sslideshow/%s/%sx2.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id) - - def has_retina(self): - return os.path.isfile('%s/slideshow/%s/%sx2.jpg' % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), self.flickr_id)) - - @property - def get_height(self): - im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT, - self.pub_date.strftime("%Y"), self.flickr_id)) - xsize, ysize = im.size - return ysize - - @property - def get_width(self): - im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT, - self.pub_date.strftime("%Y"), self.flickr_id)) - xsize, ysize = im.size - return xsize - - @property - def get_margin_top(self): - im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT, - self.pub_date.strftime("%Y"), self.flickr_id)) - xsize, ysize = im.size - mtop = 340 - (ysize / 2) - return mtop - - @property - def get_margin_left(self): - im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT, - self.pub_date.strftime("%Y"), self.flickr_id)) - xsize, ysize = im.size - mtop = 500 - (xsize / 2) - return mtop - - @property - def flickr_link(self): - return '%s%s/' % ('http://www.flickr.com/photos/luxagraf/', self.flickr_id) - - @property - def is_portait(self): - if int(self.slideshowimage_height) > int(self.slideshowimage_width): - return True - else: - return False - - def get_pic_url(self, size='small'): - # small_square=75x75 - # thumb=100 on longest side - # small=240 on longest side - # medium=500 on longest side - # large=1024 on longest side - # original=duh - base_url = "http://static.flickr.com" - size_char = 's' # default to small_square - if size == 'small_square': - size_char = '_s' - elif size == 'thumb': - size_char = '_t' - elif size == 'small': - size_char = '_m' - elif size == 'medium': - size_char = '' - elif size == 'large': - size_char = '_b' - elif size == 'original': - size_char = '_o' - - return "http://farm%s.static.flickr.com/%s/%s_%s%s.jpg" % (self.flickr_farm, self.flickr_server, self.flickr_id, self.flickr_secret, size_char) - - def get_tumble_image(self): - return "%s/crops/%s/%s.jpg" % (settings.IMAGES_URL, self.pub_date.strftime("%Y/%b").lower(), self.id) - - def get_previous_published(self): - return self.get_previous_by_pub_date() - - def get_next_published(self): - return self.get_next_by_pub_date() - - def comment_period_open(self): - return self.enable_comments and datetime.datetime.today() - datetime.timedelta(30) <= self.pub_date - - def save(self, *args, **kwargs): - super(Photo, self).save() - - -class PhotoGallery(models.Model): - set_id = models.CharField(blank=True, max_length=300) - set_title = models.CharField(blank=True, max_length=300) - set_desc = models.TextField(blank=True, null=True) - set_slug = models.CharField(blank=True, max_length=300) - primary = models.CharField(blank=True, max_length=300) - photos = models.ManyToManyField(Photo) - location = models.ForeignKey("locations.Location", on_delete=models.CASCADE, null=True) - region = models.ForeignKey("locations.Region", on_delete=models.CASCADE, null=True) - pub_date = models.DateTimeField(null=True) - - class Meta: - ordering = ('-pub_date', 'id') - verbose_name_plural = 'Photo Galleries' - get_latest_by = 'pub_date' - - def __str__(self): - return self.set_title - - def get_main_image(self): - return "%sgallery_thumbs/%s.jpg" % (settings.IMAGES_URL, self.id) - - def get_absolute_url(self): - return "/photos/galleries/%s/" % (self.set_slug) - - -class PhotoGallerySitemap(Sitemap): - changefreq = "never" - priority = 0.7 - protocol = "https" - - def items(self): - return PhotoGallery.objects.all() - - def lastmod(self, obj): - return obj.pub_date - - -def resize_luximage(self, image): - image.save() - img = Image.open(image.image.path) - base_path = "%s/galleries/" % settings.IMAGES_ROOT - if img.size[0] > img.size[1]: - resize_image(img, 2280, None, 65, base_path+'large/', image.get_image_name()) - resize_image(img, 1140, None, 72, base_path+'medium/', image.get_image_name()) - resize_image(img, 720, None, 68, base_path+'small/', image.get_image_name()) - if img.size[1] > img.size[0]: - resize_image(img, None, 1600, 65, base_path+'large/', image.get_image_name()) - resize_image(img, None, 800, 72, base_path+'medium/', image.get_image_name()) - resize_image(img, None, 460, 60, base_path+'small/', image.get_image_name()) - - resize_image(img, 160, None, 68, base_path+'thumb/', image.get_image_name()) |