Mercurial > public > sg101
comparison core/images/upload.py @ 1195:7fc6c42b2f5b
Adding a local user photo upload option.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sun, 07 May 2023 16:22:13 -0500 |
parents | 4f265f61874b |
children | e3a7e876aca7 |
comparison
equal
deleted
inserted
replaced
1194:d437d5b88c27 | 1195:7fc6c42b2f5b |
---|---|
2 | 2 |
3 The image can be resized and a thumbnail can be generated and uploaded as well. | 3 The image can be resized and a thumbnail can be generated and uploaded as well. |
4 | 4 |
5 """ | 5 """ |
6 from base64 import b64encode | 6 from base64 import b64encode |
7 import datetime | |
7 import logging | 8 import logging |
8 from io import BytesIO | 9 from io import BytesIO |
9 import os.path | 10 import os.path |
11 import shutil | |
10 import uuid | 12 import uuid |
11 | 13 |
14 from django.conf import settings | |
15 from django.contrib.sites.models import Site | |
12 from PIL import Image | 16 from PIL import Image |
13 | 17 |
14 from .utils import orient_image | 18 from .utils import orient_image |
19 from core.s3 import S3Bucket | |
15 | 20 |
16 | 21 |
17 logger = logging.getLogger(__name__) | 22 logger = logging.getLogger(__name__) |
23 | |
24 | |
25 def process_upload(user, filename): | |
26 if settings.USER_PHOTOS_LOCAL_UPLOAD: | |
27 url, thumb_url = _process_local_upload( | |
28 filename, | |
29 new_size=settings.USER_PHOTOS_MAX_SIZE, | |
30 thumb_size=settings.USER_PHOTOS_THUMB_SIZE) | |
31 else: | |
32 now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') | |
33 metadata = {'user': user.username, 'date': now} | |
34 | |
35 bucket = S3Bucket(access_key=settings.USER_PHOTOS_ACCESS_KEY, | |
36 secret_key=settings.USER_PHOTOS_SECRET_KEY, | |
37 base_url=settings.USER_PHOTOS_BASE_URL, | |
38 bucket_name=settings.USER_PHOTOS_BUCKET) | |
39 | |
40 url, thumb_url = upload(filename, | |
41 bucket=bucket, | |
42 metadata=metadata, | |
43 new_size=settings.USER_PHOTOS_MAX_SIZE, | |
44 thumb_size=settings.USER_PHOTOS_THUMB_SIZE) | |
45 return (url, thumb_url) | |
18 | 46 |
19 | 47 |
20 def make_key(): | 48 def make_key(): |
21 """Generate a random key suitable for a filename""" | 49 """Generate a random key suitable for a filename""" |
22 return b64encode(uuid.uuid4().bytes, '-_').rstrip('=') | 50 return b64encode(uuid.uuid4().bytes, '-_').rstrip('=') |
90 metadata) | 118 metadata) |
91 | 119 |
92 logger.info('Completed processing image file: %s', filename) | 120 logger.info('Completed processing image file: %s', filename) |
93 | 121 |
94 return (image_url, thumb_url) | 122 return (image_url, thumb_url) |
123 | |
124 | |
125 def _process_local_upload(filename, new_size=None, thumb_size=None): | |
126 # Re-orient if necessary | |
127 image = Image.open(filename) | |
128 changed, image = orient_image(image) | |
129 if changed: | |
130 image.save(filename) | |
131 | |
132 # Resize image if necessary | |
133 if new_size: | |
134 image = Image.open(filename) | |
135 if image.size > new_size: | |
136 logger.debug('Resizing from {} to {}'.format(image.size, new_size)) | |
137 image.thumbnail(new_size, Image.ANTIALIAS) | |
138 image.save(filename) | |
139 | |
140 # Create thumbnail if necessary | |
141 thumb = None | |
142 if thumb_size: | |
143 logger.debug('Creating thumbnail {}'.format(thumb_size)) | |
144 image = Image.open(filename) | |
145 image.thumbnail(thumb_size, Image.ANTIALIAS) | |
146 thumb = BytesIO() | |
147 image.save(thumb, format=image.format) | |
148 | |
149 # Copy file and thumbnail to our user upload files directory. | |
150 upload_dir = os.path.join(settings.MEDIA_ROOT, | |
151 settings.USER_PHOTOS_LOCAL_UPLOAD_DIR) | |
152 unique_name = uuid.uuid4().hex | |
153 ext = os.path.splitext(filename)[1] | |
154 image_name = '%s%s' % (unique_name, ext) | |
155 thumb_name = '%st%s' % (unique_name, ext) | |
156 image_path = os.path.join(upload_dir, image_name) | |
157 thumb_path = os.path.join(upload_dir, thumb_name) | |
158 | |
159 shutil.copy(filename, image_path) | |
160 if thumb: | |
161 shutil.copyfileobj(thumb, thumb_path) | |
162 | |
163 # Generate URLs for the image and thumb. | |
164 site = Site.objects.get_current() | |
165 | |
166 url_pattern = '%s://%s%s%s/%s' | |
167 | |
168 image_url = url_pattern % ( | |
169 settings.SITE_SCHEME, | |
170 site.domain, | |
171 settings.MEDIA_URL, | |
172 settings.USER_PHOTOS_LOCAL_UPLOAD_DIR, | |
173 image_name) | |
174 | |
175 thumb_url = url_pattern % ( | |
176 settings.SITE_SCHEME, | |
177 site.domain, | |
178 settings.MEDIA_URL, | |
179 settings.USER_PHOTOS_LOCAL_UPLOAD_DIR, | |
180 thumb_name) | |
181 | |
182 return (image_url, thumb_url) | |
183 |