Mercurial > public > sg101
view core/image_uploader.py @ 943:cf9918328c64
Haystack tweaks for Django 1.7.7.
I had to upgrade to Haystack 2.3.1 to get it to work with Django
1.7.7. I also had to update the Xapian backend. But I ran into
problems.
On my laptop anyway (Ubuntu 14.0.4), xapian gets mad when search terms
are greater than 245 chars (or something) when indexing. So I created
a custom field that would simply omit terms greater than 64 chars and
used this field everywhere I previously used a CharField.
Secondly, the custom search form was broken now. Something changed in
the Xapian backend and exact searches stopped working. Fortunately the
auto_query (which I was using originally and broke during an upgrade)
started working again. So I cut the search form back over to doing an
auto_query. I kept the form the same (3 fields) because I didn't want
to change the form and I think it's better that way.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 13 May 2015 20:25:07 -0500 |
parents | ee47122d6277 |
children | 51a2051588f5 |
line wrap: on
line source
"""This module contains a function to upload an image file to a S3Bucket. The image can be resized and a thumbnail can be generated and uploaded as well. """ from base64 import b64encode import logging from io import BytesIO import os.path import tempfile import uuid from PIL import Image from core.functions import temp_open from core.image import orient_image logger = logging.getLogger(__name__) def make_key(): """Generate a random key suitable for a filename""" return b64encode(uuid.uuid4().bytes, '-_').rstrip('=') def upload(fp, bucket, metadata=None, new_size=None, thumb_size=None): """Upload an image file to a given S3Bucket. The image can optionally be resized and a thumbnail can be generated and uploaded as well. Parameters: fp - The image file to process. This is expected to be an instance of Django's UploadedFile class. The file must have a name attribute and we expect the name to have an extension. This is extension is used for the uploaded image and thumbnail names. bucket - A core.s3.S3Bucket instance to upload to. metadata - If not None, must be a dictionary of metadata to apply to the uploaded file and thumbnail. new_size - If not None, the image will be resized to the dimensions specified by new_size, which must be a (width, height) tuple. thumb_size - If not None, a thumbnail image will be created with the dimensions specified by thumb_size, which must be a (width, height) tuple. The thumbnail will use the same metadata, if present, as the image. The thumbnail filename will be the same basename as the image with a 't' appended. The extension will be the same as the original image. A tuple is returned: (image_url, thumb_url) where thumb_url will be None if a thumbnail was not requested. """ filename = fp.name logger.info('Processing image file: %s', filename) # Trying to use PIL (or Pillow) on a Django UploadedFile is often # problematic because the file is often an in-memory file if it is under # a certain size. This complicates matters and many of the operations we try # to perform on it fail if this is the case. To get around these issues, # we make a copy of the file on the file system and operate on the copy. # First generate a unique name and temporary file path. unique_key = make_key() ext = os.path.splitext(fp.name)[1] temp_name = os.path.join(tempfile.gettempdir(), unique_key + ext) # Write the UploadedFile to a temporary file on disk with temp_open(temp_name, 'wb') as temp_file: for chunk in fp.chunks(): temp_file.write(chunk) temp_file.close() # Re-orient if necessary image = Image.open(temp_name) changed, image = orient_image(image) if changed: image.save(temp_name) # Resize image if necessary if new_size: image = Image.open(temp_name) if image.size > new_size: logger.debug('Resizing from {} to {}'.format(image.size, new_size)) image.thumbnail(new_size, Image.ANTIALIAS) image.save(temp_name) # Create thumbnail if necessary thumb = None if thumb_size: logger.debug('Creating thumbnail {}'.format(thumb_size)) image = Image.open(temp_name) image.thumbnail(thumb_size, Image.ANTIALIAS) thumb = BytesIO() image.save(thumb, format=image.format) # Upload images to S3 file_key = unique_key + ext logging.debug('Uploading image') image_url = bucket.upload_from_filename(file_key, temp_name, metadata) thumb_url = None if thumb: logging.debug('Uploading thumbnail') thumb_key = '{}t{}'.format(unique_key, ext) thumb_url = bucket.upload_from_string(thumb_key, thumb.getvalue(), metadata) logger.info('Completed processing image file: %s', filename) return (image_url, thumb_url)