Ticket #961: thumbnailing2.diff

File thumbnailing2.diff, 5.8 KB (added by dcwatson@…, 9 years ago)

second stab: thumb_mode, automatic deletion

  • core/meta/__init__.py

     
    832832                func.alters_data = True
    833833                setattr(new_class, 'save_%s_file' % f.name, func)
    834834                if isinstance(f, ImageField):
     835                    if f.thumb_sizes:
     836                        setattr(new_class, 'get_%s_thumbnail_url' % f.name, curry(method_get_image_thumbnail_url, f))
     837                        setattr(new_class, 'get_%s_thumbnail_sizes' % f.name, curry(method_get_image_thumbnail_sizes, f))
    835838                    # Add get_BLAH_width and get_BLAH_height methods, but only
    836839                    # if the image field doesn't have width and height cache
    837840                    # fields.
     
    10661069            # delete it from the filesystem.
    10671070            if os.path.exists(file_name) and not opts.get_model_module().get_list(**{'%s__exact' % f.name: getattr(self, f.name)}):
    10681071                os.remove(file_name)
     1072                if isinstance(f, ImageField) and f.thumb_sizes:
     1073                    from django.parts.media.photos import get_thumbnail_path
     1074                    for size in f.thumb_sizes:
     1075                        thumb_path = get_thumbnail_path(file_name, str(size))
     1076                        os.remove(thumb_path)
    10691077    # Run any post-delete hooks.
    10701078    if hasattr(self, '_post_delete'):
    10711079        self._post_delete()
     
    12901298
    12911299    # Write the file to disk.
    12921300    setattr(self, field.attname, filename)
    1293     fp = open(getattr(self, 'get_%s_filename' % field.name)(), 'wb')
     1301    path = getattr(self, 'get_%s_filename' % field.name)()
     1302    fp = open(path, 'wb')
    12941303    fp.write(raw_contents)
    12951304    fp.close()
    12961305
    1297     # Save the width and/or height, if applicable.
    1298     if isinstance(field, ImageField) and (field.width_field or field.height_field):
    1299         from django.utils.images import get_image_dimensions
    1300         width, height = get_image_dimensions(getattr(self, 'get_%s_filename' % field.name)())
    1301         if field.width_field:
    1302             setattr(self, field.width_field, width)
    1303         if field.height_field:
    1304             setattr(self, field.height_field, height)
     1306    # Save the thumbnails, width, and height, if applicable.
     1307    if isinstance(field, ImageField):
     1308        if field.thumb_sizes:
     1309            from django.parts.media.photos import generate_thumbnail
     1310            for size in field.thumb_sizes:
     1311                generate_thumbnail(path, size, field.thumb_mode)
     1312        if field.width_field or field.height_field:
     1313            from django.utils.images import get_image_dimensions
     1314            width, height = get_image_dimensions(path)
     1315            if field.width_field:
     1316                setattr(self, field.width_field, width)
     1317            if field.height_field:
     1318                setattr(self, field.height_field, height)
    13051319
    13061320    # Save the object, because it has changed.
    13071321    self.save()
    13081322
    13091323# IMAGE FIELD METHODS ######################
    13101324
     1325def method_get_image_thumbnail_url(field, self, size=None):
     1326    from django.parts.media.photos import get_thumbnail_url
     1327    # If they don't specify a size, or the size doesn't exist,
     1328    # just give them back the first available thumbnail url.
     1329    if (size == None) or (size not in field.thumb_sizes):
     1330        size = field.thumb_sizes[0]
     1331    url = getattr(self, "get_%s_url" % field.name)()
     1332    return get_thumbnail_url(url, str(size))
     1333
     1334def method_get_image_thumbnail_sizes(field, self):
     1335    return field.thumb_sizes
     1336
    13111337def method_get_image_width(field, self):
    13121338    return _get_image_dimensions(field, self)[0]
    13131339
  • core/meta/fields.py

     
    1919# Values for Relation.edit_inline.
    2020TABULAR, STACKED = 1, 2
    2121
     22# Values for ImageField's thumb_mode.
     23WIDTH, HEIGHT, BOTH = 1, 2, 3
     24
    2225RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
    2326
    2427# prepares a value for use in a LIKE query
     
    549552        return [curry(formfields.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
    550553
    551554class ImageField(FileField):
    552     def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
    553         self.width_field, self.height_field = width_field, height_field
     555    def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, thumb_sizes=None, thumb_mode=BOTH, **kwargs):
     556        self.width_field, self.height_field, self.thumb_sizes, self.thumb_mode = width_field, height_field, thumb_sizes, thumb_mode
    554557        FileField.__init__(self, verbose_name, name, **kwargs)
    555558
    556559    def get_manipulator_field_objs(self):
  • parts/media/photos.py

     
    1 import re
     1from django.core import meta
     2import re, os
    23
     4def get_thumbnail_path(photo_path, width, sep=os.path.sep):
     5    bits = photo_path.split(sep)
     6    bits[-1] = re.sub(r'(?i)\.(gif|jpg|png)$', '_t%s.\\1' % width, bits[-1])
     7    return sep.join(bits)
     8
    39def get_thumbnail_url(photo_url, width):
    4     bits = photo_url.split('/')
    5     bits[-1] = re.sub(r'(?i)\.(gif|jpg)$', '_t%s.\\1' % width, bits[-1])
    6     return '/'.join(bits)
     10    return get_thumbnail_path(photo_url, width, '/')
     11
     12def generate_thumbnail(photo_path, size, mode):
     13    from PIL import Image
     14    im = Image.open(photo_path)
     15    thumb_path = get_thumbnail_path(photo_path, str(size))
     16    thumb_size = (size, size)
     17    if mode == meta.WIDTH:
     18        thumb_size = (size, 9999)
     19    elif mode == meta.HEIGHT:
     20        thumb_size = (9999, size)
     21    im.thumbnail(thumb_size, Image.ANTIALIAS)
     22    im.save(thumb_path)
Back to Top