From c14e8b7defdf48542c4be09f5acd2da3a69b1d8b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 25 Nov 2015 17:52:29 +0530 Subject: [PATCH] [fix] handle the case when the image used for thumbnail generation does not have an extension --- frappe/core/doctype/file/file.py | 101 ++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 15cce06c57..b6403ff794 100644 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -153,43 +153,10 @@ class File(NestedSet): def make_thumbnail(self): if self.file_url: if self.file_url.startswith("/files"): - try: - image = Image.open(frappe.get_site_path("public", self.file_url.lstrip("/"))) - filename, extn = self.file_url.rsplit(".", 1) - except IOError: - frappe.msgprint("Unable to read file format for {0}".format(self.file_url)) + image, filename, extn = get_local_image(self.file_url) else: - # downlaod - file_url = frappe.utils.get_url(self.file_url) - r = requests.get(file_url, stream=True) - try: - r.raise_for_status() - except requests.exceptions.HTTPError, e: - if "404" in e.args[0]: - frappe.throw(_("File '{0}' not found").format(self.file_url)) - else: - raise - - image = Image.open(StringIO.StringIO(r.content)) - - try: - filename, extn = self.file_url.rsplit("/", 1)[1].rsplit(".", 1) - except ValueError: - # the case when the file url doesn't have filename or extension - # but is fetched due to a query string. example: https://encrypted-tbn3.gstatic.com/images?q=something - filename = get_random_filename() - extn = "" - - mimetype = None - if extn: - mimetype = mimetypes.guess_type(filename + "." + extn)[0] - - if mimetype is None or not mimetype.startswith("image/"): - # detect file extension by reading image header properties - extn = imghdr.what(filename + "." + extn, h=r.content) - - filename = "/files/" + strip(urllib.unquote(filename)) + image, filename, extn = get_web_image(self.file_url) thumbnail = ImageOps.fit( image, @@ -209,7 +176,6 @@ class File(NestedSet): return thumbnail_url - def after_delete(self): self.update_parent_folder_size() @@ -300,3 +266,66 @@ def setup_folder_path(filename, new_parent): if file.is_folder: frappe.rename_doc("File", file.name, file.get_name_based_on_parent_folder(), ignore_permissions=True) + +def get_extension(filename, extn, content): + mimetype = None + if extn: + mimetype = mimetypes.guess_type(filename + "." + extn)[0] + + if mimetype is None or not mimetype.startswith("image/") and content: + # detect file extension by reading image header properties + extn = imghdr.what(filename + "." + (extn or ""), h=content) + + return extn + +def get_local_image(file_url): + file_path = frappe.get_site_path("public", file_url.lstrip("/")) + + try: + image = Image.open(file_path) + except IOError: + frappe.msgprint("Unable to read file format for {0}".format(file_url)) + return + + content = None + + try: + filename, extn = file_url.rsplit(".", 1) + except ValueError: + # no extn + with open(file_path, "r") as f: + content = f.read() + + filename = file_url + extn = None + + extn = get_extension(filename, extn, content) + + return image, filename, extn + +def get_web_image(file_url): + # downlaod + file_url = frappe.utils.get_url(file_url) + r = requests.get(file_url, stream=True) + try: + r.raise_for_status() + except requests.exceptions.HTTPError, e: + if "404" in e.args[0]: + frappe.throw(_("File '{0}' not found").format(file_url)) + else: + raise + + image = Image.open(StringIO.StringIO(r.content)) + + try: + filename, extn = file_url.rsplit("/", 1)[1].rsplit(".", 1) + except ValueError: + # the case when the file url doesn't have filename or extension + # but is fetched due to a query string. example: https://encrypted-tbn3.gstatic.com/images?q=something + filename = get_random_filename() + extn = None + + extn = get_extension(filename, extn, r.content) + filename = "/files/" + strip(urllib.unquote(filename)) + + return image, filename, extn