in src/olympia/devhub/views.py [0:0]
def upload_image(request, addon_id, addon, upload_type):
errors = []
upload_hash = ''
if 'upload_image' in request.FILES:
upload_preview = request.FILES['upload_image']
upload_preview.seek(0)
upload_hash = uuid4().hex
loc = os.path.join(settings.TMP_PATH, upload_type, upload_hash)
with storage.open(loc, 'wb') as fd:
for chunk in upload_preview:
fd.write(chunk)
is_icon = upload_type == 'icon'
is_preview = upload_type == 'preview'
image_check = amo_utils.ImageCheck(upload_preview)
is_animated = image_check.is_animated() # will also cache .is_image()
if (
upload_preview.content_type not in amo.IMG_TYPES
or not image_check.is_image()
):
if is_icon:
errors.append(gettext('Icons must be either PNG or JPG.'))
else:
errors.append(gettext('Images must be either PNG or JPG.'))
if is_animated:
if is_icon:
errors.append(gettext('Icons cannot be animated.'))
else:
errors.append(gettext('Images cannot be animated.'))
if is_icon:
max_size = settings.MAX_ICON_UPLOAD_SIZE
else:
max_size = settings.MAX_IMAGE_UPLOAD_SIZE
if upload_preview.size > max_size:
errors.append(
gettext('Please use images smaller than %dMB.')
% (max_size // 1024 // 1024)
)
content_waffle = waffle.switch_is_active('content-optimization')
if image_check.is_image() and content_waffle and is_preview:
min_size = amo.ADDON_PREVIEW_SIZES.get('min')
# * 100 to get a nice integer to compare against rather than 1.3333
required_ratio = min_size[0] * 100 // min_size[1]
actual_size = image_check.size
actual_ratio = actual_size[0] * 100 // actual_size[1]
if actual_size[0] < min_size[0] or actual_size[1] < min_size[1]:
# L10n: {0} is an image width (in pixels), {1} is a height.
errors.append(
gettext(
'Image must be at least {0} pixels wide and {1} pixels tall.'
).format(min_size[0], min_size[1])
)
if actual_ratio != required_ratio:
errors.append(gettext('Image dimensions must be in the ratio 4:3.'))
if image_check.is_image() and content_waffle and is_icon:
standard_size = amo.ADDON_ICON_SIZES[-1]
icon_size = image_check.size
if icon_size[0] < standard_size or icon_size[1] < standard_size:
# L10n: {0} is an image width/height (in pixels).
errors.append(
gettext('Icon must be at least {0} pixels wide and tall.').format(
standard_size
)
)
if icon_size[0] != icon_size[1]:
errors.append(gettext('Icon must be square (same width and height).'))
if errors and is_preview and os.path.exists(loc):
# Delete the temporary preview file in case of error.
os.unlink(loc)
else:
errors.append(gettext('There was an error uploading your preview.'))
if errors:
upload_hash = ''
return {'upload_hash': upload_hash, 'errors': errors}