bgneal@696: """images.py bgneal@696: bgneal@696: This module contains image processing routines for the user_photos application. bgneal@696: bgneal@696: """ bgneal@696: import datetime bgneal@696: import logging bgneal@696: from io import BytesIO bgneal@696: import os.path bgneal@696: import uuid bgneal@696: bgneal@696: from django.conf import settings bgneal@696: from PIL import Image bgneal@696: bgneal@696: bgneal@696: logger = logging.getLogger(__name__) bgneal@696: bgneal@696: bgneal@697: def process_file(f, user, bucket): bgneal@696: """Perform processing on the given uploaded image file: bgneal@696: bgneal@696: * The image is resized if necessary bgneal@696: * A thumbnail version is created bgneal@696: * The image and thumbnail are uploaded to an S3 bucket bgneal@696: * The image and thumbnail URLs are returned as a tuple bgneal@696: bgneal@696: """ bgneal@696: logger.info('Processing image file for {}: {}'.format(user.username, f.name)) bgneal@696: bgneal@696: unique_key = uuid.uuid4().hex bgneal@696: ext = os.path.splitext(f.name)[1] bgneal@696: filename = '/tmp/' + unique_key + ext bgneal@696: with open(filename, 'wb') as fp: bgneal@696: for chunk in f.chunks(): bgneal@696: fp.write(chunk) bgneal@696: bgneal@696: # Resize image if necessary bgneal@696: image = Image.open(filename) bgneal@696: if image.size > settings.USER_PHOTOS_MAX_SIZE: bgneal@696: logger.debug('Resizing from {} to {}'.format(image.size, settings.USER_PHOTOS_MAX_SIZE)) bgneal@696: image.thumbnail(settings.USER_PHOTOS_MAX_SIZE, Image.ANTIALIAS) bgneal@696: image.save(filename) bgneal@696: bgneal@696: # Create thumbnail bgneal@696: logger.debug('Creating thumbnail') bgneal@696: image = Image.open(filename) bgneal@696: image.thumbnail(settings.USER_PHOTOS_THUMB_SIZE, Image.ANTIALIAS) bgneal@696: thumb = BytesIO() bgneal@696: image.save(thumb, format=image.format) bgneal@696: bgneal@696: # Upload both images to S3 bgneal@697: logging.debug('Uploading image') bgneal@696: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') bgneal@697: metadata = {'user': user.username, 'date': now} bgneal@697: file_key = unique_key + ext bgneal@697: bucket.upload_from_filename(file_key, filename, metadata) bgneal@696: bgneal@696: logging.debug('Uploading thumbnail') bgneal@697: thumb_key = '{}t{}'.format(unique_key, ext) bgneal@697: bucket.upload_from_string(thumb_key, thumb.getvalue()) bgneal@696: bgneal@696: os.remove(filename) bgneal@696: bgneal@696: logger.info('Completed processing image file for {}: {}'.format(user.username, f.name)) bgneal@696: bgneal@696: url_base = '{}/{}/'.format(settings.USER_PHOTOS_BASE_URL, bgneal@696: settings.USER_PHOTOS_BUCKET) bgneal@696: bgneal@697: return (url_base + file_key, url_base + thumb_key)