summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2016-03-20 21:30:28 -0400
committerluxagraf <sng@luxagraf.net>2016-03-20 21:30:28 -0400
commit96d80eaf238045faba45cd4b64a8d93d19a98a69 (patch)
treea12bb2c4fe7573946942c425a2d15044f7e20e4c
parent86bb919d5e87b33f93c2d09c6fe36eb2f393b7e6 (diff)
Wrote image app to work with other models. Broke galleries badly, need
to fix before posting again. Also major admin image move to pull off.
-rw-r--r--app/photos/admin.py28
-rw-r--r--app/photos/forms.py55
-rw-r--r--app/photos/migrations/0004_luximage_alt.py20
-rw-r--r--app/photos/migrations/0005_auto_20160318_1244.py25
-rw-r--r--app/photos/migrations/0006_auto_20160318_2047.py30
-rw-r--r--app/photos/migrations/0007_auto_20160320_0802.py20
-rw-r--r--app/photos/migrations/0008_luximagesize_quality.py21
-rw-r--r--app/photos/migrations/0009_auto_20160320_0907.py20
-rw-r--r--app/photos/models.py78
-rw-r--r--app/photos/readexif.py59
-rw-r--r--app/photos/templatetags/get_image_by_size.py (renamed from app/photos/templatetags/get_image_size.py)4
-rw-r--r--app/photos/utils.py4
-rw-r--r--design/templates/admin/photos/luximage/change_form.html5
13 files changed, 311 insertions, 58 deletions
diff --git a/app/photos/admin.py b/app/photos/admin.py
index 659dcb6..9453734 100644
--- a/app/photos/admin.py
+++ b/app/photos/admin.py
@@ -4,7 +4,7 @@ from django.contrib.gis.admin import OSMGeoAdmin
from django.conf.urls import patterns
from django.conf.urls import url
from django.utils.translation import ungettext, ugettext_lazy as _
-from photos.models import Photo, PhotoGallery, LuxImage, LuxGallery
+from photos.models import Photo, PhotoGallery, LuxImage, LuxGallery, LuxImageSize
from django.shortcuts import render
from django.contrib.admin import helpers
from django.http import HttpResponseRedirect
@@ -13,10 +13,17 @@ from django.http import HttpResponseRedirect
from .forms import UploadZipForm, GalleryForm
+class LuxImageSizeAdmin(OSMGeoAdmin):
+ pass
+
+
+admin.site.register(LuxImageSize, LuxImageSizeAdmin)
+
+
class LuxImageAdmin(OSMGeoAdmin):
- list_display = ('pk', 'admin_thumbnail', 'pub_date',)
- list_filter = ('pub_date',)
+ list_display = ('pk', 'admin_thumbnail', 'pub_date', 'location')
+ list_filter = ('pub_date', 'location')
search_fields = ['title', 'caption']
# Options for OSM map Using custom ESRI topo map
default_lon = -9285175
@@ -29,6 +36,21 @@ class LuxImageAdmin(OSMGeoAdmin):
map_template = 'gis/admin/osm.html'
openlayers_url = '/static/admin/js/OpenLayers.js'
+ fieldsets = (
+ (None, {
+ 'fields': (('image', 'pub_date'), 'sizes', ('title', 'alt'), 'caption', 'point', ('is_public', 'is_video'), ('photo_credit_source','photo_credit_url'))
+ }),
+ ('Exif Data', {
+ 'classes': ('collapse',),
+ 'fields': ('exif_raw', 'exif_aperture', 'exif_make', 'exif_model', 'exif_exposure', 'exif_iso', 'exif_focal_length', 'exif_lens', 'exif_date', 'height', 'width'),
+ }),
+ )
+
+
+
+
+
+
admin.site.register(LuxImage, LuxImageAdmin)
diff --git a/app/photos/forms.py b/app/photos/forms.py
index 1f80496..8ad89f2 100644
--- a/app/photos/forms.py
+++ b/app/photos/forms.py
@@ -2,10 +2,8 @@ import zipfile
from zipfile import BadZipFile
import logging
import datetime
-import time
import os
from io import BytesIO
-from fractions import Fraction
try:
import Image
except ImportError:
@@ -17,21 +15,18 @@ from django.utils.safestring import mark_safe
from django.contrib import messages
from django.core.files.base import ContentFile
from django.contrib.admin import widgets
-from django.contrib.gis.geos import Point
from django.conf import settings
-import exiftool
-from photos.models import LuxImage, LuxGallery
-from locations.models import Location
+from photos.models import LuxImage, LuxGallery, LuxImageSize
from .utils import resize_image
+from .readexif import readexif
logger = logging.getLogger('photos.forms')
class GalleryForm(forms.ModelForm):
class Meta:
- model = LuxGallery
fields = '__all__'
widgets = {
'images': forms.SelectMultiple,
@@ -152,56 +147,24 @@ class UploadZipForm(forms.Form):
image.image.save(filename, contentfile)
image.save()
gallery.images.add(image)
-
- 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:
- 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.point = Point(meta["XMP:GPSLongitude"], meta["XMP:GPSLatitude"], srid=4326)
- try:
- image.location = Location.objects.filter(geometry__contains=image.point).get()
- except Location.DoesNotExist:
- pass
- except KeyError:
- pass
- image.exif_aperture = meta["EXIF:FNumber"]
- image.exif_make = meta["EXIF:Make"]
- image.exif_model = meta["EXIF:Model"]
- image.exif_exposure = str(Fraction(float(meta["EXIF:ExposureTime"])).limit_denominator())
- image.exif_iso = meta["EXIF:ISO"]
- image.exif_focal_length = meta["EXIF:FocalLength"]
- fmt_date = time.strptime(meta["EXIF:DateTimeOriginal"], "%Y:%m:%d %H:%M:%S")
- image.exif_date = time.strftime("%Y-%m-%d %H:%M:%S", fmt_date)
- image.height = meta["File:ImageHeight"]
- image.width = meta["File:ImageWidth"]
- image.save()
+ readexif(image)
count += 1
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())
+ image.sizes.add(LuxImageSize.objects.get(size=2280))
resize_image(img, 1140, None, 72, base_path+'medium/', image.get_image_name())
+ image.sizes.add(LuxImageSize.objects.get(size=1140))
resize_image(img, 720, None, 68, base_path+'small/', image.get_image_name())
+ image.sizes.add(LuxImageSize.objects.get(size=720))
if img.size[1] > img.size[0]:
resize_image(img, None, 1600, 65, base_path+'large/', image.get_image_name())
+ image.sizes.add(LuxImageSize.objects.get(size=1600))
resize_image(img, None, 800, 72, base_path+'medium/', image.get_image_name())
+ image.sizes.add(LuxImageSize.objects.get(size=800))
resize_image(img, None, 460, 60, base_path+'small/', image.get_image_name())
+ image.sizes.add(LuxImageSize.objects.get(size=460))
resize_image(img, 160, None, 68, base_path+'thumb/', image.get_image_name())
zipper.close()
diff --git a/app/photos/migrations/0004_luximage_alt.py b/app/photos/migrations/0004_luximage_alt.py
new file mode 100644
index 0000000..ecbaf56
--- /dev/null
+++ b/app/photos/migrations/0004_luximage_alt.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-16 22:45
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0003_luxgallery_caption_style'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='luximage',
+ name='alt',
+ field=models.CharField(blank=True, max_length=300, null=True),
+ ),
+ ]
diff --git a/app/photos/migrations/0005_auto_20160318_1244.py b/app/photos/migrations/0005_auto_20160318_1244.py
new file mode 100644
index 0000000..584714e
--- /dev/null
+++ b/app/photos/migrations/0005_auto_20160318_1244.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-18 12:44
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0004_luximage_alt'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='luximage',
+ name='photo_credit_source',
+ field=models.CharField(blank=True, max_length=300, null=True),
+ ),
+ migrations.AddField(
+ model_name='luximage',
+ name='photo_credit_url',
+ field=models.CharField(blank=True, max_length=300, null=True),
+ ),
+ ]
diff --git a/app/photos/migrations/0006_auto_20160318_2047.py b/app/photos/migrations/0006_auto_20160318_2047.py
new file mode 100644
index 0000000..7cf0a4f
--- /dev/null
+++ b/app/photos/migrations/0006_auto_20160318_2047.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-18 20:47
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0005_auto_20160318_1244'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='LuxImageSize',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('size', models.IntegerField(max_length=5)),
+ ],
+ options={
+ 'verbose_name_plural': 'Image Sizes',
+ },
+ ),
+ migrations.AddField(
+ model_name='luximage',
+ name='sizes',
+ field=models.ManyToManyField(to='photos.LuxImageSize'),
+ ),
+ ]
diff --git a/app/photos/migrations/0007_auto_20160320_0802.py b/app/photos/migrations/0007_auto_20160320_0802.py
new file mode 100644
index 0000000..474bd42
--- /dev/null
+++ b/app/photos/migrations/0007_auto_20160320_0802.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-20 08:02
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0006_auto_20160318_2047'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='luximagesize',
+ name='size',
+ field=models.IntegerField(),
+ ),
+ ]
diff --git a/app/photos/migrations/0008_luximagesize_quality.py b/app/photos/migrations/0008_luximagesize_quality.py
new file mode 100644
index 0000000..06dc0cc
--- /dev/null
+++ b/app/photos/migrations/0008_luximagesize_quality.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-20 08:47
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0007_auto_20160320_0802'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='luximagesize',
+ name='quality',
+ field=models.IntegerField(default=65),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/photos/migrations/0009_auto_20160320_0907.py b/app/photos/migrations/0009_auto_20160320_0907.py
new file mode 100644
index 0000000..ccfebf5
--- /dev/null
+++ b/app/photos/migrations/0009_auto_20160320_0907.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-03-20 09:07
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('photos', '0008_luximagesize_quality'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='luximagesize',
+ old_name='size',
+ new_name='width',
+ ),
+ ]
diff --git a/app/photos/models.py b/app/photos/models.py
index 50ae43b..46c659e 100644
--- a/app/photos/models.py
+++ b/app/photos/models.py
@@ -10,14 +10,34 @@ from django.conf import settings
from taggit.managers import TaggableManager
from locations.models import Location, Region
+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/galleries/original/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
+ return "images/original/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
+
+
+class LuxImageSize(models.Model):
+ width = models.IntegerField()
+ quality = models.IntegerField()
+
+ class Meta:
+ verbose_name_plural = 'Image Sizes'
+
+ def __str__(self):
+ return str(self.width)
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()
exif_raw = models.TextField(blank=True, null=True)
@@ -35,6 +55,7 @@ class LuxImage(models.Model):
location = models.ForeignKey(Location, null=True, blank=True)
is_public = models.BooleanField(default=True)
is_video = models.BooleanField(default=False)
+ sizes = models.ManyToManyField(LuxImageSize)
flickr_id = models.CharField(null=True, blank=True, max_length=80)
class Meta:
@@ -48,15 +69,27 @@ class LuxImage(models.Model):
else:
return "%s" % self.pk
+ def get_admin_image(self):
+ for size in self.sizes.all():
+ if size.width <= 800:
+ return self.get_image_by_size(size)
+
+
def get_image_name(self):
- return self.image.url.split("galleries/original/")[1]
+ return self.image.url.split("original/")[1][5:-4]
- def get_image_size(self, size="original"):
+ def get_image_ext(self):
+ return self.image.url[-3:]
+
+ def get_image_by_size(self, size="original"):
base = self.get_image_name()
- return "%sgalleries/%s/%s" % (settings.IMAGES_URL, size, base)
+ if size == "original":
+ return "%soriginal/%s/%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, self.get_image_ext())
+ else:
+ return "%s%s/%s_%s.%s" % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), base, size, self.get_image_ext())
def admin_thumbnail(self):
- return force_text('<a href="%s"><img src="%s"></a>' % (self.get_image_size(), self.get_image_size("thumb")))
+ return force_text('<a href="%s"><img src="%s"></a>' % (self.get_image_by_size(), self.get_image_by_size("tn")))
admin_thumbnail.allow_tags = True
admin_thumbnail.short_description = 'Thumbnail'
@@ -79,6 +112,25 @@ class LuxImage(models.Model):
return "/admin/photos/luximage/%s/change/" % n.pk
+@receiver(post_save, sender=LuxImage)
+def post_save_events(sender, update_fields, created, instance, **kwargs):
+ 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):
+ print("hellow world")
+ base_path = "%s/%s/" % (settings.IMAGES_ROOT, instance.pub_date.strftime("%Y"))
+ img = Image.open(instance.image.path)
+ resize_image(img, 160, None, 65, base_path, "%s_tn.%s" % (instance.get_image_name(), instance.get_image_ext()))
+ for size in instance.sizes.all():
+ print(size.width)
+ resize_image(img, size.width, None, size.quality, base_path, "%s_%s.%s" % (instance.get_image_name(), size.width, instance.get_image_ext()))
+
+
class LuxGallery(models.Model):
title = models.CharField(blank=True, max_length=300)
description = models.TextField(blank=True, null=True)
@@ -317,3 +369,19 @@ class PhotoGallerySitemap(Sitemap):
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())
diff --git a/app/photos/readexif.py b/app/photos/readexif.py
new file mode 100644
index 0000000..0b3f7f7
--- /dev/null
+++ b/app/photos/readexif.py
@@ -0,0 +1,59 @@
+import time
+from fractions import Fraction
+
+from django.contrib.gis.geos import Point
+
+import exiftool
+
+from locations.models import Location
+
+
+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.point = Point(meta["XMP:GPSLongitude"], meta["XMP:GPSLatitude"], srid=4326)
+ try:
+ image.location = Location.objects.filter(geometry__contains=image.point).get()
+ except Location.DoesNotExist:
+ pass
+ except KeyError:
+ pass
+ try:
+ image.exif_aperture = meta["EXIF:FNumber"]
+ except:
+ pass
+ image.exif_make = meta["EXIF:Make"]
+ image.exif_model = meta["EXIF:Model"]
+ image.exif_exposure = str(Fraction(float(meta["EXIF:ExposureTime"])).limit_denominator())
+ image.exif_iso = meta["EXIF:ISO"]
+ image.exif_focal_length = meta["EXIF:FocalLength"]
+ fmt_date = time.strptime(meta["EXIF:DateTimeOriginal"], "%Y:%m:%d %H:%M:%S")
+ image.exif_date = time.strftime("%Y-%m-%d %H:%M:%S", fmt_date)
+ image.height = meta["File:ImageHeight"]
+ image.width = meta["File:ImageWidth"]
+ return image
diff --git a/app/photos/templatetags/get_image_size.py b/app/photos/templatetags/get_image_by_size.py
index 4ca6c66..c56c44e 100644
--- a/app/photos/templatetags/get_image_size.py
+++ b/app/photos/templatetags/get_image_by_size.py
@@ -3,6 +3,6 @@ from django import template
register = template.Library()
@register.simple_tag
-def get_image_size(obj, *args):
- method = getattr(obj, "get_image_size")
+def get_image_by_size(obj, *args):
+ method = getattr(obj, "get_image_by_size")
return method(*args)
diff --git a/app/photos/utils.py b/app/photos/utils.py
index 6cc64a3..e880277 100644
--- a/app/photos/utils.py
+++ b/app/photos/utils.py
@@ -1,4 +1,7 @@
import os
+import subprocess
+
+# pip install python-resize-image
from resizeimage import resizeimage
@@ -13,3 +16,4 @@ def resize_image(img, width=None, height=None, quality=72, base_path="", filenam
os.makedirs(base_path)
path = "%s%s" % (base_path, filename)
newimg.save(path, newimg.format, quality=quality)
+ subprocess.call(["jpegoptim", "%s" % path])
diff --git a/design/templates/admin/photos/luximage/change_form.html b/design/templates/admin/photos/luximage/change_form.html
index 9344372..a6222af 100644
--- a/design/templates/admin/photos/luximage/change_form.html
+++ b/design/templates/admin/photos/luximage/change_form.html
@@ -1,5 +1,5 @@
{% extends "admin/base_site.html" %}
-{% load get_image_size %}
+{% load get_image_by_size %}
{% load i18n admin_urls admin_static admin_modify %}
{% block extrahead %}{{ block.super }}
@@ -59,9 +59,10 @@
<div class="form-row field-image">
<div>
<label for="">Image:</label>
-<p class="file-upload"><img src="{% get_image_size original "small" %}"></p>
+<p class="file-upload"><img src="{{original.get_admin_image}}" /></p>
</div>
</div>
+
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}