# MG_GPL_HEADER_BEGIN
#
# This file is part of Media Gallery, GNU GPLv2.
#
# Media Gallery is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# Media Gallery is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Media Gallery; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# MG_GPL_HEADER_END
__author__ = "Media Gallery contributors <mg@lists.ssji.net>"
__copyright__ = "(c) 2010"
__credits__ = ["Dimitri Refauvelet", "Nicolas Pouillon"]
from django.db import models
from django.db.models.signals import post_save
from mg.core.element.models import Element, Thumbnail
__all__ = ['Photo', 'ResizedPhoto', 'PhotoSize']
class Photo(Element):
[docs] FORMATS = (
('RAW', 'RAW'),
('CR2', 'Canon RAW 2'),
('CRW', 'Canon RAM'),
('JPG', 'Jpeg'),
('PNG', 'PNG'),
)
BOTTOM_SIDE = (
('D', 'Default'),
('B', 'Bottom'),
('L', 'Left'),
('T', 'Top'),
('R', 'Right'),
)
width = models.IntegerField()
height = models.IntegerField()
ratio = models.FloatField(db_index = True)
largest = models.IntegerField(db_index = True)
file = models.ImageField(upload_to = "spool",
width_field = "width",
height_field = "height")
format = models.CharField(db_index = True, max_length = 3, choices = FORMATS)
bottom_side = models.CharField(db_index = True, max_length = 1, choices = BOTTOM_SIDE, default = "D")
def save(self, *args, **kwargs):
if self.width is None:
super(Photo, self).save(*args, **kwargs)
self.ratio = float(self.width)/self.height
self.largest = max((self.width, self.height))
super(Photo, self).save(*args, **kwargs)
def __unicode__(self):
return u"%s"%(self.name)
@classmethod
def __get_resizer(cls):
from mg.utils.resizer import resizer
return resizer
@property
def spool_filename(self):
[docs] from django.conf import settings
import os.path
return str(os.path.join(settings.MEDIA_ROOT, self.file.name))
def thumbnail_new(self, thumb_size):
from django.core.files.base import File
import tempfile
t = Thumbnail(
size = thumb_size,
element = self)
output = t.filename_gen()
t.save()
r = self.__get_resizer()
r.set_output_size(size = thumb_size.wh, mode = r.PAN_SCAN)
out = tempfile.NamedTemporaryFile(suffix = ".jpg", mode = "w+b")
r.resize(out.name, self.spool_filename, rot_count = self._get_rot())
out.seek(0)
t.file.save(t.filename_gen(), File(out))
return t
def _get_rot(self):
"""
Returns the number of rotations of 90 degrees, clockwise, to
apply to image
"""
# If bottom side of scene is on right side (R) of picture, we
# have to rotate the image once clockwise, so R=1, others are
# trivial.
return "BRTLD".find(self.bottom_side) % 4
Element.register_type("photo", Photo)
class PhotoSize(models.Model):
[docs] width = models.IntegerField(db_index = True)
height = models.IntegerField(db_index = True)
class Meta:
unique_together = (
("width", "height"),
)
def __unicode__(self):
return u"%dx%d"%(self.width, self.height)
@property
def wh(self):
[docs] """
property corresponding to (width, height) of photo size
"""
return self.width, self.height
class ResizedPhoto(models.Model):
[docs] photo = models.ForeignKey(Photo)
size = models.ForeignKey(PhotoSize)
file = models.ImageField(upload_to = "resized")
def filename_gen(self):
[docs] base = u"%s_%s"%(self.photo.name, self.size)
return self.file.storage.get_available_name(
self.file.storage.get_valid_name(base+".jpg"))
class Meta:
unique_together = (
('photo', 'size'),
)
def __unicode__(self):
return u"<%s @%s>"%(self.photo, self.size)
def image_changed(sender, instance, **kwargs):
instance.thumbnail_set.all().delete()
instance.resizedphoto_set.all().delete()
# Thumbnail.objects.filter(element = instance).delete()
# ResizedPhoto.objects.filter(photo = instance).delete()
print 'Deleted data associated with', instance
post_save.connect(image_changed, sender=Photo)