##// END OF EJS Templates
Added some security to prevent generation of the same user ids
Added some security to prevent generation of the same user ids

File last commit:

r452:308af8e9 1.5-dev
r485:96b161a5 1.6-dev
Show More
thumbs.py
216 lines | 7.4 KiB | text/x-python | PythonLexer
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 # -*- encoding: utf-8 -*-
"""
django-thumbs by Antonio Melé
http://django.es
"""
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452 from django.core.files.images import ImageFile
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 from django.db.models import ImageField
from django.db.models.fields.files import ImageFieldFile
from PIL import Image
from django.core.files.base import ContentFile
import cStringIO
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 def generate_thumb(img, thumb_size, format):
"""
Generates a thumbnail image and returns a ContentFile object with the thumbnail
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 Parameters:
===========
img File object
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 thumb_size desired thumbnail size, ie: (200,120)
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 format format of the original image ('jpeg','gif','png',...)
(this format will be used for the generated thumbnail, too)
"""
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 img.seek(0) # see http://code.djangoproject.com/ticket/8222 for details
image = Image.open(img)
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 # get size
thumb_w, thumb_h = thumb_size
# If you want to generate a square thumbnail
if thumb_w == thumb_h:
# quad
xsize, ysize = image.size
# get minimum size
neko259
Added user to the posts. This refs #12
r113 minsize = min(xsize, ysize)
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 # largest square possible in the image
neko259
Added user to the posts. This refs #12
r113 xnewsize = (xsize - minsize) / 2
ynewsize = (ysize - minsize) / 2
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 # crop it
neko259
Added user to the posts. This refs #12
r113 image2 = image.crop(
(xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize))
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452 # load is necessary after crop
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 image2.load()
# thumbnail of the cropped image (with ANTIALIAS to make it look better)
image2.thumbnail(thumb_size, Image.ANTIALIAS)
else:
# not quad
image2 = image
image2.thumbnail(thumb_size, Image.ANTIALIAS)
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 io = cStringIO.StringIO()
# PNG and GIF are the same, JPG is JPEG
neko259
Added user to the posts. This refs #12
r113 if format.upper() == 'JPG':
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 format = 'JPEG'
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 image2.save(io, format)
neko259
Added user to the posts. This refs #12
r113 return ContentFile(io.getvalue())
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22
class ImageWithThumbsFieldFile(ImageFieldFile):
"""
See ImageWithThumbsField for usage example
"""
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 def __init__(self, *args, **kwargs):
super(ImageWithThumbsFieldFile, self).__init__(*args, **kwargs)
self.sizes = self.field.sizes
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 if self.sizes:
def get_size(self, size):
if not self:
return ''
else:
neko259
Added user to the posts. This refs #12
r113 split = self.url.rsplit('.', 1)
thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1])
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 return thumb_url
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 for size in self.sizes:
neko259
Added user to the posts. This refs #12
r113 (w, h) = size
setattr(self, 'url_%sx%s' % (w, h), get_size(self, size))
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 def save(self, name, content, save=True):
super(ImageWithThumbsFieldFile, self).save(name, content, save)
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 if self.sizes:
for size in self.sizes:
neko259
Added user to the posts. This refs #12
r113 (w, h) = size
split = self.name.rsplit('.', 1)
thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1])
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 # you can use another thumbnailing function if you like
thumb_content = generate_thumb(content, size, split[1])
neko259
Added user to the posts. This refs #12
r113
thumb_name_ = self.storage.save(thumb_name, thumb_content)
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 if not thumb_name == thumb_name_:
neko259
Added user to the posts. This refs #12
r113 raise ValueError(
'There is already a file named %s' % thumb_name)
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 def delete(self, save=True):
neko259
Added user to the posts. This refs #12
r113 name = self.name
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 super(ImageWithThumbsFieldFile, self).delete(save)
if self.sizes:
for size in self.sizes:
neko259
Added user to the posts. This refs #12
r113 (w, h) = size
split = name.rsplit('.', 1)
thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1])
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 try:
self.storage.delete(thumb_name)
except:
pass
neko259
Added user to the posts. This refs #12
r113
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 class ImageWithThumbsField(ImageField):
attr_class = ImageWithThumbsFieldFile
"""
Usage example:
==============
photo = ImageWithThumbsField(upload_to='images', sizes=((125,125),(300,200),)
To retrieve image URL, exactly the same way as with ImageField:
my_object.photo.url
To retrieve thumbnails URL's just add the size to it:
my_object.photo.url_125x125
my_object.photo.url_300x200
Note: The 'sizes' attribute is not required. If you don't provide it,
ImageWithThumbsField will act as a normal ImageField
How it works:
=============
For each size in the 'sizes' atribute of the field it generates a
thumbnail with that size and stores it following this format:
available_filename.[width]x[height].extension
Where 'available_filename' is the available filename returned by the storage
backend for saving the original file.
Following the usage example above: For storing a file called "photo.jpg" it saves:
photo.jpg (original file)
photo.125x125.jpg (first thumbnail)
photo.300x200.jpg (second thumbnail)
With the default storage backend if photo.jpg already exists it will use these filenames:
photo_.jpg
photo_.125x125.jpg
photo_.300x200.jpg
Note: django-thumbs assumes that if filename "any_filename.jpg" is available
filenames with this format "any_filename.[widht]x[height].jpg" will be available, too.
To do:
======
Add method to regenerate thubmnails
neko259
Added initial database migration. Added south support. This fixes #41
r114
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22
"""
neko259
Added user to the posts. This refs #12
r113
def __init__(self, verbose_name=None, name=None, width_field=None,
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452 height_field=None, sizes=None,
preview_width_field=None, preview_height_field=None,
**kwargs):
neko259
Added user to the posts. This refs #12
r113 self.verbose_name = verbose_name
self.name = name
self.width_field = width_field
self.height_field = height_field
neko259
Added images upload. Changed the design a bit. Reformatted some code by PEP 8. Changed the urls: not the main site is located at /, not /boards/.
r22 self.sizes = sizes
neko259
Added initial database migration. Added south support. This fixes #41
r114 super(ImageField, self).__init__(**kwargs)
neko259
Saving image thumbnails size to the database and using this size in the HTML
r452 if sizes is not None and len(sizes) == 1:
self.preview_width_field = preview_width_field
self.preview_height_field = preview_height_field
def update_dimension_fields(self, instance, force=False, *args, **kwargs):
"""
Update original image dimension fields and thumb dimension fields
(only if 1 thumb size is defined)
"""
super(ImageWithThumbsField, self).update_dimension_fields(instance,
force, *args,
**kwargs)
thumb_width_field = self.preview_width_field
thumb_height_field = self.preview_height_field
if thumb_width_field is None or thumb_height_field is None \
or len(self.sizes) != 1:
return
original_width = getattr(instance, self.width_field)
original_height = getattr(instance, self.height_field)
if original_width > 0 and original_height > 0:
thumb_width, thumb_height = self.sizes[0]
w_scale = float(thumb_width) / original_width
h_scale = float(thumb_height) / original_height
scale_ratio = min(w_scale, h_scale)
if scale_ratio >= 1:
thumb_width_ratio = original_width
thumb_height_ratio = original_height
else:
thumb_width_ratio = int(original_width * scale_ratio)
thumb_height_ratio = int(original_height * scale_ratio)
setattr(instance, thumb_width_field, thumb_width_ratio)
setattr(instance, thumb_height_field, thumb_height_ratio)
neko259
Added initial database migration. Added south support. This fixes #41
r114
from south.modelsinspector import add_introspection_rules
neko259
Merged with default branch
r137 add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"])