Show More
@@ -0,0 +1,92 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | from south.utils import datetime_utils as datetime | |||
|
3 | from south.db import db | |||
|
4 | from south.v2 import SchemaMigration | |||
|
5 | from django.db import models | |||
|
6 | ||||
|
7 | ||||
|
8 | class Migration(SchemaMigration): | |||
|
9 | ||||
|
10 | def forwards(self, orm): | |||
|
11 | # Adding field 'Post.image_pre_width' | |||
|
12 | db.add_column(u'boards_post', 'image_pre_width', | |||
|
13 | self.gf('django.db.models.fields.IntegerField')(default=0), | |||
|
14 | keep_default=False) | |||
|
15 | ||||
|
16 | # Adding field 'Post.image_pre_height' | |||
|
17 | db.add_column(u'boards_post', 'image_pre_height', | |||
|
18 | self.gf('django.db.models.fields.IntegerField')(default=0), | |||
|
19 | keep_default=False) | |||
|
20 | ||||
|
21 | ||||
|
22 | def backwards(self, orm): | |||
|
23 | # Deleting field 'Post.image_pre_width' | |||
|
24 | db.delete_column(u'boards_post', 'image_pre_width') | |||
|
25 | ||||
|
26 | # Deleting field 'Post.image_pre_height' | |||
|
27 | db.delete_column(u'boards_post', 'image_pre_height') | |||
|
28 | ||||
|
29 | ||||
|
30 | models = { | |||
|
31 | 'boards.ban': { | |||
|
32 | 'Meta': {'object_name': 'Ban'}, | |||
|
33 | 'can_read': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |||
|
34 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
35 | 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
36 | 'reason': ('django.db.models.fields.CharField', [], {'default': "'Auto'", 'max_length': '200'}) | |||
|
37 | }, | |||
|
38 | 'boards.post': { | |||
|
39 | 'Meta': {'object_name': 'Post'}, | |||
|
40 | '_text_rendered': ('django.db.models.fields.TextField', [], {}), | |||
|
41 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
42 | 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), | |||
|
43 | 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
44 | 'image_pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
45 | 'image_pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
46 | 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
47 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
48 | 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
49 | 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), | |||
|
50 | 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
51 | 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rfp+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |||
|
52 | 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), | |||
|
53 | 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}), | |||
|
54 | 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Post']", 'null': 'True'}), | |||
|
55 | 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Thread']", 'null': 'True'}), | |||
|
56 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | |||
|
57 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.User']", 'null': 'True'}) | |||
|
58 | }, | |||
|
59 | 'boards.setting': { | |||
|
60 | 'Meta': {'object_name': 'Setting'}, | |||
|
61 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
62 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | |||
|
63 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.User']"}), | |||
|
64 | 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |||
|
65 | }, | |||
|
66 | 'boards.tag': { | |||
|
67 | 'Meta': {'object_name': 'Tag'}, | |||
|
68 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
69 | 'linked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), | |||
|
70 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |||
|
71 | 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Thread']"}) | |||
|
72 | }, | |||
|
73 | 'boards.thread': { | |||
|
74 | 'Meta': {'object_name': 'Thread'}, | |||
|
75 | 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
76 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
77 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
78 | 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tre+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |||
|
79 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Tag']", 'symmetrical': 'False'}) | |||
|
80 | }, | |||
|
81 | 'boards.user': { | |||
|
82 | 'Meta': {'object_name': 'User'}, | |||
|
83 | 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), | |||
|
84 | 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |||
|
85 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
86 | 'rank': ('django.db.models.fields.IntegerField', [], {}), | |||
|
87 | 'registration_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
88 | 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |||
|
89 | } | |||
|
90 | } | |||
|
91 | ||||
|
92 | complete_apps = ['boards'] No newline at end of file |
@@ -235,10 +235,15 b' class Post(models.Model):' | |||||
235 | image_width = models.IntegerField(default=0) |
|
235 | image_width = models.IntegerField(default=0) | |
236 | image_height = models.IntegerField(default=0) |
|
236 | image_height = models.IntegerField(default=0) | |
237 |
|
237 | |||
|
238 | image_pre_width = models.IntegerField(default=0) | |||
|
239 | image_pre_height = models.IntegerField(default=0) | |||
|
240 | ||||
238 | image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename, |
|
241 | image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename, | |
239 | blank=True, sizes=(IMAGE_THUMB_SIZE,), |
|
242 | blank=True, sizes=(IMAGE_THUMB_SIZE,), | |
240 | width_field='image_width', |
|
243 | width_field='image_width', | |
241 |
height_field='image_height' |
|
244 | height_field='image_height', | |
|
245 | preview_width_field='image_pre_width', | |||
|
246 | preview_height_field='image_pre_height') | |||
242 |
|
247 | |||
243 | poster_ip = models.GenericIPAddressField() |
|
248 | poster_ip = models.GenericIPAddressField() | |
244 | poster_user_agent = models.TextField() |
|
249 | poster_user_agent = models.TextField() |
@@ -173,8 +173,6 b' blockquote {' | |||||
173 | min-width: 1px; |
|
173 | min-width: 1px; | |
174 | text-align: center; |
|
174 | text-align: center; | |
175 | display: table-row; |
|
175 | display: table-row; | |
176 |
|
||||
177 | height: 150px; |
|
|||
178 | } |
|
176 | } | |
179 |
|
177 | |||
180 | .post > .metadata { |
|
178 | .post > .metadata { |
@@ -171,8 +171,6 b' blockquote {' | |||||
171 | min-width: 1px; |
|
171 | min-width: 1px; | |
172 | text-align: center; |
|
172 | text-align: center; | |
173 | display: table-row; |
|
173 | display: table-row; | |
174 |
|
||||
175 | height: 150px; |
|
|||
176 | } |
|
174 | } | |
177 |
|
175 | |||
178 | .post > .metadata { |
|
176 | .post > .metadata { |
@@ -79,6 +79,8 b'' | |||||
79 | href="{{ thread.op.image.url }}"><img |
|
79 | href="{{ thread.op.image.url }}"><img | |
80 | src="{{ thread.op.image.url_200x150 }}" |
|
80 | src="{{ thread.op.image.url_200x150 }}" | |
81 | alt="{{ thread.op.id }}" |
|
81 | alt="{{ thread.op.id }}" | |
|
82 | width="{{ thread.op.image_pre_width }}" | |||
|
83 | height="{{ thread.op.image_pre_height }}" | |||
82 | data-width="{{ thread.op.image_width }}" |
|
84 | data-width="{{ thread.op.image_width }}" | |
83 | data-height="{{ thread.op.image_height }}"/> |
|
85 | data-height="{{ thread.op.image_height }}"/> | |
84 | </a> |
|
86 | </a> | |
@@ -154,6 +156,8 b'' | |||||
154 | href="{{ post.image.url }}"><img |
|
156 | href="{{ post.image.url }}"><img | |
155 | src=" {{ post.image.url_200x150 }}" |
|
157 | src=" {{ post.image.url_200x150 }}" | |
156 | alt="{{ post.id }}" |
|
158 | alt="{{ post.id }}" | |
|
159 | width="{{ post.image_pre_width }}" | |||
|
160 | height="{{ post.image_pre_height }}" | |||
157 | data-width="{{ post.image_width }}" |
|
161 | data-width="{{ post.image_width }}" | |
158 | data-height="{{ post.image_height }}"/> |
|
162 | data-height="{{ post.image_height }}"/> | |
159 | </a> |
|
163 | </a> | |
@@ -227,7 +231,7 b'' | |||||
227 | {% block metapanel %} |
|
231 | {% block metapanel %} | |
228 |
|
232 | |||
229 | <span class="metapanel"> |
|
233 | <span class="metapanel"> | |
230 |
<b><a href="{% url "authors" %}">Neboard</a> 1. |
|
234 | <b><a href="{% url "authors" %}">Neboard</a> 1.5</b> | |
231 | {% trans "Pages:" %} |
|
235 | {% trans "Pages:" %} | |
232 | {% for page in pages %} |
|
236 | {% for page in pages %} | |
233 | [<a href=" |
|
237 | [<a href=" |
@@ -40,6 +40,8 b'' | |||||
40 | href="{{ post.image.url }}"><img |
|
40 | href="{{ post.image.url }}"><img | |
41 | src="{{ post.image.url_200x150 }}" |
|
41 | src="{{ post.image.url_200x150 }}" | |
42 | alt="{{ post.id }}" |
|
42 | alt="{{ post.id }}" | |
|
43 | width="{{ post.image_pre_width }}" | |||
|
44 | height="{{ post.image_pre_height }}" | |||
43 | data-width="{{ post.image_width }}" |
|
45 | data-width="{{ post.image_width }}" | |
44 | data-height="{{ post.image_height }}"/> |
|
46 | data-height="{{ post.image_height }}"/> | |
45 | </a> |
|
47 | </a> |
@@ -3,6 +3,7 b'' | |||||
3 | django-thumbs by Antonio MelΓ© |
|
3 | django-thumbs by Antonio MelΓ© | |
4 | http://django.es |
|
4 | http://django.es | |
5 | """ |
|
5 | """ | |
|
6 | from django.core.files.images import ImageFile | |||
6 | from django.db.models import ImageField |
|
7 | from django.db.models import ImageField | |
7 | from django.db.models.fields.files import ImageFieldFile |
|
8 | from django.db.models.fields.files import ImageFieldFile | |
8 | from PIL import Image |
|
9 | from PIL import Image | |
@@ -13,13 +14,13 b' import cStringIO' | |||||
13 | def generate_thumb(img, thumb_size, format): |
|
14 | def generate_thumb(img, thumb_size, format): | |
14 | """ |
|
15 | """ | |
15 | Generates a thumbnail image and returns a ContentFile object with the thumbnail |
|
16 | Generates a thumbnail image and returns a ContentFile object with the thumbnail | |
16 |
|
17 | |||
17 | Parameters: |
|
18 | Parameters: | |
18 | =========== |
|
19 | =========== | |
19 | img File object |
|
20 | img File object | |
20 |
|
21 | |||
21 | thumb_size desired thumbnail size, ie: (200,120) |
|
22 | thumb_size desired thumbnail size, ie: (200,120) | |
22 |
|
23 | |||
23 | format format of the original image ('jpeg','gif','png',...) |
|
24 | format format of the original image ('jpeg','gif','png',...) | |
24 | (this format will be used for the generated thumbnail, too) |
|
25 | (this format will be used for the generated thumbnail, too) | |
25 | """ |
|
26 | """ | |
@@ -41,7 +42,7 b' def generate_thumb(img, thumb_size, form' | |||||
41 | # crop it |
|
42 | # crop it | |
42 | image2 = image.crop( |
|
43 | image2 = image.crop( | |
43 | (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize)) |
|
44 | (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize)) | |
44 |
# load is necessary after crop |
|
45 | # load is necessary after crop | |
45 | image2.load() |
|
46 | image2.load() | |
46 | # thumbnail of the cropped image (with ANTIALIAS to make it look better) |
|
47 | # thumbnail of the cropped image (with ANTIALIAS to make it look better) | |
47 | image2.thumbnail(thumb_size, Image.ANTIALIAS) |
|
48 | image2.thumbnail(thumb_size, Image.ANTIALIAS) | |
@@ -160,7 +161,9 b' class ImageWithThumbsField(ImageField):' | |||||
160 | """ |
|
161 | """ | |
161 |
|
162 | |||
162 | def __init__(self, verbose_name=None, name=None, width_field=None, |
|
163 | def __init__(self, verbose_name=None, name=None, width_field=None, | |
163 |
height_field=None, sizes=None, |
|
164 | height_field=None, sizes=None, | |
|
165 | preview_width_field=None, preview_height_field=None, | |||
|
166 | **kwargs): | |||
164 | self.verbose_name = verbose_name |
|
167 | self.verbose_name = verbose_name | |
165 | self.name = name |
|
168 | self.name = name | |
166 | self.width_field = width_field |
|
169 | self.width_field = width_field | |
@@ -168,6 +171,46 b' class ImageWithThumbsField(ImageField):' | |||||
168 | self.sizes = sizes |
|
171 | self.sizes = sizes | |
169 | super(ImageField, self).__init__(**kwargs) |
|
172 | super(ImageField, self).__init__(**kwargs) | |
170 |
|
173 | |||
|
174 | if sizes is not None and len(sizes) == 1: | |||
|
175 | self.preview_width_field = preview_width_field | |||
|
176 | self.preview_height_field = preview_height_field | |||
|
177 | ||||
|
178 | def update_dimension_fields(self, instance, force=False, *args, **kwargs): | |||
|
179 | """ | |||
|
180 | Update original image dimension fields and thumb dimension fields | |||
|
181 | (only if 1 thumb size is defined) | |||
|
182 | """ | |||
|
183 | ||||
|
184 | super(ImageWithThumbsField, self).update_dimension_fields(instance, | |||
|
185 | force, *args, | |||
|
186 | **kwargs) | |||
|
187 | thumb_width_field = self.preview_width_field | |||
|
188 | thumb_height_field = self.preview_height_field | |||
|
189 | ||||
|
190 | if thumb_width_field is None or thumb_height_field is None \ | |||
|
191 | or len(self.sizes) != 1: | |||
|
192 | return | |||
|
193 | ||||
|
194 | original_width = getattr(instance, self.width_field) | |||
|
195 | original_height = getattr(instance, self.height_field) | |||
|
196 | ||||
|
197 | if original_width > 0 and original_height > 0: | |||
|
198 | thumb_width, thumb_height = self.sizes[0] | |||
|
199 | ||||
|
200 | w_scale = float(thumb_width) / original_width | |||
|
201 | h_scale = float(thumb_height) / original_height | |||
|
202 | scale_ratio = min(w_scale, h_scale) | |||
|
203 | ||||
|
204 | if scale_ratio >= 1: | |||
|
205 | thumb_width_ratio = original_width | |||
|
206 | thumb_height_ratio = original_height | |||
|
207 | else: | |||
|
208 | thumb_width_ratio = int(original_width * scale_ratio) | |||
|
209 | thumb_height_ratio = int(original_height * scale_ratio) | |||
|
210 | ||||
|
211 | setattr(instance, thumb_width_field, thumb_width_ratio) | |||
|
212 | setattr(instance, thumb_height_field, thumb_height_ratio) | |||
|
213 | ||||
171 |
|
214 | |||
172 | from south.modelsinspector import add_introspection_rules |
|
215 | from south.modelsinspector import add_introspection_rules | |
173 | add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"]) |
|
216 | add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"]) |
General Comments 0
You need to be logged in to leave comments.
Login now