annotate gpp/potd/models.py @ 6:b6263ac72052

Use DRY principle to manage third party javascript libraries. Created script_tags template tags to generate the correct link and script tags for 3rd party libraries. The settings.py file is the only place where the full path name is specified.
author Brian Neal <bgneal@gmail.com>
date Sat, 11 Apr 2009 22:50:56 +0000
parents dbd703f7d63a
children 7b6540b185d9
rev   line source
gremmie@1 1 """
gremmie@1 2 Models for the Photo Of The Day (POTD) application.
gremmie@1 3 """
gremmie@1 4 import os
gremmie@1 5 from PIL import ImageFile
gremmie@1 6 from PIL import Image
gremmie@1 7 try:
gremmie@1 8 from cStringIO import StringIO
gremmie@1 9 except:
gremmie@1 10 from StringIO import StringIO
gremmie@1 11
gremmie@1 12 from django.db import models
gremmie@1 13 from django.contrib.auth.models import User
gremmie@1 14 from django.core.files.base import ContentFile
gremmie@1 15
gremmie@1 16 POTD_THUMB_WIDTH = 120
gremmie@1 17
gremmie@1 18 def scale_image(image):
gremmie@1 19 (w, h) = image.size
gremmie@1 20 if w <= POTD_THUMB_WIDTH:
gremmie@1 21 return image
gremmie@1 22 scale_factor = float(POTD_THUMB_WIDTH) / w
gremmie@1 23 new_height = int(scale_factor * h)
gremmie@1 24 return image.resize((POTD_THUMB_WIDTH, new_height), Image.ANTIALIAS)
gremmie@1 25
gremmie@1 26
gremmie@1 27 class Photo(models.Model):
gremmie@1 28 """Model to represent a POTD"""
gremmie@1 29 photo = models.ImageField(upload_to='potd/%Y/%m/%d')
gremmie@1 30 thumb = models.ImageField(upload_to='potd/%Y/%m/%d/thumbs', blank=True, null=True)
gremmie@1 31 caption = models.CharField(max_length=128)
gremmie@1 32 description = models.TextField()
gremmie@1 33 user = models.ForeignKey(User)
gremmie@1 34 date_added = models.DateField(auto_now_add=True)
gremmie@1 35 potd_count = models.IntegerField(default=0)
gremmie@1 36
gremmie@1 37 def __unicode__(self):
gremmie@1 38 return u'%s (%s)' % (self.caption, self.pk)
gremmie@1 39
gremmie@1 40 class Meta:
gremmie@1 41 ordering = ('-date_added', '-caption')
gremmie@1 42
gremmie@1 43 def save(self, force_insert=False, force_update=False):
gremmie@1 44
gremmie@1 45 if self.thumb:
gremmie@1 46 self.thumb.delete(save=False)
gremmie@1 47
gremmie@1 48 parser = ImageFile.Parser()
gremmie@1 49 for chunk in self.photo.chunks():
gremmie@1 50 parser.feed(chunk)
gremmie@1 51 image = parser.close()
gremmie@1 52 format = image.format
gremmie@1 53 image = scale_image(image)
gremmie@1 54 s = StringIO()
gremmie@1 55 image.save(s, format)
gremmie@1 56 thumb_name = os.path.basename(self.photo.path)
gremmie@1 57 self.thumb.save(thumb_name, ContentFile(s.getvalue()), save=False)
gremmie@1 58
gremmie@1 59 super(Photo, self).save(force_insert, force_update)
gremmie@1 60 Sequence.objects.insert_photo(self.pk)
gremmie@1 61
gremmie@1 62 def delete(self):
gremmie@1 63 Sequence.objects.remove_photo(self.pk)
gremmie@1 64 super(Photo, self).delete()
gremmie@1 65
gremmie@1 66 def can_comment_on(self):
gremmie@1 67 return Current.objects.get_current_id() == self.id
gremmie@1 68
gremmie@1 69
gremmie@1 70 class CurrentManager(models.Manager):
gremmie@1 71 def get_current_photo(self):
gremmie@1 72 try:
gremmie@1 73 c = self.get(pk=1)
gremmie@1 74 return c.potd
gremmie@1 75 except Current.DoesNotExist:
gremmie@1 76 return None
gremmie@1 77
gremmie@1 78 def get_current_id(self):
gremmie@1 79 potd = self.get_current_photo()
gremmie@1 80 if potd is not None:
gremmie@1 81 return potd.pk
gremmie@1 82 return None
gremmie@1 83
gremmie@1 84
gremmie@1 85 class Current(models.Model):
gremmie@1 86 """This model simply stores the current POTD."""
gremmie@1 87 potd = models.ForeignKey(Photo)
gremmie@1 88
gremmie@1 89 objects = CurrentManager()
gremmie@1 90
gremmie@1 91 def __unicode__(self):
gremmie@1 92 return self.potd.__unicode__()
gremmie@1 93
gremmie@1 94 class Meta:
gremmie@1 95 verbose_name_plural = 'Current'
gremmie@1 96
gremmie@1 97
gremmie@1 98 class SequenceManager(models.Manager):
gremmie@1 99 def insert_photo(self, photo_id):
gremmie@1 100 current = Current.objects.get_current_id()
gremmie@1 101 if current is not None:
gremmie@1 102 try:
gremmie@1 103 s = self.get(pk=1)
gremmie@1 104 seq = [int(x) for x in s.seq.split(',')]
gremmie@1 105 if photo_id not in seq:
gremmie@1 106 i = seq.index(current)
gremmie@1 107 seq.insert(i + 1, photo_id)
gremmie@1 108 s.seq = ','.join([str(x) for x in seq])
gremmie@1 109 s.save()
gremmie@1 110 except:
gremmie@1 111 pass
gremmie@1 112
gremmie@1 113 def remove_photo(self, photo_id):
gremmie@1 114 try:
gremmie@1 115 s = self.get(pk=1)
gremmie@1 116 seq = [int(x) for x in s.seq.split(',')]
gremmie@1 117 if photo_id in seq:
gremmie@1 118 seq.remove(photo_id)
gremmie@1 119 s.seq = ','.join([str(x) for x in seq])
gremmie@1 120 s.save()
gremmie@1 121 except:
gremmie@1 122 pass
gremmie@1 123
gremmie@1 124
gremmie@1 125 class Sequence(models.Model):
gremmie@1 126 """This model stores the sequence of photos for the POTD."""
gremmie@1 127 seq = models.CommaSeparatedIntegerField(max_length=4096)
gremmie@1 128
gremmie@1 129 objects = SequenceManager()
gremmie@1 130
gremmie@1 131 def __unicode__(self):
gremmie@1 132 return self.seq
gremmie@1 133
gremmie@1 134 class Meta:
gremmie@1 135 verbose_name_plural = 'Sequence'
gremmie@1 136