bgneal@700
|
1 """This module contains a function to upload an image file to a S3Bucket.
|
bgneal@696
|
2
|
bgneal@700
|
3 The image can be resized and a thumbnail can be generated and uploaded as well.
|
bgneal@696
|
4
|
bgneal@696
|
5 """
|
bgneal@885
|
6 from base64 import b64encode
|
bgneal@696
|
7 import logging
|
bgneal@696
|
8 from io import BytesIO
|
bgneal@696
|
9 import os.path
|
bgneal@696
|
10 import uuid
|
bgneal@696
|
11
|
bgneal@696
|
12 from PIL import Image
|
bgneal@696
|
13
|
bgneal@971
|
14 from .utils import orient_image
|
bgneal@700
|
15
|
bgneal@696
|
16
|
bgneal@696
|
17 logger = logging.getLogger(__name__)
|
bgneal@696
|
18
|
bgneal@696
|
19
|
bgneal@885
|
20 def make_key():
|
bgneal@885
|
21 """Generate a random key suitable for a filename"""
|
bgneal@885
|
22 return b64encode(uuid.uuid4().bytes, '-_').rstrip('=')
|
bgneal@885
|
23
|
bgneal@885
|
24
|
bgneal@964
|
25 def upload(filename, bucket, metadata=None, new_size=None, thumb_size=None):
|
bgneal@700
|
26 """Upload an image file to a given S3Bucket.
|
bgneal@696
|
27
|
bgneal@700
|
28 The image can optionally be resized and a thumbnail can be generated and
|
bgneal@700
|
29 uploaded as well.
|
bgneal@696
|
30
|
bgneal@700
|
31 Parameters:
|
bgneal@964
|
32 filename - The path to the file to process. The filename should have an
|
bgneal@964
|
33 extension, and this is used for the uploaded image & thumbnail
|
bgneal@964
|
34 names.
|
bgneal@700
|
35 bucket - A core.s3.S3Bucket instance to upload to.
|
bgneal@700
|
36 metadata - If not None, must be a dictionary of metadata to apply to the
|
bgneal@700
|
37 uploaded file and thumbnail.
|
bgneal@700
|
38 new_size - If not None, the image will be resized to the dimensions
|
bgneal@700
|
39 specified by new_size, which must be a (width, height) tuple.
|
bgneal@700
|
40 thumb_size - If not None, a thumbnail image will be created with the
|
bgneal@700
|
41 dimensions specified by thumb_size, which must be a (width,
|
bgneal@700
|
42 height) tuple. The thumbnail will use the same metadata, if
|
bgneal@700
|
43 present, as the image. The thumbnail filename will be the
|
bgneal@700
|
44 same basename as the image with a 't' appended. The
|
bgneal@700
|
45 extension will be the same as the original image.
|
bgneal@700
|
46
|
bgneal@700
|
47 A tuple is returned: (image_url, thumb_url) where thumb_url will be None if
|
bgneal@700
|
48 a thumbnail was not requested.
|
bgneal@696
|
49 """
|
bgneal@696
|
50
|
bgneal@737
|
51 logger.info('Processing image file: %s', filename)
|
bgneal@700
|
52
|
bgneal@885
|
53 unique_key = make_key()
|
bgneal@964
|
54 ext = os.path.splitext(filename)[1]
|
bgneal@696
|
55
|
bgneal@964
|
56 # Re-orient if necessary
|
bgneal@964
|
57 image = Image.open(filename)
|
bgneal@964
|
58 changed, image = orient_image(image)
|
bgneal@964
|
59 if changed:
|
bgneal@964
|
60 image.save(filename)
|
bgneal@696
|
61
|
bgneal@964
|
62 # Resize image if necessary
|
bgneal@964
|
63 if new_size:
|
bgneal@964
|
64 image = Image.open(filename)
|
bgneal@964
|
65 if image.size > new_size:
|
bgneal@964
|
66 logger.debug('Resizing from {} to {}'.format(image.size, new_size))
|
bgneal@964
|
67 image.thumbnail(new_size, Image.ANTIALIAS)
|
bgneal@964
|
68 image.save(filename)
|
bgneal@837
|
69
|
bgneal@964
|
70 # Create thumbnail if necessary
|
bgneal@964
|
71 thumb = None
|
bgneal@964
|
72 if thumb_size:
|
bgneal@964
|
73 logger.debug('Creating thumbnail {}'.format(thumb_size))
|
bgneal@964
|
74 image = Image.open(filename)
|
bgneal@964
|
75 image.thumbnail(thumb_size, Image.ANTIALIAS)
|
bgneal@964
|
76 thumb = BytesIO()
|
bgneal@964
|
77 image.save(thumb, format=image.format)
|
bgneal@696
|
78
|
bgneal@964
|
79 # Upload images to S3
|
bgneal@964
|
80 file_key = unique_key + ext
|
bgneal@964
|
81 logging.debug('Uploading image')
|
bgneal@964
|
82 image_url = bucket.upload_from_filename(file_key, filename, metadata)
|
bgneal@696
|
83
|
bgneal@700
|
84 thumb_url = None
|
bgneal@700
|
85 if thumb:
|
bgneal@700
|
86 logging.debug('Uploading thumbnail')
|
bgneal@700
|
87 thumb_key = '{}t{}'.format(unique_key, ext)
|
bgneal@700
|
88 thumb_url = bucket.upload_from_string(thumb_key,
|
bgneal@700
|
89 thumb.getvalue(),
|
bgneal@700
|
90 metadata)
|
bgneal@696
|
91
|
bgneal@737
|
92 logger.info('Completed processing image file: %s', filename)
|
bgneal@696
|
93
|
bgneal@700
|
94 return (image_url, thumb_url)
|