misc: caching for thumbnails (#52528)

This commit is contained in:
Lauréline Guérin 2021-04-09 11:45:00 +02:00
parent 93b951e02a
commit d38db142c6
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 53 additions and 1 deletions

View File

@ -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)

View File

@ -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()