def clean_image(self): """Check the image is of a supported type. """ image = self.cleaned_data.get('image') if image and not image.content_type in ALLOWED_MIMETYPES: types = "/".join([x for x in ALLOWED_MIMETYPES.itervalues()]) error = "Image is not of an allowed type: %s." % types raise forms.ValidationError(error) return image
def download_and_validate_image(url, temp_folder=None): """Tries to download and save a given URL to a temporary location, checking it is a valid image using PIL. For small images we simply save to a memory buffer, for larger images, we take the safe option of saving them to disk first. """ ret_dict = {'image': '', 'filetype': '', 'mimetype': '', 'message': ''} if temp_folder is None: temp_folder = settings.FILE_UPLOAD_TEMP_DIR req = requests.get(url) if not req.ok: error_messages = {404: "The image could not be found.", 410: "The server says the image has been removed.", 500: "There was an error with the remote server."} msg = error_messages.get(req.status_code, "An unknown error occured.") ret_dict['message'] = "Sorry, the image retrieval failed. %s" % msg return ret_dict mimetype = req.headers['content-type'] if mimetype not in ALLOWED_MIMETYPES: ret_dict['message'] = "Image is not of an allowed type: %s." % \ "/".join([x for x in ALLOWED_MIMETYPES.itervalues()]) return ret_dict if len(req.content) > UPLOAD_MAX_SIZE: ret_dict['message'] = "The image exceeds our maximum allowed size" \ " of %s bytes." % UPLOAD_MAX_SIZE return ret_dict try: # To test it's actually an image we can use, we translate # to an in memory IOString and try an open with PIL. buffer = cStringIO.StringIO(req.content) buffered_image = Image.open(buffer) except IOError: ret_dict['message'] = "We are unable to open the image, is it corrupt?" return ret_dict else: ret_dict.update({'image': ContentFile(req.content), 'filetype': ALLOWED_MIMETYPES[mimetype], 'mimetype': mimetype, 'message': 'Success'}) return ret_dict