From 0a267b3336d513bb4ea1190401547601291ceecb Mon Sep 17 00:00:00 2001 From: "Julien (jula)" Date: Tue, 18 Apr 2023 08:15:34 +0000 Subject: [PATCH] [FIX] tools: x_studio image field size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __Current behavior before PR:__ The size of an image field is guessed using the field name. For instance, an image field with `field_name = "XXXX_123"` is resized to 123 pixels when fetched. This is can be an issue if a user creates an image field using studio in a form view. If the user sets the label of the field as "Image 1", the technical name will become `x_studio_image_1`. Therefore, the image field will be resized to 1 pixel width. __Description of the fix:__ Refactor the `image_guess_size_from_field_name` method to return `(0, 0)` when the field name starts with `x_studio_`. __Steps to reproduce the issue:__ 1. Open a form view (of any model) 2. Open studio 3. Add an image field with label "Image 1" (notice the technical name becomes in `x_studio_image_1` in debug mode) 4. Close studio 5. Upload an image on the created field 6. Save... The image is resized to 1 pixel width opw-3242084 opw-3249632 opw-3253133 closes odoo/odoo#118960 X-original-commit: 3318f0e67da40983f52595aba933d8c8fd0f5cc5 Signed-off-by: Sébastien Theys (seb) --- odoo/addons/base/tests/test_image.py | 25 +++++++++++++++++++++++++ odoo/tools/image.py | 15 ++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/odoo/addons/base/tests/test_image.py b/odoo/addons/base/tests/test_image.py index 28edd9e5694..9db2b9e2e52 100644 --- a/odoo/addons/base/tests/test_image.py +++ b/odoo/addons/base/tests/test_image.py @@ -276,6 +276,31 @@ class TestImage(TransactionCase): """Test that image_data_uri is working as expected.""" self.assertEqual(tools.image_data_uri(base64.b64encode(self.img_1x1_png)), 'data:image/png;base64,' + base64.b64encode(self.img_1x1_png).decode('ascii')) + def test_21_image_guess_size_from_field_name(self): + f = tools.image_guess_size_from_field_name + # Test case: empty field_name input + self.assertEqual(f(''), (0, 0)) + # Test case: custom field_name input + self.assertEqual(f('custom_field'), (0, 0)) + # Test case: field_name input that starts with 'x_' + self.assertEqual(f('x_field'), (0, 0)) + # Test case: field_name input that starts with 'x_' and ends with a number less than 16 + self.assertEqual(f('x_studio_image_1'), (0, 0)) + # Test case: field_name input that starts with 'x_' and ends with a number greater than 16 + self.assertEqual(f('x_studio_image_32'), (0, 0)) + # Test case: field_name input that has a suffix less than 16 + self.assertEqual(f('image_15'), (0, 0)) + # Test case: field_name input that has a suffix equal to 16 + self.assertEqual(f('image_16'), (16, 16)) + # Test case: field_name input that has a suffix greater than 16 + self.assertEqual(f('image_32'), (32, 32)) + # Test case: field_name input that has a suffix with 2 numbers + self.assertEqual(f('image_1920_1080'), (1080, 1080)) + # Test case: field_name input that has a float as suffix + self.assertEqual(f('image_32.5'), (0, 0)) + # Test case: field_name input that has a suffix greater than 16 but no underscore + self.assertEqual(f('image32'), (0, 0)) + def _assertAlmostEqualSequence(self, rgb1, rgb2, delta=10): self.assertEqual(len(rgb1), len(rgb2)) for index, t in enumerate(zip(rgb1, rgb2)): diff --git a/odoo/tools/image.py b/odoo/tools/image.py index d357abfff6f..a4d8e4604de 100644 --- a/odoo/tools/image.py +++ b/odoo/tools/image.py @@ -449,18 +449,27 @@ def is_image_size_above(base64_source_1, base64_source_2): def image_guess_size_from_field_name(field_name): """Attempt to guess the image size based on `field_name`. - If it can't be guessed, return (0, 0) instead. + If it can't be guessed or if it is a custom field: return (0, 0) instead. :param str field_name: the name of a field :return: the guessed size :rtype: tuple (width, height) """ - suffix = '1024' if field_name == 'image' else field_name.split('_')[-1] + if field_name == 'image': + return (1024, 1024) + if field_name.startswith('x_'): + return (0, 0) try: - return (int(suffix), int(suffix)) + suffix = int(field_name.split('_')[-1]) except ValueError: return (0, 0) + if suffix < 16: + # If the suffix is less than 16, it's probably not the size + return (0, 0) + + return (suffix, suffix) + def image_data_uri(base64_source): """This returns data URL scheme according RFC 2397