From 78535e0c488b540a898b373d2363b261fc60995d Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Sun, 3 Sep 2023 15:43:14 +0200 Subject: [PATCH 01/32] [ADD] fs_image: Field to store images Store your image into an external filesystem --- fs_image/README.rst | 35 +++ fs_image/__init__.py | 1 + fs_image/__manifest__.py | 22 ++ fs_image/fields.py | 226 ++++++++++++++++++ fs_image/models/__init__.py | 2 + fs_image/models/fs_image_mixin.py | 17 ++ fs_image/models/ir_attachment.py | 15 ++ fs_image/readme/CONTRIBUTORS.rst | 1 + fs_image/readme/DESCRIPTION.rst | 15 ++ fs_image/readme/USAGE.rst | 113 +++++++++ fs_image/static/description/icon.png | Bin 0 -> 9455 bytes fs_image/static/src/scss/fsimage_field.scss | 0 .../src/views/dialogs/alttext_dialog.esm.js | 40 ++++ .../src/views/dialogs/alttext_dialog.xml | 33 +++ .../src/views/fields/fsimage_field.esm.js | 100 ++++++++ .../static/src/views/fields/fsimage_field.xml | 65 +++++ fs_image/tests/__init__.py | 1 + fs_image/tests/models.py | 32 +++ fs_image/tests/test_fs_image.py | 222 +++++++++++++++++ 19 files changed, 940 insertions(+) create mode 100644 fs_image/README.rst create mode 100644 fs_image/__init__.py create mode 100644 fs_image/__manifest__.py create mode 100644 fs_image/fields.py create mode 100644 fs_image/models/__init__.py create mode 100644 fs_image/models/fs_image_mixin.py create mode 100644 fs_image/models/ir_attachment.py create mode 100644 fs_image/readme/CONTRIBUTORS.rst create mode 100644 fs_image/readme/DESCRIPTION.rst create mode 100644 fs_image/readme/USAGE.rst create mode 100644 fs_image/static/description/icon.png create mode 100644 fs_image/static/src/scss/fsimage_field.scss create mode 100644 fs_image/static/src/views/dialogs/alttext_dialog.esm.js create mode 100644 fs_image/static/src/views/dialogs/alttext_dialog.xml create mode 100644 fs_image/static/src/views/fields/fsimage_field.esm.js create mode 100644 fs_image/static/src/views/fields/fsimage_field.xml create mode 100644 fs_image/tests/__init__.py create mode 100644 fs_image/tests/models.py create mode 100644 fs_image/tests/test_fs_image.py diff --git a/fs_image/README.rst b/fs_image/README.rst new file mode 100644 index 0000000000..38929e8775 --- /dev/null +++ b/fs_image/README.rst @@ -0,0 +1,35 @@ +**This file is going to be generated by oca-gen-addon-readme.** + +*Manual changes will be overwritten.* + +Please provide content in the ``readme`` directory: + +* **DESCRIPTION.rst** (required) +* INSTALL.rst (optional) +* CONFIGURE.rst (optional) +* **USAGE.rst** (optional, highly recommended) +* DEVELOP.rst (optional) +* ROADMAP.rst (optional) +* HISTORY.rst (optional, recommended) +* **CONTRIBUTORS.rst** (optional, highly recommended) +* CREDITS.rst (optional) + +Content of this README will also be drawn from the addon manifest, +from keys such as name, authors, maintainers, development_status, +and license. + +A good, one sentence summary in the manifest is also highly recommended. + + +Automatic changelog generation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`HISTORY.rst` can be auto generated using `towncrier `_. + +Just put towncrier compatible changelog fragments into `readme/newsfragments` +and the changelog file will be automatically generated and updated when a new fragment is added. + +Please refer to `towncrier` documentation to know more. + +NOTE: the changelog will be automatically generated when using `/ocabot merge $option`. +If you need to run it manually, refer to `OCA/maintainer-tools README `_. diff --git a/fs_image/__init__.py b/fs_image/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_image/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py new file mode 100644 index 0000000000..c415948adf --- /dev/null +++ b/fs_image/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Fs Image", + "summary": """ + Field to store images into filesystem storages""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/storage", + "depends": ["fs_file"], + "data": [], + "demo": [], + "maintainers": ["lmignon"], + "development_status": "Alpha", + "assets": { + "web.assets_backend": [ + "fs_image/static/src/**/*", + ], + }, +} diff --git a/fs_image/fields.py b/fs_image/fields.py new file mode 100644 index 0000000000..f746c0f1e4 --- /dev/null +++ b/fs_image/fields.py @@ -0,0 +1,226 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +# pylint: disable=method-required-super +from contextlib import contextmanager +from io import BytesIO, IOBase + +from odoo import _ +from odoo.exceptions import UserError +from odoo.tools.image import image_process + +from odoo.addons.fs_attachment.models.ir_attachment import IrAttachment +from odoo.addons.fs_file.fields import FSFile, FSFileValue + + +class FSImageValue(FSFileValue): + """Value for the FSImage field""" + + def __init__( + self, + attachment: IrAttachment = None, + name: str = None, + value: bytes | IOBase = None, + alt_text: str = None, + ) -> None: + super().__init__(attachment, name, value) + self.alt_text = alt_text + + @property + def alt_text(self) -> str: + alt_text = self._attachment.alt_text if self._attachment else self._alt_text + return alt_text + + @alt_text.setter + def alt_text(self, value: str) -> None: + if self._attachment: + self._attachment.alt_text = value + else: + self._alt_text = value + + @classmethod + def from_fs_file_value(cls, fs_file_value: FSFileValue) -> "FSImageValue": + if isinstance(fs_file_value, FSImageValue): + return fs_file_value + alt_text = ( + fs_file_value.attachment.alt_text if fs_file_value.attachment else None + ) + alt_text = alt_text or None + return cls( + attachment=fs_file_value.attachment, + name=fs_file_value.name if not fs_file_value.attachment else None, + value=fs_file_value._buffer + if not fs_file_value.attachment + else fs_file_value._buffer, + alt_text=alt_text, + ) + + def image_process( + self, + size=(0, 0), + verify_resolution=False, + quality=0, + crop=None, + colorize=False, + output_format="", + ): + """ + Process the image to adapt it to the given parameters. + :param size: a tuple (max_width, max_height) containing the maximum + width and height of the processed image. + If one of the value is 0, it will be calculated to keep the aspect + ratio. + If both values are 0, the image will not be resized. + :param verify_resolution: if True, make sure the original image size is not + excessive before starting to process it. The max allowed resolution is + defined by `IMAGE_MAX_RESOLUTION` in :class:`odoo.tools.image.ImageProcess`. + :param int quality: quality setting to apply. Default to 0. + + - for JPEG: 1 is worse, 95 is best. Values above 95 should be + avoided. Falsy values will fallback to 95, but only if the image + was changed, otherwise the original image is returned. + - for PNG: set falsy to prevent conversion to a WEB palette. + - for other formats: no effect. + :param crop: (True | 'top' | 'bottom'): + * True, the image will be cropped to the given size. + * 'top', the image will be cropped at the top to the given size. + * 'bottom', the image will be cropped at the bottom to the given size. + Otherwise, it will be resized to fit the given size. + :param colorize: if True, the transparent background of the image + will be colorized in a random color. + :param str output_format: the output format. Can be PNG, JPEG, GIF, or ICO. + Default to the format of the original image. BMP is converted to + PNG, other formats than those mentioned above are converted to JPEG. + :return: the processed image as bytes + """ + return image_process( + self.getvalue(), + size=size, + crop=crop, + quality=quality, + verify_resolution=verify_resolution, + colorize=colorize, + output_format=output_format, + ) + + +class FSImage(FSFile): + """ + This field is a FSFile field with an alt_text attribute used to encapsulate + an image file stored in a filesystem storage. + + It's inspired by the 'image' field of odoo :class:`odoo.fields.Binary` but + is designed to store the image in a filesystem storage instead of the + database. + + If image size is greater than the ``max_width``/``max_height`` limit of pixels, + the image will be resized to the limit by keeping aspect ratio. + + :param int max_width: the maximum width of the image (default: ``0``, no limit) + :param int max_height: the maximum height of the image (default: ``0``, no limit) + :param bool verify_resolution: whether the image resolution should be verified + to ensure it doesn't go over the maximum image resolution + (default: ``True``). + See :class:`odoo.tools.image.ImageProcess` for maximum image resolution + (default: ``50e6``). + """ + + type = "fs_image" + + max_width = 0 + max_height = 0 + verify_resolution = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._image_process_mode = False + + def create(self, record_values): + with self._set_image_process_mode(): + return super().create(record_values) + + def write(self, records, value): + if isinstance(value, dict) and "content" not in value: + # we are writing on the alt_text field only + return self._update_alt_text(records, value) + with self._set_image_process_mode(): + return super().write(records, value) + + def convert_to_cache(self, value, record, validate=True): + if not value: + return None + if isinstance(value, FSImageValue): + cache_value = value + else: + cache_value = super().convert_to_cache(value, record, validate) + if not isinstance(cache_value, FSImageValue): + cache_value = FSImageValue.from_fs_file_value(cache_value) + if isinstance(value, dict) and "alt_text" in value: + cache_value.alt_text = value["alt_text"] + if self._image_process_mode and cache_value.is_new: + name = cache_value.name + new_value = BytesIO(self._image_process(cache_value)) + cache_value._buffer = new_value + cache_value.name = name + return cache_value + + def _create_attachment(self, record, cache_value): + attachment = super()._create_attachment(record, cache_value) + # odoo filter out additional fields in create method on ir.attachment + # so we need to write the alt_text after the creation + attachment.alt_text = cache_value.alt_text + return attachment + + def _convert_attachment_to_cache(self, attachment: IrAttachment) -> FSImageValue: + cache_value = super()._convert_attachment_to_cache(attachment) + return FSImageValue.from_fs_file_value(cache_value) + + def _image_process(self, cache_value: FSImageValue) -> bytes | None: + if self.readonly and not self.max_width and not self.max_height: + # no need to process images for computed fields, or related fields + return cache_value.getvalue() + return ( + cache_value.image_process( + size=(self.max_width, self.max_height), + verify_resolution=self.verify_resolution, + ) + or None + ) + + def convert_to_read(self, value, record, use_name_get=True) -> dict | None: + vals = super().convert_to_read(value, record, use_name_get) + if isinstance(value, FSImageValue): + vals["alt_text"] = value.alt_text or None + return vals + + @contextmanager + def _set_image_process_mode(self): + self._image_process_mode = True + try: + yield + finally: + self._image_process_mode = False + + def _process_related(self, value: FSImageValue): + """Override to resize the related value before saving it on self.""" + if not value: + return None + if self.readonly and not self.max_width and not self.max_height: + # no need to process images for computed fields, or related fields + # without max_width/max_height + return value + value = super()._process_related(value) + new_value = BytesIO(self._image_process(value)) + return FSImageValue(value=new_value, alt_text=value.alt_text, name=value.name) + + def _update_alt_text(self, records, value: dict): + for record in records: + if not record[self.name]: + raise UserError( + _( + "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)", + record=record, + field_name=self.name, + ) + ) + record[self.name].alt_text = value["alt_text"] + return True diff --git a/fs_image/models/__init__.py b/fs_image/models/__init__.py new file mode 100644 index 0000000000..17f08cdf4d --- /dev/null +++ b/fs_image/models/__init__.py @@ -0,0 +1,2 @@ +from . import ir_attachment +from . import fs_image_mixin diff --git a/fs_image/models/fs_image_mixin.py b/fs_image/models/fs_image_mixin.py new file mode 100644 index 0000000000..eb5684069f --- /dev/null +++ b/fs_image/models/fs_image_mixin.py @@ -0,0 +1,17 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + +from ..fields import FSImage + + +class FSImageMixin(models.AbstractModel): + _name = "fs.image.mixin" + _description = "Image Mixin" + + image = FSImage("Image") + # resized fields stored (as attachment) for performance + image_medium = FSImage( + "Image medium", related="image", max_width=128, max_height=128, store=True + ) diff --git a/fs_image/models/ir_attachment.py b/fs_image/models/ir_attachment.py new file mode 100644 index 0000000000..2856e98c34 --- /dev/null +++ b/fs_image/models/ir_attachment.py @@ -0,0 +1,15 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class IrAttachment(models.Model): + + _inherit = "ir.attachment" + + alt_text = fields.Char( + "Alternative Text", + help="Alternative text for the image. Only used for images on a website.", + translate=False, + ) diff --git a/fs_image/readme/CONTRIBUTORS.rst b/fs_image/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..172b2d223c --- /dev/null +++ b/fs_image/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Laurent Mignon diff --git a/fs_image/readme/DESCRIPTION.rst b/fs_image/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..9315e90ab2 --- /dev/null +++ b/fs_image/readme/DESCRIPTION.rst @@ -0,0 +1,15 @@ +This addon defines a new field **FSImage** to use in your models. It is a +subclass of the **FSFile** field and comes with the same features. It extends +the **FSFile** field with specific properties dedicated to images. On the field +definition, the following additional properties are available: + +* **max_width** (int): maximum width of the image in pixels (default: ``0``, no limit) +* **max_height** (int): maximum height of the image in pixels (default: ``0``, no limit) +* **verify_resolution** (bool):whether the image resolution should be verified + to ensure it doesn't go over the maximum image resolution (default: ``True``). + See `odoo.tools.image.ImageProcess` for maximum image resolution (default: ``50e6``). + +On the field's value side, the value is an instance of a subclass of +`odoo.addons.fs_file.fields.FSFileValue`. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that will be +displayed when the image cannot be displayed. diff --git a/fs_image/readme/USAGE.rst b/fs_image/readme/USAGE.rst new file mode 100644 index 0000000000..1db6920db7 --- /dev/null +++ b/fs_image/readme/USAGE.rst @@ -0,0 +1,113 @@ +This new field type can be used in the same way as the odoo 'Image' field type. + +.. code-block:: python + + from odoo import models + from odoo.addons.fs_image.fields import FSImage + + class MyModel(models.Model): + _name = 'my.model' + + image = FSImage('Image', max_width=1920, max_height=1920) + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
+ + +In the example above, the image will be resized to 1920x1920px if it is larger than that. +The widget used in the form view will also allow the user set an 'alt' text for the image. + + +A mode advanced and useful example is the following: + +.. code-block:: python + + from odoo import models + from odoo.addons.fs_image.fields import FSImage + + class MyModel(models.Model): + _name = 'my.model' + + image_1920 = FSImage('Image', max_width=1920, max_height=1920) + image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True) + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
+ +In the example above we have two fields, one for the original image and one for a thumbnail. +As the thumbnail is defined as a related stored field it's automatically generated +from the original image, resized at the given size and stored in the database. +The thumbnail is then used as a preview image for the original image in the form view. +The main advantage of this approach is that the original image is not loaded in the form view +and the thumbnail is used instead, which is much smaller in size and faster to load. +The 'zoom' option allows the user to see the original image in a popup when clicking on the thumbnail. + +For convenience, the 'fs_image' module also provides a 'FSImageMixin' mixin class +that can be used to add the 'image' and 'image_medium' fields to a model. It only +define the medium thumbnail as a 128x128px image since it's the most common use case. +When using an image field in a model, it's recommended to use this mixin class +in order ensure that the 'image_medium' field is always defined. A good practice +is to use the `image_medium` field as a preview image for the `image` field in +the form view to avoid to overload the form view with a large image and consume +too much bandwidth. + +.. code-block:: python + + from odoo import models + + class MyModel(models.Model): + _name = 'my.model' + _inherit = ['fs_image.mixin'] + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
diff --git a/fs_image/static/description/icon.png b/fs_image/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_image/static/src/scss/fsimage_field.scss b/fs_image/static/src/scss/fsimage_field.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fs_image/static/src/views/dialogs/alttext_dialog.esm.js b/fs_image/static/src/views/dialogs/alttext_dialog.esm.js new file mode 100644 index 0000000000..b648fb1791 --- /dev/null +++ b/fs_image/static/src/views/dialogs/alttext_dialog.esm.js @@ -0,0 +1,40 @@ +/** @odoo-module */ + +/** + * Copyright 2023 ACSONE SA/NV + */ + +import {Dialog} from "@web/core/dialog/dialog"; + +const {Component, useRef} = owl; + +export class AltTextDialog extends Component { + setup() { + this.altText = useRef("altText"); + } + + async onClose() { + if (this.props.close) { + this.props.close(); + } + } + + async onConfirm() { + try { + await this.props.confirm(this.altText.el.value); + } catch (e) { + this.props.close(); + throw e; + } + this.onClose(); + } +} + +AltTextDialog.components = {Dialog}; +AltTextDialog.template = "fs_image.AltTextDialog"; +AltTextDialog.props = { + title: String, + altText: String, + confirm: Function, + close: {type: Function, optional: true}, +}; diff --git a/fs_image/static/src/views/dialogs/alttext_dialog.xml b/fs_image/static/src/views/dialogs/alttext_dialog.xml new file mode 100644 index 0000000000..afdd22c838 --- /dev/null +++ b/fs_image/static/src/views/dialogs/alttext_dialog.xml @@ -0,0 +1,33 @@ + + + + +
+ + + +
+ +
+
+ + + + +
+
+
diff --git a/fs_image/static/src/views/fields/fsimage_field.esm.js b/fs_image/static/src/views/fields/fsimage_field.esm.js new file mode 100644 index 0000000000..adc4ffc618 --- /dev/null +++ b/fs_image/static/src/views/fields/fsimage_field.esm.js @@ -0,0 +1,100 @@ +/** @odoo-module */ + +/** + * Copyright 2023 ACSONE SA/NV + */ +import { + ImageField, + fileTypeMagicWordMap, + imageCacheKey, +} from "@web/views/fields/image/image_field"; +import {onWillUpdateProps, useState} from "@odoo/owl"; + +import {AltTextDialog} from "../dialogs/alttext_dialog.esm"; +import {registry} from "@web/core/registry"; +import {url} from "@web/core/utils/urls"; +import {useService} from "@web/core/utils/hooks"; + +const placeholder = "/web/static/img/placeholder.png"; + +export class FSImageField extends ImageField { + setup() { + // Call super.setup() to initialize the state + super.setup(); + this.state = useState({ + ...this.props.value, + ...this.state, + }); + onWillUpdateProps((nextProps) => { + this.state.isUploading = false; + const {filename, mimetype, alt_text, url} = nextProps.value || {}; + this.state.filename = filename; + this.state.mimetype = mimetype; + this.state.url = url; + this.state.alt_text = alt_text; + }); + this.dialogService = useService("dialog"); + } + + getUrl(previewFieldName) { + if ( + this.state.isValid && + this.props.value && + typeof this.props.value === "object" + ) { + // Check if value is a dict + if (this.props.value.content) { + // We use the binary content of the value + // Use magic-word technique for detecting image type + const magic = + fileTypeMagicWordMap[this.props.value.content[0]] || "png"; + return `data:image/${magic};base64,${this.props.value.content}`; + } + if (!this.rawCacheKey) { + this.rawCacheKey = this.props.record.data.__last_update; + } + const model = this.props.record.resModel; + const id = this.props.record.resId; + let base_url = this.props.value.url; + if (id !== undefined && id !== null && id !== false) { + const field = previewFieldName; + const filename = this.props.value.filename; + base_url = `/web/image/${model}/${id}/${field}/${filename}`; + } + return url(base_url, {unique: imageCacheKey(this.rawCacheKey)}); + } + return placeholder; + } + + get hasTooltip() { + return this.props.enableZoom && !this.props.isDebugMode && this.props.value; + } + + onFileUploaded(info) { + this.state.isValid = true; + // Invalidate the `rawCacheKey`. + this.rawCacheKey = null; + this.props.update({ + filename: info.name, + content: info.data, + }); + } + onAltTextEdit() { + const self = this; + const altText = this.props.value.alt_text || ""; + const dialogProps = { + title: this.env._t("Alt Text"), + altText: altText, + confirm: (value) => { + self.props.update({ + ...self.props.value, + alt_text: value, + }); + }, + }; + this.dialogService.add(AltTextDialog, dialogProps); + } +} + +FSImageField.template = "fs_image.FSImageField"; +registry.category("fields").add("fs_image", FSImageField); diff --git a/fs_image/static/src/views/fields/fsimage_field.xml b/fs_image/static/src/views/fields/fsimage_field.xml new file mode 100644 index 0000000000..cc1eeb507a --- /dev/null +++ b/fs_image/static/src/views/fields/fsimage_field.xml @@ -0,0 +1,65 @@ + + + + +
+
+ + + + + + + + + +
+ Binary file +
+
+ +
diff --git a/fs_image/tests/__init__.py b/fs_image/tests/__init__.py new file mode 100644 index 0000000000..fec1f1d8e7 --- /dev/null +++ b/fs_image/tests/__init__.py @@ -0,0 +1 @@ +from . import test_fs_image diff --git a/fs_image/tests/models.py b/fs_image/tests/models.py new file mode 100644 index 0000000000..c48020241a --- /dev/null +++ b/fs_image/tests/models.py @@ -0,0 +1,32 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + +from ..fields import FSImage + + +class TestImageModel(models.Model): + + _name = "test.image.model" + _description = "Test Model" + _log_access = False + + fs_image = FSImage(verify_resolution=False) + fs_image_1024 = FSImage("Image 1024", max_width=1024, max_height=1024) + + +class TestRelatedImageModel(models.Model): + + _name = "test.related.image.model" + _description = "Test Related Image Model" + _log_access = False + + fs_image = FSImage(verify_resolution=False) + # resized fields stored (as attachment) for performance + fs_image_1024 = FSImage( + "Image 1024", related="fs_image", max_width=1024, max_height=1024, store=True + ) + fs_image_512 = FSImage( + "Image 512", related="fs_image", max_width=512, max_height=512, store=True + ) diff --git a/fs_image/tests/test_fs_image.py b/fs_image/tests/test_fs_image.py new file mode 100644 index 0000000000..296c6420d8 --- /dev/null +++ b/fs_image/tests/test_fs_image.py @@ -0,0 +1,222 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import base64 +import io +import os +import tempfile + +from odoo_test_helper import FakeModelLoader +from PIL import Image + +from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase + +from odoo.addons.fs_storage.models.fs_storage import FSStorage + +from ..fields import FSImageValue + + +class TestFsImage(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.env["ir.config_parameter"].set_param( + "base.image_autoresize_max_px", "10000x10000" + ) + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .models import TestImageModel, TestRelatedImageModel + + cls.loader.update_registry((TestImageModel, TestRelatedImageModel)) + + cls.image_w = cls._create_image(4000, 2000) + cls.image_h = cls._create_image(2000, 4000) + + cls.create_content = cls.image_w + cls.write_content = cls.image_h + cls.tmpfile_path = tempfile.mkstemp(suffix=".png")[1] + with open(cls.tmpfile_path, "wb") as f: + f.write(cls.create_content) + cls.filename = os.path.basename(cls.tmpfile_path) + + def setUp(self): + super().setUp() + self.temp_dir: FSStorage = self.env["fs.storage"].create( + { + "name": "Temp FS Storage", + "protocol": "memory", + "code": "mem_dir", + "directory_path": "/tmp/", + "model_xmlids": "fs_file.model_test_model", + } + ) + + @classmethod + def tearDownClass(cls): + if os.path.exists(cls.tmpfile_path): + os.remove(cls.tmpfile_path) + cls.loader.restore_registry() + return super().tearDownClass() + + @classmethod + def _create_image(cls, width, height, color="#4169E1", img_format="PNG"): + f = io.BytesIO() + Image.new("RGB", (width, height), color).save(f, img_format) + f.seek(0) + return f.read() + + def _test_create(self, fs_image_value): + model = self.env["test.image.model"] + instance = model.create({"fs_image": fs_image_value}) + self.assertTrue(isinstance(instance.fs_image, FSImageValue)) + self.assertEqual(instance.fs_image.getvalue(), self.create_content) + self.assertEqual(instance.fs_image.name, self.filename) + return instance + + def _test_write(self, fs_image_value, **ctx): + instance = self.env["test.image.model"].create({}) + if ctx: + instance = instance.with_context(**ctx) + instance.fs_image = fs_image_value + self.assertEqual(instance.fs_image.getvalue(), self.write_content) + self.assertEqual(instance.fs_image.name, self.filename) + return instance + + def assert_image_size(self, value: bytes, width, height): + self.assertEqual(Image.open(io.BytesIO(value)).size, (width, height)) + + def test_read(self): + instance = self.env["test.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.create_content)} + ) + info = instance.read(["fs_image"])[0] + self.assertDictEqual( + info["fs_image"], + { + "alt_text": None, + "filename": self.filename, + "mimetype": "image/png", + "size": len(self.create_content), + "url": instance.fs_image.internal_url, + }, + ) + + def test_create_with_FsImagebytesio(self): + self._test_create(FSImageValue(name=self.filename, value=self.create_content)) + + def test_create_with_dict(self): + instance = self._test_create( + { + "filename": self.filename, + "content": base64.b64encode(self.create_content), + "alt_text": "test", + } + ) + self.assertEqual(instance.fs_image.alt_text, "test") + + def test_write_with_dict(self): + instance = self._test_write( + { + "filename": self.filename, + "content": base64.b64encode(self.write_content), + "alt_text": "test_bis", + } + ) + self.assertEqual(instance.fs_image.alt_text, "test_bis") + + def test_create_with_file_like(self): + with open(self.tmpfile_path, "rb") as f: + self._test_create(f) + + def test_create_in_b64(self): + instance = self.env["test.image.model"].create( + {"fs_image": base64.b64encode(self.create_content)} + ) + self.assertTrue(isinstance(instance.fs_image, FSImageValue)) + self.assertEqual(instance.fs_image.getvalue(), self.create_content) + + def test_write_in_b64(self): + instance = self.env["test.image.model"].create({"fs_image": b"test"}) + instance.write({"fs_image": base64.b64encode(self.create_content)}) + self.assertTrue(isinstance(instance.fs_image, FSImageValue)) + self.assertEqual(instance.fs_image.getvalue(), self.create_content) + + def test_write_in_b64_with_specified_filename(self): + self._test_write( + base64.b64encode(self.write_content), fs_filename=self.filename + ) + + def test_create_with_io(self): + instance = self.env["test.image.model"].create( + {"fs_image": io.BytesIO(self.create_content)} + ) + self.assertTrue(isinstance(instance.fs_image, FSImageValue)) + self.assertEqual(instance.fs_image.getvalue(), self.create_content) + + def test_write_with_io(self): + instance = self.env["test.image.model"].create( + {"fs_image": io.BytesIO(self.create_content)} + ) + instance.write({"fs_image": io.BytesIO(b"test3")}) + self.assertTrue(isinstance(instance.fs_image, FSImageValue)) + self.assertEqual(instance.fs_image.getvalue(), b"test3") + + def test_modify_FsImagebytesio(self): + """If you modify the content of the FSImageValue, + the changes will be directly applied + and a new file in the storage must be created for the new content. + """ + instance = self.env["test.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.create_content)} + ) + initial_store_fname = instance.fs_image.attachment.store_fname + with instance.fs_image.open(mode="wb") as f: + f.write(b"new_content") + self.assertNotEqual( + instance.fs_image.attachment.store_fname, initial_store_fname + ) + self.assertEqual(instance.fs_image.getvalue(), b"new_content") + + def test_image_resize(self): + instance = self.env["test.image.model"].create( + {"fs_image_1024": FSImageValue(name=self.filename, value=self.image_w)} + ) + # the image is resized to 1024x512 even if the field is 1024x1024 since + # we keep the ratio + self.assert_image_size(instance.fs_image_1024.getvalue(), 1024, 512) + + def test_image_resize_related(self): + instance = self.env["test.related.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.image_w)} + ) + self.assert_image_size(instance.fs_image.getvalue(), 4000, 2000) + self.assert_image_size(instance.fs_image_1024.getvalue(), 1024, 512) + self.assert_image_size(instance.fs_image_512.getvalue(), 512, 256) + + def test_related_with_b64(self): + instance = self.env["test.related.image.model"].create( + {"fs_image": base64.b64encode(self.create_content)} + ) + self.assert_image_size(instance.fs_image.getvalue(), 4000, 2000) + self.assert_image_size(instance.fs_image_1024.getvalue(), 1024, 512) + self.assert_image_size(instance.fs_image_512.getvalue(), 512, 256) + + def test_write_alt_text(self): + instance = self.env["test.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.image_w)} + ) + instance.fs_image.alt_text = "test" + self.assertEqual(instance.fs_image.alt_text, "test") + + def test_write_alt_text_with_dict(self): + instance = self.env["test.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.image_w)} + ) + instance.write({"fs_image": {"alt_text": "test"}}) + self.assertEqual(instance.fs_image.alt_text, "test") + + def test_write_alt_text_on_empty_with_dict(self): + instance = self.env["test.image.model"].create({}) + with self.assertRaisesRegex(UserError, "Cannot set alt_text on empty image"): + instance.write({"fs_image": {"alt_text": "test"}}) From 95ea19bc943a39b52c543df8d1d89526c321fafe Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 22 Sep 2023 06:24:11 +0000 Subject: [PATCH 02/32] [UPD] Update fs_image.pot --- fs_image/i18n/fs_image.pot | 100 +++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 fs_image/i18n/fs_image.pot diff --git a/fs_image/i18n/fs_image.pot b/fs_image/i18n/fs_image.pot new file mode 100644 index 0000000000..d80a4e6137 --- /dev/null +++ b/fs_image/i18n/fs_image.pot @@ -0,0 +1,100 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#, python-format +msgid "Alt Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +msgid "Alternative Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +msgid "Alternative text for the image. Only used for images on a website." +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Binary file" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: fs_image +#. odoo-python +#: code:addons/fs_image/fields.py:0 +#, python-format +msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Clear" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Edit" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image +msgid "Image" +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_fs_image_mixin +msgid "Image Mixin" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium +msgid "Image medium" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Save changes" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Set Alt Text" +msgstr "" From 3781460f29ad3bac0d50cd66bcec8d50628d61e3 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 22 Sep 2023 06:26:34 +0000 Subject: [PATCH 03/32] [BOT] post-merge updates --- fs_image/README.rst | 233 +++++++++-- fs_image/static/description/index.html | 545 +++++++++++++++++++++++++ 2 files changed, 754 insertions(+), 24 deletions(-) create mode 100644 fs_image/static/description/index.html diff --git a/fs_image/README.rst b/fs_image/README.rst index 38929e8775..adfdec8ee5 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -1,35 +1,220 @@ -**This file is going to be generated by oca-gen-addon-readme.** +======== +Fs Image +======== -*Manual changes will be overwritten.* +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:117413401c2187f3807cd4ce73ae108acacc5347ac150ec1fce965b5d073ee25 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -Please provide content in the ``readme`` directory: +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/16.0/fs_image + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=16.0 + :alt: Try me on Runboat -* **DESCRIPTION.rst** (required) -* INSTALL.rst (optional) -* CONFIGURE.rst (optional) -* **USAGE.rst** (optional, highly recommended) -* DEVELOP.rst (optional) -* ROADMAP.rst (optional) -* HISTORY.rst (optional, recommended) -* **CONTRIBUTORS.rst** (optional, highly recommended) -* CREDITS.rst (optional) +|badge1| |badge2| |badge3| |badge4| |badge5| -Content of this README will also be drawn from the addon manifest, -from keys such as name, authors, maintainers, development_status, -and license. +This addon defines a new field **FSImage** to use in your models. It is a +subclass of the **FSFile** field and comes with the same features. It extends +the **FSFile** field with specific properties dedicated to images. On the field +definition, the following additional properties are available: -A good, one sentence summary in the manifest is also highly recommended. +* **max_width** (int): maximum width of the image in pixels (default: ``0``, no limit) +* **max_height** (int): maximum height of the image in pixels (default: ``0``, no limit) +* **verify_resolution** (bool):whether the image resolution should be verified + to ensure it doesn't go over the maximum image resolution (default: ``True``). + See `odoo.tools.image.ImageProcess` for maximum image resolution (default: ``50e6``). +On the field's value side, the value is an instance of a subclass of +`odoo.addons.fs_file.fields.FSFileValue`. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that will be +displayed when the image cannot be displayed. -Automatic changelog generation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ -`HISTORY.rst` can be auto generated using `towncrier `_. +**Table of contents** -Just put towncrier compatible changelog fragments into `readme/newsfragments` -and the changelog file will be automatically generated and updated when a new fragment is added. +.. contents:: + :local: -Please refer to `towncrier` documentation to know more. +Usage +===== -NOTE: the changelog will be automatically generated when using `/ocabot merge $option`. -If you need to run it manually, refer to `OCA/maintainer-tools README `_. +This new field type can be used in the same way as the odoo 'Image' field type. + +.. code-block:: python + + from odoo import models + from odoo.addons.fs_image.fields import FSImage + + class MyModel(models.Model): + _name = 'my.model' + + image = FSImage('Image', max_width=1920, max_height=1920) + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
+ + +In the example above, the image will be resized to 1920x1920px if it is larger than that. +The widget used in the form view will also allow the user set an 'alt' text for the image. + + +A mode advanced and useful example is the following: + +.. code-block:: python + + from odoo import models + from odoo.addons.fs_image.fields import FSImage + + class MyModel(models.Model): + _name = 'my.model' + + image_1920 = FSImage('Image', max_width=1920, max_height=1920) + image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True) + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
+ +In the example above we have two fields, one for the original image and one for a thumbnail. +As the thumbnail is defined as a related stored field it's automatically generated +from the original image, resized at the given size and stored in the database. +The thumbnail is then used as a preview image for the original image in the form view. +The main advantage of this approach is that the original image is not loaded in the form view +and the thumbnail is used instead, which is much smaller in size and faster to load. +The 'zoom' option allows the user to see the original image in a popup when clicking on the thumbnail. + +For convenience, the 'fs_image' module also provides a 'FSImageMixin' mixin class +that can be used to add the 'image' and 'image_medium' fields to a model. It only +define the medium thumbnail as a 128x128px image since it's the most common use case. +When using an image field in a model, it's recommended to use this mixin class +in order ensure that the 'image_medium' field is always defined. A good practice +is to use the `image_medium` field as a preview image for the `image` field in +the form view to avoid to overload the form view with a large image and consume +too much bandwidth. + +.. code-block:: python + + from odoo import models + + class MyModel(models.Model): + _name = 'my.model' + _inherit = ['fs_image.mixin'] + + +.. code-block:: xml + + + my.model.form + my.model + +
+ + + + + +
+
+
+ +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Laurent Mignon + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-lmignon| image:: https://github.com/lmignon.png?size=40px + :target: https://github.com/lmignon + :alt: lmignon + +Current `maintainer `__: + +|maintainer-lmignon| + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html new file mode 100644 index 0000000000..9cedc21bdd --- /dev/null +++ b/fs_image/static/description/index.html @@ -0,0 +1,545 @@ + + + + + + +Fs Image + + + +
+

Fs Image

+ + +

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

This addon defines a new field FSImage to use in your models. It is a +subclass of the FSFile field and comes with the same features. It extends +the FSFile field with specific properties dedicated to images. On the field +definition, the following additional properties are available:

+
    +
  • max_width (int): maximum width of the image in pixels (default: 0, no limit)
  • +
  • max_height (int): maximum height of the image in pixels (default: 0, no limit)
  • +
  • verify_resolution (bool):whether the image resolution should be verified +to ensure it doesn’t go over the maximum image resolution (default: True). +See odoo.tools.image.ImageProcess for maximum image resolution (default: 50e6).
  • +
+

On the field’s value side, the value is an instance of a subclass of +odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that will be +displayed when the image cannot be displayed.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Usage

+

This new field type can be used in the same way as the odoo ‘Image’ field type.

+
+from odoo import models
+from odoo.addons.fs_image.fields import FSImage
+
+class MyModel(models.Model):
+    _name = 'my.model'
+
+    image = FSImage('Image', max_width=1920, max_height=1920)
+
+
+<record id="my_model_form" model="ir.ui.view">
+    <field name="name">my.model.form</field>
+    <field name="model">my.model</field>
+    <field name="arch" type="xml">
+        <form>
+            <sheet>
+                <group>
+                    <field name="image" class="oe_avatar"/>
+                </group>
+            </sheet>
+        </form>
+    </field>
+</record>
+
+

In the example above, the image will be resized to 1920x1920px if it is larger than that. +The widget used in the form view will also allow the user set an ‘alt’ text for the image.

+

A mode advanced and useful example is the following:

+
+from odoo import models
+from odoo.addons.fs_image.fields import FSImage
+
+class MyModel(models.Model):
+    _name = 'my.model'
+
+    image_1920 = FSImage('Image', max_width=1920, max_height=1920)
+    image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True)
+
+
+<record id="my_model_form" model="ir.ui.view">
+    <field name="name">my.model.form</field>
+    <field name="model">my.model</field>
+    <field name="arch" type="xml">
+        <form>
+            <sheet>
+                <group>
+                    <field
+                        name="image_1920"
+                        class="oe_avatar"
+                         options="{'preview_image': 'image_128', 'zoom': true}"
+                     />
+                </group>
+            </sheet>
+        </form>
+    </field>
+</record>
+
+

In the example above we have two fields, one for the original image and one for a thumbnail. +As the thumbnail is defined as a related stored field it’s automatically generated +from the original image, resized at the given size and stored in the database. +The thumbnail is then used as a preview image for the original image in the form view. +The main advantage of this approach is that the original image is not loaded in the form view +and the thumbnail is used instead, which is much smaller in size and faster to load. +The ‘zoom’ option allows the user to see the original image in a popup when clicking on the thumbnail.

+

For convenience, the ‘fs_image’ module also provides a ‘FSImageMixin’ mixin class +that can be used to add the ‘image’ and ‘image_medium’ fields to a model. It only +define the medium thumbnail as a 128x128px image since it’s the most common use case. +When using an image field in a model, it’s recommended to use this mixin class +in order ensure that the ‘image_medium’ field is always defined. A good practice +is to use the image_medium field as a preview image for the image field in +the form view to avoid to overload the form view with a large image and consume +too much bandwidth.

+
+from odoo import models
+
+class MyModel(models.Model):
+    _name = 'my.model'
+    _inherit = ['fs_image.mixin']
+
+
+<record id="my_model_form" model="ir.ui.view">
+    <field name="name">my.model.form</field>
+    <field name="model">my.model</field>
+    <field name="arch" type="xml">
+        <form>
+            <sheet>
+                <group>
+                    <field
+                        name="image"
+                        class="oe_avatar"
+                        options="{'preview_image': 'image_medium', 'zoom': true}"
+                    />
+                </group>
+            </sheet>
+        </form>
+    </field>
+</record>
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

lmignon

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 72d31ec8fabe9964e12a57688a874b480eb0bfe8 Mon Sep 17 00:00:00 2001 From: Ivorra78 Date: Fri, 27 Oct 2023 15:00:06 +0000 Subject: [PATCH 04/32] Added translation using Weblate (Spanish) --- fs_image/i18n/es.po | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 fs_image/i18n/es.po diff --git a/fs_image/i18n/es.po b/fs_image/i18n/es.po new file mode 100644 index 0000000000..665c9b1c58 --- /dev/null +++ b/fs_image/i18n/es.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#, python-format +msgid "Alt Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +msgid "Alternative Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +msgid "Alternative text for the image. Only used for images on a website." +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Binary file" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: fs_image +#. odoo-python +#: code:addons/fs_image/fields.py:0 +#, python-format +msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Clear" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Edit" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image +msgid "Image" +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_fs_image_mixin +msgid "Image Mixin" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium +msgid "Image medium" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Save changes" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Set Alt Text" +msgstr "" From 50181281bab513f79eeea470a4638e5d8b6fea94 Mon Sep 17 00:00:00 2001 From: Ivorra78 Date: Fri, 27 Oct 2023 15:00:59 +0000 Subject: [PATCH 05/32] Translated using Weblate (Spanish) Currently translated at 100.0% (14 of 14 strings) Translation: storage-16.0/storage-16.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image/es/ --- fs_image/i18n/es.po | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/fs_image/i18n/es.po b/fs_image/i18n/es.po index 665c9b1c58..19d6335bdb 100644 --- a/fs_image/i18n/es.po +++ b/fs_image/i18n/es.po @@ -6,49 +6,53 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2023-10-29 00:15+0000\n" +"Last-Translator: Ivorra78 \n" "Language-Team: none\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 #, python-format msgid "Alt Text" -msgstr "" +msgstr "Texto Alt" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text msgid "Alternative Text" -msgstr "" +msgstr "Texto Alternativo" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" +"Texto alternativo para la imagen. Solo se utiliza para imágenes de un sitio " +"web." #. module: fs_image #: model:ir.model,name:fs_image.model_ir_attachment msgid "Attachment" -msgstr "" +msgstr "Archivo Adjunto" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Binary file" -msgstr "" +msgstr "Archivo binario" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Cancel" -msgstr "" +msgstr "Cancelar" #. module: fs_image #. odoo-python @@ -56,46 +60,48 @@ msgstr "" #, python-format msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" msgstr "" +"No se puede establecer alt_text en una imagen vacía (record " +"%(record)s.%(field_name)s)" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Clear" -msgstr "" +msgstr "Limpiar" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Edit" -msgstr "" +msgstr "Editar" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image msgid "Image" -msgstr "" +msgstr "Imagen" #. module: fs_image #: model:ir.model,name:fs_image.model_fs_image_mixin msgid "Image Mixin" -msgstr "" +msgstr "Mezcla de Imágenes" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium msgid "Image medium" -msgstr "" +msgstr "Imagen mediana" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Save changes" -msgstr "" +msgstr "Guardar cambios" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Set Alt Text" -msgstr "" +msgstr "Establecer Texto Alt" From 9e8e42c0d72c2ed2f79c49f8fc21d22050090500 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 28 Nov 2023 06:52:51 +0000 Subject: [PATCH 06/32] Added translation using Weblate (Italian) --- fs_image/i18n/it.po | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 fs_image/i18n/it.po diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po new file mode 100644 index 0000000000..eedc20d85a --- /dev/null +++ b/fs_image/i18n/it.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#, python-format +msgid "Alt Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +msgid "Alternative Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +msgid "Alternative text for the image. Only used for images on a website." +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Binary file" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: fs_image +#. odoo-python +#: code:addons/fs_image/fields.py:0 +#, python-format +msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Clear" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Edit" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image +msgid "Image" +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_fs_image_mixin +msgid "Image Mixin" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium +msgid "Image medium" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Save changes" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Set Alt Text" +msgstr "" From 635b40e309e32eb61f8dda50ffc492714f052d57 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 28 Nov 2023 12:02:34 +0000 Subject: [PATCH 07/32] Translated using Weblate (Italian) Currently translated at 92.8% (13 of 14 strings) Translation: storage-16.0/storage-16.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image/it/ --- fs_image/i18n/it.po | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po index eedc20d85a..97f4f46b6c 100644 --- a/fs_image/i18n/it.po +++ b/fs_image/i18n/it.po @@ -6,49 +6,53 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2023-11-28 14:33+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 #, python-format msgid "Alt Text" -msgstr "" +msgstr "Testo alternativo" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text msgid "Alternative Text" -msgstr "" +msgstr "Testo alternativo" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" +"Testo alternativo per l'immagine. Utilizzato solo per le immagini nel sito " +"web." #. module: fs_image #: model:ir.model,name:fs_image.model_ir_attachment msgid "Attachment" -msgstr "" +msgstr "Allegato" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Binary file" -msgstr "" +msgstr "file binario" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Cancel" -msgstr "" +msgstr "Annulla" #. module: fs_image #. odoo-python @@ -56,6 +60,8 @@ msgstr "" #, python-format msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" msgstr "" +"Non si può impostare il campo alt_text nelle immagini vuote (record " +"%(record)s.%(field_name)s)" #. module: fs_image #. odoo-javascript @@ -69,33 +75,33 @@ msgstr "" #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Edit" -msgstr "" +msgstr "Modifica" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image msgid "Image" -msgstr "" +msgstr "Immagine" #. module: fs_image #: model:ir.model,name:fs_image.model_fs_image_mixin msgid "Image Mixin" -msgstr "" +msgstr "Mixin immagine" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium msgid "Image medium" -msgstr "" +msgstr "Immagine media" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Save changes" -msgstr "" +msgstr "Salva modifiche" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Set Alt Text" -msgstr "" +msgstr "Imposta testo alternativo" From 8b1be571bae2cee3382fccf55c2e8fa0fea19ec0 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 29 Nov 2023 17:36:26 +0000 Subject: [PATCH 08/32] Translated using Weblate (Italian) Currently translated at 100.0% (14 of 14 strings) Translation: storage-16.0/storage-16.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image/it/ --- fs_image/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po index 97f4f46b6c..3094961f29 100644 --- a/fs_image/i18n/it.po +++ b/fs_image/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-11-28 14:33+0000\n" +"PO-Revision-Date: 2023-11-29 20:33+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -68,7 +68,7 @@ msgstr "" #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Clear" -msgstr "" +msgstr "Pulisci" #. module: fs_image #. odoo-javascript From 1e712cfb47eb38a275208216d4e85eb0a4648a13 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 30 Nov 2023 11:05:36 +0100 Subject: [PATCH 09/32] [FIX] fs_image: Avoid update attachment on read Fix a bug in the initialization of the image field value object when the field is read. Before this fix, every time the value object was initialized with an attachment, an assignment of the alt text was done into the constructor. This assignment triggered the mark of the field as modified and an SQL update query was generated at the end of the request. The alt text in the constructor of the FSImageValue class must only be used when the class is initialized without an attachment. We now check if an attachment and an alt text are provided at the same time and throw an exception if this is the case. --- fs_image/README.rst | 2 +- fs_image/fields.py | 16 +++++++++------- fs_image/readme/newsfragments/.gitignore | 0 fs_image/readme/newsfragments/307.bugfix | 10 ++++++++++ fs_image/static/description/index.html | 2 +- fs_image/tests/test_fs_image.py | 19 ++++++++++++++++++- 6 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 fs_image/readme/newsfragments/.gitignore create mode 100644 fs_image/readme/newsfragments/307.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index adfdec8ee5..0eb150a614 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:117413401c2187f3807cd4ce73ae108acacc5347ac150ec1fce965b5d073ee25 + !! source digest: sha256:8743df12cbf6e8e739aa2d6241767c1f54c7ab74c7956fb93523758dbaa19a66 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image/fields.py b/fs_image/fields.py index f746c0f1e4..9d50e2691a 100644 --- a/fs_image/fields.py +++ b/fs_image/fields.py @@ -23,7 +23,13 @@ def __init__( alt_text: str = None, ) -> None: super().__init__(attachment, name, value) - self.alt_text = alt_text + if self._attachment and alt_text is not None: + raise ValueError( + "FSImageValue cannot be initialized with an attachment and an" + " alt_text at the same time. When initializing with an attachment," + " you can't pass any other argument." + ) + self._alt_text = alt_text @property def alt_text(self) -> str: @@ -41,17 +47,12 @@ def alt_text(self, value: str) -> None: def from_fs_file_value(cls, fs_file_value: FSFileValue) -> "FSImageValue": if isinstance(fs_file_value, FSImageValue): return fs_file_value - alt_text = ( - fs_file_value.attachment.alt_text if fs_file_value.attachment else None - ) - alt_text = alt_text or None return cls( attachment=fs_file_value.attachment, name=fs_file_value.name if not fs_file_value.attachment else None, value=fs_file_value._buffer if not fs_file_value.attachment else fs_file_value._buffer, - alt_text=alt_text, ) def image_process( @@ -167,7 +168,8 @@ def _create_attachment(self, record, cache_value): attachment = super()._create_attachment(record, cache_value) # odoo filter out additional fields in create method on ir.attachment # so we need to write the alt_text after the creation - attachment.alt_text = cache_value.alt_text + if cache_value.alt_text: + attachment.alt_text = cache_value.alt_text return attachment def _convert_attachment_to_cache(self, attachment: IrAttachment) -> FSImageValue: diff --git a/fs_image/readme/newsfragments/.gitignore b/fs_image/readme/newsfragments/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fs_image/readme/newsfragments/307.bugfix b/fs_image/readme/newsfragments/307.bugfix new file mode 100644 index 0000000000..66ef8ccdfe --- /dev/null +++ b/fs_image/readme/newsfragments/307.bugfix @@ -0,0 +1,10 @@ +Avoid to generate an SQL update query when an image field is read. + +Fix a bug in the initialization of the image field value object when the field +is read. Before this fix, every time the value object was initialized with +an attachment, an assignment of the alt text was done into the constructor. +This assignment triggered the mark of the field as modified and an SQL update +query was generated at the end of the request. The alt text in the constructor +of the FSImageValue class must only be used when the class is initialized without +an attachment. We now check if an attachment and an alt text are provided at +the same time and throw an exception if this is the case. diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 9cedc21bdd..7789318cb5 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -367,7 +367,7 @@

Fs Image

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:117413401c2187f3807cd4ce73ae108acacc5347ac150ec1fce965b5d073ee25 +!! source digest: sha256:8743df12cbf6e8e739aa2d6241767c1f54c7ab74c7956fb93523758dbaa19a66 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon defines a new field FSImage to use in your models. It is a diff --git a/fs_image/tests/test_fs_image.py b/fs_image/tests/test_fs_image.py index 296c6420d8..fb9a9b8f64 100644 --- a/fs_image/tests/test_fs_image.py +++ b/fs_image/tests/test_fs_image.py @@ -9,7 +9,7 @@ from PIL import Image from odoo.exceptions import UserError -from odoo.tests.common import TransactionCase +from odoo.tests.common import TransactionCase, users, warmup from odoo.addons.fs_storage.models.fs_storage import FSStorage @@ -220,3 +220,20 @@ def test_write_alt_text_on_empty_with_dict(self): instance = self.env["test.image.model"].create({}) with self.assertRaisesRegex(UserError, "Cannot set alt_text on empty image"): instance.write({"fs_image": {"alt_text": "test"}}) + + @users("__system__") + @warmup + def test_generated_sql_commands(self): + # The following tests will never fail, but they will output a warning + # if the number of SQL queries changes into the logs. They + # are to help us keep track of the number of SQL queries generated + # by the module. + with self.assertQueryCount(__system__=3): + instance = self.env["test.image.model"].create( + {"fs_image": FSImageValue(name=self.filename, value=self.image_w)} + ) + + instance.invalidate_recordset() + with self.assertQueryCount(__system__=1): + self.assertEqual(instance.fs_image.getvalue(), self.image_w) + self.env.flush_all() From 87bc4918201586e617e48e8409f96e4c9864031d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sat, 2 Dec 2023 08:28:08 +0000 Subject: [PATCH 10/32] [BOT] post-merge updates --- fs_image/README.rst | 21 ++++++++++- fs_image/__manifest__.py | 2 +- fs_image/readme/HISTORY.rst | 15 ++++++++ fs_image/readme/newsfragments/307.bugfix | 10 ------ fs_image/static/description/index.html | 45 ++++++++++++++++++------ 5 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 fs_image/readme/HISTORY.rst delete mode 100644 fs_image/readme/newsfragments/307.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index 0eb150a614..525f007350 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8743df12cbf6e8e739aa2d6241767c1f54c7ab74c7956fb93523758dbaa19a66 + !! source digest: sha256:8eb8ee4966145a3d8461a1c8a25b79ea08a357c40a16ad606ea61ac6de31e6a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -171,6 +171,25 @@ too much bandwidth. +Changelog +========= + +16.0.1.0.1 (2023-12-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Avoid to generate an SQL update query when an image field is read. + + Fix a bug in the initialization of the image field value object when the field + is read. Before this fix, every time the value object was initialized with + an attachment, an assignment of the alt text was done into the constructor. + This assignment triggered the mark of the field as modified and an SQL update + query was generated at the end of the request. The alt text in the constructor + of the FSImageValue class must only be used when the class is initialized without + an attachment. We now check if an attachment and an alt text are provided at + the same time and throw an exception if this is the case. (`#307 `_) + Bug Tracker =========== diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index c415948adf..7bc4312346 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image/readme/HISTORY.rst b/fs_image/readme/HISTORY.rst new file mode 100644 index 0000000000..a9286177ad --- /dev/null +++ b/fs_image/readme/HISTORY.rst @@ -0,0 +1,15 @@ +16.0.1.0.1 (2023-12-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Avoid to generate an SQL update query when an image field is read. + + Fix a bug in the initialization of the image field value object when the field + is read. Before this fix, every time the value object was initialized with + an attachment, an assignment of the alt text was done into the constructor. + This assignment triggered the mark of the field as modified and an SQL update + query was generated at the end of the request. The alt text in the constructor + of the FSImageValue class must only be used when the class is initialized without + an attachment. We now check if an attachment and an alt text are provided at + the same time and throw an exception if this is the case. (`#307 `_) diff --git a/fs_image/readme/newsfragments/307.bugfix b/fs_image/readme/newsfragments/307.bugfix deleted file mode 100644 index 66ef8ccdfe..0000000000 --- a/fs_image/readme/newsfragments/307.bugfix +++ /dev/null @@ -1,10 +0,0 @@ -Avoid to generate an SQL update query when an image field is read. - -Fix a bug in the initialization of the image field value object when the field -is read. Before this fix, every time the value object was initialized with -an attachment, an assignment of the alt text was done into the constructor. -This assignment triggered the mark of the field as modified and an SQL update -query was generated at the end of the request. The alt text in the constructor -of the FSImageValue class must only be used when the class is initialized without -an attachment. We now check if an attachment and an alt text are provided at -the same time and throw an exception if this is the case. diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 7789318cb5..6550839892 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -367,7 +367,7 @@

Fs Image

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:8743df12cbf6e8e739aa2d6241767c1f54c7ab74c7956fb93523758dbaa19a66 +!! source digest: sha256:8eb8ee4966145a3d8461a1c8a25b79ea08a357c40a16ad606ea61ac6de31e6a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon defines a new field FSImage to use in your models. It is a @@ -395,11 +395,15 @@

Fs Image

+
+

Changelog

+
+

16.0.1.0.1 (2023-12-02)

+

Bugfixes

+
    +
  • Avoid to generate an SQL update query when an image field is read.

    +

    Fix a bug in the initialization of the image field value object when the field +is read. Before this fix, every time the value object was initialized with +an attachment, an assignment of the alt text was done into the constructor. +This assignment triggered the mark of the field as modified and an SQL update +query was generated at the end of the request. The alt text in the constructor +of the FSImageValue class must only be used when the class is initialized without +an attachment. We now check if an attachment and an alt text are provided at +the same time and throw an exception if this is the case. (#307)

    +
  • +
+
+
-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -514,21 +537,21 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose From 4e3d8ca7869bb37c4f2b2cd1ad935a48e1415885 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Wed, 29 Nov 2023 15:12:27 +0100 Subject: [PATCH 11/32] [FIX] fs_image: remove rawCacheKey invalidation rawCacheKey is properly managed by STD --- fs_image/README.rst | 2 +- fs_image/readme/newsfragments/305.bugfix | 6 ++++++ fs_image/static/description/index.html | 2 +- fs_image/static/src/views/fields/fsimage_field.esm.js | 5 ----- 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 fs_image/readme/newsfragments/305.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index 525f007350..1b88840576 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8eb8ee4966145a3d8461a1c8a25b79ea08a357c40a16ad606ea61ac6de31e6a8 + !! source digest: sha256:ec5ca93b7010a87e11c66139815adfbcd5da6df9f8508d27c7da172a5513a424 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image/readme/newsfragments/305.bugfix b/fs_image/readme/newsfragments/305.bugfix new file mode 100644 index 0000000000..85eff0f21a --- /dev/null +++ b/fs_image/readme/newsfragments/305.bugfix @@ -0,0 +1,6 @@ +Fix view crash when uploading an image + +The rawCacheKey is appropriately managed by the base class and reflects the +record's last update datetime (write_date). +Since it lacks a setter, attempting to invalidate its value results in a view crash. +Nevertheless, the value will automatically be updated upon saving the record. diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 6550839892..9d2d51255d 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -367,7 +367,7 @@

Fs Image

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:8eb8ee4966145a3d8461a1c8a25b79ea08a357c40a16ad606ea61ac6de31e6a8 +!! source digest: sha256:ec5ca93b7010a87e11c66139815adfbcd5da6df9f8508d27c7da172a5513a424 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon defines a new field FSImage to use in your models. It is a diff --git a/fs_image/static/src/views/fields/fsimage_field.esm.js b/fs_image/static/src/views/fields/fsimage_field.esm.js index adc4ffc618..fe286764f5 100644 --- a/fs_image/static/src/views/fields/fsimage_field.esm.js +++ b/fs_image/static/src/views/fields/fsimage_field.esm.js @@ -50,9 +50,6 @@ export class FSImageField extends ImageField { fileTypeMagicWordMap[this.props.value.content[0]] || "png"; return `data:image/${magic};base64,${this.props.value.content}`; } - if (!this.rawCacheKey) { - this.rawCacheKey = this.props.record.data.__last_update; - } const model = this.props.record.resModel; const id = this.props.record.resId; let base_url = this.props.value.url; @@ -72,8 +69,6 @@ export class FSImageField extends ImageField { onFileUploaded(info) { this.state.isValid = true; - // Invalidate the `rawCacheKey`. - this.rawCacheKey = null; this.props.update({ filename: info.name, content: info.data, From 7fe0200df9096909074a545c1a8da661786fdf3e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sat, 2 Dec 2023 09:12:57 +0000 Subject: [PATCH 12/32] [BOT] post-merge updates --- fs_image/README.rst | 15 ++++++++- fs_image/__manifest__.py | 2 +- fs_image/readme/HISTORY.rst | 13 ++++++++ fs_image/readme/newsfragments/305.bugfix | 6 ---- fs_image/static/description/index.html | 39 ++++++++++++++++-------- 5 files changed, 54 insertions(+), 21 deletions(-) delete mode 100644 fs_image/readme/newsfragments/305.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index 1b88840576..37a88a8f0f 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ec5ca93b7010a87e11c66139815adfbcd5da6df9f8508d27c7da172a5513a424 + !! source digest: sha256:12aa6d80ddfd410f208443e5310a2f25fff947aa627b08d582649dd2187fa471 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -174,6 +174,19 @@ too much bandwidth. Changelog ========= +16.0.1.0.2 (2023-12-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix view crash when uploading an image + + The rawCacheKey is appropriately managed by the base class and reflects the + record's last update datetime (write_date). + Since it lacks a setter, attempting to invalidate its value results in a view crash. + Nevertheless, the value will automatically be updated upon saving the record. (`#305 `_) + + 16.0.1.0.1 (2023-12-02) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index 7bc4312346..d7bb31d3db 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "16.0.1.0.1", + "version": "16.0.1.0.2", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image/readme/HISTORY.rst b/fs_image/readme/HISTORY.rst index a9286177ad..45df0dd013 100644 --- a/fs_image/readme/HISTORY.rst +++ b/fs_image/readme/HISTORY.rst @@ -1,3 +1,16 @@ +16.0.1.0.2 (2023-12-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix view crash when uploading an image + + The rawCacheKey is appropriately managed by the base class and reflects the + record's last update datetime (write_date). + Since it lacks a setter, attempting to invalidate its value results in a view crash. + Nevertheless, the value will automatically be updated upon saving the record. (`#305 `_) + + 16.0.1.0.1 (2023-12-02) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/fs_image/readme/newsfragments/305.bugfix b/fs_image/readme/newsfragments/305.bugfix deleted file mode 100644 index 85eff0f21a..0000000000 --- a/fs_image/readme/newsfragments/305.bugfix +++ /dev/null @@ -1,6 +0,0 @@ -Fix view crash when uploading an image - -The rawCacheKey is appropriately managed by the base class and reflects the -record's last update datetime (write_date). -Since it lacks a setter, attempting to invalidate its value results in a view crash. -Nevertheless, the value will automatically be updated upon saving the record. diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 9d2d51255d..3d38bf187a 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -367,7 +367,7 @@

Fs Image

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ec5ca93b7010a87e11c66139815adfbcd5da6df9f8508d27c7da172a5513a424 +!! source digest: sha256:12aa6d80ddfd410f208443e5310a2f25fff947aa627b08d582649dd2187fa471 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon defines a new field FSImage to use in your models. It is a @@ -396,14 +396,15 @@

Fs Image

  • Usage
  • Changelog
  • -
  • Bug Tracker
  • -
  • Credits @@ -512,7 +513,19 @@

    Usage

    Changelog

    -

    16.0.1.0.1 (2023-12-02)

    +

    16.0.1.0.2 (2023-12-02)

    +

    Bugfixes

    +
      +
    • Fix view crash when uploading an image

      +

      The rawCacheKey is appropriately managed by the base class and reflects the +record’s last update datetime (write_date). +Since it lacks a setter, attempting to invalidate its value results in a view crash. +Nevertheless, the value will automatically be updated upon saving the record. (#305)

      +
    • +
    +
    +
    +

    16.0.1.0.1 (2023-12-02)

    Bugfixes

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -537,21 +550,21 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose From d7eb7cf6fc649acdd0ffbe6629f1ba7dfeb518d8 Mon Sep 17 00:00:00 2001 From: "Benjamin Willig (ACSONE)" Date: Thu, 15 Feb 2024 15:33:00 +0000 Subject: [PATCH 13/32] Added translation using Weblate (French) --- fs_image/i18n/fr.po | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 fs_image/i18n/fr.po diff --git a/fs_image/i18n/fr.po b/fs_image/i18n/fr.po new file mode 100644 index 0000000000..279d6852cc --- /dev/null +++ b/fs_image/i18n/fr.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#, python-format +msgid "Alt Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +msgid "Alternative Text" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +msgid "Alternative text for the image. Only used for images on a website." +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Binary file" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: fs_image +#. odoo-python +#: code:addons/fs_image/fields.py:0 +#, python-format +msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Clear" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Edit" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image +msgid "Image" +msgstr "" + +#. module: fs_image +#: model:ir.model,name:fs_image.model_fs_image_mixin +msgid "Image Mixin" +msgstr "" + +#. module: fs_image +#: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium +msgid "Image medium" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 +#, python-format +msgid "Save changes" +msgstr "" + +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Set Alt Text" +msgstr "" From 671ac7a221b346d8758f790ea7232e0aa7988d96 Mon Sep 17 00:00:00 2001 From: "Benjamin Willig (ACSONE)" Date: Thu, 15 Feb 2024 15:33:27 +0000 Subject: [PATCH 14/32] Translated using Weblate (French) Currently translated at 78.5% (11 of 14 strings) Translation: storage-16.0/storage-16.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image/fr/ --- fs_image/i18n/fr.po | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/fs_image/i18n/fr.po b/fs_image/i18n/fr.po index 279d6852cc..7c9463c7ba 100644 --- a/fs_image/i18n/fr.po +++ b/fs_image/i18n/fr.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2024-02-15 17:37+0000\n" +"Last-Translator: \"Benjamin Willig (ACSONE)\" \n" "Language-Team: none\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" #. module: fs_image #. odoo-javascript @@ -24,31 +26,33 @@ msgstr "" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text msgid "Alternative Text" -msgstr "" +msgstr "Texte alternatif" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" +"Texte alternatif pour une image. Utilisé seulement pour les images sur un " +"site web." #. module: fs_image #: model:ir.model,name:fs_image.model_ir_attachment msgid "Attachment" -msgstr "" +msgstr "Pièce jointe" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Binary file" -msgstr "" +msgstr "Fichier binaire" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Cancel" -msgstr "" +msgstr "Annuler" #. module: fs_image #. odoo-python @@ -56,25 +60,27 @@ msgstr "" #, python-format msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" msgstr "" +"Impossible d'appliquer un texte alternatif sur une image vide (" +"enregistrement %(record)s.%(field_name)s)" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Clear" -msgstr "" +msgstr "Effacer" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Edit" -msgstr "" +msgstr "Modifier" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image msgid "Image" -msgstr "" +msgstr "Image" #. module: fs_image #: model:ir.model,name:fs_image.model_fs_image_mixin @@ -84,14 +90,14 @@ msgstr "" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_fs_image_mixin__image_medium msgid "Image medium" -msgstr "" +msgstr "Image moyenne" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/dialogs/alttext_dialog.xml:0 #, python-format msgid "Save changes" -msgstr "" +msgstr "Sauvegarder les changements" #. module: fs_image #. odoo-javascript From 46aeaf83c026a86b2094524acd54b409538be1fd Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 21 Feb 2024 12:54:13 +0100 Subject: [PATCH 15/32] [FIX] fs_file: Support for empty file Before this change the creation of empty file was not supported. The issue was mainly due to the fact that at create of a FSFileValue instance with a name but without content, the name was no preserved. As result, the insert of the attachement into the DB failed since the name is a required field. If a FSFileValue instance is now created without content but with a name, the name is now preserved on an empty buffer. --- fs_image/README.rst | 2 +- fs_image/readme/newsfragments/305.bugfix | 0 fs_image/static/description/index.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 fs_image/readme/newsfragments/305.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index 37a88a8f0f..68af2ad3fd 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:12aa6d80ddfd410f208443e5310a2f25fff947aa627b08d582649dd2187fa471 + !! source digest: sha256:73f0f6a521e4fb7c934a122c5ed688cfe01b0113eb11d560b9440b1eb7b7b58c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image/readme/newsfragments/305.bugfix b/fs_image/readme/newsfragments/305.bugfix new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 3d38bf187a..b61c599956 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -367,7 +367,7 @@

    Fs Image

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:12aa6d80ddfd410f208443e5310a2f25fff947aa627b08d582649dd2187fa471 +!! source digest: sha256:73f0f6a521e4fb7c934a122c5ed688cfe01b0113eb11d560b9440b1eb7b7b58c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    This addon defines a new field FSImage to use in your models. It is a From 0e14f3f0a03b6ec2b175095b2d5a98caf82477e5 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 23 Feb 2024 07:54:15 +0000 Subject: [PATCH 16/32] [BOT] post-merge updates --- fs_image/README.rst | 10 +++++- fs_image/__manifest__.py | 2 +- fs_image/readme/HISTORY.rst | 8 +++++ fs_image/readme/newsfragments/305.bugfix | 0 fs_image/static/description/index.html | 41 ++++++++++++++---------- 5 files changed, 42 insertions(+), 19 deletions(-) delete mode 100644 fs_image/readme/newsfragments/305.bugfix diff --git a/fs_image/README.rst b/fs_image/README.rst index 68af2ad3fd..505bc5c4db 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:73f0f6a521e4fb7c934a122c5ed688cfe01b0113eb11d560b9440b1eb7b7b58c + !! source digest: sha256:1540b42d1613eaf43667fc3e275e1bde17a911ec129db3c15a9290dc127e3560 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -174,6 +174,14 @@ too much bandwidth. Changelog ========= +16.0.1.0.3 (2024-02-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- (`#305 `_) + + 16.0.1.0.2 (2023-12-02) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index d7bb31d3db..58e3b05d41 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "16.0.1.0.2", + "version": "16.0.1.0.3", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image/readme/HISTORY.rst b/fs_image/readme/HISTORY.rst index 45df0dd013..10acfdc14c 100644 --- a/fs_image/readme/HISTORY.rst +++ b/fs_image/readme/HISTORY.rst @@ -1,3 +1,11 @@ +16.0.1.0.3 (2024-02-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- (`#305 `_) + + 16.0.1.0.2 (2023-12-02) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/fs_image/readme/newsfragments/305.bugfix b/fs_image/readme/newsfragments/305.bugfix deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index b61c599956..56151287ca 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -1,4 +1,3 @@ - @@ -367,7 +366,7 @@

    Fs Image

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:73f0f6a521e4fb7c934a122c5ed688cfe01b0113eb11d560b9440b1eb7b7b58c +!! source digest: sha256:1540b42d1613eaf43667fc3e275e1bde17a911ec129db3c15a9290dc127e3560 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    This addon defines a new field FSImage to use in your models. It is a @@ -396,15 +395,16 @@

    Fs Image

    • Usage
    • Changelog
    • -
    • Bug Tracker
    • -
    • Credits @@ -513,7 +513,14 @@

      Usage

      Changelog

      +
      +

      16.0.1.0.2 (2023-12-02)

      Bugfixes

      -
      -

      16.0.1.0.1 (2023-12-02)

      +
      +

      16.0.1.0.1 (2023-12-02)

      Bugfixes

      -

      Bug Tracker

      +

      Bug Tracker

      Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -550,21 +557,21 @@

      Bug Tracker

      Do not contact contributors directly about support or help with technical issues.

      -

      Credits

      +

      Credits

      -

      Authors

      +

      Authors

      • ACSONE SA/NV
      -

      Maintainers

      +

      Maintainers

      This module is maintained by the OCA.

      Odoo Community Association

      OCA, or the Odoo Community Association, is a nonprofit organization whose From 8f6c8a021745a66991482346d94e47b0705e8959 Mon Sep 17 00:00:00 2001 From: chien Date: Fri, 23 Feb 2024 16:57:30 +0700 Subject: [PATCH 17/32] [IMP] fs_image: pre-commit auto fixes --- fs_image/README.rst | 294 +++++++++++++------------ fs_image/models/ir_attachment.py | 1 - fs_image/pyproject.toml | 3 + fs_image/readme/CONTRIBUTORS.md | 1 + fs_image/readme/CONTRIBUTORS.rst | 1 - fs_image/readme/DESCRIPTION.md | 19 ++ fs_image/readme/DESCRIPTION.rst | 15 -- fs_image/readme/HISTORY.md | 35 +++ fs_image/readme/HISTORY.rst | 36 --- fs_image/readme/USAGE.md | 113 ++++++++++ fs_image/readme/USAGE.rst | 113 ---------- fs_image/static/description/index.html | 104 +++++---- fs_image/tests/models.py | 2 - 13 files changed, 380 insertions(+), 357 deletions(-) create mode 100644 fs_image/pyproject.toml create mode 100644 fs_image/readme/CONTRIBUTORS.md delete mode 100644 fs_image/readme/CONTRIBUTORS.rst create mode 100644 fs_image/readme/DESCRIPTION.md delete mode 100644 fs_image/readme/DESCRIPTION.rst create mode 100644 fs_image/readme/HISTORY.md delete mode 100644 fs_image/readme/HISTORY.rst create mode 100644 fs_image/readme/USAGE.md delete mode 100644 fs_image/readme/USAGE.rst diff --git a/fs_image/README.rst b/fs_image/README.rst index 505bc5c4db..5e63a11bc3 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -17,32 +17,36 @@ Fs Image :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github - :target: https://github.com/OCA/storage/tree/16.0/fs_image + :target: https://github.com/OCA/storage/tree/17.0/fs_image :alt: OCA/storage .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image + :target: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This addon defines a new field **FSImage** to use in your models. It is a -subclass of the **FSFile** field and comes with the same features. It extends -the **FSFile** field with specific properties dedicated to images. On the field -definition, the following additional properties are available: - -* **max_width** (int): maximum width of the image in pixels (default: ``0``, no limit) -* **max_height** (int): maximum height of the image in pixels (default: ``0``, no limit) -* **verify_resolution** (bool):whether the image resolution should be verified - to ensure it doesn't go over the maximum image resolution (default: ``True``). - See `odoo.tools.image.ImageProcess` for maximum image resolution (default: ``50e6``). +This addon defines a new field **FSImage** to use in your models. It is +a subclass of the **FSFile** field and comes with the same features. It +extends the **FSFile** field with specific properties dedicated to +images. On the field definition, the following additional properties are +available: + +- **max_width** (int): maximum width of the image in pixels (default: + ``0``, no limit) +- **max_height** (int): maximum height of the image in pixels (default: + ``0``, no limit) +- **verify_resolution** (bool):whether the image resolution should be + verified to ensure it doesn't go over the maximum image resolution + (default: ``True``). See odoo.tools.image.ImageProcess for maximum + image resolution (default: ``50e6``). On the field's value side, the value is an instance of a subclass of -`odoo.addons.fs_file.fields.FSFileValue`. It extends the class to allows -you to manage an alt_text for the image. The alt_text is a text that will be -displayed when the image cannot be displayed. +odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that +will be displayed when the image cannot be displayed. .. IMPORTANT:: This is an alpha version, the data model and design can change at any time without warning. @@ -57,159 +61,161 @@ displayed when the image cannot be displayed. Usage ===== -This new field type can be used in the same way as the odoo 'Image' field type. - -.. code-block:: python - - from odoo import models - from odoo.addons.fs_image.fields import FSImage +This new field type can be used in the same way as the odoo 'Image' +field type. - class MyModel(models.Model): - _name = 'my.model' +.. code:: python - image = FSImage('Image', max_width=1920, max_height=1920) + from odoo import models + from odoo.addons.fs_image.fields import FSImage + class MyModel(models.Model): + _name = 'my.model' -.. code-block:: xml + image = FSImage('Image', max_width=1920, max_height=1920) - - my.model.form - my.model - -

      - - - - - -
      - - +.. code:: xml + + my.model.form + my.model + +
      + + + + + +
      +
      +
      -In the example above, the image will be resized to 1920x1920px if it is larger than that. -The widget used in the form view will also allow the user set an 'alt' text for the image. - +In the example above, the image will be resized to 1920x1920px if it is +larger than that. The widget used in the form view will also allow the +user set an 'alt' text for the image. A mode advanced and useful example is the following: -.. code-block:: python - - from odoo import models - from odoo.addons.fs_image.fields import FSImage - - class MyModel(models.Model): - _name = 'my.model' - - image_1920 = FSImage('Image', max_width=1920, max_height=1920) - image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True) - - -.. code-block:: xml - - - my.model.form - my.model - -
      - - - + my.model.form + my.model + + + + + + + + + +
      + +In the example above we have two fields, one for the original image and +one for a thumbnail. As the thumbnail is defined as a related stored +field it's automatically generated from the original image, resized at +the given size and stored in the database. The thumbnail is then used as +a preview image for the original image in the form view. The main +advantage of this approach is that the original image is not loaded in +the form view and the thumbnail is used instead, which is much smaller +in size and faster to load. The 'zoom' option allows the user to see the +original image in a popup when clicking on the thumbnail. + +For convenience, the 'fs_image' module also provides a 'FSImageMixin' +mixin class that can be used to add the 'image' and 'image_medium' +fields to a model. It only define the medium thumbnail as a 128x128px +image since it's the most common use case. When using an image field in +a model, it's recommended to use this mixin class in order ensure that +the 'image_medium' field is always defined. A good practice is to use +the image_medium field as a preview image for the image field in the +form view to avoid to overload the form view with a large image and +consume too much bandwidth. + +.. code:: python + + from odoo import models + + class MyModel(models.Model): + _name = 'my.model' + _inherit = ['fs_image.mixin'] + +.. code:: xml + + + my.model.form + my.model + +
      + + + - - -
      -
      -
      - -In the example above we have two fields, one for the original image and one for a thumbnail. -As the thumbnail is defined as a related stored field it's automatically generated -from the original image, resized at the given size and stored in the database. -The thumbnail is then used as a preview image for the original image in the form view. -The main advantage of this approach is that the original image is not loaded in the form view -and the thumbnail is used instead, which is much smaller in size and faster to load. -The 'zoom' option allows the user to see the original image in a popup when clicking on the thumbnail. - -For convenience, the 'fs_image' module also provides a 'FSImageMixin' mixin class -that can be used to add the 'image' and 'image_medium' fields to a model. It only -define the medium thumbnail as a 128x128px image since it's the most common use case. -When using an image field in a model, it's recommended to use this mixin class -in order ensure that the 'image_medium' field is always defined. A good practice -is to use the `image_medium` field as a preview image for the `image` field in -the form view to avoid to overload the form view with a large image and consume -too much bandwidth. - -.. code-block:: python - - from odoo import models - - class MyModel(models.Model): - _name = 'my.model' - _inherit = ['fs_image.mixin'] - - -.. code-block:: xml - - - my.model.form - my.model - -
      - - - - - -
      -
      -
      + + + + + Changelog ========= 16.0.1.0.3 (2024-02-23) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- **Bugfixes** -- (`#305 `_) - +- (`#305 `__) 16.0.1.0.2 (2023-12-02) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- **Bugfixes** -- Fix view crash when uploading an image - - The rawCacheKey is appropriately managed by the base class and reflects the - record's last update datetime (write_date). - Since it lacks a setter, attempting to invalidate its value results in a view crash. - Nevertheless, the value will automatically be updated upon saving the record. (`#305 `_) +- Fix view crash when uploading an image + The rawCacheKey is appropriately managed by the base class and + reflects the record's last update datetime (write_date). Since it + lacks a setter, attempting to invalidate its value results in a view + crash. Nevertheless, the value will automatically be updated upon + saving the record. + (`#305 `__) 16.0.1.0.1 (2023-12-02) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- **Bugfixes** -- Avoid to generate an SQL update query when an image field is read. +- Avoid to generate an SQL update query when an image field is read. - Fix a bug in the initialization of the image field value object when the field - is read. Before this fix, every time the value object was initialized with - an attachment, an assignment of the alt text was done into the constructor. - This assignment triggered the mark of the field as modified and an SQL update - query was generated at the end of the request. The alt text in the constructor - of the FSImageValue class must only be used when the class is initialized without - an attachment. We now check if an attachment and an alt text are provided at - the same time and throw an exception if this is the case. (`#307 `_) + Fix a bug in the initialization of the image field value object when + the field is read. Before this fix, every time the value object was + initialized with an attachment, an assignment of the alt text was + done into the constructor. This assignment triggered the mark of the + field as modified and an SQL update query was generated at the end of + the request. The alt text in the constructor of the FSImageValue + class must only be used when the class is initialized without an + attachment. We now check if an attachment and an alt text are + provided at the same time and throw an exception if this is the case. + (`#307 `__) Bug Tracker =========== @@ -217,7 +223,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -225,17 +231,17 @@ Credits ======= Authors -~~~~~~~ +------- * ACSONE SA/NV Contributors -~~~~~~~~~~~~ +------------ -* Laurent Mignon +- Laurent Mignon Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -255,6 +261,6 @@ Current `maintainer `__: |maintainer-lmignon| -This module is part of the `OCA/storage `_ project on GitHub. +This module is part of the `OCA/storage `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_image/models/ir_attachment.py b/fs_image/models/ir_attachment.py index 2856e98c34..0ce5afea7f 100644 --- a/fs_image/models/ir_attachment.py +++ b/fs_image/models/ir_attachment.py @@ -5,7 +5,6 @@ class IrAttachment(models.Model): - _inherit = "ir.attachment" alt_text = fields.Char( diff --git a/fs_image/pyproject.toml b/fs_image/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_image/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_image/readme/CONTRIBUTORS.md b/fs_image/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..f2af9193ce --- /dev/null +++ b/fs_image/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Laurent Mignon \<\> diff --git a/fs_image/readme/CONTRIBUTORS.rst b/fs_image/readme/CONTRIBUTORS.rst deleted file mode 100644 index 172b2d223c..0000000000 --- a/fs_image/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1 +0,0 @@ -* Laurent Mignon diff --git a/fs_image/readme/DESCRIPTION.md b/fs_image/readme/DESCRIPTION.md new file mode 100644 index 0000000000..8214c3fa44 --- /dev/null +++ b/fs_image/readme/DESCRIPTION.md @@ -0,0 +1,19 @@ +This addon defines a new field **FSImage** to use in your models. It is +a subclass of the **FSFile** field and comes with the same features. It +extends the **FSFile** field with specific properties dedicated to +images. On the field definition, the following additional properties are +available: + +- **max_width** (int): maximum width of the image in pixels (default: + `0`, no limit) +- **max_height** (int): maximum height of the image in pixels (default: + `0`, no limit) +- **verify_resolution** (bool):whether the image resolution should be + verified to ensure it doesn't go over the maximum image resolution + (default: `True`). See odoo.tools.image.ImageProcess for maximum image + resolution (default: `50e6`). + +On the field's value side, the value is an instance of a subclass of +odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that +will be displayed when the image cannot be displayed. diff --git a/fs_image/readme/DESCRIPTION.rst b/fs_image/readme/DESCRIPTION.rst deleted file mode 100644 index 9315e90ab2..0000000000 --- a/fs_image/readme/DESCRIPTION.rst +++ /dev/null @@ -1,15 +0,0 @@ -This addon defines a new field **FSImage** to use in your models. It is a -subclass of the **FSFile** field and comes with the same features. It extends -the **FSFile** field with specific properties dedicated to images. On the field -definition, the following additional properties are available: - -* **max_width** (int): maximum width of the image in pixels (default: ``0``, no limit) -* **max_height** (int): maximum height of the image in pixels (default: ``0``, no limit) -* **verify_resolution** (bool):whether the image resolution should be verified - to ensure it doesn't go over the maximum image resolution (default: ``True``). - See `odoo.tools.image.ImageProcess` for maximum image resolution (default: ``50e6``). - -On the field's value side, the value is an instance of a subclass of -`odoo.addons.fs_file.fields.FSFileValue`. It extends the class to allows -you to manage an alt_text for the image. The alt_text is a text that will be -displayed when the image cannot be displayed. diff --git a/fs_image/readme/HISTORY.md b/fs_image/readme/HISTORY.md new file mode 100644 index 0000000000..784ed81ecf --- /dev/null +++ b/fs_image/readme/HISTORY.md @@ -0,0 +1,35 @@ +## 16.0.1.0.3 (2024-02-23) + +**Bugfixes** + +- ([\#305](https://github.com/OCA/storage/issues/305)) + +## 16.0.1.0.2 (2023-12-02) + +**Bugfixes** + +- Fix view crash when uploading an image + + The rawCacheKey is appropriately managed by the base class and + reflects the record's last update datetime (write_date). Since it + lacks a setter, attempting to invalidate its value results in a view + crash. Nevertheless, the value will automatically be updated upon + saving the record. + ([\#305](https://github.com/OCA/storage/issues/305)) + +## 16.0.1.0.1 (2023-12-02) + +**Bugfixes** + +- Avoid to generate an SQL update query when an image field is read. + + Fix a bug in the initialization of the image field value object when + the field is read. Before this fix, every time the value object was + initialized with an attachment, an assignment of the alt text was done + into the constructor. This assignment triggered the mark of the field + as modified and an SQL update query was generated at the end of the + request. The alt text in the constructor of the FSImageValue class + must only be used when the class is initialized without an attachment. + We now check if an attachment and an alt text are provided at the same + time and throw an exception if this is the case. + ([\#307](https://github.com/OCA/storage/issues/307)) diff --git a/fs_image/readme/HISTORY.rst b/fs_image/readme/HISTORY.rst deleted file mode 100644 index 10acfdc14c..0000000000 --- a/fs_image/readme/HISTORY.rst +++ /dev/null @@ -1,36 +0,0 @@ -16.0.1.0.3 (2024-02-23) -~~~~~~~~~~~~~~~~~~~~~~~ - -**Bugfixes** - -- (`#305 `_) - - -16.0.1.0.2 (2023-12-02) -~~~~~~~~~~~~~~~~~~~~~~~ - -**Bugfixes** - -- Fix view crash when uploading an image - - The rawCacheKey is appropriately managed by the base class and reflects the - record's last update datetime (write_date). - Since it lacks a setter, attempting to invalidate its value results in a view crash. - Nevertheless, the value will automatically be updated upon saving the record. (`#305 `_) - - -16.0.1.0.1 (2023-12-02) -~~~~~~~~~~~~~~~~~~~~~~~ - -**Bugfixes** - -- Avoid to generate an SQL update query when an image field is read. - - Fix a bug in the initialization of the image field value object when the field - is read. Before this fix, every time the value object was initialized with - an attachment, an assignment of the alt text was done into the constructor. - This assignment triggered the mark of the field as modified and an SQL update - query was generated at the end of the request. The alt text in the constructor - of the FSImageValue class must only be used when the class is initialized without - an attachment. We now check if an attachment and an alt text are provided at - the same time and throw an exception if this is the case. (`#307 `_) diff --git a/fs_image/readme/USAGE.md b/fs_image/readme/USAGE.md new file mode 100644 index 0000000000..abfd872a43 --- /dev/null +++ b/fs_image/readme/USAGE.md @@ -0,0 +1,113 @@ +This new field type can be used in the same way as the odoo 'Image' +field type. + +``` python +from odoo import models +from odoo.addons.fs_image.fields import FSImage + +class MyModel(models.Model): + _name = 'my.model' + + image = FSImage('Image', max_width=1920, max_height=1920) +``` + +``` xml + + my.model.form + my.model + +
      + + + + + +
      +
      +
      +``` + +In the example above, the image will be resized to 1920x1920px if it is +larger than that. The widget used in the form view will also allow the +user set an 'alt' text for the image. + +A mode advanced and useful example is the following: + +``` python +from odoo import models +from odoo.addons.fs_image.fields import FSImage + +class MyModel(models.Model): + _name = 'my.model' + + image_1920 = FSImage('Image', max_width=1920, max_height=1920) + image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True) +``` + +``` xml + + my.model.form + my.model + +
      + + + + + +
      +
      +
      +``` + +In the example above we have two fields, one for the original image and +one for a thumbnail. As the thumbnail is defined as a related stored +field it's automatically generated from the original image, resized at +the given size and stored in the database. The thumbnail is then used as +a preview image for the original image in the form view. The main +advantage of this approach is that the original image is not loaded in +the form view and the thumbnail is used instead, which is much smaller +in size and faster to load. The 'zoom' option allows the user to see the +original image in a popup when clicking on the thumbnail. + +For convenience, the 'fs_image' module also provides a 'FSImageMixin' +mixin class that can be used to add the 'image' and 'image_medium' +fields to a model. It only define the medium thumbnail as a 128x128px +image since it's the most common use case. When using an image field in +a model, it's recommended to use this mixin class in order ensure that +the 'image_medium' field is always defined. A good practice is to use +the image_medium field as a preview image for the image field in the +form view to avoid to overload the form view with a large image and +consume too much bandwidth. + +``` python +from odoo import models + +class MyModel(models.Model): + _name = 'my.model' + _inherit = ['fs_image.mixin'] +``` + +``` xml + + my.model.form + my.model + +
      + + + + + +
      +
      +
      +``` diff --git a/fs_image/readme/USAGE.rst b/fs_image/readme/USAGE.rst deleted file mode 100644 index 1db6920db7..0000000000 --- a/fs_image/readme/USAGE.rst +++ /dev/null @@ -1,113 +0,0 @@ -This new field type can be used in the same way as the odoo 'Image' field type. - -.. code-block:: python - - from odoo import models - from odoo.addons.fs_image.fields import FSImage - - class MyModel(models.Model): - _name = 'my.model' - - image = FSImage('Image', max_width=1920, max_height=1920) - - -.. code-block:: xml - - - my.model.form - my.model - -
      - - - - - -
      -
      -
      - - -In the example above, the image will be resized to 1920x1920px if it is larger than that. -The widget used in the form view will also allow the user set an 'alt' text for the image. - - -A mode advanced and useful example is the following: - -.. code-block:: python - - from odoo import models - from odoo.addons.fs_image.fields import FSImage - - class MyModel(models.Model): - _name = 'my.model' - - image_1920 = FSImage('Image', max_width=1920, max_height=1920) - image_128 = FSImage('Image', max_width=128, max_height=128, related='image_1920', store=True) - - -.. code-block:: xml - - - my.model.form - my.model - -
      - - - - - -
      -
      -
      - -In the example above we have two fields, one for the original image and one for a thumbnail. -As the thumbnail is defined as a related stored field it's automatically generated -from the original image, resized at the given size and stored in the database. -The thumbnail is then used as a preview image for the original image in the form view. -The main advantage of this approach is that the original image is not loaded in the form view -and the thumbnail is used instead, which is much smaller in size and faster to load. -The 'zoom' option allows the user to see the original image in a popup when clicking on the thumbnail. - -For convenience, the 'fs_image' module also provides a 'FSImageMixin' mixin class -that can be used to add the 'image' and 'image_medium' fields to a model. It only -define the medium thumbnail as a 128x128px image since it's the most common use case. -When using an image field in a model, it's recommended to use this mixin class -in order ensure that the 'image_medium' field is always defined. A good practice -is to use the `image_medium` field as a preview image for the `image` field in -the form view to avoid to overload the form view with a large image and consume -too much bandwidth. - -.. code-block:: python - - from odoo import models - - class MyModel(models.Model): - _name = 'my.model' - _inherit = ['fs_image.mixin'] - - -.. code-block:: xml - - - my.model.form - my.model - -
      - - - - - -
      -
      -
      diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 56151287ca..ec1bb759fb 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -1,3 +1,4 @@ + @@ -368,22 +369,26 @@

      Fs Image

      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:1540b42d1613eaf43667fc3e275e1bde17a911ec129db3c15a9290dc127e3560 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

      Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

      -

      This addon defines a new field FSImage to use in your models. It is a -subclass of the FSFile field and comes with the same features. It extends -the FSFile field with specific properties dedicated to images. On the field -definition, the following additional properties are available:

      +

      Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

      +

      This addon defines a new field FSImage to use in your models. It is +a subclass of the FSFile field and comes with the same features. It +extends the FSFile field with specific properties dedicated to +images. On the field definition, the following additional properties are +available:

        -
      • max_width (int): maximum width of the image in pixels (default: 0, no limit)
      • -
      • max_height (int): maximum height of the image in pixels (default: 0, no limit)
      • -
      • verify_resolution (bool):whether the image resolution should be verified -to ensure it doesn’t go over the maximum image resolution (default: True). -See odoo.tools.image.ImageProcess for maximum image resolution (default: 50e6).
      • +
      • max_width (int): maximum width of the image in pixels (default: +0, no limit)
      • +
      • max_height (int): maximum height of the image in pixels (default: +0, no limit)
      • +
      • verify_resolution (bool):whether the image resolution should be +verified to ensure it doesn’t go over the maximum image resolution +(default: True). See odoo.tools.image.ImageProcess for maximum +image resolution (default: 50e6).

      On the field’s value side, the value is an instance of a subclass of -odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows -you to manage an alt_text for the image. The alt_text is a text that will be -displayed when the image cannot be displayed.

      +odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows +you to manage an alt_text for the image. The alt_text is a text that +will be displayed when the image cannot be displayed.

      Important

      This is an alpha version, the data model and design can change at any time without warning. @@ -411,7 +416,8 @@

      Fs Image

      Usage

      -

      This new field type can be used in the same way as the odoo ‘Image’ field type.

      +

      This new field type can be used in the same way as the odoo ‘Image’ +field type.

       from odoo import models
       from odoo.addons.fs_image.fields import FSImage
      @@ -436,8 +442,9 @@ 

      Usage

      </field> </record>
      -

      In the example above, the image will be resized to 1920x1920px if it is larger than that. -The widget used in the form view will also allow the user set an ‘alt’ text for the image.

      +

      In the example above, the image will be resized to 1920x1920px if it is +larger than that. The widget used in the form view will also allow the +user set an ‘alt’ text for the image.

      A mode advanced and useful example is the following:

       from odoo import models
      @@ -468,21 +475,24 @@ 

      Usage

      </field> </record>
      -

      In the example above we have two fields, one for the original image and one for a thumbnail. -As the thumbnail is defined as a related stored field it’s automatically generated -from the original image, resized at the given size and stored in the database. -The thumbnail is then used as a preview image for the original image in the form view. -The main advantage of this approach is that the original image is not loaded in the form view -and the thumbnail is used instead, which is much smaller in size and faster to load. -The ‘zoom’ option allows the user to see the original image in a popup when clicking on the thumbnail.

      -

      For convenience, the ‘fs_image’ module also provides a ‘FSImageMixin’ mixin class -that can be used to add the ‘image’ and ‘image_medium’ fields to a model. It only -define the medium thumbnail as a 128x128px image since it’s the most common use case. -When using an image field in a model, it’s recommended to use this mixin class -in order ensure that the ‘image_medium’ field is always defined. A good practice -is to use the image_medium field as a preview image for the image field in -the form view to avoid to overload the form view with a large image and consume -too much bandwidth.

      +

      In the example above we have two fields, one for the original image and +one for a thumbnail. As the thumbnail is defined as a related stored +field it’s automatically generated from the original image, resized at +the given size and stored in the database. The thumbnail is then used as +a preview image for the original image in the form view. The main +advantage of this approach is that the original image is not loaded in +the form view and the thumbnail is used instead, which is much smaller +in size and faster to load. The ‘zoom’ option allows the user to see the +original image in a popup when clicking on the thumbnail.

      +

      For convenience, the ‘fs_image’ module also provides a ‘FSImageMixin’ +mixin class that can be used to add the ‘image’ and ‘image_medium’ +fields to a model. It only define the medium thumbnail as a 128x128px +image since it’s the most common use case. When using an image field in +a model, it’s recommended to use this mixin class in order ensure that +the ‘image_medium’ field is always defined. A good practice is to use +the image_medium field as a preview image for the image field in the +form view to avoid to overload the form view with a large image and +consume too much bandwidth.

       from odoo import models
       
      @@ -524,10 +534,12 @@ 

      16.0.1.0.2 (2023-12-02)

      Bugfixes

      • Fix view crash when uploading an image

        -

        The rawCacheKey is appropriately managed by the base class and reflects the -record’s last update datetime (write_date). -Since it lacks a setter, attempting to invalidate its value results in a view crash. -Nevertheless, the value will automatically be updated upon saving the record. (#305)

        +

        The rawCacheKey is appropriately managed by the base class and +reflects the record’s last update datetime (write_date). Since it +lacks a setter, attempting to invalidate its value results in a view +crash. Nevertheless, the value will automatically be updated upon +saving the record. +(#305)

      @@ -536,14 +548,16 @@

      16.0.1.0.1 (2023-12-02)

      Bugfixes

      • Avoid to generate an SQL update query when an image field is read.

        -

        Fix a bug in the initialization of the image field value object when the field -is read. Before this fix, every time the value object was initialized with -an attachment, an assignment of the alt text was done into the constructor. -This assignment triggered the mark of the field as modified and an SQL update -query was generated at the end of the request. The alt text in the constructor -of the FSImageValue class must only be used when the class is initialized without -an attachment. We now check if an attachment and an alt text are provided at -the same time and throw an exception if this is the case. (#307)

        +

        Fix a bug in the initialization of the image field value object when +the field is read. Before this fix, every time the value object was +initialized with an attachment, an assignment of the alt text was +done into the constructor. This assignment triggered the mark of the +field as modified and an SQL update query was generated at the end of +the request. The alt text in the constructor of the FSImageValue +class must only be used when the class is initialized without an +attachment. We now check if an attachment and an alt text are +provided at the same time and throw an exception if this is the case. +(#307)

      @@ -553,7 +567,7 @@

      Bug Tracker

      Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

      +feedback.

      Do not contact contributors directly about support or help with technical issues.

      @@ -579,7 +593,7 @@

      Maintainers

      promote its widespread use.

      Current maintainer:

      lmignon

      -

      This module is part of the OCA/storage project on GitHub.

      +

      This module is part of the OCA/storage project on GitHub.

      You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

      diff --git a/fs_image/tests/models.py b/fs_image/tests/models.py index c48020241a..7efda51d17 100644 --- a/fs_image/tests/models.py +++ b/fs_image/tests/models.py @@ -7,7 +7,6 @@ class TestImageModel(models.Model): - _name = "test.image.model" _description = "Test Model" _log_access = False @@ -17,7 +16,6 @@ class TestImageModel(models.Model): class TestRelatedImageModel(models.Model): - _name = "test.related.image.model" _description = "Test Related Image Model" _log_access = False From 14811a374c2ce7c1d77bb48e1dfad144f32ccc34 Mon Sep 17 00:00:00 2001 From: chien Date: Wed, 28 Feb 2024 10:04:27 +0700 Subject: [PATCH 18/32] [MIG] fs_image: Migration to 17.0 --- fs_image/README.rst | 1 + fs_image/__manifest__.py | 4 +- fs_image/fields.py | 4 +- fs_image/readme/CONTRIBUTORS.md | 1 + fs_image/static/description/index.html | 2 +- .../src/views/dialogs/alttext_dialog.xml | 4 +- .../src/views/fields/fsimage_field.esm.js | 75 +++++++++---------- .../static/src/views/fields/fsimage_field.xml | 14 ++-- 8 files changed, 52 insertions(+), 53 deletions(-) diff --git a/fs_image/README.rst b/fs_image/README.rst index 5e63a11bc3..8937e4e069 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -239,6 +239,7 @@ Contributors ------------ - Laurent Mignon +- Nguyen Minh Chien Maintainers ----------- diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index 58e3b05d41..31377443b7 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,11 +5,11 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "16.0.1.0.3", + "version": "17.0.1.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", - "depends": ["fs_file"], + "depends": ["fs_file", "web"], "data": [], "demo": [], "maintainers": ["lmignon"], diff --git a/fs_image/fields.py b/fs_image/fields.py index 9d50e2691a..fe1b813edd 100644 --- a/fs_image/fields.py +++ b/fs_image/fields.py @@ -202,7 +202,7 @@ def _set_image_process_mode(self): finally: self._image_process_mode = False - def _process_related(self, value: FSImageValue): + def _process_related(self, value: FSImageValue, env): """Override to resize the related value before saving it on self.""" if not value: return None @@ -210,7 +210,7 @@ def _process_related(self, value: FSImageValue): # no need to process images for computed fields, or related fields # without max_width/max_height return value - value = super()._process_related(value) + value = super()._process_related(value, env) new_value = BytesIO(self._image_process(value)) return FSImageValue(value=new_value, alt_text=value.alt_text, name=value.name) diff --git a/fs_image/readme/CONTRIBUTORS.md b/fs_image/readme/CONTRIBUTORS.md index f2af9193ce..da20decb6f 100644 --- a/fs_image/readme/CONTRIBUTORS.md +++ b/fs_image/readme/CONTRIBUTORS.md @@ -1 +1,2 @@ - Laurent Mignon \<\> +- Nguyen Minh Chien \<\> diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index ec1bb759fb..8c622717bf 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -1,4 +1,3 @@ - @@ -582,6 +581,7 @@

      Authors

      Contributors

    diff --git a/fs_image/static/src/views/dialogs/alttext_dialog.xml b/fs_image/static/src/views/dialogs/alttext_dialog.xml index afdd22c838..ecdc476de3 100644 --- a/fs_image/static/src/views/dialogs/alttext_dialog.xml +++ b/fs_image/static/src/views/dialogs/alttext_dialog.xml @@ -1,6 +1,6 @@ - +
    @@ -16,7 +16,7 @@ />
    - +
    Binary file From eed80506eae0134f4797627740ab46af91f37ab9 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 25 Apr 2024 12:33:20 +0000 Subject: [PATCH 19/32] [UPD] Update fs_image.pot --- fs_image/i18n/fs_image.pot | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs_image/i18n/fs_image.pot b/fs_image/i18n/fs_image.pot index d80a4e6137..5bd9584699 100644 --- a/fs_image/i18n/fs_image.pot +++ b/fs_image/i18n/fs_image.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -16,6 +16,7 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Alt Text" msgstr "" @@ -59,6 +60,7 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Clear" msgstr "" @@ -66,6 +68,7 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Edit" msgstr "" From 7233eee17eedfcba062b57e45cb64aa4325fd107 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 25 Apr 2024 12:35:25 +0000 Subject: [PATCH 20/32] [BOT] post-merge updates --- fs_image/README.rst | 2 +- fs_image/static/description/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs_image/README.rst b/fs_image/README.rst index 8937e4e069..5c76bd9df5 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:1540b42d1613eaf43667fc3e275e1bde17a911ec129db3c15a9290dc127e3560 + !! source digest: sha256:61bc0b86ef2cee84cec80cefb31ce770c9484fb883adc2e7ef7304f20c70dc3f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 8c622717bf..64940318a7 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -366,7 +366,7 @@

    Fs Image

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:1540b42d1613eaf43667fc3e275e1bde17a911ec129db3c15a9290dc127e3560 +!! source digest: sha256:61bc0b86ef2cee84cec80cefb31ce770c9484fb883adc2e7ef7304f20c70dc3f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    This addon defines a new field FSImage to use in your models. It is From 0a3ad3e9e8d6f42cb8ea996b41bb7b9f1f820373 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 2 May 2024 10:07:39 +0200 Subject: [PATCH 21/32] [FIX] pre-commit --- fs_image/fields.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs_image/fields.py b/fs_image/fields.py index fe1b813edd..1513f6aad4 100644 --- a/fs_image/fields.py +++ b/fs_image/fields.py @@ -219,7 +219,8 @@ def _update_alt_text(self, records, value: dict): if not record[self.name]: raise UserError( _( - "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)", + "Cannot set alt_text on empty image " + "(record %(record)s.%(field_name)s)", record=record, field_name=self.name, ) From af5ba32e9585c5aa4665a3bb2bd99977fb477194 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 2 May 2024 08:21:20 +0000 Subject: [PATCH 22/32] [BOT] post-merge updates --- fs_image/README.rst | 2 +- fs_image/__manifest__.py | 2 +- fs_image/static/description/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs_image/README.rst b/fs_image/README.rst index 5c76bd9df5..eafa817d47 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:61bc0b86ef2cee84cec80cefb31ce770c9484fb883adc2e7ef7304f20c70dc3f + !! source digest: sha256:321a582f0e0e62d4fc72c83ad9d603d7f9d1dedb0b29af0f28e76943ac60a23b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index 31377443b7..d40d29f381 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "17.0.1.0.0", + "version": "17.0.1.0.1", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 64940318a7..8b81a55cdc 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -366,7 +366,7 @@

    Fs Image

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:61bc0b86ef2cee84cec80cefb31ce770c9484fb883adc2e7ef7304f20c70dc3f +!! source digest: sha256:321a582f0e0e62d4fc72c83ad9d603d7f9d1dedb0b29af0f28e76943ac60a23b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    This addon defines a new field FSImage to use in your models. It is From 6af35cebd502889aba966398a1bcd05e6e9a6426 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 3 May 2024 07:55:43 +0000 Subject: [PATCH 23/32] [UPD] Update fs_image.pot --- fs_image/i18n/fs_image.pot | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs_image/i18n/fs_image.pot b/fs_image/i18n/fs_image.pot index 5bd9584699..895126b347 100644 --- a/fs_image/i18n/fs_image.pot +++ b/fs_image/i18n/fs_image.pot @@ -23,11 +23,13 @@ msgstr "" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,field_description:fs_image.field_product_document__alt_text msgid "Alternative Text" msgstr "" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,help:fs_image.field_product_document__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" From a093bcff711528315e6ad1511f2c30b89790b3c6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 3 May 2024 07:58:07 +0000 Subject: [PATCH 24/32] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: storage-17.0/storage-17.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image/ --- fs_image/i18n/es.po | 7 +++++-- fs_image/i18n/fr.po | 7 +++++-- fs_image/i18n/it.po | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/fs_image/i18n/es.po b/fs_image/i18n/es.po index 19d6335bdb..8c0e9fae62 100644 --- a/fs_image/i18n/es.po +++ b/fs_image/i18n/es.po @@ -19,17 +19,20 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Alt Text" msgstr "Texto Alt" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,field_description:fs_image.field_product_document__alt_text msgid "Alternative Text" msgstr "Texto Alternativo" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,help:fs_image.field_product_document__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" "Texto alternativo para la imagen. Solo se utiliza para imágenes de un sitio " @@ -60,8 +63,8 @@ msgstr "Cancelar" #, python-format msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" msgstr "" -"No se puede establecer alt_text en una imagen vacía (record " -"%(record)s.%(field_name)s)" +"No se puede establecer alt_text en una imagen vacía (record %(record)s." +"%(field_name)s)" #. module: fs_image #. odoo-javascript diff --git a/fs_image/i18n/fr.po b/fs_image/i18n/fr.po index 7c9463c7ba..a8fd8bc769 100644 --- a/fs_image/i18n/fr.po +++ b/fs_image/i18n/fr.po @@ -19,17 +19,20 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Alt Text" msgstr "" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,field_description:fs_image.field_product_document__alt_text msgid "Alternative Text" msgstr "Texte alternatif" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,help:fs_image.field_product_document__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" "Texte alternatif pour une image. Utilisé seulement pour les images sur un " @@ -60,8 +63,8 @@ msgstr "Annuler" #, python-format msgid "Cannot set alt_text on empty image (record %(record)s.%(field_name)s)" msgstr "" -"Impossible d'appliquer un texte alternatif sur une image vide (" -"enregistrement %(record)s.%(field_name)s)" +"Impossible d'appliquer un texte alternatif sur une image vide " +"(enregistrement %(record)s.%(field_name)s)" #. module: fs_image #. odoo-javascript diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po index 3094961f29..6a931686f1 100644 --- a/fs_image/i18n/it.po +++ b/fs_image/i18n/it.po @@ -19,17 +19,20 @@ msgstr "" #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.esm.js:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Alt Text" msgstr "Testo alternativo" #. module: fs_image #: model:ir.model.fields,field_description:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,field_description:fs_image.field_product_document__alt_text msgid "Alternative Text" msgstr "Testo alternativo" #. module: fs_image #: model:ir.model.fields,help:fs_image.field_ir_attachment__alt_text +#: model:ir.model.fields,help:fs_image.field_product_document__alt_text msgid "Alternative text for the image. Only used for images on a website." msgstr "" "Testo alternativo per l'immagine. Utilizzato solo per le immagini nel sito " From d1b94579c0ae90a2836ed90ce5d348c7dc294be3 Mon Sep 17 00:00:00 2001 From: "Laurent Mignonn (ACSONE)" Date: Wed, 13 Nov 2024 14:06:42 +0100 Subject: [PATCH 25/32] [IMP] fs_image: Add download button On image hover, a download button is now available to easily download the image --- fs_image/static/src/scss/fsimage_field.scss | 5 ++ .../src/views/fields/fsimage_field.esm.js | 22 +++++++++ .../static/src/views/fields/fsimage_field.xml | 46 +++++++++++-------- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/fs_image/static/src/scss/fsimage_field.scss b/fs_image/static/src/scss/fsimage_field.scss index e69de29bb2..053fd35479 100644 --- a/fs_image/static/src/scss/fsimage_field.scss +++ b/fs_image/static/src/scss/fsimage_field.scss @@ -0,0 +1,5 @@ +.fs_file_download_button { + top: 10% !important; + left: 50% !important; + position: absolute !important; +} diff --git a/fs_image/static/src/views/fields/fsimage_field.esm.js b/fs_image/static/src/views/fields/fsimage_field.esm.js index 053e6fe4a2..fe811f2eec 100644 --- a/fs_image/static/src/views/fields/fsimage_field.esm.js +++ b/fs_image/static/src/views/fields/fsimage_field.esm.js @@ -11,6 +11,7 @@ import { } from "@web/views/fields/image/image_field"; import {AltTextDialog} from "../dialogs/alttext_dialog.esm"; import {_t} from "@web/core/l10n/translation"; +import {download, downloadFile} from "@web/core/network/download"; import {registry} from "@web/core/registry"; import {useService} from "@web/core/utils/hooks"; import {url as utilUrl} from "@web/core/utils/urls"; @@ -80,6 +81,27 @@ export class FSImageField extends ImageField { }; this.dialogService.add(AltTextDialog, dialogProps); } + async onFileDownload() { + if (this.props.value.content) { + const magic = fileTypeMagicWordMap[this.props.value.content[0]] || "png"; + await downloadFile( + `data:image/${magic};base64,${this.props.value.content}`, + this.state.filename, + `image/${magic}` + ); + } else { + await download({ + data: { + model: this.props.record.resModel, + id: this.props.record.resId, + field: this.props.name, + filename: this.state.filename || "download", + download: true, + }, + url: "/web/image", + }); + } + } } FSImageField.template = "fs_image.FSImageField"; diff --git a/fs_image/static/src/views/fields/fsimage_field.xml b/fs_image/static/src/views/fields/fsimage_field.xml index 511bdd7cd9..743c03eed8 100644 --- a/fs_image/static/src/views/fields/fsimage_field.xml +++ b/fs_image/static/src/views/fields/fsimage_field.xml @@ -23,24 +23,24 @@ - - + + + +

@@ -59,6 +59,16 @@ t-att-data-tooltip-info="hasTooltip and tooltipAttributes.info" t-att-data-tooltip-delay="hasTooltip and props.zoomDelay" /> + +
From 798275416c08b9f7e800daa46843a117c27f2653 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 11 Feb 2025 09:20:28 +0000 Subject: [PATCH 26/32] [UPD] Update fs_image.pot --- fs_image/i18n/fs_image.pot | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs_image/i18n/fs_image.pot b/fs_image/i18n/fs_image.pot index 895126b347..e34bae0cdb 100644 --- a/fs_image/i18n/fs_image.pot +++ b/fs_image/i18n/fs_image.pot @@ -67,6 +67,14 @@ msgstr "" msgid "Clear" msgstr "" +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Download" +msgstr "" + #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 From ba686d0247cf9e805357ae2d5d5f6b03b5a90111 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 11 Feb 2025 09:23:11 +0000 Subject: [PATCH 27/32] [BOT] post-merge updates --- fs_image/README.rst | 60 +++++++++++++------------- fs_image/__manifest__.py | 2 +- fs_image/static/description/index.html | 27 ++++++------ 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/fs_image/README.rst b/fs_image/README.rst index eafa817d47..c4c43e7ac8 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -7,7 +7,7 @@ Fs Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:321a582f0e0e62d4fc72c83ad9d603d7f9d1dedb0b29af0f28e76943ac60a23b + !! source digest: sha256:83bf3d081cee121382989912937b99966b63f14d37195a0258d4221c3bb34ee3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -34,14 +34,14 @@ extends the **FSFile** field with specific properties dedicated to images. On the field definition, the following additional properties are available: -- **max_width** (int): maximum width of the image in pixels (default: - ``0``, no limit) -- **max_height** (int): maximum height of the image in pixels (default: - ``0``, no limit) -- **verify_resolution** (bool):whether the image resolution should be - verified to ensure it doesn't go over the maximum image resolution - (default: ``True``). See odoo.tools.image.ImageProcess for maximum - image resolution (default: ``50e6``). +- **max_width** (int): maximum width of the image in pixels (default: + ``0``, no limit) +- **max_height** (int): maximum height of the image in pixels (default: + ``0``, no limit) +- **verify_resolution** (bool):whether the image resolution should be + verified to ensure it doesn't go over the maximum image resolution + (default: ``True``). See odoo.tools.image.ImageProcess for maximum + image resolution (default: ``50e6``). On the field's value side, the value is an instance of a subclass of odoo.addons.fs_file.fields.FSFileValue. It extends the class to allows @@ -183,39 +183,39 @@ Changelog **Bugfixes** -- (`#305 `__) +- (`#305 `__) 16.0.1.0.2 (2023-12-02) ----------------------- **Bugfixes** -- Fix view crash when uploading an image +- Fix view crash when uploading an image - The rawCacheKey is appropriately managed by the base class and - reflects the record's last update datetime (write_date). Since it - lacks a setter, attempting to invalidate its value results in a view - crash. Nevertheless, the value will automatically be updated upon - saving the record. - (`#305 `__) + The rawCacheKey is appropriately managed by the base class and + reflects the record's last update datetime (write_date). Since it + lacks a setter, attempting to invalidate its value results in a view + crash. Nevertheless, the value will automatically be updated upon + saving the record. + (`#305 `__) 16.0.1.0.1 (2023-12-02) ----------------------- **Bugfixes** -- Avoid to generate an SQL update query when an image field is read. +- Avoid to generate an SQL update query when an image field is read. - Fix a bug in the initialization of the image field value object when - the field is read. Before this fix, every time the value object was - initialized with an attachment, an assignment of the alt text was - done into the constructor. This assignment triggered the mark of the - field as modified and an SQL update query was generated at the end of - the request. The alt text in the constructor of the FSImageValue - class must only be used when the class is initialized without an - attachment. We now check if an attachment and an alt text are - provided at the same time and throw an exception if this is the case. - (`#307 `__) + Fix a bug in the initialization of the image field value object when + the field is read. Before this fix, every time the value object was + initialized with an attachment, an assignment of the alt text was done + into the constructor. This assignment triggered the mark of the field + as modified and an SQL update query was generated at the end of the + request. The alt text in the constructor of the FSImageValue class + must only be used when the class is initialized without an attachment. + We now check if an attachment and an alt text are provided at the same + time and throw an exception if this is the case. + (`#307 `__) Bug Tracker =========== @@ -238,8 +238,8 @@ Authors Contributors ------------ -- Laurent Mignon -- Nguyen Minh Chien +- Laurent Mignon +- Nguyen Minh Chien Maintainers ----------- diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index d40d29f381..26d62bd28a 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "17.0.1.0.1", + "version": "17.0.1.0.2", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index 8b81a55cdc..a86294736c 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -274,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -300,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -366,7 +367,7 @@

Fs Image

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:321a582f0e0e62d4fc72c83ad9d603d7f9d1dedb0b29af0f28e76943ac60a23b +!! source digest: sha256:83bf3d081cee121382989912937b99966b63f14d37195a0258d4221c3bb34ee3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon defines a new field FSImage to use in your models. It is @@ -549,13 +550,13 @@

16.0.1.0.1 (2023-12-02)

  • Avoid to generate an SQL update query when an image field is read.

    Fix a bug in the initialization of the image field value object when the field is read. Before this fix, every time the value object was -initialized with an attachment, an assignment of the alt text was -done into the constructor. This assignment triggered the mark of the -field as modified and an SQL update query was generated at the end of -the request. The alt text in the constructor of the FSImageValue -class must only be used when the class is initialized without an -attachment. We now check if an attachment and an alt text are -provided at the same time and throw an exception if this is the case. +initialized with an attachment, an assignment of the alt text was done +into the constructor. This assignment triggered the mark of the field +as modified and an SQL update query was generated at the end of the +request. The alt text in the constructor of the FSImageValue class +must only be used when the class is initialized without an attachment. +We now check if an attachment and an alt text are provided at the same +time and throw an exception if this is the case. (#307)

  • @@ -587,7 +588,9 @@

    Contributors

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +Odoo Community Association +

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    From 054962be7884eeaac6dcbd1282e123c703c94e68 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 11 Feb 2025 09:23:20 +0000 Subject: [PATCH 28/32] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: storage-17.0/storage-17.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image/ --- fs_image/i18n/es.po | 7 +++++++ fs_image/i18n/fr.po | 7 +++++++ fs_image/i18n/it.po | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/fs_image/i18n/es.po b/fs_image/i18n/es.po index 8c0e9fae62..51fbe0162f 100644 --- a/fs_image/i18n/es.po +++ b/fs_image/i18n/es.po @@ -73,6 +73,13 @@ msgstr "" msgid "Clear" msgstr "Limpiar" +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Download" +msgstr "" + #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 diff --git a/fs_image/i18n/fr.po b/fs_image/i18n/fr.po index a8fd8bc769..8b29ab3e90 100644 --- a/fs_image/i18n/fr.po +++ b/fs_image/i18n/fr.po @@ -73,6 +73,13 @@ msgstr "" msgid "Clear" msgstr "Effacer" +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Download" +msgstr "" + #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po index 6a931686f1..f9792193bf 100644 --- a/fs_image/i18n/it.po +++ b/fs_image/i18n/it.po @@ -73,6 +73,13 @@ msgstr "" msgid "Clear" msgstr "Pulisci" +#. module: fs_image +#. odoo-javascript +#: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 +#, python-format +msgid "Download" +msgstr "" + #. module: fs_image #. odoo-javascript #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 From 4fae5d5c08261ee5205638d1ebf1e57e5325f521 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 12 Feb 2025 13:57:41 +0000 Subject: [PATCH 29/32] Translated using Weblate (Italian) Currently translated at 100.0% (15 of 15 strings) Translation: storage-17.0/storage-17.0-fs_image Translate-URL: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image/it/ --- fs_image/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs_image/i18n/it.po b/fs_image/i18n/it.po index f9792193bf..7ffaca24c4 100644 --- a/fs_image/i18n/it.po +++ b/fs_image/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-11-29 20:33+0000\n" +"PO-Revision-Date: 2025-02-12 16:06+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.6.2\n" #. module: fs_image #. odoo-javascript @@ -78,7 +78,7 @@ msgstr "Pulisci" #: code:addons/fs_image/static/src/views/fields/fsimage_field.xml:0 #, python-format msgid "Download" -msgstr "" +msgstr "Scarica" #. module: fs_image #. odoo-javascript From 0e6e63f6ac42aec47cede9503b161cbd042f8d9a Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 19 Feb 2025 16:50:22 +0100 Subject: [PATCH 30/32] [IMP] fs_image: pre-commit autofixes --- fs_image/static/src/views/fields/fsimage_field.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/fs_image/static/src/views/fields/fsimage_field.xml b/fs_image/static/src/views/fields/fsimage_field.xml index 743c03eed8..5edd3cd01c 100644 --- a/fs_image/static/src/views/fields/fsimage_field.xml +++ b/fs_image/static/src/views/fields/fsimage_field.xml @@ -68,7 +68,6 @@ > -
    From 47b05bb150b79efe7883708f6a01f90d1d355c41 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 19 Feb 2025 16:54:12 +0100 Subject: [PATCH 31/32] [MIG] fs_image: Migration to 18.0 --- fs_image/README.rst | 11 ++++++----- fs_image/__manifest__.py | 4 +--- fs_image/fields.py | 3 +-- fs_image/readme/CONTRIBUTORS.md | 1 + fs_image/static/description/index.html | 23 ++++++++++++----------- test-requirements.txt | 3 +++ 6 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 test-requirements.txt diff --git a/fs_image/README.rst b/fs_image/README.rst index c4c43e7ac8..7e4eb0ed09 100644 --- a/fs_image/README.rst +++ b/fs_image/README.rst @@ -17,13 +17,13 @@ Fs Image :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github - :target: https://github.com/OCA/storage/tree/17.0/fs_image + :target: https://github.com/OCA/storage/tree/18.0/fs_image :alt: OCA/storage .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_image :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -223,7 +223,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -240,6 +240,7 @@ Contributors - Laurent Mignon - Nguyen Minh Chien +- Denis Roussel Maintainers ----------- @@ -262,6 +263,6 @@ Current `maintainer `__: |maintainer-lmignon| -This module is part of the `OCA/storage `_ project on GitHub. +This module is part of the `OCA/storage `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_image/__manifest__.py b/fs_image/__manifest__.py index 26d62bd28a..566b5a7649 100644 --- a/fs_image/__manifest__.py +++ b/fs_image/__manifest__.py @@ -5,13 +5,11 @@ "name": "Fs Image", "summary": """ Field to store images into filesystem storages""", - "version": "17.0.1.0.2", + "version": "18.0.1.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", "depends": ["fs_file", "web"], - "data": [], - "demo": [], "maintainers": ["lmignon"], "development_status": "Alpha", "assets": { diff --git a/fs_image/fields.py b/fs_image/fields.py index 1513f6aad4..dd6c98ecfb 100644 --- a/fs_image/fields.py +++ b/fs_image/fields.py @@ -4,7 +4,6 @@ from contextlib import contextmanager from io import BytesIO, IOBase -from odoo import _ from odoo.exceptions import UserError from odoo.tools.image import image_process @@ -218,7 +217,7 @@ def _update_alt_text(self, records, value: dict): for record in records: if not record[self.name]: raise UserError( - _( + record.env._( "Cannot set alt_text on empty image " "(record %(record)s.%(field_name)s)", record=record, diff --git a/fs_image/readme/CONTRIBUTORS.md b/fs_image/readme/CONTRIBUTORS.md index da20decb6f..829016a80c 100644 --- a/fs_image/readme/CONTRIBUTORS.md +++ b/fs_image/readme/CONTRIBUTORS.md @@ -1,2 +1,3 @@ - Laurent Mignon \<\> - Nguyen Minh Chien \<\> +- Denis Roussel \<\> diff --git a/fs_image/static/description/index.html b/fs_image/static/description/index.html index a86294736c..88a0eb394c 100644 --- a/fs_image/static/description/index.html +++ b/fs_image/static/description/index.html @@ -369,7 +369,7 @@

    Fs Image

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:83bf3d081cee121382989912937b99966b63f14d37195a0258d4221c3bb34ee3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Alpha License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    This addon defines a new field FSImage to use in your models. It is a subclass of the FSFile field and comes with the same features. It extends the FSFile field with specific properties dedicated to @@ -419,10 +419,10 @@

    Usage

    This new field type can be used in the same way as the odoo ‘Image’ field type.

    -from odoo import models
    -from odoo.addons.fs_image.fields import FSImage
    +from odoo import models
    +from odoo.addons.fs_image.fields import FSImage
     
    -class MyModel(models.Model):
    +class MyModel(models.Model):
         _name = 'my.model'
     
         image = FSImage('Image', max_width=1920, max_height=1920)
    @@ -447,10 +447,10 @@ 

    Usage

    user set an ‘alt’ text for the image.

    A mode advanced and useful example is the following:

    -from odoo import models
    -from odoo.addons.fs_image.fields import FSImage
    +from odoo import models
    +from odoo.addons.fs_image.fields import FSImage
     
    -class MyModel(models.Model):
    +class MyModel(models.Model):
         _name = 'my.model'
     
         image_1920 = FSImage('Image', max_width=1920, max_height=1920)
    @@ -494,9 +494,9 @@ 

    Usage

    form view to avoid to overload the form view with a large image and consume too much bandwidth.

    -from odoo import models
    +from odoo import models
     
    -class MyModel(models.Model):
    +class MyModel(models.Model):
         _name = 'my.model'
         _inherit = ['fs_image.mixin']
     
    @@ -567,7 +567,7 @@

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -583,6 +583,7 @@

    Contributors

    @@ -596,7 +597,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    lmignon

    -

    This module is part of the OCA/storage project on GitHub.

    +

    This module is part of the OCA/storage project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000..6a58871771 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,3 @@ +odoo_test_helper + +odoo-addon-fs-file @ git+https://github.com/OCA/storage.git@refs/pull/445/head#subdirectory=fs_file From 2f7a338a338e60f038243b7f6e4a95895972daa3 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 20 Feb 2025 19:21:11 +0100 Subject: [PATCH 32/32] [FIX] fs_image: Use rawCacheKey as unique --- fs_image/static/src/views/fields/fsimage_field.esm.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs_image/static/src/views/fields/fsimage_field.esm.js b/fs_image/static/src/views/fields/fsimage_field.esm.js index fe811f2eec..250fbd3066 100644 --- a/fs_image/static/src/views/fields/fsimage_field.esm.js +++ b/fs_image/static/src/views/fields/fsimage_field.esm.js @@ -6,7 +6,6 @@ import { ImageField, fileTypeMagicWordMap, - imageCacheKey, imageField, } from "@web/views/fields/image/image_field"; import {AltTextDialog} from "../dialogs/alttext_dialog.esm"; @@ -51,7 +50,7 @@ export class FSImageField extends ImageField { const filename = this.props.record.data[this.props.name].filename; base_url = `/web/image/${model}/${id}/${field}/${filename}`; } - return utilUrl(base_url, {unique: imageCacheKey(this.rawCacheKey)}); + return utilUrl(base_url, {unique: this.rawCacheKey}); } return placeholder; }