diff --git a/tests/test_upload_storage.py b/tests/test_upload_storage.py index 4d6a3742f..2f30e8955 100644 --- a/tests/test_upload_storage.py +++ b/tests/test_upload_storage.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- +import hashlib import json import os import mock import pytest +from django.utils.encoding import force_bytes from webtest import Upload from wcs import fields @@ -241,6 +243,41 @@ def test_form_file_field_upload_storage(wscall, pub): } +def test_thumbnail_caching(pub): + create_user_and_admin(pub) + FormDef.wipe() + formdef = FormDef() + formdef.name = 'test' + formdef.fields = [ + fields.FileField(id='0', label='file', varname='file'), + ] + formdef.store() + + assert formdef.fields[0].storage == 'default' + + image_content = open(os.path.join(os.path.dirname(__file__), 'image-with-gps-data.jpeg'), 'rb').read() + upload = Upload('file.jpg', image_content, 'image/jpeg') + + resp = get_app(pub).get('/test/') + resp.forms[0]['f0$file'] = upload + resp = resp.forms[0].submit('submit') + assert 'Check values then click submit.' in resp.text + resp = resp.forms[0].submit('submit') + assert resp.status_int == 302 + resp = resp.follow() + assert 'The form has been recorded' in resp.text + + data_file = formdef.data_class().get(1).data['0'] + thumbs_dir = os.path.join(pub.app_dir, 'thumbs') + thumb_filepath = os.path.join( + thumbs_dir, hashlib.sha256(force_bytes(data_file.get_fs_filename())).hexdigest() + ) + assert os.path.exists(thumb_filepath) is False + admin_app = login(get_app(pub), username='admin', password='admin') + admin_app.get('/backoffice/management/test/1/download?f=0&thumbnail=1').follow() + assert os.path.exists(thumb_filepath) is True + + @mock.patch('wcs.wscalls.call_webservice') def test_remoteopaque_in_attachmentevolutionpart(wscall, pub): create_user_and_admin(pub) diff --git a/wcs/qommon/misc.py b/wcs/qommon/misc.py index a8f1e30bc..7f313a0c0 100644 --- a/wcs/qommon/misc.py +++ b/wcs/qommon/misc.py @@ -40,7 +40,7 @@ except ImportError: from django.conf import settings from django.template import TemplateSyntaxError, VariableDoesNotExist from django.utils import datetime_safe -from django.utils.encoding import force_text +from django.utils.encoding import force_bytes, force_text from django.utils.formats import localize from django.utils.html import strip_tags from django.utils.text import Truncator @@ -655,6 +655,16 @@ def get_thumbnail(filepath, content_type=None): if not can_thumbnail(content_type or ''): raise ThumbnailError() + # check if thumbnail already exists + thumbs_dir = os.path.join(get_publisher().app_dir, 'thumbs') + if not os.path.exists(thumbs_dir): + os.mkdir(thumbs_dir) + thumb_filepath = os.path.join(thumbs_dir, hashlib.sha256(force_bytes(filepath)).hexdigest()) + if os.path.exists(thumb_filepath): + with open(thumb_filepath, 'rb') as f: + return f.read() + + # generate thumbnail if content_type == 'application/pdf': try: fp = io.BytesIO( @@ -705,6 +715,11 @@ def get_thumbnail(filepath, content_type=None): except IOError: # failed to create thumbnail. raise ThumbnailError() + + # store thumbnail + with open(thumb_filepath, 'wb') as f: + f.write(image_thumb_fp.getvalue()) + return image_thumb_fp.getvalue()