Mercurial > public > sg101
diff potd/models.py @ 581:ee87ea74d46b
For Django 1.4, rearranged project structure for new manage.py.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 05 May 2012 17:10:48 -0500 |
parents | gpp/potd/models.py@4021ea1045f7 |
children | 2d35e5f97a99 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/potd/models.py Sat May 05 17:10:48 2012 -0500 @@ -0,0 +1,177 @@ +""" +Models for the Photo Of The Day (POTD) application. + +""" +import datetime +import os +from PIL import ImageFile +from PIL import Image +try: + from cStringIO import StringIO +except: + from StringIO import StringIO + +from django.db import models +from django.contrib.auth.models import User +from django.core.files.base import ContentFile + +POTD_THUMB_WIDTH = 120 + +def scale_image(image): + (w, h) = image.size + if w <= POTD_THUMB_WIDTH: + return image + scale_factor = float(POTD_THUMB_WIDTH) / w + new_height = int(scale_factor * h) + return image.resize((POTD_THUMB_WIDTH, new_height), Image.ANTIALIAS) + + +class Photo(models.Model): + """Model to represent a POTD""" + photo = models.ImageField(upload_to='potd/%Y/%m/%d') + thumb = models.ImageField(upload_to='potd/%Y/%m/%d/thumbs', blank=True, null=True) + caption = models.CharField(max_length=128) + description = models.TextField() + user = models.ForeignKey(User) + date_added = models.DateField() + potd_count = models.IntegerField(default=0) + + class Meta: + ordering = ('-date_added', '-caption') + + def __unicode__(self): + return u'%s (%s)' % (self.caption, self.pk) + + @models.permalink + def get_absolute_url(self): + return ('potd-archive', [str(self.id)]) + + def save(self, *args, **kwargs): + if not self.pk: + self.generate_thumb() + self.date_added = datetime.datetime.now() + + super(Photo, self).save(*args, **kwargs) + + def can_comment_on(self): + return Current.objects.get_current_id() == self.id + + def generate_thumb(self): + if self.thumb: + self.thumb.delete(save=False) + + parser = ImageFile.Parser() + for chunk in self.photo.chunks(): + parser.feed(chunk) + image = parser.close() + format = image.format + image = scale_image(image) + s = StringIO() + image.save(s, format) + thumb_name = os.path.basename(self.photo.path) + self.thumb.save(thumb_name, ContentFile(s.getvalue()), save=False) + + def ogp_tags(self): + """ + Returns a dict of Open Graph Protocol meta tags. + + """ + desc = "Photo of the day: %s." % self.caption + return { + 'og:title': self.caption, + 'og:type': 'article', + 'og:url': self.get_absolute_url(), + 'og:image': self.photo.url, + 'og:description': desc, + } + + +class CurrentManager(models.Manager): + """ + Manager for the Current model. + + """ + def get_current_photo(self): + """ + Retrieves the current photo object from the current record. + + """ + try: + c = self.get(pk=1) + return c.potd + except Current.DoesNotExist: + return None + + def get_current_id(self): + """ + Returns the ID of the current POTD from the current record. + + """ + potd = self.get_current_photo() + if potd is not None: + return potd.pk + return None + + +class Current(models.Model): + """This model simply stores the current POTD.""" + potd = models.ForeignKey(Photo) + + objects = CurrentManager() + + def __unicode__(self): + return self.potd.__unicode__() + + class Meta: + verbose_name_plural = 'Current' + + +class SequenceManager(models.Manager): + """ + Manager for the Sequence model. + + """ + def insert_photo(self, photo_id): + """ + Inserts the given photo_id just after the current photo so it + will appear as tomorrow's POTD. + + """ + current = Current.objects.get_current_id() + if current is not None: + s = self.get(pk=1) + seq = [int(x) for x in s.seq.split(',')] + if photo_id not in seq: + i = seq.index(current) + seq.insert(i + 1, photo_id) + s.seq = ','.join([str(x) for x in seq]) + s.save() + + def remove_photo(self, photo_id): + """ + Removes a given photo id from the sequence of photos. + + """ + try: + s = self.get(pk=1) + except Sequence.DoesNotExist: + pass + else: + seq = [int(x) for x in s.seq.split(',')] + if photo_id in seq: + seq.remove(photo_id) + s.seq = ','.join([str(x) for x in seq]) + s.save() + + +class Sequence(models.Model): + """This model stores the sequence of photos for the POTD.""" + seq = models.CommaSeparatedIntegerField(max_length=4096) + + objects = SequenceManager() + + def __unicode__(self): + return u'POTD Sequence %d' % self.id + + class Meta: + verbose_name_plural = 'Sequence'