From bd2cb5e96d4bd02c1bde60772d9bfa9b92e9c336 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Mon, 18 Sep 2023 16:55:26 +0200 Subject: [PATCH 01/17] [ADD] fs_image_thumbnail: A drop-in replacement of storage_thumbnail --- fs_image_thumbnail/README.rst | 35 +++ fs_image_thumbnail/__init__.py | 1 + fs_image_thumbnail/__manifest__.py | 23 ++ .../i18n/fs_image_thumbnail.pot | 170 +++++++++++++ fs_image_thumbnail/models/__init__.py | 3 + .../models/fs_image_thumbnail_mixin.py | 238 ++++++++++++++++++ fs_image_thumbnail/models/fs_thumbnail.py | 11 + fs_image_thumbnail/models/ir_attachment.py | 16 ++ fs_image_thumbnail/readme/CONTEXT.rst | 17 ++ fs_image_thumbnail/readme/CONTRIBUTORS.rst | 1 + fs_image_thumbnail/readme/CREDITS.rst | 3 + fs_image_thumbnail/readme/DESCRIPTION.rst | 4 + fs_image_thumbnail/readme/USAGE.rst | 57 +++++ fs_image_thumbnail/security/fs_thumbnail.xml | 16 ++ .../static/description/icon.png | Bin 0 -> 9455 bytes fs_image_thumbnail/tests/__init__.py | 1 + .../tests/test_fs_image_thumbnail.py | 81 ++++++ .../views/fs_image_thumbnail_mixin.xml | 84 +++++++ fs_image_thumbnail/views/fs_thumbnail.xml | 62 +++++ fs_image_thumbnail/views/ir_attachment.xml | 19 ++ 20 files changed, 842 insertions(+) create mode 100644 fs_image_thumbnail/README.rst create mode 100644 fs_image_thumbnail/__init__.py create mode 100644 fs_image_thumbnail/__manifest__.py create mode 100644 fs_image_thumbnail/i18n/fs_image_thumbnail.pot create mode 100644 fs_image_thumbnail/models/__init__.py create mode 100644 fs_image_thumbnail/models/fs_image_thumbnail_mixin.py create mode 100644 fs_image_thumbnail/models/fs_thumbnail.py create mode 100644 fs_image_thumbnail/models/ir_attachment.py create mode 100644 fs_image_thumbnail/readme/CONTEXT.rst create mode 100644 fs_image_thumbnail/readme/CONTRIBUTORS.rst create mode 100644 fs_image_thumbnail/readme/CREDITS.rst create mode 100644 fs_image_thumbnail/readme/DESCRIPTION.rst create mode 100644 fs_image_thumbnail/readme/USAGE.rst create mode 100644 fs_image_thumbnail/security/fs_thumbnail.xml create mode 100644 fs_image_thumbnail/static/description/icon.png create mode 100644 fs_image_thumbnail/tests/__init__.py create mode 100644 fs_image_thumbnail/tests/test_fs_image_thumbnail.py create mode 100644 fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml create mode 100644 fs_image_thumbnail/views/fs_thumbnail.xml create mode 100644 fs_image_thumbnail/views/ir_attachment.xml diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst new file mode 100644 index 0000000000..38929e8775 --- /dev/null +++ b/fs_image_thumbnail/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_thumbnail/__init__.py b/fs_image_thumbnail/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_image_thumbnail/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_image_thumbnail/__manifest__.py b/fs_image_thumbnail/__manifest__.py new file mode 100644 index 0000000000..ac56be61ba --- /dev/null +++ b/fs_image_thumbnail/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Fs Image Thumbnail", + "summary": """ + Generate and store thumbnail for images""", + "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_image", "base_partition"], + "data": [ + "views/ir_attachment.xml", + "security/fs_thumbnail.xml", + "views/fs_image_thumbnail_mixin.xml", + "views/fs_thumbnail.xml", + ], + "demo": [], + "maintainers": ["lmignon"], + "development_status": "Alpha", + "external_dependencies": {"python": ["python_slugify"]}, +} diff --git a/fs_image_thumbnail/i18n/fs_image_thumbnail.pot b/fs_image_thumbnail/i18n/fs_image_thumbnail.pot new file mode 100644 index 0000000000..6c712d97e7 --- /dev/null +++ b/fs_image_thumbnail/i18n/fs_image_thumbnail.pot @@ -0,0 +1,170 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image_thumbnail +# +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_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_ir_attachment +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__attachment_id +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__attachment_id +msgid "Attachment containing the original image" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Base Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_uid +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_thumbnail_search_view +msgid "Created by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_date +msgid "Created on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__display_name +msgid "Display Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_image_thumbnail_mixin +msgid "Fs Image Thumbnail Mixin" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.ui.menu,name:fs_image_thumbnail.fs_thumbnail_menu +msgid "Fs Image Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.actions.act_window,name:fs_image_thumbnail.fs_thumbnail_act_window +msgid "Fs Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Group By" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__id +msgid "ID" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image +msgid "Image" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail +msgid "Image Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update +msgid "Last Modified on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_date +msgid "Last Updated on" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "MimeType" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__mimetype +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__mimetype +msgid "Mimetype" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__name +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__original_image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__original_image +msgid "Original Image" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The base name must be set when multiple images are given" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "The base name of the thumbnail image (without extension)" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The image %(name)s must be attached to an attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "" +"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" +"If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view +msgid "Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_x +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_x +msgid "X size" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_y +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y +msgid "Y size" +msgstr "" diff --git a/fs_image_thumbnail/models/__init__.py b/fs_image_thumbnail/models/__init__.py new file mode 100644 index 0000000000..0ef2d28a1d --- /dev/null +++ b/fs_image_thumbnail/models/__init__.py @@ -0,0 +1,3 @@ +from . import fs_image_thumbnail_mixin +from . import fs_thumbnail +from . import ir_attachment diff --git a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py new file mode 100644 index 0000000000..5a42730e2c --- /dev/null +++ b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py @@ -0,0 +1,238 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from slugify import slugify + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +from odoo.addons.fs_image.fields import FSImage, FSImageValue + + +class FsImageThumbnailMixin(models.AbstractModel): + """Mixin defining what is a thumbnail image and providing a + method to generate a thumbnail image from an image. + + """ + + _name = "fs.image.thumbnail.mixin" + _description = "Fs Image Thumbnail Mixin" + + image = FSImage("Image", required=True) + original_image = FSImage("Original Image", compute="_compute_original_image") + size_x = fields.Integer("X size", required=True) + size_y = fields.Integer("Y size", required=True) + base_name = fields.Char( + "The base name of the thumbnail image (without extension)", + required=True, + help="The thumbnail image will be named as base_name " + "+ _ + size_x + _ + size_y + . + extension.\n" + "If not set, the base name will be the name of the original image." + "This base name is used to find all existing thumbnail of an image generated " + "for the same base name.", + ) + + attachment_id = fields.Many2one( + comodel_name="ir.attachment", + string="Attachment", + help="Attachment containing the original image", + required=True, + ) + name = fields.Char( + compute="_compute_name", + store=True, + ) + mimetype = fields.Char( + compute="_compute_mimetype", + store=True, + ) + + @api.depends("image") + def _compute_name(self): + for record in self: + record.name = record.image.name if record.image else None + + @api.depends("image") + def _compute_mimetype(self): + for record in self: + record.mimetype = record.image.mimetype if record.image else None + + @api.depends("attachment_id") + def _compute_original_image(self): + original_image_field = self._fields["original_image"] + for record in self: + value = None + if record.attachment_id: + value = original_image_field._convert_attachment_to_cache( + record.attachment_id + ) + record.original_image = value + + @api.model + def _resize(self, image: FSImage, size_x: int, size_y: int, fmt: str = "") -> bytes: + """Resize the given image to the given size. + + :param image: the image to resize + :param size_x: the new width of the image + :param size_y: the new height of the image + :param fmt: the output format of the image. 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 resized image + """ + # image_process only accept PNG, JPEG, GIF, or ICO as output format + # in uppercase. Remove the dot if present and convert to uppercase. + fmt = fmt.upper().replace(".", "") + return image.image_process(size=(size_x, size_y), output_format=fmt) + + @api.model + def _get_resize_format(self, image: FSImage) -> str: + """Get the format to use to resize an image. + + :return: the format to use to resize an image + """ + fmt = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("fs_image_thumbnail.resize_format") + ) + return fmt or image.extension + + @api.model + def _prepare_tumbnail( + self, image: FSImage, size_x: int, size_y: int, base_name: str + ) -> dict: + """Prepare the values to create a thumbnail image from the given image. + + :param image: the image to resize + :param size_x: the new width of the image + :param size_y: the new height of the image + :param base_name: the base name of the thumbnail image (without extension) + :return: the values to create a thumbnail image + """ + fmt = self._get_resize_format(image) + extension = fmt + # Add a dot before the extension if needed and convert to lowercase. + extension = extension.lower() + if extension and not extension.startswith("."): + extension = "." + extension + new_image = FSImageValue( + value=self._resize(image, size_x, size_y, fmt), + name="%s_%s_%s%s" % (base_name, size_x, size_y, extension), + alt_text=image.alt_text, + ) + return { + "image": new_image, + "size_x": size_x, + "size_y": size_y, + "base_name": base_name, + "attachment_id": image.attachment.id, + } + + @api.model + def _slugify_base_name(self, base_name: str) -> str: + """Slugify the given base name. + + :param base_name: the base name to slugify + :return: the slugified base name + """ + return slugify(base_name) if base_name else base_name + + @api.model + def _get_existing_thumbnail_domain( + self, *images: tuple[FSImageValue], base_name: str = "" + ) -> list: + """Get the domain to find existing thumbnail images from the given image. + + :param images: a list of images we want to find existing thumbnails + :param base_name: the base name of the thumbnail image (without extension) + The base name must be set when multiple images are given. + :return: the domain to find existing thumbnail images + """ + attachment_ids = [] + for image in images: + if image.attachment: + attachment_ids.append(image.attachment.id) + else: + raise UserError( + _( + "The image %(name)s must be attached to an attachment", + name=image.name, + ) + ) + base_name = self._get_slugified_base_name(*images, base_name=base_name) + return [ + ("attachment_id", "in", attachment_ids), + ("base_name", "=", base_name), + ] + + @api.model + def get_thumbnails( + self, *images: tuple[FSImageValue], base_name: str = "" + ) -> list["FsImageThumbnailMixin"]: + """Get existing thumbnail images from the given image. + + :param images: a list of images we want to find existing thumbnails + :param base_name: the base name of the thumbnail image (without extension) + The base name must be set when multiple images are given. + :return: a recordset of thumbnail images + """ + domain = self._get_existing_thumbnail_domain(*images, base_name=base_name) + return self.search(domain) + + @api.model + def get_or_create_thumbnails( + self, + *images: tuple[FSImageValue], + sizes: list[tuple[int, int]], + base_name: str = "" + ) -> list["FsImageThumbnailMixin"]: + """Get or create a thumbnail images from the given image. + + :param images: the list of images we want to get or create thumbnails + :param sizes: the list of sizes to use to resize the image + (list of tuple (size_x, size_y)) + :param base_name: the base name of the thumbnail image (without extension) + The base name must be set when multiple images are given. + :return: a dictionary where the key is the original image and the value is + a recordset of thumbnail images + """ + base_name = self._get_slugified_base_name(*images, base_name=base_name) + thumbnails = self.get_thumbnails(*images, base_name=base_name) + thumbnails_by_attachment_id = thumbnails.partition("attachment_id") + ret = {} + for image in images: + thumbnails_by_size = { + (thumbnail.size_x, thumbnail.size_y): thumbnail + for thumbnail in thumbnails_by_attachment_id.get(image.attachment, []) + } + ids_to_return = [] + for size_x, size_y in sizes: + thumbnail = thumbnails_by_size.get((size_x, size_y)) + if not thumbnail: + values = self._prepare_tumbnail(image, size_x, size_y, base_name) + # no creation possible outside of this method -> sudo() is + # required since no access rights defined on create + thumbnail = self.sudo().create(values) + ids_to_return.append(thumbnail.id) + # return the thumbnails browsed in the same security context as the method + # caller + ret[image] = self.browse(ids_to_return) + return ret + + @api.model + def _get_slugified_base_name( + self, *images: tuple[FSImageValue], base_name: str + ) -> str: + """Get the base name of the thumbnail image (without extension). + + :param images: the list of images we want to get the base name + :return: the base name of the thumbnail image + """ + if not base_name: + if len(images) > 1: + raise UserError( + _("The base name must be set when multiple images are given") + ) + base_name = images[0].name + return self._slugify_base_name(base_name) diff --git a/fs_image_thumbnail/models/fs_thumbnail.py b/fs_image_thumbnail/models/fs_thumbnail.py new file mode 100644 index 0000000000..bf2df3d097 --- /dev/null +++ b/fs_image_thumbnail/models/fs_thumbnail.py @@ -0,0 +1,11 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class FsThumbnail(models.Model): + + _name = "fs.thumbnail" + _inherit = "fs.image.thumbnail.mixin" + _description = "Image Thumbnail" diff --git a/fs_image_thumbnail/models/ir_attachment.py b/fs_image_thumbnail/models/ir_attachment.py new file mode 100644 index 0000000000..23116ecb9b --- /dev/null +++ b/fs_image_thumbnail/models/ir_attachment.py @@ -0,0 +1,16 @@ +# 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" + + thumbnail_ids = fields.One2many( + comodel_name="fs.thumbnail", + inverse_name="attachment_id", + string="Thumbnails", + readonly=True, + ) diff --git a/fs_image_thumbnail/readme/CONTEXT.rst b/fs_image_thumbnail/readme/CONTEXT.rst new file mode 100644 index 0000000000..4c7e0559ac --- /dev/null +++ b/fs_image_thumbnail/readme/CONTEXT.rst @@ -0,0 +1,17 @@ +In some specific cases you may need to generate and store thumbnails of images in Odoo. +This is the case for example when you want to provide image in specific sizes for a website +or a mobile application. + +This module provides a generic way to generate thumbnails of images and store them in a +specific filesystem storage. Indeed, you could need to store the thumbnails in a different +storage than the original image (eg: store the thumbnails in a CDN) to make sure the +thumbnails are served quickly when requested by an external application and to +avoid to expose the original image storage. + +This module uses the `fs_image `_ +module to store the thumbnails in a filesystem storage. + +The `shopinvader_product_image `_ addon uses this module to generate and +store the thumbnails of the images of the products and categories to be accessible +by the website. diff --git a/fs_image_thumbnail/readme/CONTRIBUTORS.rst b/fs_image_thumbnail/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..1480ca2b76 --- /dev/null +++ b/fs_image_thumbnail/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Laurent Mignon (https://acsone.eu) diff --git a/fs_image_thumbnail/readme/CREDITS.rst b/fs_image_thumbnail/readme/CREDITS.rst new file mode 100644 index 0000000000..82c081d258 --- /dev/null +++ b/fs_image_thumbnail/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* `Alcyon Belux `_ diff --git a/fs_image_thumbnail/readme/DESCRIPTION.rst b/fs_image_thumbnail/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..6ce408a456 --- /dev/null +++ b/fs_image_thumbnail/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This module extends the **fs_image** addon to support the creation and the storage of +thumbnails for images. This module is a **technical module** and is not +meant to be installed by end-users. It only provides a mixin to be used +by other modules and a model to store the thumbnails. diff --git a/fs_image_thumbnail/readme/USAGE.rst b/fs_image_thumbnail/readme/USAGE.rst new file mode 100644 index 0000000000..4a539166fe --- /dev/null +++ b/fs_image_thumbnail/readme/USAGE.rst @@ -0,0 +1,57 @@ +This addon provides a convenient way to get and create if not exists image +thumbnails. All the logic is implemented by the abstract model +`fs.image.thumbnail.mixin`. The main method is `get_or_create_thumbnails` which +accepts a *FSImageValue* instance, a list of thumbnail sizes and a base name. + +When the method is called, it will check if the thumbnail exists for the given +sizes and base name. If not, it will create it. + +The `fs.thumbnail` model provided by this addon is a concrete implementation of +the abstract model `fs.image.thumbnail.mixin`. The motivation to implement all the +logic in an abstract model is to allow developers to create their own thumbnail +models. This could be useful if you want to store the thumbnails in a different +storage since you can specify the storage to use by model on the `fs.storage` +form view. + +Creating / retrieving thumbnails is as simple as: + +.. code-block:: python + + from odoo.addons.fs_image.fields import FSImageValue + + # create an attachment with a image file + attachment = self.env['ir.attachment'].create({ + 'name': 'test', + 'datas': base64.b64encode(open('test.png', 'rb').read()), + 'datas_fname': 'test.png', + }) + + # create a FSImageValue instance for the attachment + image_value = FSImageValue(attachment) + + # get or create the thumbnails + thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( + image_value, [(800,600), (400, 200)], 'my base name') + + + +If you've a model with a *FSImage* field, the call to `get_or_create_thumbnails` +is even simpler: + +.. 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') + + my_record = cls.env['my.model'].create({ + 'image': open('test.png', 'rb'), + }) + + # get or create the thumbnails + thumbnails = record.image.get_or_create_thumbnails(my_record.image, + [(800,600), (400, 200)], 'my base name') diff --git a/fs_image_thumbnail/security/fs_thumbnail.xml b/fs_image_thumbnail/security/fs_thumbnail.xml new file mode 100644 index 0000000000..7690d990f4 --- /dev/null +++ b/fs_image_thumbnail/security/fs_thumbnail.xml @@ -0,0 +1,16 @@ + + + + + + fs.thumbnail access read + + + + + + + + + diff --git a/fs_image_thumbnail/static/description/icon.png b/fs_image_thumbnail/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_image_thumbnail/tests/__init__.py b/fs_image_thumbnail/tests/__init__.py new file mode 100644 index 0000000000..919947aec7 --- /dev/null +++ b/fs_image_thumbnail/tests/__init__.py @@ -0,0 +1 @@ +from . import test_fs_image_thumbnail diff --git a/fs_image_thumbnail/tests/test_fs_image_thumbnail.py b/fs_image_thumbnail/tests/test_fs_image_thumbnail.py new file mode 100644 index 0000000000..3caa4b5265 --- /dev/null +++ b/fs_image_thumbnail/tests/test_fs_image_thumbnail.py @@ -0,0 +1,81 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import base64 +import io + +from PIL import Image + +from odoo.tests.common import TransactionCase + +from odoo.addons.fs_image.fields import FSImageValue + + +class TestFsImageThumbnail(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.white_image = cls._create_image(32, 32, color="#FFFFFF") + + cls.image_attachment = cls.env["ir.attachment"].create( + { + "name": "Test Image", + "datas": base64.b64encode(cls.white_image), + "mimetype": "image/png", + } + ) + + cls.fs_image_value = FSImageValue(attachment=cls.image_attachment) + cls.fs_thumbnail_model = cls.env["fs.thumbnail"] + + def setUp(self): + super().setUp() + self.temp_dir = self.env["fs.storage"].create( + { + "name": "Temp FS Storage", + "protocol": "memory", + "code": "mem_dir", + "directory_path": "/tmp/", + "model_xmlids": "fs_image_thumbnail.model_fs_thumbnail", + } + ) + + @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 assert_image_size(self, value: bytes, width, height): + self.assertEqual(Image.open(io.BytesIO(value)).size, (width, height)) + + def test_create_multi(self): + self.assertFalse(self.image_attachment.thumbnail_ids) + thumbnails = self.fs_thumbnail_model.get_or_create_thumbnails( + self.fs_image_value, sizes=[(16, 16), (8, 8)], base_name="My super test" + )[self.fs_image_value] + self.assertEqual(len(thumbnails), 2) + self.assertEqual(thumbnails[0].name, "my-super-test_16_16.png") + self.assert_image_size(thumbnails[0].image.getvalue(), 16, 16) + self.assertEqual(thumbnails[1].name, "my-super-test_8_8.png") + self.assert_image_size(thumbnails[1].image.getvalue(), 8, 8) + + self.assertEqual(self.image_attachment.thumbnail_ids, thumbnails) + + # if we call the method again for the same size, we should get the same thumbnail + new_thumbnails = self.fs_thumbnail_model.get_or_create_thumbnails( + self.fs_image_value, sizes=[(16, 16), (8, 8)], base_name="My super test" + )[self.fs_image_value] + self.assertEqual(new_thumbnails, thumbnails) + + def test_create_with_specific_format(self): + self.env["ir.config_parameter"].set_param( + "fs_image_thumbnail.resize_format", "JPEG" + ) + thumbnail = self.fs_thumbnail_model.get_or_create_thumbnails( + self.fs_image_value, sizes=[(8, 8)], base_name="My super test" + )[self.fs_image_value] + self.assertEqual(thumbnail[0].name, "my-super-test_8_8.jpeg") + self.assertEqual(thumbnail[0].mimetype, "image/jpeg") + self.assert_image_size(thumbnail[0].image.getvalue(), 8, 8) diff --git a/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml b/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml new file mode 100644 index 0000000000..8dfac21a0f --- /dev/null +++ b/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml @@ -0,0 +1,84 @@ + + + + + + fs.image.thumbnail.mixin.form (in fs_image_thumbnail) + fs.image.thumbnail.mixin + +
+
+
+ + +
+
+
+ + + fs.image.thumbnail.mixin.search (in fs_image_thumbnail) + fs.image.thumbnail.mixin + + + + + + + + + + + + + + + fs.image.thumbnail.mixin.tree (in fs_image_thumbnail) + fs.image.thumbnail.mixin + + + + + + + + + + + +
diff --git a/fs_image_thumbnail/views/fs_thumbnail.xml b/fs_image_thumbnail/views/fs_thumbnail.xml new file mode 100644 index 0000000000..9de1fd6cf4 --- /dev/null +++ b/fs_image_thumbnail/views/fs_thumbnail.xml @@ -0,0 +1,62 @@ + + + + + + fs.thumbnail.form + fs.thumbnail + + primary + + + + + + + + + + fs.thumbnail.search + fs.thumbnail + + primary + + + + + + + + + fs.thumbnail.tree + fs.thumbnail + + primary + + + + + + + + + + Fs Thumbnail + fs.thumbnail + tree,form + [] + {} + + + + Fs Image Thumbnails + + + + + diff --git a/fs_image_thumbnail/views/ir_attachment.xml b/fs_image_thumbnail/views/ir_attachment.xml new file mode 100644 index 0000000000..2855a1c64f --- /dev/null +++ b/fs_image_thumbnail/views/ir_attachment.xml @@ -0,0 +1,19 @@ + + + + + + ir.attachment.form (in fs_image_thumbnail) + ir.attachment + + + + + + + + + + + From e3be12d48bc635e547435f3077cc9f38d77db202 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 25 Sep 2023 07:49:18 +0000 Subject: [PATCH 02/17] [BOT] post-merge updates --- fs_image_thumbnail/README.rst | 194 ++++++- .../static/description/index.html | 510 ++++++++++++++++++ 2 files changed, 680 insertions(+), 24 deletions(-) create mode 100644 fs_image_thumbnail/static/description/index.html diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index 38929e8775..bc2c1d9c01 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -1,35 +1,181 @@ -**This file is going to be generated by oca-gen-addon-readme.** +================== +Fs Image Thumbnail +================== -*Manual changes will be overwritten.* +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2870e8b0fff2e9c98e03464d4e19512a1b92c822997d6cd7ca1fd062805d7931 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -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_thumbnail + :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_thumbnail + :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 module extends the **fs_image** addon to support the creation and the storage of +thumbnails for images. This module is a **technical module** and is not +meant to be installed by end-users. It only provides a mixin to be used +by other modules and a model to store the thumbnails. -A good, one sentence summary in the manifest is also highly recommended. +.. 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** -Automatic changelog generation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. contents:: + :local: -`HISTORY.rst` can be auto generated using `towncrier `_. +Use Cases / Context +=================== -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. +In some specific cases you may need to generate and store thumbnails of images in Odoo. +This is the case for example when you want to provide image in specific sizes for a website +or a mobile application. -Please refer to `towncrier` documentation to know more. +This module provides a generic way to generate thumbnails of images and store them in a +specific filesystem storage. Indeed, you could need to store the thumbnails in a different +storage than the original image (eg: store the thumbnails in a CDN) to make sure the +thumbnails are served quickly when requested by an external application and to +avoid to expose the original image storage. -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 module uses the `fs_image `_ +module to store the thumbnails in a filesystem storage. + +The `shopinvader_product_image `_ addon uses this module to generate and +store the thumbnails of the images of the products and categories to be accessible +by the website. + +Usage +===== + +This addon provides a convenient way to get and create if not exists image +thumbnails. All the logic is implemented by the abstract model +`fs.image.thumbnail.mixin`. The main method is `get_or_create_thumbnails` which +accepts a *FSImageValue* instance, a list of thumbnail sizes and a base name. + +When the method is called, it will check if the thumbnail exists for the given +sizes and base name. If not, it will create it. + +The `fs.thumbnail` model provided by this addon is a concrete implementation of +the abstract model `fs.image.thumbnail.mixin`. The motivation to implement all the +logic in an abstract model is to allow developers to create their own thumbnail +models. This could be useful if you want to store the thumbnails in a different +storage since you can specify the storage to use by model on the `fs.storage` +form view. + +Creating / retrieving thumbnails is as simple as: + +.. code-block:: python + + from odoo.addons.fs_image.fields import FSImageValue + + # create an attachment with a image file + attachment = self.env['ir.attachment'].create({ + 'name': 'test', + 'datas': base64.b64encode(open('test.png', 'rb').read()), + 'datas_fname': 'test.png', + }) + + # create a FSImageValue instance for the attachment + image_value = FSImageValue(attachment) + + # get or create the thumbnails + thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( + image_value, [(800,600), (400, 200)], 'my base name') + + + +If you've a model with a *FSImage* field, the call to `get_or_create_thumbnails` +is even simpler: + +.. 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') + + my_record = cls.env['my.model'].create({ + 'image': open('test.png', 'rb'), + }) + + # get or create the thumbnails + thumbnails = record.image.get_or_create_thumbnails(my_record.image, + [(800,600), (400, 200)], 'my base name') + +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 (https://acsone.eu) + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* `Alcyon Belux `_ + +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_thumbnail/static/description/index.html b/fs_image_thumbnail/static/description/index.html new file mode 100644 index 0000000000..0e75991e04 --- /dev/null +++ b/fs_image_thumbnail/static/description/index.html @@ -0,0 +1,510 @@ + + + + + + +Fs Image Thumbnail + + + +
+

Fs Image Thumbnail

+ + +

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

+

This module extends the fs_image addon to support the creation and the storage of +thumbnails for images. This module is a technical module and is not +meant to be installed by end-users. It only provides a mixin to be used +by other modules and a model to store the thumbnails.

+
+

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

+ +
+

Use Cases / Context

+

In some specific cases you may need to generate and store thumbnails of images in Odoo. +This is the case for example when you want to provide image in specific sizes for a website +or a mobile application.

+

This module provides a generic way to generate thumbnails of images and store them in a +specific filesystem storage. Indeed, you could need to store the thumbnails in a different +storage than the original image (eg: store the thumbnails in a CDN) to make sure the +thumbnails are served quickly when requested by an external application and to +avoid to expose the original image storage.

+

This module uses the fs_image +module to store the thumbnails in a filesystem storage.

+

The shopinvader_product_image addon uses this module to generate and +store the thumbnails of the images of the products and categories to be accessible +by the website.

+
+
+

Usage

+

This addon provides a convenient way to get and create if not exists image +thumbnails. All the logic is implemented by the abstract model +fs.image.thumbnail.mixin. The main method is get_or_create_thumbnails which +accepts a FSImageValue instance, a list of thumbnail sizes and a base name.

+

When the method is called, it will check if the thumbnail exists for the given +sizes and base name. If not, it will create it.

+

The fs.thumbnail model provided by this addon is a concrete implementation of +the abstract model fs.image.thumbnail.mixin. The motivation to implement all the +logic in an abstract model is to allow developers to create their own thumbnail +models. This could be useful if you want to store the thumbnails in a different +storage since you can specify the storage to use by model on the fs.storage +form view.

+

Creating / retrieving thumbnails is as simple as:

+
+from odoo.addons.fs_image.fields import FSImageValue
+
+# create an attachment with a image file
+attachment = self.env['ir.attachment'].create({
+    'name': 'test',
+    'datas': base64.b64encode(open('test.png', 'rb').read()),
+    'datas_fname': 'test.png',
+})
+
+# create a FSImageValue instance for the attachment
+image_value = FSImageValue(attachment)
+
+# get or create the thumbnails
+thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails(
+    image_value, [(800,600), (400, 200)], 'my base name')
+
+

If you’ve a model with a FSImage field, the call to get_or_create_thumbnails +is even simpler:

+
+from odoo import models
+from odoo.addons.fs_image.fields import FSImage
+
+class MyModel(models.Model):
+    _name = 'my.model'
+
+    image = FSImage('Image')
+
+my_record = cls.env['my.model'].create({
+    'image': open('test.png', 'rb'),
+})
+
+# get or create the thumbnails
+thumbnails = record.image.get_or_create_thumbnails(my_record.image,
+    [(800,600), (400, 200)], 'my base name')
+
+
+
+

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
  • +
+
+ +
+

Other credits

+

The development of this module has been financially supported by:

+ +
+
+

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 7088309942e7a84d3c87a72dc8e5d0dc077083cd Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 4 Oct 2023 09:20:22 +0200 Subject: [PATCH 03/17] [FIX] fs_image_thumbnail: Keep images order in result of get_or_create_thumbnails --- fs_image_thumbnail/models/fs_image_thumbnail_mixin.py | 11 +++++++---- fs_image_thumbnail/readme/newsfragments/.gitignore | 0 fs_image_thumbnail/readme/newsfragments/282.bugfix | 6 ++++++ 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 fs_image_thumbnail/readme/newsfragments/.gitignore create mode 100644 fs_image_thumbnail/readme/newsfragments/282.bugfix diff --git a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py index 5a42730e2c..af59f0b88d 100644 --- a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py +++ b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py @@ -1,6 +1,8 @@ # Copyright 2023 ACSONE SA/NV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from collections import OrderedDict + from slugify import slugify from odoo import _, api, fields, models @@ -186,7 +188,7 @@ def get_or_create_thumbnails( *images: tuple[FSImageValue], sizes: list[tuple[int, int]], base_name: str = "" - ) -> list["FsImageThumbnailMixin"]: + ) -> OrderedDict[FSImageValue, list["FsImageThumbnailMixin"]]: """Get or create a thumbnail images from the given image. :param images: the list of images we want to get or create thumbnails @@ -194,13 +196,14 @@ def get_or_create_thumbnails( (list of tuple (size_x, size_y)) :param base_name: the base name of the thumbnail image (without extension) The base name must be set when multiple images are given. - :return: a dictionary where the key is the original image and the value is - a recordset of thumbnail images + :return: an ordered dictionary where the key is the original image and + the value is a recordset of thumbnail images. The order of the dict + is the order of the images passed to the method. """ base_name = self._get_slugified_base_name(*images, base_name=base_name) thumbnails = self.get_thumbnails(*images, base_name=base_name) thumbnails_by_attachment_id = thumbnails.partition("attachment_id") - ret = {} + ret = OrderedDict[FSImageValue, list["FsImageThumbnailMixin"]]() for image in images: thumbnails_by_size = { (thumbnail.size_x, thumbnail.size_y): thumbnail diff --git a/fs_image_thumbnail/readme/newsfragments/.gitignore b/fs_image_thumbnail/readme/newsfragments/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fs_image_thumbnail/readme/newsfragments/282.bugfix b/fs_image_thumbnail/readme/newsfragments/282.bugfix new file mode 100644 index 0000000000..f96616eabf --- /dev/null +++ b/fs_image_thumbnail/readme/newsfragments/282.bugfix @@ -0,0 +1,6 @@ +The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* +class returns now an ordered dictionary where the key is the original image and +the value is a recordset of thumbnail images. The order of the dict is the order +of the images passed to the method. This ensures that when you process the result +of the method you can be sure that the order of the images is the same as the +order of the images passed to the method. From e95e8e0b24805cea0ac41eb3f7ab9ba8909e7973 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 4 Oct 2023 07:52:30 +0000 Subject: [PATCH 04/17] [BOT] post-merge updates --- fs_image_thumbnail/README.rst | 17 ++++++- fs_image_thumbnail/__manifest__.py | 2 +- fs_image_thumbnail/readme/HISTORY.rst | 11 +++++ .../readme/newsfragments/282.bugfix | 6 --- .../static/description/index.html | 45 +++++++++++++------ 5 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 fs_image_thumbnail/readme/HISTORY.rst delete mode 100644 fs_image_thumbnail/readme/newsfragments/282.bugfix diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index bc2c1d9c01..2a3b987440 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -7,7 +7,7 @@ Fs Image Thumbnail !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2870e8b0fff2e9c98e03464d4e19512a1b92c822997d6cd7ca1fd062805d7931 + !! source digest: sha256:3bb3cbeae4c613ddad99937001cf3035bbfc1097e93d97c8d4caf64e941256fe !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -125,6 +125,21 @@ is even simpler: thumbnails = record.image.get_or_create_thumbnails(my_record.image, [(800,600), (400, 200)], 'my base name') +Changelog +========= + +16.0.1.0.1 (2023-10-04) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* + class returns now an ordered dictionary where the key is the original image and + the value is a recordset of thumbnail images. The order of the dict is the order + of the images passed to the method. This ensures that when you process the result + of the method you can be sure that the order of the images is the same as the + order of the images passed to the method. (`#282 `_) + Bug Tracker =========== diff --git a/fs_image_thumbnail/__manifest__.py b/fs_image_thumbnail/__manifest__.py index ac56be61ba..718307fe94 100644 --- a/fs_image_thumbnail/__manifest__.py +++ b/fs_image_thumbnail/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image Thumbnail", "summary": """ Generate and store thumbnail for images""", - "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_thumbnail/readme/HISTORY.rst b/fs_image_thumbnail/readme/HISTORY.rst new file mode 100644 index 0000000000..f02120778a --- /dev/null +++ b/fs_image_thumbnail/readme/HISTORY.rst @@ -0,0 +1,11 @@ +16.0.1.0.1 (2023-10-04) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* + class returns now an ordered dictionary where the key is the original image and + the value is a recordset of thumbnail images. The order of the dict is the order + of the images passed to the method. This ensures that when you process the result + of the method you can be sure that the order of the images is the same as the + order of the images passed to the method. (`#282 `_) diff --git a/fs_image_thumbnail/readme/newsfragments/282.bugfix b/fs_image_thumbnail/readme/newsfragments/282.bugfix deleted file mode 100644 index f96616eabf..0000000000 --- a/fs_image_thumbnail/readme/newsfragments/282.bugfix +++ /dev/null @@ -1,6 +0,0 @@ -The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* -class returns now an ordered dictionary where the key is the original image and -the value is a recordset of thumbnail images. The order of the dict is the order -of the images passed to the method. This ensures that when you process the result -of the method you can be sure that the order of the images is the same as the -order of the images passed to the method. diff --git a/fs_image_thumbnail/static/description/index.html b/fs_image_thumbnail/static/description/index.html index 0e75991e04..4b108fcaeb 100644 --- a/fs_image_thumbnail/static/description/index.html +++ b/fs_image_thumbnail/static/description/index.html @@ -367,7 +367,7 @@

Fs Image Thumbnail

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:2870e8b0fff2e9c98e03464d4e19512a1b92c822997d6cd7ca1fd062805d7931 +!! source digest: sha256:3bb3cbeae4c613ddad99937001cf3035bbfc1097e93d97c8d4caf64e941256fe !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

This module extends the fs_image addon to support the creation and the storage of @@ -385,12 +385,16 @@

Fs Image Thumbnail

  • Use Cases / Context
  • Usage
  • -
  • Bug Tracker
  • -
  • Credits @@ -463,8 +467,23 @@

    Usage

    [(800,600), (400, 200)], 'my base name') +
    +

    Changelog

    +
    +

    16.0.1.0.1 (2023-10-04)

    +

    Bugfixes

    +
      +
    • The call to the method get_or_create_thumbnails on the fs.image.thumbnail.mixin +class returns now an ordered dictionary where the key is the original image and +the value is a recordset of thumbnail images. The order of the dict is the order +of the images passed to the method. This ensures that when you process the result +of the method you can be sure that the order of the images is the same as the +order of the images passed to the method. (#282)
    • +
    +
    +
    -

    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 @@ -472,28 +491,28 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose From 90ad63bbb33bc886b5951afecb8cf4ae8c41b34d Mon Sep 17 00:00:00 2001 From: Ivorra78 Date: Fri, 27 Oct 2023 11:46:13 +0000 Subject: [PATCH 05/17] Added translation using Weblate (Spanish) --- fs_image_thumbnail/i18n/es.po | 171 ++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 fs_image_thumbnail/i18n/es.po diff --git a/fs_image_thumbnail/i18n/es.po b/fs_image_thumbnail/i18n/es.po new file mode 100644 index 0000000000..95c09fd30c --- /dev/null +++ b/fs_image_thumbnail/i18n/es.po @@ -0,0 +1,171 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image_thumbnail +# +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_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_ir_attachment +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__attachment_id +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__attachment_id +msgid "Attachment containing the original image" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Base Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_uid +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_thumbnail_search_view +msgid "Created by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_date +msgid "Created on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__display_name +msgid "Display Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_image_thumbnail_mixin +msgid "Fs Image Thumbnail Mixin" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.ui.menu,name:fs_image_thumbnail.fs_thumbnail_menu +msgid "Fs Image Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.actions.act_window,name:fs_image_thumbnail.fs_thumbnail_act_window +msgid "Fs Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Group By" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__id +msgid "ID" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image +msgid "Image" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail +msgid "Image Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update +msgid "Last Modified on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_date +msgid "Last Updated on" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "MimeType" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__mimetype +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__mimetype +msgid "Mimetype" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__name +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__original_image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__original_image +msgid "Original Image" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The base name must be set when multiple images are given" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "The base name of the thumbnail image (without extension)" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The image %(name)s must be attached to an attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "" +"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" +"If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view +msgid "Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_x +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_x +msgid "X size" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_y +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y +msgid "Y size" +msgstr "" From f7be722ed5cd6487c5509b4338ea09b6ea071c22 Mon Sep 17 00:00:00 2001 From: Ivorra78 Date: Fri, 27 Oct 2023 11:46:55 +0000 Subject: [PATCH 06/17] Translated using Weblate (Spanish) Currently translated at 100.0% (27 of 27 strings) Translation: storage-16.0/storage-16.0-fs_image_thumbnail Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image_thumbnail/es/ --- fs_image_thumbnail/i18n/es.po | 61 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/fs_image_thumbnail/i18n/es.po b/fs_image_thumbnail/i18n/es.po index 95c09fd30c..bad8caae96 100644 --- a/fs_image_thumbnail/i18n/es.po +++ b/fs_image_thumbnail/i18n/es.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: 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_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_ir_attachment @@ -20,129 +22,129 @@ msgstr "" #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__attachment_id #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Attachment" -msgstr "" +msgstr "Archivo Adjunto" #. module: fs_image_thumbnail #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__attachment_id msgid "Attachment containing the original image" -msgstr "" +msgstr "Archivo adjunto con la imagen original" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Base Name" -msgstr "" +msgstr "Nombre de la Base" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_uid #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_thumbnail_search_view msgid "Created by" -msgstr "" +msgstr "Creado por" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_date msgid "Created on" -msgstr "" +msgstr "Creado el" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__display_name msgid "Display Name" -msgstr "" +msgstr "Mostrar Nombre" #. module: fs_image_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_fs_image_thumbnail_mixin msgid "Fs Image Thumbnail Mixin" -msgstr "" +msgstr "Mezcla de Miniaturas de imágenes Fs" #. module: fs_image_thumbnail #: model:ir.ui.menu,name:fs_image_thumbnail.fs_thumbnail_menu msgid "Fs Image Thumbnails" -msgstr "" +msgstr "Miniaturas de imágenes Fs" #. module: fs_image_thumbnail #: model:ir.actions.act_window,name:fs_image_thumbnail.fs_thumbnail_act_window msgid "Fs Thumbnail" -msgstr "" +msgstr "Miniatura Fs" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Group By" -msgstr "" +msgstr "Agrupado Por" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__id msgid "ID" -msgstr "" +msgstr "ID (identificación)" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image msgid "Image" -msgstr "" +msgstr "Imagen" #. module: fs_image_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail msgid "Image Thumbnail" -msgstr "" +msgstr "Imagen en Miniatura" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update msgid "Last Modified on" -msgstr "" +msgstr "Última Modificación el" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Última Actualización por" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_date msgid "Last Updated on" -msgstr "" +msgstr "Última Actualización el" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "MimeType" -msgstr "" +msgstr "Tipo Mimo" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__mimetype #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__mimetype msgid "Mimetype" -msgstr "" +msgstr "Tipo Mimo" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__name #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__name #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Name" -msgstr "" +msgstr "Nombre" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__original_image #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__original_image msgid "Original Image" -msgstr "" +msgstr "Imagen Original" #. module: fs_image_thumbnail #. odoo-python #: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 #, python-format msgid "The base name must be set when multiple images are given" -msgstr "" +msgstr "El nombre base debe establecerse cuando se dan varias imágenes" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__base_name msgid "The base name of the thumbnail image (without extension)" -msgstr "" +msgstr "El nombre base de la imagen en miniatura (sin extensión)" #. module: fs_image_thumbnail #. odoo-python #: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 #, python-format msgid "The image %(name)s must be attached to an attachment" -msgstr "" +msgstr "La imagen %(name)s debe adjuntarse a un archivo adjunto" #. module: fs_image_thumbnail #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name @@ -151,21 +153,26 @@ msgid "" "The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" "If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." msgstr "" +"La imagen en miniatura se denominará como nombre_base + _ + tamaño_x + _ + " +"tamaño_y + . + extensión.\n" +"Si no se establece, el nombre base será el nombre de la imagen original. " +"Este nombre base se utiliza para encontrar todas las miniaturas existentes " +"de una imagen generada para el mismo nombre base." #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view msgid "Thumbnails" -msgstr "" +msgstr "Miniaturas" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_x #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_x msgid "X size" -msgstr "" +msgstr "Tamaño X" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_y #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y msgid "Y size" -msgstr "" +msgstr "Talla Y" From e210a769a6c99e6eaa686472da8fd586cb6b3c94 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 28 Nov 2023 06:52:46 +0000 Subject: [PATCH 07/17] Added translation using Weblate (Italian) --- fs_image_thumbnail/i18n/it.po | 171 ++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 fs_image_thumbnail/i18n/it.po diff --git a/fs_image_thumbnail/i18n/it.po b/fs_image_thumbnail/i18n/it.po new file mode 100644 index 0000000000..aeac84c30e --- /dev/null +++ b/fs_image_thumbnail/i18n/it.po @@ -0,0 +1,171 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fs_image_thumbnail +# +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_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_ir_attachment +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__attachment_id +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__attachment_id +msgid "Attachment containing the original image" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Base Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_uid +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_thumbnail_search_view +msgid "Created by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_date +msgid "Created on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__display_name +msgid "Display Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_image_thumbnail_mixin +msgid "Fs Image Thumbnail Mixin" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.ui.menu,name:fs_image_thumbnail.fs_thumbnail_menu +msgid "Fs Image Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.actions.act_window,name:fs_image_thumbnail.fs_thumbnail_act_window +msgid "Fs Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Group By" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__id +msgid "ID" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image +msgid "Image" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail +msgid "Image Thumbnail" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update +msgid "Last Modified on" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_date +msgid "Last Updated on" +msgstr "" + +#. module: fs_image_thumbnail +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "MimeType" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__mimetype +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__mimetype +msgid "Mimetype" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__name +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view +msgid "Name" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__original_image +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__original_image +msgid "Original Image" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The base name must be set when multiple images are given" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "The base name of the thumbnail image (without extension)" +msgstr "" + +#. module: fs_image_thumbnail +#. odoo-python +#: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 +#, python-format +msgid "The image %(name)s must be attached to an attachment" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name +#: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__base_name +msgid "" +"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" +"If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view +msgid "Thumbnails" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_x +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_x +msgid "X size" +msgstr "" + +#. module: fs_image_thumbnail +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_y +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y +msgid "Y size" +msgstr "" From 144b9eff56bc64cd0263f66d17d8a0c74e3c03e8 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 28 Nov 2023 12:21:18 +0000 Subject: [PATCH 08/17] Translated using Weblate (Italian) Currently translated at 100.0% (27 of 27 strings) Translation: storage-16.0/storage-16.0-fs_image_thumbnail Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image_thumbnail/it/ --- fs_image_thumbnail/i18n/it.po | 61 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/fs_image_thumbnail/i18n/it.po b/fs_image_thumbnail/i18n/it.po index aeac84c30e..502eb4b1ae 100644 --- a/fs_image_thumbnail/i18n/it.po +++ b/fs_image_thumbnail/i18n/it.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: 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_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_ir_attachment @@ -20,129 +22,129 @@ msgstr "" #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__attachment_id #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Attachment" -msgstr "" +msgstr "Allegato" #. module: fs_image_thumbnail #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__attachment_id #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__attachment_id msgid "Attachment containing the original image" -msgstr "" +msgstr "Allegato contenente l'immagine originale" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Base Name" -msgstr "" +msgstr "Nome base" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_uid #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_thumbnail_search_view msgid "Created by" -msgstr "" +msgstr "Creato da" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__create_date msgid "Created on" -msgstr "" +msgstr "Creato il" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__display_name msgid "Display Name" -msgstr "" +msgstr "Nome visualizzato" #. module: fs_image_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_fs_image_thumbnail_mixin msgid "Fs Image Thumbnail Mixin" -msgstr "" +msgstr "Mixin anteprima immagine FS" #. module: fs_image_thumbnail #: model:ir.ui.menu,name:fs_image_thumbnail.fs_thumbnail_menu msgid "Fs Image Thumbnails" -msgstr "" +msgstr "Anteprima immagine FS" #. module: fs_image_thumbnail #: model:ir.actions.act_window,name:fs_image_thumbnail.fs_thumbnail_act_window msgid "Fs Thumbnail" -msgstr "" +msgstr "Anteprima FS" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Group By" -msgstr "" +msgstr "Raggruppa per" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__id msgid "ID" -msgstr "" +msgstr "ID" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image msgid "Image" -msgstr "" +msgstr "Immgine" #. module: fs_image_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail msgid "Image Thumbnail" -msgstr "" +msgstr "Anteprima immagine" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update msgid "Last Modified on" -msgstr "" +msgstr "Ultima modifica il" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Ultimo aggiornamento di" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_date msgid "Last Updated on" -msgstr "" +msgstr "Ultimo aggiornamento il" #. module: fs_image_thumbnail #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "MimeType" -msgstr "" +msgstr "Tipo MIME" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__mimetype #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__mimetype msgid "Mimetype" -msgstr "" +msgstr "Tipo MIME" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__name #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__name #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.fs_image_thumbnail_mixin_search_view msgid "Name" -msgstr "" +msgstr "Nome" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__original_image #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__original_image msgid "Original Image" -msgstr "" +msgstr "Immagine originale" #. module: fs_image_thumbnail #. odoo-python #: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 #, python-format msgid "The base name must be set when multiple images are given" -msgstr "" +msgstr "Il nome base deve essere impostato qando vengono fornite più immagini" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__base_name msgid "The base name of the thumbnail image (without extension)" -msgstr "" +msgstr "Il nome base dell'immagIne anteprima (senza estensione)" #. module: fs_image_thumbnail #. odoo-python #: code:addons/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py:0 #, python-format msgid "The image %(name)s must be attached to an attachment" -msgstr "" +msgstr "L'immagine %(name)s deve essere collegata ad una allegato" #. module: fs_image_thumbnail #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name @@ -151,21 +153,26 @@ msgid "" "The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" "If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." msgstr "" +"L'immagine anteprima verrà denominata come " +"nome_bae+_+dimensione_x+dimensione_y+.+estensione.\n" +"Se non impostato, il nome base sarà il nome dell'immagine originale. Questo " +"nome base è utilizzato per trovare tutte le anteprime di una immagine " +"generate per lo stesso nome base." #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view msgid "Thumbnails" -msgstr "" +msgstr "Anteprime" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_x #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_x msgid "X size" -msgstr "" +msgstr "Dimensione X" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__size_y #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y msgid "Y size" -msgstr "" +msgstr "Dimensione Y" From abd681c10c1366e9f309903e8bcbad2c79897b1c Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 12 Dec 2023 08:40:38 +0000 Subject: [PATCH 09/17] Translated using Weblate (Italian) Currently translated at 100.0% (27 of 27 strings) Translation: storage-16.0/storage-16.0-fs_image_thumbnail Translate-URL: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_image_thumbnail/it/ --- fs_image_thumbnail/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs_image_thumbnail/i18n/it.po b/fs_image_thumbnail/i18n/it.po index 502eb4b1ae..b03afa19b2 100644 --- a/fs_image_thumbnail/i18n/it.po +++ b/fs_image_thumbnail/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-12-12 11:33+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -80,7 +80,7 @@ msgstr "ID" #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_image_thumbnail_mixin__image #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__image msgid "Image" -msgstr "Immgine" +msgstr "Immagine" #. module: fs_image_thumbnail #: model:ir.model,name:fs_image_thumbnail.model_fs_thumbnail From 769a6df132b0fb7920036a66c959de563b5fce2a Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 19 Feb 2024 14:01:28 +0100 Subject: [PATCH 10/17] [FIX] delete FsImageThumbnail on attachment delete --- fs_image_thumbnail/models/fs_image_thumbnail_mixin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py index af59f0b88d..ab13a9c9f5 100644 --- a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py +++ b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py @@ -39,6 +39,7 @@ class FsImageThumbnailMixin(models.AbstractModel): string="Attachment", help="Attachment containing the original image", required=True, + ondelete="cascade", ) name = fields.Char( compute="_compute_name", From c0a957a549a63d559c6bf78d202e2b861cba2f05 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 Feb 2024 08:56:34 +0000 Subject: [PATCH 11/17] [BOT] post-merge updates --- fs_image_thumbnail/README.rst | 2 +- fs_image_thumbnail/__manifest__.py | 2 +- fs_image_thumbnail/static/description/index.html | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index 2a3b987440..157c1fac93 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -7,7 +7,7 @@ Fs Image Thumbnail !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3bb3cbeae4c613ddad99937001cf3035bbfc1097e93d97c8d4caf64e941256fe + !! source digest: sha256:ae84af058fd490c7c8916156dc7db31813b6d5f7535e722740b152d6955e0d57 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image_thumbnail/__manifest__.py b/fs_image_thumbnail/__manifest__.py index 718307fe94..6f0b67c173 100644 --- a/fs_image_thumbnail/__manifest__.py +++ b/fs_image_thumbnail/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image Thumbnail", "summary": """ Generate and store thumbnail for images""", - "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_thumbnail/static/description/index.html b/fs_image_thumbnail/static/description/index.html index 4b108fcaeb..f02ae6037d 100644 --- a/fs_image_thumbnail/static/description/index.html +++ b/fs_image_thumbnail/static/description/index.html @@ -1,4 +1,3 @@ - @@ -367,7 +366,7 @@

    Fs Image Thumbnail

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:3bb3cbeae4c613ddad99937001cf3035bbfc1097e93d97c8d4caf64e941256fe +!! source digest: sha256:ae84af058fd490c7c8916156dc7db31813b6d5f7535e722740b152d6955e0d57 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

    This module extends the fs_image addon to support the creation and the storage of From 13479a8fd3c60e23fea5d850a5bfa65717cda469 Mon Sep 17 00:00:00 2001 From: chien Date: Wed, 28 Feb 2024 11:56:56 +0700 Subject: [PATCH 12/17] [IMP] fs_image_thumbnail: pre-commit auto fixes --- fs_image_thumbnail/README.rst | 155 +++++++++--------- .../models/fs_image_thumbnail_mixin.py | 2 +- fs_image_thumbnail/models/fs_thumbnail.py | 1 - fs_image_thumbnail/models/ir_attachment.py | 1 - fs_image_thumbnail/pyproject.toml | 3 + fs_image_thumbnail/readme/CONTEXT.md | 20 +++ fs_image_thumbnail/readme/CONTEXT.rst | 17 -- fs_image_thumbnail/readme/CONTRIBUTORS.md | 1 + fs_image_thumbnail/readme/CONTRIBUTORS.rst | 1 - .../readme/{CREDITS.rst => CREDITS.md} | 2 +- fs_image_thumbnail/readme/DESCRIPTION.md | 4 + fs_image_thumbnail/readme/DESCRIPTION.rst | 4 - fs_image_thumbnail/readme/HISTORY.md | 12 ++ fs_image_thumbnail/readme/HISTORY.rst | 11 -- fs_image_thumbnail/readme/USAGE.md | 56 +++++++ fs_image_thumbnail/readme/USAGE.rst | 57 ------- 16 files changed, 177 insertions(+), 170 deletions(-) create mode 100644 fs_image_thumbnail/pyproject.toml create mode 100644 fs_image_thumbnail/readme/CONTEXT.md delete mode 100644 fs_image_thumbnail/readme/CONTEXT.rst create mode 100644 fs_image_thumbnail/readme/CONTRIBUTORS.md delete mode 100644 fs_image_thumbnail/readme/CONTRIBUTORS.rst rename fs_image_thumbnail/readme/{CREDITS.rst => CREDITS.md} (58%) create mode 100644 fs_image_thumbnail/readme/DESCRIPTION.md delete mode 100644 fs_image_thumbnail/readme/DESCRIPTION.rst create mode 100644 fs_image_thumbnail/readme/HISTORY.md delete mode 100644 fs_image_thumbnail/readme/HISTORY.rst create mode 100644 fs_image_thumbnail/readme/USAGE.md delete mode 100644 fs_image_thumbnail/readme/USAGE.rst diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index 157c1fac93..6381166810 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -17,21 +17,21 @@ Fs Image Thumbnail :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_thumbnail + :target: https://github.com/OCA/storage/tree/17.0/fs_image_thumbnail :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_thumbnail + :target: https://translation.odoo-community.org/projects/storage-17-0/storage-17-0-fs_image_thumbnail :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 module extends the **fs_image** addon to support the creation and the storage of -thumbnails for images. This module is a **technical module** and is not -meant to be installed by end-users. It only provides a mixin to be used -by other modules and a model to store the thumbnails. +This module extends the **fs_image** addon to support the creation and +the storage of thumbnails for images. This module is a **technical +module** and is not meant to be installed by end-users. It only provides +a mixin to be used by other modules and a model to store the thumbnails. .. IMPORTANT:: This is an alpha version, the data model and design can change at any time without warning. @@ -46,99 +46,102 @@ by other modules and a model to store the thumbnails. Use Cases / Context =================== -In some specific cases you may need to generate and store thumbnails of images in Odoo. -This is the case for example when you want to provide image in specific sizes for a website -or a mobile application. +In some specific cases you may need to generate and store thumbnails of +images in Odoo. This is the case for example when you want to provide +image in specific sizes for a website or a mobile application. -This module provides a generic way to generate thumbnails of images and store them in a -specific filesystem storage. Indeed, you could need to store the thumbnails in a different -storage than the original image (eg: store the thumbnails in a CDN) to make sure the -thumbnails are served quickly when requested by an external application and to -avoid to expose the original image storage. +This module provides a generic way to generate thumbnails of images and +store them in a specific filesystem storage. Indeed, you could need to +store the thumbnails in a different storage than the original image (eg: +store the thumbnails in a CDN) to make sure the thumbnails are served +quickly when requested by an external application and to avoid to expose +the original image storage. -This module uses the `fs_image `_ +This module uses the +`fs_image `__ module to store the thumbnails in a filesystem storage. -The `shopinvader_product_image `_ addon uses this module to generate and -store the thumbnails of the images of the products and categories to be accessible -by the website. +The `shopinvader_product_image +< <>`__\ https://github.com/shopinvader/odoo-shopinvader/\ `blob/16.0/shopinvader_product_image> <>`__ +addon uses this module to generate and store the thumbnails of the +images of the products and categories to be accessible by the website. Usage ===== -This addon provides a convenient way to get and create if not exists image -thumbnails. All the logic is implemented by the abstract model -`fs.image.thumbnail.mixin`. The main method is `get_or_create_thumbnails` which -accepts a *FSImageValue* instance, a list of thumbnail sizes and a base name. +This addon provides a convenient way to get and create if not exists +image thumbnails. All the logic is implemented by the abstract model +fs.image.thumbnail.mixin. The main method is get_or_create_thumbnails +which accepts a *FSImageValue* instance, a list of thumbnail sizes and a +base name. -When the method is called, it will check if the thumbnail exists for the given -sizes and base name. If not, it will create it. +When the method is called, it will check if the thumbnail exists for the +given sizes and base name. If not, it will create it. -The `fs.thumbnail` model provided by this addon is a concrete implementation of -the abstract model `fs.image.thumbnail.mixin`. The motivation to implement all the -logic in an abstract model is to allow developers to create their own thumbnail -models. This could be useful if you want to store the thumbnails in a different -storage since you can specify the storage to use by model on the `fs.storage` -form view. +The fs.thumbnail model provided by this addon is a concrete +implementation of the abstract model fs.image.thumbnail.mixin. The +motivation to implement all the logic in an abstract model is to allow +developers to create their own thumbnail models. This could be useful if +you want to store the thumbnails in a different storage since you can +specify the storage to use by model on the fs.storage form view. Creating / retrieving thumbnails is as simple as: -.. code-block:: python +.. code:: python - from odoo.addons.fs_image.fields import FSImageValue + from odoo.addons.fs_image.fields import FSImageValue - # create an attachment with a image file - attachment = self.env['ir.attachment'].create({ - 'name': 'test', - 'datas': base64.b64encode(open('test.png', 'rb').read()), - 'datas_fname': 'test.png', - }) + # create an attachment with a image file + attachment = self.env['ir.attachment'].create({ + 'name': 'test', + 'datas': base64.b64encode(open('test.png', 'rb').read()), + 'datas_fname': 'test.png', + }) - # create a FSImageValue instance for the attachment - image_value = FSImageValue(attachment) + # create a FSImageValue instance for the attachment + image_value = FSImageValue(attachment) - # get or create the thumbnails - thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( - image_value, [(800,600), (400, 200)], 'my base name') + # get or create the thumbnails + thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( + image_value, [(800,600), (400, 200)], 'my base name') +If you've a model with a *FSImage* field, the call to +get_or_create_thumbnails is even simpler: +.. code:: python -If you've a model with a *FSImage* field, the call to `get_or_create_thumbnails` -is even simpler: + from odoo import models + from odoo.addons.fs_image.fields import FSImage -.. code-block:: python + class MyModel(models.Model): + _name = 'my.model' - from odoo import models - from odoo.addons.fs_image.fields import FSImage + image = FSImage('Image') - class MyModel(models.Model): - _name = 'my.model' + my_record = cls.env['my.model'].create({ + 'image': open('test.png', 'rb'), + }) - image = FSImage('Image') - - my_record = cls.env['my.model'].create({ - 'image': open('test.png', 'rb'), - }) - - # get or create the thumbnails - thumbnails = record.image.get_or_create_thumbnails(my_record.image, - [(800,600), (400, 200)], 'my base name') + # get or create the thumbnails + thumbnails = record.image.get_or_create_thumbnails(my_record.image, + [(800,600), (400, 200)], 'my base name') Changelog ========= 16.0.1.0.1 (2023-10-04) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- **Bugfixes** -- The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* - class returns now an ordered dictionary where the key is the original image and - the value is a recordset of thumbnail images. The order of the dict is the order - of the images passed to the method. This ensures that when you process the result - of the method you can be sure that the order of the images is the same as the - order of the images passed to the method. (`#282 `_) +- The call to the method *get_or_create_thumbnails* on the + *fs.image.thumbnail.mixin* class returns now an ordered dictionary + where the key is the original image and the value is a recordset of + thumbnail images. The order of the dict is the order of the images + passed to the method. This ensures that when you process the result + of the method you can be sure that the order of the images is the + same as the order of the images passed to the method. + (`#282 `__) Bug Tracker =========== @@ -146,7 +149,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. @@ -154,24 +157,24 @@ Credits ======= Authors -~~~~~~~ +------- * ACSONE SA/NV Contributors -~~~~~~~~~~~~ +------------ -* Laurent Mignon (https://acsone.eu) +- Laurent Mignon (https://acsone.eu) Other credits -~~~~~~~~~~~~~ +------------- The development of this module has been financially supported by: -* `Alcyon Belux `_ +- `Alcyon Belux `__ Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -191,6 +194,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_thumbnail/models/fs_image_thumbnail_mixin.py b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py index ab13a9c9f5..f4124b6a89 100644 --- a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py +++ b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py @@ -188,7 +188,7 @@ def get_or_create_thumbnails( self, *images: tuple[FSImageValue], sizes: list[tuple[int, int]], - base_name: str = "" + base_name: str = "", ) -> OrderedDict[FSImageValue, list["FsImageThumbnailMixin"]]: """Get or create a thumbnail images from the given image. diff --git a/fs_image_thumbnail/models/fs_thumbnail.py b/fs_image_thumbnail/models/fs_thumbnail.py index bf2df3d097..462fa46e2f 100644 --- a/fs_image_thumbnail/models/fs_thumbnail.py +++ b/fs_image_thumbnail/models/fs_thumbnail.py @@ -5,7 +5,6 @@ class FsThumbnail(models.Model): - _name = "fs.thumbnail" _inherit = "fs.image.thumbnail.mixin" _description = "Image Thumbnail" diff --git a/fs_image_thumbnail/models/ir_attachment.py b/fs_image_thumbnail/models/ir_attachment.py index 23116ecb9b..849c2d4a20 100644 --- a/fs_image_thumbnail/models/ir_attachment.py +++ b/fs_image_thumbnail/models/ir_attachment.py @@ -5,7 +5,6 @@ class IrAttachment(models.Model): - _inherit = "ir.attachment" thumbnail_ids = fields.One2many( diff --git a/fs_image_thumbnail/pyproject.toml b/fs_image_thumbnail/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_image_thumbnail/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_image_thumbnail/readme/CONTEXT.md b/fs_image_thumbnail/readme/CONTEXT.md new file mode 100644 index 0000000000..9e1fc8726f --- /dev/null +++ b/fs_image_thumbnail/readme/CONTEXT.md @@ -0,0 +1,20 @@ +In some specific cases you may need to generate and store thumbnails of +images in Odoo. This is the case for example when you want to provide +image in specific sizes for a website or a mobile application. + +This module provides a generic way to generate thumbnails of images and +store them in a specific filesystem storage. Indeed, you could need to +store the thumbnails in a different storage than the original image (eg: +store the thumbnails in a CDN) to make sure the thumbnails are served +quickly when requested by an external application and to avoid to expose +the original image storage. + +This module uses the +[fs_image](https://github.com/oca/storage/blob/16.0/fs_image/README.rst) +module to store the thumbnails in a filesystem storage. + +The [shopinvader_product_image +\]() addon uses this module to +generate and store the thumbnails of the images of the products and +categories to be accessible by the website. diff --git a/fs_image_thumbnail/readme/CONTEXT.rst b/fs_image_thumbnail/readme/CONTEXT.rst deleted file mode 100644 index 4c7e0559ac..0000000000 --- a/fs_image_thumbnail/readme/CONTEXT.rst +++ /dev/null @@ -1,17 +0,0 @@ -In some specific cases you may need to generate and store thumbnails of images in Odoo. -This is the case for example when you want to provide image in specific sizes for a website -or a mobile application. - -This module provides a generic way to generate thumbnails of images and store them in a -specific filesystem storage. Indeed, you could need to store the thumbnails in a different -storage than the original image (eg: store the thumbnails in a CDN) to make sure the -thumbnails are served quickly when requested by an external application and to -avoid to expose the original image storage. - -This module uses the `fs_image `_ -module to store the thumbnails in a filesystem storage. - -The `shopinvader_product_image `_ addon uses this module to generate and -store the thumbnails of the images of the products and categories to be accessible -by the website. diff --git a/fs_image_thumbnail/readme/CONTRIBUTORS.md b/fs_image_thumbnail/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..05e5563b81 --- /dev/null +++ b/fs_image_thumbnail/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Laurent Mignon \<\> () diff --git a/fs_image_thumbnail/readme/CONTRIBUTORS.rst b/fs_image_thumbnail/readme/CONTRIBUTORS.rst deleted file mode 100644 index 1480ca2b76..0000000000 --- a/fs_image_thumbnail/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1 +0,0 @@ -* Laurent Mignon (https://acsone.eu) diff --git a/fs_image_thumbnail/readme/CREDITS.rst b/fs_image_thumbnail/readme/CREDITS.md similarity index 58% rename from fs_image_thumbnail/readme/CREDITS.rst rename to fs_image_thumbnail/readme/CREDITS.md index 82c081d258..77743cd65f 100644 --- a/fs_image_thumbnail/readme/CREDITS.rst +++ b/fs_image_thumbnail/readme/CREDITS.md @@ -1,3 +1,3 @@ The development of this module has been financially supported by: -* `Alcyon Belux `_ +- [Alcyon Belux](https://www.alcyonbelux.be/) diff --git a/fs_image_thumbnail/readme/DESCRIPTION.md b/fs_image_thumbnail/readme/DESCRIPTION.md new file mode 100644 index 0000000000..39466d487b --- /dev/null +++ b/fs_image_thumbnail/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +This module extends the **fs_image** addon to support the creation and +the storage of thumbnails for images. This module is a **technical +module** and is not meant to be installed by end-users. It only provides +a mixin to be used by other modules and a model to store the thumbnails. diff --git a/fs_image_thumbnail/readme/DESCRIPTION.rst b/fs_image_thumbnail/readme/DESCRIPTION.rst deleted file mode 100644 index 6ce408a456..0000000000 --- a/fs_image_thumbnail/readme/DESCRIPTION.rst +++ /dev/null @@ -1,4 +0,0 @@ -This module extends the **fs_image** addon to support the creation and the storage of -thumbnails for images. This module is a **technical module** and is not -meant to be installed by end-users. It only provides a mixin to be used -by other modules and a model to store the thumbnails. diff --git a/fs_image_thumbnail/readme/HISTORY.md b/fs_image_thumbnail/readme/HISTORY.md new file mode 100644 index 0000000000..23dc6efaf0 --- /dev/null +++ b/fs_image_thumbnail/readme/HISTORY.md @@ -0,0 +1,12 @@ +## 16.0.1.0.1 (2023-10-04) + +**Bugfixes** + +- The call to the method *get_or_create_thumbnails* on the + *fs.image.thumbnail.mixin* class returns now an ordered dictionary + where the key is the original image and the value is a recordset of + thumbnail images. The order of the dict is the order of the images + passed to the method. This ensures that when you process the result of + the method you can be sure that the order of the images is the same as + the order of the images passed to the method. + ([\#282](https://github.com/OCA/storage/issues/282)) diff --git a/fs_image_thumbnail/readme/HISTORY.rst b/fs_image_thumbnail/readme/HISTORY.rst deleted file mode 100644 index f02120778a..0000000000 --- a/fs_image_thumbnail/readme/HISTORY.rst +++ /dev/null @@ -1,11 +0,0 @@ -16.0.1.0.1 (2023-10-04) -~~~~~~~~~~~~~~~~~~~~~~~ - -**Bugfixes** - -- The call to the method *get_or_create_thumbnails* on the *fs.image.thumbnail.mixin* - class returns now an ordered dictionary where the key is the original image and - the value is a recordset of thumbnail images. The order of the dict is the order - of the images passed to the method. This ensures that when you process the result - of the method you can be sure that the order of the images is the same as the - order of the images passed to the method. (`#282 `_) diff --git a/fs_image_thumbnail/readme/USAGE.md b/fs_image_thumbnail/readme/USAGE.md new file mode 100644 index 0000000000..46ae7e1ea4 --- /dev/null +++ b/fs_image_thumbnail/readme/USAGE.md @@ -0,0 +1,56 @@ +This addon provides a convenient way to get and create if not exists +image thumbnails. All the logic is implemented by the abstract model +fs.image.thumbnail.mixin. The main method is get_or_create_thumbnails +which accepts a *FSImageValue* instance, a list of thumbnail sizes and a +base name. + +When the method is called, it will check if the thumbnail exists for the +given sizes and base name. If not, it will create it. + +The fs.thumbnail model provided by this addon is a concrete +implementation of the abstract model fs.image.thumbnail.mixin. The +motivation to implement all the logic in an abstract model is to allow +developers to create their own thumbnail models. This could be useful if +you want to store the thumbnails in a different storage since you can +specify the storage to use by model on the fs.storage form view. + +Creating / retrieving thumbnails is as simple as: + +``` python +from odoo.addons.fs_image.fields import FSImageValue + +# create an attachment with a image file +attachment = self.env['ir.attachment'].create({ + 'name': 'test', + 'datas': base64.b64encode(open('test.png', 'rb').read()), + 'datas_fname': 'test.png', +}) + +# create a FSImageValue instance for the attachment +image_value = FSImageValue(attachment) + +# get or create the thumbnails +thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( + image_value, [(800,600), (400, 200)], 'my base name') +``` + +If you've a model with a *FSImage* field, the call to +get_or_create_thumbnails is even simpler: + +``` python +from odoo import models +from odoo.addons.fs_image.fields import FSImage + +class MyModel(models.Model): + _name = 'my.model' + + image = FSImage('Image') + +my_record = cls.env['my.model'].create({ + 'image': open('test.png', 'rb'), +}) + +# get or create the thumbnails +thumbnails = record.image.get_or_create_thumbnails(my_record.image, + [(800,600), (400, 200)], 'my base name') +``` diff --git a/fs_image_thumbnail/readme/USAGE.rst b/fs_image_thumbnail/readme/USAGE.rst deleted file mode 100644 index 4a539166fe..0000000000 --- a/fs_image_thumbnail/readme/USAGE.rst +++ /dev/null @@ -1,57 +0,0 @@ -This addon provides a convenient way to get and create if not exists image -thumbnails. All the logic is implemented by the abstract model -`fs.image.thumbnail.mixin`. The main method is `get_or_create_thumbnails` which -accepts a *FSImageValue* instance, a list of thumbnail sizes and a base name. - -When the method is called, it will check if the thumbnail exists for the given -sizes and base name. If not, it will create it. - -The `fs.thumbnail` model provided by this addon is a concrete implementation of -the abstract model `fs.image.thumbnail.mixin`. The motivation to implement all the -logic in an abstract model is to allow developers to create their own thumbnail -models. This could be useful if you want to store the thumbnails in a different -storage since you can specify the storage to use by model on the `fs.storage` -form view. - -Creating / retrieving thumbnails is as simple as: - -.. code-block:: python - - from odoo.addons.fs_image.fields import FSImageValue - - # create an attachment with a image file - attachment = self.env['ir.attachment'].create({ - 'name': 'test', - 'datas': base64.b64encode(open('test.png', 'rb').read()), - 'datas_fname': 'test.png', - }) - - # create a FSImageValue instance for the attachment - image_value = FSImageValue(attachment) - - # get or create the thumbnails - thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( - image_value, [(800,600), (400, 200)], 'my base name') - - - -If you've a model with a *FSImage* field, the call to `get_or_create_thumbnails` -is even simpler: - -.. 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') - - my_record = cls.env['my.model'].create({ - 'image': open('test.png', 'rb'), - }) - - # get or create the thumbnails - thumbnails = record.image.get_or_create_thumbnails(my_record.image, - [(800,600), (400, 200)], 'my base name') From d3a231dea5b41fb222db75c93cfbb958140a0bb6 Mon Sep 17 00:00:00 2001 From: chien Date: Wed, 28 Feb 2024 15:27:05 +0700 Subject: [PATCH 13/17] [MIG] fs_image_thumbnail: Migration to 17.0 --- fs_image_thumbnail/README.rst | 4 +- fs_image_thumbnail/__manifest__.py | 2 +- .../i18n/fs_image_thumbnail.pot | 8 +- .../models/fs_image_thumbnail_mixin.py | 6 +- fs_image_thumbnail/readme/CONTEXT.md | 8 +- .../static/description/index.html | 84 ++++++++++--------- .../tests/test_fs_image_thumbnail.py | 3 +- fs_image_thumbnail/views/fs_thumbnail.xml | 2 +- 8 files changed, 59 insertions(+), 58 deletions(-) diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index 6381166810..41db42c20b 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -61,8 +61,8 @@ This module uses the `fs_image `__ module to store the thumbnails in a filesystem storage. -The `shopinvader_product_image -< <>`__\ https://github.com/shopinvader/odoo-shopinvader/\ `blob/16.0/shopinvader_product_image> <>`__ +The +`shopinvader_product_image `__ addon uses this module to generate and store the thumbnails of the images of the products and categories to be accessible by the website. diff --git a/fs_image_thumbnail/__manifest__.py b/fs_image_thumbnail/__manifest__.py index 6f0b67c173..983a4feb61 100644 --- a/fs_image_thumbnail/__manifest__.py +++ b/fs_image_thumbnail/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Image Thumbnail", "summary": """ Generate and store thumbnail for images""", - "version": "16.0.1.0.2", + "version": "17.0.1.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_image_thumbnail/i18n/fs_image_thumbnail.pot b/fs_image_thumbnail/i18n/fs_image_thumbnail.pot index 6c712d97e7..3ed95f232a 100644 --- a/fs_image_thumbnail/i18n/fs_image_thumbnail.pot +++ b/fs_image_thumbnail/i18n/fs_image_thumbnail.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" @@ -84,11 +84,6 @@ msgstr "" msgid "Image Thumbnail" msgstr "" -#. module: fs_image_thumbnail -#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update -msgid "Last Modified on" -msgstr "" - #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid msgid "Last Updated by" @@ -153,6 +148,7 @@ msgstr "" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_product_document__thumbnail_ids #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view msgid "Thumbnails" msgstr "" diff --git a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py index f4124b6a89..eac28b3b08 100644 --- a/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py +++ b/fs_image_thumbnail/models/fs_image_thumbnail_mixin.py @@ -102,7 +102,7 @@ def _get_resize_format(self, image: FSImage) -> str: return fmt or image.extension @api.model - def _prepare_tumbnail( + def _prepare_thumbnail( self, image: FSImage, size_x: int, size_y: int, base_name: str ) -> dict: """Prepare the values to create a thumbnail image from the given image. @@ -121,7 +121,7 @@ def _prepare_tumbnail( extension = "." + extension new_image = FSImageValue( value=self._resize(image, size_x, size_y, fmt), - name="%s_%s_%s%s" % (base_name, size_x, size_y, extension), + name=f"{base_name}_{size_x}_{size_y}{extension}", alt_text=image.alt_text, ) return { @@ -214,7 +214,7 @@ def get_or_create_thumbnails( for size_x, size_y in sizes: thumbnail = thumbnails_by_size.get((size_x, size_y)) if not thumbnail: - values = self._prepare_tumbnail(image, size_x, size_y, base_name) + values = self._prepare_thumbnail(image, size_x, size_y, base_name) # no creation possible outside of this method -> sudo() is # required since no access rights defined on create thumbnail = self.sudo().create(values) diff --git a/fs_image_thumbnail/readme/CONTEXT.md b/fs_image_thumbnail/readme/CONTEXT.md index 9e1fc8726f..3ffc22bee9 100644 --- a/fs_image_thumbnail/readme/CONTEXT.md +++ b/fs_image_thumbnail/readme/CONTEXT.md @@ -13,8 +13,6 @@ This module uses the [fs_image](https://github.com/oca/storage/blob/16.0/fs_image/README.rst) module to store the thumbnails in a filesystem storage. -The [shopinvader_product_image -\]() addon uses this module to -generate and store the thumbnails of the images of the products and -categories to be accessible by the website. +The [shopinvader_product_image](https://github.com/shopinvader/odoo-shopinvader/blob/16.0/shopinvader_product_image) addon uses this module to generate and store +the thumbnails of the images of the products and categories to be +accessible by the website. diff --git a/fs_image_thumbnail/static/description/index.html b/fs_image_thumbnail/static/description/index.html index f02ae6037d..cc3af6f013 100644 --- a/fs_image_thumbnail/static/description/index.html +++ b/fs_image_thumbnail/static/description/index.html @@ -368,11 +368,11 @@

    Fs Image Thumbnail

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:ae84af058fd490c7c8916156dc7db31813b6d5f7535e722740b152d6955e0d57 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

    -

    This module extends the fs_image addon to support the creation and the storage of -thumbnails for images. This module is a technical module and is not -meant to be installed by end-users. It only provides a mixin to be used -by other modules and a model to store the thumbnails.

    +

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

    +

    This module extends the fs_image addon to support the creation and +the storage of thumbnails for images. This module is a technical +module and is not meant to be installed by end-users. It only provides +a mixin to be used by other modules and a model to store the thumbnails.

    Important

    This is an alpha version, the data model and design can change at any time without warning. @@ -400,34 +400,38 @@

    Fs Image Thumbnail

    Use Cases / Context

    -

    In some specific cases you may need to generate and store thumbnails of images in Odoo. -This is the case for example when you want to provide image in specific sizes for a website -or a mobile application.

    -

    This module provides a generic way to generate thumbnails of images and store them in a -specific filesystem storage. Indeed, you could need to store the thumbnails in a different -storage than the original image (eg: store the thumbnails in a CDN) to make sure the -thumbnails are served quickly when requested by an external application and to -avoid to expose the original image storage.

    -

    This module uses the fs_image +

    In some specific cases you may need to generate and store thumbnails of +images in Odoo. This is the case for example when you want to provide +image in specific sizes for a website or a mobile application.

    +

    This module provides a generic way to generate thumbnails of images and +store them in a specific filesystem storage. Indeed, you could need to +store the thumbnails in a different storage than the original image (eg: +store the thumbnails in a CDN) to make sure the thumbnails are served +quickly when requested by an external application and to avoid to expose +the original image storage.

    +

    This module uses the +fs_image module to store the thumbnails in a filesystem storage.

    -

    The shopinvader_product_image addon uses this module to generate and -store the thumbnails of the images of the products and categories to be accessible -by the website.

    +

    The +shopinvader_product_image +addon uses this module to generate and store the thumbnails of the +images of the products and categories to be accessible by the website.

    Usage

    -

    This addon provides a convenient way to get and create if not exists image -thumbnails. All the logic is implemented by the abstract model -fs.image.thumbnail.mixin. The main method is get_or_create_thumbnails which -accepts a FSImageValue instance, a list of thumbnail sizes and a base name.

    -

    When the method is called, it will check if the thumbnail exists for the given -sizes and base name. If not, it will create it.

    -

    The fs.thumbnail model provided by this addon is a concrete implementation of -the abstract model fs.image.thumbnail.mixin. The motivation to implement all the -logic in an abstract model is to allow developers to create their own thumbnail -models. This could be useful if you want to store the thumbnails in a different -storage since you can specify the storage to use by model on the fs.storage -form view.

    +

    This addon provides a convenient way to get and create if not exists +image thumbnails. All the logic is implemented by the abstract model +fs.image.thumbnail.mixin. The main method is get_or_create_thumbnails +which accepts a FSImageValue instance, a list of thumbnail sizes and a +base name.

    +

    When the method is called, it will check if the thumbnail exists for the +given sizes and base name. If not, it will create it.

    +

    The fs.thumbnail model provided by this addon is a concrete +implementation of the abstract model fs.image.thumbnail.mixin. The +motivation to implement all the logic in an abstract model is to allow +developers to create their own thumbnail models. This could be useful if +you want to store the thumbnails in a different storage since you can +specify the storage to use by model on the fs.storage form view.

    Creating / retrieving thumbnails is as simple as:

     from odoo.addons.fs_image.fields import FSImageValue
    @@ -446,8 +450,8 @@ 

    Usage

    thumbnails = self.env['fs.thumbnail'].get_or_create_thumbnails( image_value, [(800,600), (400, 200)], 'my base name')
    -

    If you’ve a model with a FSImage field, the call to get_or_create_thumbnails -is even simpler:

    +

    If you’ve a model with a FSImage field, the call to +get_or_create_thumbnails is even simpler:

     from odoo import models
     from odoo.addons.fs_image.fields import FSImage
    @@ -472,12 +476,14 @@ 

    Changelog

    16.0.1.0.1 (2023-10-04)

    Bugfixes

      -
    • The call to the method get_or_create_thumbnails on the fs.image.thumbnail.mixin -class returns now an ordered dictionary where the key is the original image and -the value is a recordset of thumbnail images. The order of the dict is the order -of the images passed to the method. This ensures that when you process the result -of the method you can be sure that the order of the images is the same as the -order of the images passed to the method. (#282)
    • +
    • The call to the method get_or_create_thumbnails on the +fs.image.thumbnail.mixin class returns now an ordered dictionary +where the key is the original image and the value is a recordset of +thumbnail images. The order of the dict is the order of the images +passed to the method. This ensures that when you process the result +of the method you can be sure that the order of the images is the +same as the order of the images passed to the method. +(#282)
    @@ -486,7 +492,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.

    @@ -519,7 +525,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_thumbnail/tests/test_fs_image_thumbnail.py b/fs_image_thumbnail/tests/test_fs_image_thumbnail.py index 3caa4b5265..1f425f1059 100644 --- a/fs_image_thumbnail/tests/test_fs_image_thumbnail.py +++ b/fs_image_thumbnail/tests/test_fs_image_thumbnail.py @@ -63,7 +63,8 @@ def test_create_multi(self): self.assertEqual(self.image_attachment.thumbnail_ids, thumbnails) - # if we call the method again for the same size, we should get the same thumbnail + # if we call the method again for the same size, we should get the same + # thumbnail new_thumbnails = self.fs_thumbnail_model.get_or_create_thumbnails( self.fs_image_value, sizes=[(16, 16), (8, 8)], base_name="My super test" )[self.fs_image_value] diff --git a/fs_image_thumbnail/views/fs_thumbnail.xml b/fs_image_thumbnail/views/fs_thumbnail.xml index 9de1fd6cf4..c6b8c1d3d3 100644 --- a/fs_image_thumbnail/views/fs_thumbnail.xml +++ b/fs_image_thumbnail/views/fs_thumbnail.xml @@ -40,7 +40,7 @@ defined for the mixin --> - + From 24d017ed5acdf2eada11eb8670652d42345eaae8 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 31 May 2024 07:20:55 +0000 Subject: [PATCH 14/17] [BOT] post-merge updates --- fs_image_thumbnail/README.rst | 2 +- fs_image_thumbnail/i18n/es.po | 16 ++++++++------- fs_image_thumbnail/i18n/it.po | 20 ++++++++++--------- .../static/description/index.html | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/fs_image_thumbnail/README.rst b/fs_image_thumbnail/README.rst index 41db42c20b..8ccce0e025 100644 --- a/fs_image_thumbnail/README.rst +++ b/fs_image_thumbnail/README.rst @@ -7,7 +7,7 @@ Fs Image Thumbnail !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ae84af058fd490c7c8916156dc7db31813b6d5f7535e722740b152d6955e0d57 + !! source digest: sha256:1d1af8339aa4aee943dad48c165b12fca74f0dd16f574469fb90c58c8c073a47 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png diff --git a/fs_image_thumbnail/i18n/es.po b/fs_image_thumbnail/i18n/es.po index bad8caae96..fe8e152507 100644 --- a/fs_image_thumbnail/i18n/es.po +++ b/fs_image_thumbnail/i18n/es.po @@ -87,11 +87,6 @@ msgstr "Imagen" msgid "Image Thumbnail" msgstr "Imagen en Miniatura" -#. module: fs_image_thumbnail -#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update -msgid "Last Modified on" -msgstr "Última Modificación el" - #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid msgid "Last Updated by" @@ -150,8 +145,11 @@ msgstr "La imagen %(name)s debe adjuntarse a un archivo adjunto" #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__base_name msgid "" -"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" -"If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." +"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . " +"+ extension.\n" +"If not set, the base name will be the name of the original image.This base " +"name is used to find all existing thumbnail of an image generated for the " +"same base name." msgstr "" "La imagen en miniatura se denominará como nombre_base + _ + tamaño_x + _ + " "tamaño_y + . + extensión.\n" @@ -161,6 +159,7 @@ msgstr "" #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_product_document__thumbnail_ids #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view msgid "Thumbnails" msgstr "Miniaturas" @@ -176,3 +175,6 @@ msgstr "Tamaño X" #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y msgid "Y size" msgstr "Talla Y" + +#~ msgid "Last Modified on" +#~ msgstr "Última Modificación el" diff --git a/fs_image_thumbnail/i18n/it.po b/fs_image_thumbnail/i18n/it.po index b03afa19b2..267c55e745 100644 --- a/fs_image_thumbnail/i18n/it.po +++ b/fs_image_thumbnail/i18n/it.po @@ -87,11 +87,6 @@ msgstr "Immagine" msgid "Image Thumbnail" msgstr "Anteprima immagine" -#. module: fs_image_thumbnail -#: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" - #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__write_uid msgid "Last Updated by" @@ -150,17 +145,21 @@ msgstr "L'immagine %(name)s deve essere collegata ad una allegato" #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_image_thumbnail_mixin__base_name #: model:ir.model.fields,help:fs_image_thumbnail.field_fs_thumbnail__base_name msgid "" -"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . + extension.\n" -"If not set, the base name will be the name of the original image.This base name is used to find all existing thumbnail of an image generated for the same base name." +"The thumbnail image will be named as base_name + _ + size_x + _ + size_y + . " +"+ extension.\n" +"If not set, the base name will be the name of the original image.This base " +"name is used to find all existing thumbnail of an image generated for the " +"same base name." msgstr "" -"L'immagine anteprima verrà denominata come " -"nome_bae+_+dimensione_x+dimensione_y+.+estensione.\n" +"L'immagine anteprima verrà denominata come nome_bae+_+dimensione_x" +"+dimensione_y+.+estensione.\n" "Se non impostato, il nome base sarà il nome dell'immagine originale. Questo " "nome base è utilizzato per trovare tutte le anteprime di una immagine " "generate per lo stesso nome base." #. module: fs_image_thumbnail #: model:ir.model.fields,field_description:fs_image_thumbnail.field_ir_attachment__thumbnail_ids +#: model:ir.model.fields,field_description:fs_image_thumbnail.field_product_document__thumbnail_ids #: model_terms:ir.ui.view,arch_db:fs_image_thumbnail.ir_attachment_form_view msgid "Thumbnails" msgstr "Anteprime" @@ -176,3 +175,6 @@ msgstr "Dimensione X" #: model:ir.model.fields,field_description:fs_image_thumbnail.field_fs_thumbnail__size_y msgid "Y size" msgstr "Dimensione Y" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/fs_image_thumbnail/static/description/index.html b/fs_image_thumbnail/static/description/index.html index cc3af6f013..77ae54b004 100644 --- a/fs_image_thumbnail/static/description/index.html +++ b/fs_image_thumbnail/static/description/index.html @@ -366,7 +366,7 @@

    Fs Image Thumbnail

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ae84af058fd490c7c8916156dc7db31813b6d5f7535e722740b152d6955e0d57 +!! source digest: sha256:1d1af8339aa4aee943dad48c165b12fca74f0dd16f574469fb90c58c8c073a47 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

    This module extends the fs_image addon to support the creation and From 63df4c2515fed4db4e53564c5a35f2706702a92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duy=20=28=C4=90=E1=BB=97=20Anh=29?= Date: Thu, 17 Apr 2025 15:43:40 +0700 Subject: [PATCH 15/17] [IMP] fs_image_thumbnail: pre-commit auto fixes --- fs_image_thumbnail/security/fs_thumbnail.xml | 2 -- fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml | 8 +++----- fs_image_thumbnail/views/fs_thumbnail.xml | 4 +--- fs_image_thumbnail/views/ir_attachment.xml | 2 -- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/fs_image_thumbnail/security/fs_thumbnail.xml b/fs_image_thumbnail/security/fs_thumbnail.xml index 7690d990f4..dc10b5852f 100644 --- a/fs_image_thumbnail/security/fs_thumbnail.xml +++ b/fs_image_thumbnail/security/fs_thumbnail.xml @@ -2,7 +2,6 @@ - fs.thumbnail access read @@ -12,5 +11,4 @@ - diff --git a/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml b/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml index 8dfac21a0f..09a23518f5 100644 --- a/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml +++ b/fs_image_thumbnail/views/fs_image_thumbnail_mixin.xml @@ -2,14 +2,12 @@ - fs.image.thumbnail.mixin.form (in fs_image_thumbnail) fs.image.thumbnail.mixin

    -
    -
    +