Source code for mg.media.photo.models

# 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)