Skip to content

Commit 6b77e20

Browse files
committed
Limit width of uploaded images to 3840 pixels
1 parent 1482ec2 commit 6b77e20

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

finder/admin/inode.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def get_favorite_folders(self, request, current_folder):
188188
return folders
189189

190190
def changelist_view(self, request, extra_context=None):
191-
# always redirect the list view to the detail view of either the last used, or the root folder
191+
# always redirect the list view to the detail view of either the latest used, or the root folder
192192
fallback_folder = self.get_fallback_folder(request)
193193
return HttpResponseRedirect(reverse(
194194
'admin:finder_inodemodel_change',
@@ -228,8 +228,10 @@ def get_editor_settings(self, request, inode):
228228
return settings
229229

230230
def get_folderitem_settings(self, request, inode):
231+
"""
232+
Hook to return the context for the folder item.
233+
"""
231234
raise NotImplementedError()
232-
return {}
233235

234236
def get_menu_extension_settings(self, request):
235237
"""

finder/contrib/image/pil/models.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class PILImageModel(ImageFileModel):
1313
"""
1414
accept_mime_types = ['image/jpeg', 'image/webp', 'image/png', 'image/gif']
1515
exif_values = set(ExifTags.Base.__members__.values()) # TODO: some EXIF values can be removed
16+
MAX_STORED_IMAGE_WIDTH = 3840
1617

1718
class Meta:
1819
app_label = 'finder'
@@ -23,6 +24,15 @@ class Meta:
2324
def save(self, **kwargs):
2425
try:
2526
image = Image.open(default_storage.open(self.file_path))
27+
image = self.orientate_top(image)
28+
if self.MAX_STORED_IMAGE_WIDTH and image.width > self.MAX_STORED_IMAGE_WIDTH:
29+
# limit the width of the stored image to prevent excessive disk usage
30+
height = round(self.MAX_STORED_IMAGE_WIDTH * image.height / image.width)
31+
image = image.resize((self.MAX_STORED_IMAGE_WIDTH, height))
32+
image.save(default_storage.open(self.file_path, 'wb'), image.format)
33+
# recompute the file size and SHA1 hash
34+
self.file_size = default_storage.size(self.file_path)
35+
self.sha1 = self.digest_sha1()
2636
self.width = image.width
2737
self.height = image.height
2838
except Exception:
@@ -75,7 +85,9 @@ def orientate_top(self, image):
7585
def crop(self, thumbnail_path, width, height):
7686
aspect_ratio = width / height
7787
image = Image.open(default_storage.open(self.file_path))
78-
image = self.orientate_top(image)
88+
assert width <= image.width and height <= image.height, \
89+
"The requested thumbnail size ({width}x{height}) is larger than the original image " \
90+
"({0}x{1})".format(*image.size, width=width, height=height)
7991
orig_aspect_ratio = image.width / image.height
8092
crop_x, crop_y, crop_size, gravity = (
8193
self.meta_data.get('crop_x'),
@@ -137,7 +149,6 @@ def crop(self, thumbnail_path, width, height):
137149
crop_y = max(crop_y - max(min(crop_height - crop_size, crop_height), 0), 0)
138150
else: # centered crop
139151
crop_y = max(crop_y - (crop_height - crop_size) / 2, 0)
140-
crop_size = crop_resize
141152

142153
min_x = crop_x
143154
if min_x + crop_width > image.width:

finder/models/file.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ def receive_file(self, uploaded_file):
242242
self.sha1 = sha1.hexdigest()
243243
self._for_write = True
244244

245+
def digest_sha1(self):
246+
"""
247+
Generate the SHA1 hash for the file.
248+
"""
249+
sha1 = hashlib.sha1()
250+
with self.open('rb') as readhandle:
251+
for chunk in readhandle.chunks():
252+
sha1.update(chunk)
253+
return sha1.hexdigest()
254+
245255
def copy_to(self, folder, **kwargs):
246256
"""
247257
Copy the file to a destination folder and returns it.

0 commit comments

Comments
 (0)