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
|
bgneal@14
|
37 class Meta:
|
bgneal@14
|
38 ordering = ('-date_added', '-caption')
|
bgneal@14
|
39
|
gremmie@1
|
40 def __unicode__(self):
|
gremmie@1
|
41 return u'%s (%s)' % (self.caption, self.pk)
|
gremmie@1
|
42
|
bgneal@14
|
43 @models.permalink
|
bgneal@14
|
44 def get_absolute_url(self):
|
bgneal@14
|
45 return ('potd-archive', [str(self.id)])
|
gremmie@1
|
46
|
gremmie@1
|
47 def save(self, force_insert=False, force_update=False):
|
gremmie@1
|
48
|
gremmie@1
|
49 if self.thumb:
|
gremmie@1
|
50 self.thumb.delete(save=False)
|
gremmie@1
|
51
|
gremmie@1
|
52 parser = ImageFile.Parser()
|
gremmie@1
|
53 for chunk in self.photo.chunks():
|
gremmie@1
|
54 parser.feed(chunk)
|
gremmie@1
|
55 image = parser.close()
|
gremmie@1
|
56 format = image.format
|
gremmie@1
|
57 image = scale_image(image)
|
gremmie@1
|
58 s = StringIO()
|
gremmie@1
|
59 image.save(s, format)
|
gremmie@1
|
60 thumb_name = os.path.basename(self.photo.path)
|
gremmie@1
|
61 self.thumb.save(thumb_name, ContentFile(s.getvalue()), save=False)
|
gremmie@1
|
62
|
gremmie@1
|
63 super(Photo, self).save(force_insert, force_update)
|
gremmie@1
|
64 Sequence.objects.insert_photo(self.pk)
|
gremmie@1
|
65
|
gremmie@1
|
66 def delete(self):
|
gremmie@1
|
67 Sequence.objects.remove_photo(self.pk)
|
gremmie@1
|
68 super(Photo, self).delete()
|
gremmie@1
|
69
|
gremmie@1
|
70 def can_comment_on(self):
|
gremmie@1
|
71 return Current.objects.get_current_id() == self.id
|
gremmie@1
|
72
|
gremmie@1
|
73
|
gremmie@1
|
74 class CurrentManager(models.Manager):
|
gremmie@1
|
75 def get_current_photo(self):
|
gremmie@1
|
76 try:
|
gremmie@1
|
77 c = self.get(pk=1)
|
gremmie@1
|
78 return c.potd
|
gremmie@1
|
79 except Current.DoesNotExist:
|
gremmie@1
|
80 return None
|
gremmie@1
|
81
|
gremmie@1
|
82 def get_current_id(self):
|
gremmie@1
|
83 potd = self.get_current_photo()
|
gremmie@1
|
84 if potd is not None:
|
gremmie@1
|
85 return potd.pk
|
gremmie@1
|
86 return None
|
gremmie@1
|
87
|
gremmie@1
|
88
|
gremmie@1
|
89 class Current(models.Model):
|
gremmie@1
|
90 """This model simply stores the current POTD."""
|
gremmie@1
|
91 potd = models.ForeignKey(Photo)
|
gremmie@1
|
92
|
gremmie@1
|
93 objects = CurrentManager()
|
gremmie@1
|
94
|
gremmie@1
|
95 def __unicode__(self):
|
gremmie@1
|
96 return self.potd.__unicode__()
|
gremmie@1
|
97
|
gremmie@1
|
98 class Meta:
|
gremmie@1
|
99 verbose_name_plural = 'Current'
|
gremmie@1
|
100
|
gremmie@1
|
101
|
gremmie@1
|
102 class SequenceManager(models.Manager):
|
gremmie@1
|
103 def insert_photo(self, photo_id):
|
gremmie@1
|
104 current = Current.objects.get_current_id()
|
gremmie@1
|
105 if current is not None:
|
gremmie@1
|
106 try:
|
gremmie@1
|
107 s = self.get(pk=1)
|
gremmie@1
|
108 seq = [int(x) for x in s.seq.split(',')]
|
gremmie@1
|
109 if photo_id not in seq:
|
gremmie@1
|
110 i = seq.index(current)
|
gremmie@1
|
111 seq.insert(i + 1, photo_id)
|
gremmie@1
|
112 s.seq = ','.join([str(x) for x in seq])
|
gremmie@1
|
113 s.save()
|
gremmie@1
|
114 except:
|
gremmie@1
|
115 pass
|
gremmie@1
|
116
|
gremmie@1
|
117 def remove_photo(self, photo_id):
|
gremmie@1
|
118 try:
|
gremmie@1
|
119 s = self.get(pk=1)
|
gremmie@1
|
120 seq = [int(x) for x in s.seq.split(',')]
|
gremmie@1
|
121 if photo_id in seq:
|
gremmie@1
|
122 seq.remove(photo_id)
|
gremmie@1
|
123 s.seq = ','.join([str(x) for x in seq])
|
gremmie@1
|
124 s.save()
|
gremmie@1
|
125 except:
|
gremmie@1
|
126 pass
|
gremmie@1
|
127
|
gremmie@1
|
128
|
gremmie@1
|
129 class Sequence(models.Model):
|
gremmie@1
|
130 """This model stores the sequence of photos for the POTD."""
|
gremmie@1
|
131 seq = models.CommaSeparatedIntegerField(max_length=4096)
|
gremmie@1
|
132
|
gremmie@1
|
133 objects = SequenceManager()
|
gremmie@1
|
134
|
gremmie@1
|
135 def __unicode__(self):
|
gremmie@1
|
136 return self.seq
|
gremmie@1
|
137
|
gremmie@1
|
138 class Meta:
|
gremmie@1
|
139 verbose_name_plural = 'Sequence'
|
gremmie@1
|
140
|