From da5df0759f74f139cd2df7c9d7eef61590c9b0a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 16 Dec 2022 10:11:59 +0100
Subject: [PATCH] misc: thumbnail param when serving cards file fields (#72533)

---
 tests/api/test_carddata.py | 53 ++++++++++++++++++++++++++++++++++++++
 tests/api/test_carddef.py  | 29 ---------------------
 wcs/forms/common.py        |  5 +++-
 3 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/tests/api/test_carddata.py b/tests/api/test_carddata.py
index 0386a823d..5d5cd9659 100644
--- a/tests/api/test_carddata.py
+++ b/tests/api/test_carddata.py
@@ -1,6 +1,9 @@
+import hashlib
 import os
 
 import pytest
+from django.utils.encoding import force_bytes
+from webtest import Upload
 
 from wcs import fields
 from wcs.admin.settings import UserFieldsFormDef
@@ -287,3 +290,53 @@ def test_carddata_user_fields(pub, local_user):
         'var1': 'toto',
         'var2': 'nono',
     }
+
+
+def test_card_get_file(pub):
+    pub.role_class.wipe()
+
+    CardDef.wipe()
+    carddef = CardDef()
+    carddef.name = 'test'
+    carddef.fields = [
+        fields.StringField(id='0', label='foobar', varname='foobar'),
+        fields.FileField(id='3', label='foobar4', varname='file'),
+    ]
+    carddef.store()
+
+    upload = PicklableUpload('test.txt', 'text/plain', 'ascii')
+    upload.receive([b'file content'])
+
+    carddef.data_class().wipe()
+    formdata = carddef.data_class()()
+    formdata.data = {'0': 'blah', '3': upload}
+    formdata.just_created()
+    formdata.store()
+
+    resp = get_app(pub).get(sign_uri('/api/cards/test/%s/' % formdata.id))
+    file_url = resp.json['fields']['file']['url']
+    assert get_app(pub).get(file_url, status=403)
+
+    resp = get_app(pub).get(sign_uri(file_url), status=200)
+    assert resp.text == 'file content'
+
+    upload = PicklableUpload('test.jpeg', 'image/jpeg')
+    with open(os.path.join(os.path.dirname(__file__), '../image-with-gps-data.jpeg'), 'rb') as fd:
+        upload.receive([fd.read()])
+    formdata.data = {'0': 'blah', '3': upload}
+    formdata.store()
+
+    resp = get_app(pub).get(sign_uri('/api/cards/test/%s/' % formdata.id))
+    file_url = resp.json['fields']['file']['url']
+    assert upload.can_thumbnail() is True
+    thumbs_dir = os.path.join(pub.app_dir, 'thumbs')
+    thumb_filepath = os.path.join(
+        thumbs_dir, hashlib.sha256(force_bytes(upload.get_fs_filename())).hexdigest()
+    )
+    assert os.path.exists(thumbs_dir) is False
+    assert os.path.exists(thumb_filepath) is False
+    get_app(pub).get(sign_uri(file_url + '&thumbnail=1'), status=200)
+    assert os.path.exists(thumbs_dir) is True
+    assert os.path.exists(thumb_filepath) is True
+    # again, thumbs_dir already exists
+    get_app(pub).get(sign_uri(file_url + '&thumbnail=1'), status=200)
diff --git a/tests/api/test_carddef.py b/tests/api/test_carddef.py
index 3a60b5c84..d53e53dfa 100644
--- a/tests/api/test_carddef.py
+++ b/tests/api/test_carddef.py
@@ -882,35 +882,6 @@ def test_cards_http_auth_access(pub, local_user):
     assert resp.json['err_desc'] == 'unsufficient roles'
 
 
-def test_card_get_file(pub):
-    pub.role_class.wipe()
-
-    CardDef.wipe()
-    carddef = CardDef()
-    carddef.name = 'test'
-    carddef.fields = [
-        fields.StringField(id='0', label='foobar', varname='foobar'),
-        fields.FileField(id='3', label='foobar4', varname='file'),
-    ]
-    carddef.store()
-
-    upload = PicklableUpload('test.txt', 'text/plain', 'ascii')
-    upload.receive([b'file content'])
-
-    carddef.data_class().wipe()
-    formdata = carddef.data_class()()
-    formdata.data = {'0': 'blah', '3': upload}
-    formdata.just_created()
-    formdata.store()
-
-    resp = get_app(pub).get(sign_uri('/api/cards/test/%s/' % formdata.id))
-    file_url = resp.json['fields']['file']['url']
-    assert get_app(pub).get(file_url, status=403)
-
-    resp = get_app(pub).get(sign_uri(file_url), status=200)
-    assert resp.text == 'file content'
-
-
 def test_post_invalid_json(pub, local_user):
     resp = get_app(pub).post(
         '/api/cards/test/submit', params='not a json payload', content_type='application/json', status=400
diff --git a/wcs/forms/common.py b/wcs/forms/common.py
index ff43cf14a..15977afd0 100644
--- a/wcs/forms/common.py
+++ b/wcs/forms/common.py
@@ -772,7 +772,10 @@ class FormStatusPage(Directory, FormTemplateMixin):
                 if not hasattr(field_data, 'file_digest'):
                     continue
                 if field_data.file_digest() == file_digest:
-                    return FileDirectory.serve_file(field_data)
+                    return FileDirectory.serve_file(
+                        field_data,
+                        thumbnail=bool(get_request().form.get('thumbnail') and field_data.can_thumbnail()),
+                    )
         elif get_request().form and get_request().form.get('f'):
             try:
                 fn = get_request().form['f']
-- 
2.35.1

