summaryrefslogtreecommitdiff
path: root/app/media
diff options
context:
space:
mode:
Diffstat (limited to 'app/media')
-rw-r--r--app/media/0002_auto_20201201_2054.py46
-rw-r--r--app/media/0003_auto_20201201_2055.py118
-rw-r--r--app/media/admin.py49
-rw-r--r--app/media/migrations/0001_initial.py30
-rw-r--r--app/media/migrations/0002_auto_20211030_1634.py38
-rw-r--r--app/media/models.py215
-rw-r--r--app/media/readexif.py76
-rw-r--r--app/media/static/image-preview.js2
-rw-r--r--app/media/templatetags/get_image_by_size.py2
-rw-r--r--app/media/utils.py24
-rw-r--r--app/media/views.py24
11 files changed, 455 insertions, 169 deletions
diff --git a/app/media/0002_auto_20201201_2054.py b/app/media/0002_auto_20201201_2054.py
new file mode 100644
index 0000000..843f48b
--- /dev/null
+++ b/app/media/0002_auto_20201201_2054.py
@@ -0,0 +1,46 @@
+# Generated by Django 3.1 on 2020-12-01 19:26
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('media', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RunSQL("""
+ INSERT INTO media_luximagesize (
+ id,
+ name,
+ width,
+ height,
+ quality
+ )
+ SELECT
+ id,
+ name,
+ width,
+ height,
+ quality
+ FROM
+ photos_luximagesize;
+ """, reverse_sql="""
+ INSERT INTO photos_luximagesize (
+ id,
+ name,
+ width,
+ height,
+ quality
+ )
+ SELECT
+ id,
+ name,
+ width,
+ height,
+ quality
+ FROM
+ media_luximagesize;
+ """)
+ ]
diff --git a/app/media/0003_auto_20201201_2055.py b/app/media/0003_auto_20201201_2055.py
new file mode 100644
index 0000000..4aeec12
--- /dev/null
+++ b/app/media/0003_auto_20201201_2055.py
@@ -0,0 +1,118 @@
+# Generated by Django 3.1 on 2020-12-01 20:49
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('media', '0002_auto_20201201_2054'),
+ ]
+
+ operations = [
+ migrations.RunSQL("""
+ INSERT INTO media_luximage (
+ id,
+ image,
+ title,
+ alt,
+ photo_credit_source,
+ photo_credit_url,
+ caption,
+ pub_date,
+ height,
+ width,
+ is_public,
+ exif_raw,
+ exif_aperture,
+ exif_make,
+ exif_model,
+ exif_exposure,
+ exif_iso,
+ exif_focal_length,
+ exif_lens,
+ exif_date,
+ point,
+ location,
+ sizes
+ )
+ SELECT
+ id,
+ image,
+ title,
+ alt,
+ photo_credit_source,
+ photo_credit_url,
+ caption,
+ pub_date,
+ height,
+ width,
+ is_public,
+ exif_raw,
+ exif_aperture,
+ exif_make,
+ exif_model,
+ exif_exposure,
+ exif_iso,
+ exif_focal_length,
+ exif_lens,
+ exif_date,
+ point,
+ location,
+ sizes
+ FROM
+ photos_luximage;
+ """, reverse_sql="""
+ INSERT INTO photos_luximage (
+ id,
+ image,
+ title,
+ alt,
+ photo_credit_source,
+ photo_credit_url,
+ caption,
+ pub_date,
+ height,
+ width,
+ is_public,
+ sizes,
+ exif_raw,
+ exif_aperture,
+ exif_make,
+ exif_model,
+ exif_exposure,
+ exif_iso,
+ exif_focal_length,
+ exif_lens,
+ exif_date,
+ point,
+ location
+ )
+ SELECT
+ id,
+ image,
+ title,
+ alt,
+ photo_credit_source,
+ photo_credit_url,
+ caption,
+ pub_date,
+ height,
+ width,
+ is_public,
+ sizes,
+ exif_raw,
+ exif_aperture,
+ exif_make,
+ exif_model,
+ exif_exposure,
+ exif_iso,
+ exif_focal_length,
+ exif_lens,
+ exif_date,
+ point,
+ location
+ FROM
+ media_luximage;
+ """)
+ ]
diff --git a/app/media/admin.py b/app/media/admin.py
index 12d0509..50eb879 100644
--- a/app/media/admin.py
+++ b/app/media/admin.py
@@ -1,12 +1,15 @@
from django.contrib import admin
+from django import forms
from django.contrib.gis.admin import OSMGeoAdmin
-
-from .models import LuxImage, LuxGallery, LuxImageSize, LuxVideo, LuxAudio
+from .models import LuxImage, LuxGallery, LuxImageSize, LuxVideo
+from django.shortcuts import render
+from django.contrib.admin import helpers
+from django.http import HttpResponseRedirect
@admin.register(LuxImageSize)
class LuxImageSizeAdmin(OSMGeoAdmin):
- list_display = ('name', 'width', 'height', 'quality')
+ list_display = ('name','slug', 'width', 'height', 'quality')
@admin.register(LuxVideo)
@@ -18,20 +21,44 @@ class LuxVideoAdmin(OSMGeoAdmin):
class LuxImageAdmin(OSMGeoAdmin):
list_display = ('pk', 'admin_thumbnail', 'pub_date', 'caption')
list_filter = ('pub_date',)
- search_fields = ['title', 'caption']
+ search_fields = ['title', 'caption', 'alt']
# Options for OSM map Using custom ESRI topo map
+ default_lon = -9285175
+ default_lat = 4025046
+ default_zoom = 6
+ units = True
+ scrollable = False
+ map_width = 700
+ map_height = 425
+ map_template = 'gis/admin/osm.html'
+ openlayers_url = '/static/admin/js/OpenLayers.js'
fieldsets = (
(None, {
- 'fields': ('title', ('image'), 'pub_date', 'sizes', 'alt', 'caption', ('is_public'), ('photo_credit_source', 'photo_credit_url'))
+ 'fields': (
+ 'image',
+ 'alt',
+ 'sizes',
+ 'caption',
+ 'pub_date',
+ 'title',
+ )
+ }),
+ ('Exif and Other Data', {
+ 'classes': ('collapse',),
+ 'fields': (
+ 'point',
+ ('is_public'),
+ ('photo_credit_source', 'photo_credit_url'),
+ 'exif_raw', 'exif_aperture', 'exif_make', 'exif_model', 'exif_exposure', 'exif_iso', 'exif_focal_length', 'exif_lens', 'exif_date', 'height', 'width'),
}),
)
+ def save_related(self, request, form, formsets, change):
+ super(LuxImageAdmin, self).save_related(request, form, formsets, change)
+ if not form.instance.sizes.all():
+ print("there are no sizes")
+ form.instance.sizes.add(*LuxImageSize.objects.filter(slug__in=["picwide-sm", "picwide-med", "picwide"]))
+
class Media:
js = ('image-preview.js', 'next-prev-links.js')
-
-
-@admin.register(LuxAudio)
-class LuxAudioAdmin(OSMGeoAdmin):
- list_display = ('pk', 'title', 'pub_date')
- list_filter = ('pub_date',)
diff --git a/app/media/migrations/0001_initial.py b/app/media/migrations/0001_initial.py
index 8ca4631..886a36e 100644
--- a/app/media/migrations/0001_initial.py
+++ b/app/media/migrations/0001_initial.py
@@ -1,6 +1,7 @@
-# Generated by Django 3.1.3 on 2020-11-30 22:44
+# Generated by Django 4.1.3 on 2022-12-02 20:09
import datetime
+import django.contrib.gis.db.models.fields
from django.db import migrations, models
import django.db.models.deletion
import media.models
@@ -17,7 +18,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LuxAudio',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('subtitle', models.CharField(blank=True, max_length=200)),
('slug', models.SlugField(blank=True, unique_for_date='pub_date')),
@@ -26,6 +27,7 @@ class Migration(migrations.Migration):
('pub_date', models.DateTimeField(default=datetime.datetime.now)),
('mp3', models.FileField(blank=True, null=True, upload_to=media.models.get_audio_upload_path)),
('ogg', models.FileField(blank=True, null=True, upload_to=media.models.get_audio_upload_path)),
+ ('point', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)),
],
options={
'verbose_name': 'Audio',
@@ -37,8 +39,9 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LuxImageSize',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=30, null=True)),
+ ('slug', models.SlugField(blank=True, null=True)),
('width', models.IntegerField(blank=True, null=True)),
('height', models.IntegerField(blank=True, null=True)),
('quality', models.IntegerField()),
@@ -51,7 +54,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LuxVideo',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('video_mp4', models.FileField(blank=True, null=True, upload_to=media.models.get_vid_upload_path)),
('video_webm', models.FileField(blank=True, null=True, upload_to=media.models.get_vid_upload_path)),
('video_poster', models.FileField(blank=True, null=True, upload_to=media.models.get_vid_upload_path)),
@@ -70,7 +73,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LuxImage',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.FileField(blank=True, null=True, upload_to=media.models.get_upload_path)),
('title', models.CharField(blank=True, max_length=300, null=True)),
('alt', models.CharField(blank=True, max_length=300, null=True)),
@@ -78,10 +81,21 @@ class Migration(migrations.Migration):
('photo_credit_url', models.CharField(blank=True, max_length=300, null=True)),
('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(blank=True, max_length=50, null=True)),
+ ('exif_make', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_model', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_exposure', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_iso', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_focal_length', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_lens', models.CharField(blank=True, max_length=50, null=True)),
+ ('exif_date', models.DateTimeField(blank=True, null=True)),
('height', models.CharField(blank=True, max_length=6, null=True)),
('width', models.CharField(blank=True, max_length=6, null=True)),
+ ('point', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)),
('is_public', models.BooleanField(default=True)),
- ('sizes', models.ManyToManyField(blank=True, to='media.LuxImageSize')),
+ ('sizes_cache', models.CharField(blank=True, max_length=300, null=True)),
+ ('sizes', models.ManyToManyField(blank=True, related_name='sizes', to='media.luximagesize')),
],
options={
'verbose_name_plural': 'Images',
@@ -92,14 +106,14 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LuxGallery',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=300)),
('description', models.TextField(blank=True, null=True)),
('slug', models.CharField(blank=True, max_length=300)),
('pub_date', models.DateTimeField(null=True)),
('is_public', models.BooleanField(default=True)),
('caption_style', models.CharField(blank=True, max_length=400, null=True)),
- ('images', models.ManyToManyField(to='media.LuxImage')),
+ ('images', models.ManyToManyField(to='media.luximage')),
('thumb', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gallery_thumb', to='media.luximage')),
],
options={
diff --git a/app/media/migrations/0002_auto_20211030_1634.py b/app/media/migrations/0002_auto_20211030_1634.py
deleted file mode 100644
index abebed9..0000000
--- a/app/media/migrations/0002_auto_20211030_1634.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Generated by Django 3.2.8 on 2021-10-30 16:34
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('media', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='luxaudio',
- name='id',
- field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.AlterField(
- model_name='luxgallery',
- name='id',
- field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.AlterField(
- model_name='luximage',
- name='id',
- field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.AlterField(
- model_name='luximagesize',
- name='id',
- field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.AlterField(
- model_name='luxvideo',
- name='id',
- field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- ]
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")
diff --git a/app/media/readexif.py b/app/media/readexif.py
new file mode 100644
index 0000000..d9e5d70
--- /dev/null
+++ b/app/media/readexif.py
@@ -0,0 +1,76 @@
+import time
+from fractions import Fraction
+
+from django.contrib.gis.geos import Point
+
+import exiftool
+
+
+def readexif(image):
+ """
+ takes an image and fills in all the exif data tracked in the image model
+
+ """
+ with exiftool.ExifTool() as et:
+ meta = et.get_metadata(image.image.path)
+ et.terminate()
+ image.exif_raw = meta
+ try:
+ image.title = meta["EXIF:ImageDescription"]
+ except:
+ try:
+ image.title = meta["XMP:Title"]
+ except:
+ pass
+ try:
+ image.caption = meta["EXIF:UserComment"]
+ except:
+ pass
+ try:
+ image.exif_lens = meta["MakerNotes:LensType"]
+ except:
+ try:
+ image.exif_lens = meta["XMP:Lens"]
+ except:
+ pass
+ try:
+ image.exif_aperture = meta["EXIF:FNumber"]
+ except:
+ pass
+ try:
+ image.exif_make = meta["EXIF:Make"]
+ except:
+ pass
+ try:
+ image.exif_model = meta["EXIF:Model"]
+ except:
+ pass
+ try:
+ image.exif_exposure = str(Fraction(float(meta["EXIF:ExposureTime"])).limit_denominator())
+ except:
+ pass
+ try:
+ image.exif_iso = meta["EXIF:ISO"]
+ except:
+ pass
+ try:
+ image.exif_focal_length = meta["EXIF:FocalLength"]
+ except:
+ pass
+ try:
+ fmt_date = time.strptime(meta["EXIF:DateTimeOriginal"], "%Y:%m:%d %H:%M:%S")
+ except:
+ pass
+ try:
+ image.exif_date = time.strftime("%Y-%m-%d %H:%M:%S", fmt_date)
+ except:
+ pass
+ try:
+ image.height = meta["File:ImageHeight"]
+ except:
+ pass
+ try:
+ image.width = meta["File:ImageWidth"]
+ except:
+ pass
+ return image
diff --git a/app/media/static/image-preview.js b/app/media/static/image-preview.js
index b8fead5..c829084 100644
--- a/app/media/static/image-preview.js
+++ b/app/media/static/image-preview.js
@@ -11,7 +11,7 @@ function build_image_preview () {
var img = document.createElement("img");
var request = new XMLHttpRequest();
- request.open('GET', '/photos/luximage/data/admin/preview/'+cur+'/', true);
+ request.open('GET', '/photos/data/admin/preview/'+cur+'/', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText);
diff --git a/app/media/templatetags/get_image_by_size.py b/app/media/templatetags/get_image_by_size.py
index c56c44e..a0a62f0 100644
--- a/app/media/templatetags/get_image_by_size.py
+++ b/app/media/templatetags/get_image_by_size.py
@@ -4,5 +4,5 @@ register = template.Library()
@register.simple_tag
def get_image_by_size(obj, *args):
- method = getattr(obj, "get_image_by_size")
+ method = getattr(obj, "get_image_url_by_size")
return method(*args)
diff --git a/app/media/utils.py b/app/media/utils.py
index 84e72f5..893663c 100644
--- a/app/media/utils.py
+++ b/app/media/utils.py
@@ -1,28 +1,26 @@
import os
-import re
import subprocess
-from django.apps import apps
-from django.conf import settings
-
from PIL import ImageFile
-from bs4 import BeautifulSoup
# pip install python-resize-image
from resizeimage import resizeimage
-def resize_image(img, width=None, height=None, quality=72, base_path="", filename=""):
+def resize_image(img, width=None, height=None, quality=72, filepath=""):
+ """
+ given an image object, size, and filepath
+ resize the image, then save it , size, and filepath
+ resize the image, then save it at the filepath
+ """
+ base_path = os.path.dirname(filepath)
+ if not os.path.isdir(base_path):
+ os.makedirs(base_path)
if width and height:
newimg = resizeimage.resize_cover(img, [width, height])
if width and not height:
newimg = resizeimage.resize_width(img, width)
if height and not width:
newimg = resizeimage.resize_height(img, height)
- if not os.path.isdir(base_path):
- os.makedirs(base_path)
- path = "%s%s" % (base_path, filename)
ImageFile.MAXBLOCK = img.size[0] * img.size[1] * 4
- newimg.save(path, newimg.format, quality=quality)
- subprocess.call(["jpegoptim", "%s" % path])
-
-
+ newimg.save(filepath, newimg.format, quality=quality)
+ subprocess.call(["jpegoptim", "%s" % filepath])
diff --git a/app/media/views.py b/app/media/views.py
index 915b022..04ac11c 100644
--- a/app/media/views.py
+++ b/app/media/views.py
@@ -1,10 +1,10 @@
import json
-from django.shortcuts import render_to_response, render
+from django.shortcuts import render
from django.template import RequestContext
from django.http import Http404, HttpResponse
from django.core import serializers
-from .models import Photo, PhotoGallery, LuxGallery, LuxImage
+from .models import LuxGallery, LuxImage
from locations.models import Country, Region
from utils.views import PaginatedListView
@@ -52,10 +52,10 @@ class GalleryList(PaginatedListView):
class OldGalleryList(PaginatedListView):
template_name = 'archives/gallery_list.html'
- model = PhotoGallery
+ model = LuxGallery
def get_queryset(self):
- return PhotoGallery.objects.filter(is_public=True)
+ return LuxGallery.objects.filter(is_public=True)
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
@@ -74,7 +74,7 @@ def gallery_list(request, page):
request.page_url = '/photos/%d/'
request.page = int(page)
context = {
- 'object_list': PhotoGallery.objects.all(),
+ 'object_list': LuxGallery.objects.all(),
'page': page,
}
return render(request, "archives/photos.html", context)
@@ -82,13 +82,13 @@ def gallery_list(request, page):
def gallery(request, slug):
context = {
- 'object': PhotoGallery.objects.get(set_slug=slug)
+ 'object': LuxGallery.objects.get(set_slug=slug)
}
- return render_to_response('details/photo_galleries.html', context, context_instance=RequestContext(request))
+ return render(request, 'details/photo_galleries.html', context)
def photo_json(request, slug):
- p = PhotoGallery.objects.filter(set_slug=slug)
+ p = LuxGallery.objects.filter(set_slug=slug)
return HttpResponse(serializers.serialize('json', p), mimetype='application/json')
@@ -103,7 +103,7 @@ def photo_preview_json(request, pk):
def thumb_preview_json(request, pk):
p = LuxImage.objects.get(pk=pk)
data = {}
- data['url'] = p.get_admin_insert()
+ data['url'] = p.get_image_url_by_size('tn')
data = json.dumps(data)
return HttpResponse(data)
@@ -114,10 +114,10 @@ def gallery_list_by_area(request, slug, page):
request.page = int(page)
try:
region = Region.objects.get(slug__exact=slug)
- qs = PhotoGallery.objects.filter(region=region).order_by('-id')
+ qs = LuxGallery.objects.filter(region=region).order_by('-id')
except:
region = Country.objects.get(slug__exact=slug)
- qs = PhotoGallery.objects.filter(location__state__country=region).order_by('-id')
+ qs = LuxGallery.objects.filter(location__state__country=region).order_by('-id')
if not region:
raise Http404
context = {
@@ -127,4 +127,4 @@ def gallery_list_by_area(request, slug, page):
'region': region,
'page': page
}
- return render_to_response("archives/photos.html", context, context_instance=RequestContext(request))
+ return render(request, "archives/photos.html", context)