misc: add a |strip_metadata filter (#51483)

This commit is contained in:
Frédéric Péters 2021-04-12 22:17:28 +02:00
parent 5fce2f27a9
commit e5f06accdb
4 changed files with 44 additions and 25 deletions

View File

@ -4460,6 +4460,21 @@ def test_set_backoffice_field_file(http_requests, two_pubs):
== open(os.path.join(os.path.dirname(__file__), 'image-with-gps-data.jpeg'), 'rb').read()
)
# check |strip_metadata filter
formdata = formdef.data_class()()
formdata.data = {'00': upload}
formdata.just_created()
formdata.store()
two_pubs.substitutions.feed(formdata)
item.fields = [{'field_id': 'bo1', 'value': '{{form_var_file|strip_metadata}}'}]
item.perform(formdata)
assert formdata.data['bo1'].base_filename == 'test.jpeg'
assert formdata.data['bo1'].content_type == 'image/jpeg'
assert b'JFIF' in formdata.data['bo1'].get_content()
assert b'<exif:XResolution>' not in formdata.data['bo1'].get_content()
# check with a template string, into a string field
two_pubs.substitutions.feed(formdata)
item.fields = [{'field_id': 'bo2', 'value': '{{form_var_file}}'}]

View File

@ -21,7 +21,6 @@ get_global_eval_dict.
"""
import base64
import datetime
import io
import time
from django.utils.encoding import force_bytes
@ -31,12 +30,6 @@ from wcs.qommon.upload_storage import UploadStorage
from .misc import get_as_datetime
try:
from PIL import Image
except ImportError:
Image = None
today = datetime.date.today
now = datetime.datetime.now
@ -154,23 +147,8 @@ def attachment(content, filename='', content_type=None, strip_metadata=False):
upload = FileField.convert_value_from_anything(content)
UploadStorage().save(upload)
if strip_metadata and Image:
try:
image = Image.open(io.BytesIO(upload.get_content()))
except OSError:
pass
else:
image_without_exif = Image.new(image.mode, image.size)
image_without_exif.putdata(image.getdata())
content = io.BytesIO()
image_without_exif.save(content, image.format)
upload = FileField.convert_value_from_anything(
{
'filename': upload.base_filename,
'content_type': upload.content_type,
'content': content.getvalue(),
}
)
if strip_metadata:
upload = upload.strip_metadata()
if filename:
upload.base_filename = filename
if content_type:

View File

@ -772,3 +772,10 @@ def is_empty(value):
if isinstance(value, (LazyFormDefObjectsManager, LazyList)):
return not list(value)
return value is None
@register.filter
def strip_metadata(value):
if hasattr(value, 'get_value'):
value = value.get_value() # unlazy
return value.strip_metadata()

View File

@ -24,7 +24,7 @@ from quixote import get_publisher
from quixote.http_request import Upload
from .errors import ConnectionError
from .misc import can_thumbnail, file_digest, json_loads
from .misc import Image, can_thumbnail, file_digest, json_loads
from .storage import atomic_write
@ -72,6 +72,9 @@ class PicklableUpload(Upload):
filename = os.path.join(get_publisher().app_dir, 'uploads', self.qfilename)
with open(filename, 'rb') as fd:
return fd.read()
if self.fp:
get_storage_object(getattr(self, 'storage', None)).save(self)
return self.get_content()
return None
def get_base64_content(self):
@ -96,6 +99,22 @@ class PicklableUpload(Upload):
self, backoffice=backoffice
)
def strip_metadata(self):
if Image is None:
return self
try:
image = Image.open(io.BytesIO(self.get_content()))
except OSError:
return self
image_without_exif = Image.new(image.mode, image.size)
image_without_exif.putdata(image.getdata())
content = io.BytesIO()
image_without_exif.save(content, image.format)
new_file = PicklableUpload(self.base_filename, self.content_type)
new_file.receive([content.getvalue()])
return new_file
class UploadStorageError(Exception):
pass