diff --git a/README.md b/README.md index 662f1868aa0..27fced4e853 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,11 @@ Available addons ---------------- addon | version | maintainers | summary --- | --- | --- | --- +[attachment_logging](attachment_logging/) | 17.0.1.0.0 | | Show attachment information in chatter [attachment_queue](attachment_queue/) | 17.0.1.0.0 | florian-dacosta sebastienbeau | Base module adding the concept of queue for processing files [auditlog](auditlog/) | 17.0.1.1.0 | | Audit Log [auto_backup](auto_backup/) | 17.0.1.1.0 | | Backups database +[auto_backup_fs_file](auto_backup_fs_file/) | 17.0.1.0.0 | | Store backups using some FSSPEC implementation [base_cron_exclusion](base_cron_exclusion/) | 17.0.1.0.0 | LoisRForgeFlow ChrisOForgeFlow | Allow you to select scheduled actions that should not run simultaneously. [base_exception](base_exception/) | 17.0.1.1.0 | hparfr sebastienbeau | This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...) [base_fontawesome](base_fontawesome/) | 17.0.1.1.0 | | Up to date Fontawesome resources. diff --git a/attachment_logging/README.rst b/attachment_logging/README.rst new file mode 100644 index 00000000000..28348613344 --- /dev/null +++ b/attachment_logging/README.rst @@ -0,0 +1,113 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================== +Attachment Logging +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:61878ebe5df7c1dfd773c842b660cb795baa2d5ab9363557168a8c54ebd47d29 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/17.0/attachment_logging + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-17-0/server-tools-17-0-attachment_logging + :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/server-tools&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module shows attachment information in chatter. Following data is +displayed: + +- User, who has created the attachment +- Attachment creation date + +It also allows to log attachment related actions in the record chatter. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To enable note logging of attachment operations in record chatter: + +- Go to "Settings > General Settings" and scroll to the "Discuss" + section. +- Activate the "Attachment Logging" checkbox. + +|image| + +.. |image| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/attachment_logging/static/src/img/settings.png + +Usage +===== + +Create date and user are displayed next to attachments in chatter. When +attachment is added or removed a note is logged in chatter if the +corresponding option is enabled in the General Settings. + +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 +------- + +* Cetmix + +Contributors +------------ + +- Cetmix + + - Ivan Sokolov + - Maksim Shurupov + +- Binhex <`www.binhex.com\\> >`__ + + - Adasat Torres de León a.torres@binhex.cloud + +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. + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_logging/__init__.py b/attachment_logging/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/attachment_logging/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/attachment_logging/__manifest__.py b/attachment_logging/__manifest__.py new file mode 100644 index 00000000000..a4f4874b286 --- /dev/null +++ b/attachment_logging/__manifest__.py @@ -0,0 +1,19 @@ +{ + "name": "Attachment Logging", + "version": "17.0.1.0.0", + "author": "Cetmix, Odoo Community Association (OCA)", + "summary": "Show attachment information in chatter", + "website": "https://github.com/OCA/server-tools", + "license": "AGPL-3", + "category": "Hidden/Tools", + "depends": ["mail"], + "data": [ + "data/mail_message_subtype_data.xml", + "views/res_config_settings_views.xml", + ], + "assets": { + "web.assets_backend": [ + "attachment_logging/static/src/**/*", + ] + }, +} diff --git a/attachment_logging/data/mail_message_subtype_data.xml b/attachment_logging/data/mail_message_subtype_data.xml new file mode 100644 index 00000000000..36b3ef688c4 --- /dev/null +++ b/attachment_logging/data/mail_message_subtype_data.xml @@ -0,0 +1,11 @@ + + + + + Attachments + + + + + + diff --git a/attachment_logging/i18n/attachment_logging.pot b/attachment_logging/i18n/attachment_logging.pot new file mode 100644 index 00000000000..fa121c6ea2f --- /dev/null +++ b/attachment_logging/i18n/attachment_logging.pot @@ -0,0 +1,76 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_logging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "%(username)s %(action)s a file: %(filename)s" +msgstr "" + +#. module: attachment_logging +#: model:ir.model,name:attachment_logging.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: attachment_logging +#: model_terms:ir.ui.view,arch_db:attachment_logging.res_config_settings_form_view +msgid "Attachment Logging" +msgstr "" + +#. module: attachment_logging +#: model:mail.message.subtype,name:attachment_logging.mt_attachment +msgid "Attachments" +msgstr "" + +#. module: attachment_logging +#: model:ir.model,name:attachment_logging.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: attachment_logging +#: model_terms:ir.ui.view,arch_db:attachment_logging.res_config_settings_form_view +msgid "Log a note in record chatter when an attachment is added or removed." +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,help:attachment_logging.field_res_config_settings__use_attachment_log +msgid "Log attachment operations in chatter" +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,field_description:attachment_logging.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_logging.field_res_config_settings__smart_search +msgid "Smart Search" +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,field_description:attachment_logging.field_res_config_settings__use_attachment_log +msgid "Use Attachment Log" +msgstr "" + +#. module: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "attached" +msgstr "" + +#. module: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "unlinked" +msgstr "" diff --git a/attachment_logging/i18n/it.po b/attachment_logging/i18n/it.po new file mode 100644 index 00000000000..cadda644d9c --- /dev/null +++ b/attachment_logging/i18n/it.po @@ -0,0 +1,77 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_logging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "%(username)s %(action)s a file: %(filename)s" +msgstr "" + +#. module: attachment_logging +#: model:ir.model,name:attachment_logging.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: attachment_logging +#: model_terms:ir.ui.view,arch_db:attachment_logging.res_config_settings_form_view +msgid "Attachment Logging" +msgstr "" + +#. module: attachment_logging +#: model:mail.message.subtype,name:attachment_logging.mt_attachment +msgid "Attachments" +msgstr "" + +#. module: attachment_logging +#: model:ir.model,name:attachment_logging.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: attachment_logging +#: model_terms:ir.ui.view,arch_db:attachment_logging.res_config_settings_form_view +msgid "Log a note in record chatter when an attachment is added or removed." +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,help:attachment_logging.field_res_config_settings__use_attachment_log +msgid "Log attachment operations in chatter" +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,field_description:attachment_logging.field_ir_attachment__smart_search +#: model:ir.model.fields,field_description:attachment_logging.field_res_config_settings__smart_search +msgid "Smart Search" +msgstr "" + +#. module: attachment_logging +#: model:ir.model.fields,field_description:attachment_logging.field_res_config_settings__use_attachment_log +msgid "Use Attachment Log" +msgstr "" + +#. module: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "attached" +msgstr "" + +#. module: attachment_logging +#. odoo-python +#: code:addons/attachment_logging/models/ir_attachment.py:0 +#, python-format +msgid "unlinked" +msgstr "" diff --git a/attachment_logging/models/__init__.py b/attachment_logging/models/__init__.py new file mode 100644 index 00000000000..075fb0e6284 --- /dev/null +++ b/attachment_logging/models/__init__.py @@ -0,0 +1,2 @@ +from . import ir_attachment +from . import res_config_settings diff --git a/attachment_logging/models/ir_attachment.py b/attachment_logging/models/ir_attachment.py new file mode 100644 index 00000000000..4388f9a82f0 --- /dev/null +++ b/attachment_logging/models/ir_attachment.py @@ -0,0 +1,76 @@ +from odoo import _, api, models +from odoo.tools.misc import format_datetime + + +class IrAttachment(models.Model): + _inherit = "ir.attachment" + + def _send_attachment_notification(self, is_create=False, is_unlink=False): + """ + Send attachment notification + + :param is_create: send notification for create method + :param is_unlink: send notification for unlink method + """ + if is_create: + action = _("attached") + elif is_unlink: + action = _("unlinked") + else: + return + record = self.env[self.res_model].sudo().browse(self.res_id) + message_text = _( + "%(username)s %(action)s a file: %(filename)s", + username=self.create_uid.name, + filename=self.name, + action=action, + ) + record.message_post( + body=message_text, + message_type="notification", + author_id=self.env.ref("base.user_root").partner_id.id, + subtype_xmlid="attachment_logging.mt_attachment", + ) + + @api.model + def _is_use_attachment_log(self): + """Check use attachment log""" + return ( + self.env["ir.config_parameter"] + .sudo() + .get_param("attachment_logging.use_attachment_log", False) + ) + + def _post_add_create(self, **kwargs): + result = super()._post_add_create(**kwargs) + if self._is_use_attachment_log(): + # Send notification after creation attachments + for attachment in self: + if self.pool and issubclass( + self.pool[attachment.res_model], self.pool["mail.thread"] + ): + attachment._send_attachment_notification(is_create=True) + return result + + def _delete_and_notify(self, message=None): + if self._is_use_attachment_log(): + for attachment in self: + if self.pool and issubclass( + self.pool[attachment.res_model], self.pool["mail.thread"] + ): + attachment._send_attachment_notification(is_unlink=True) + return super()._delete_and_notify(message) + + def _attachment_format(self): + attachment_vals = super()._attachment_format() + for attachment_val in attachment_vals: + attachment = self.browse(attachment_val["id"]) + attachment_val.update( + { + "create_user": attachment.create_uid.name, + "create_date": format_datetime( + self.env, attachment_val["create_date"] + ), + } + ) + return attachment_vals diff --git a/attachment_logging/models/res_config_settings.py b/attachment_logging/models/res_config_settings.py new file mode 100644 index 00000000000..d553ebce731 --- /dev/null +++ b/attachment_logging/models/res_config_settings.py @@ -0,0 +1,10 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + use_attachment_log = fields.Boolean( + config_parameter="attachment_logging.use_attachment_log", + help="Log attachment operations in chatter", + ) diff --git a/attachment_logging/pyproject.toml b/attachment_logging/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/attachment_logging/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/attachment_logging/readme/CONFIGURE.md b/attachment_logging/readme/CONFIGURE.md new file mode 100644 index 00000000000..7344c19d05b --- /dev/null +++ b/attachment_logging/readme/CONFIGURE.md @@ -0,0 +1,7 @@ +To enable note logging of attachment operations in record chatter: + +- Go to "Settings \> General Settings" and scroll to the "Discuss" + section. +- Activate the "Attachment Logging" checkbox. + +![image](../static/src/img/settings.png) diff --git a/attachment_logging/readme/CONTRIBUTORS.md b/attachment_logging/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..c55f2162889 --- /dev/null +++ b/attachment_logging/readme/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +- Cetmix \ + - Ivan Sokolov + - Maksim Shurupov +- Binhex \ + - Adasat Torres de León + diff --git a/attachment_logging/readme/DESCRIPTION.md b/attachment_logging/readme/DESCRIPTION.md new file mode 100644 index 00000000000..8a61fbe31d7 --- /dev/null +++ b/attachment_logging/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +This module shows attachment information in chatter. Following data is +displayed: + +- User, who has created the attachment +- Attachment creation date + +It also allows to log attachment related actions in the record chatter. diff --git a/attachment_logging/readme/USAGE.md b/attachment_logging/readme/USAGE.md new file mode 100644 index 00000000000..46f1aaa842c --- /dev/null +++ b/attachment_logging/readme/USAGE.md @@ -0,0 +1,3 @@ +Create date and user are displayed next to attachments in chatter. When +attachment is added or removed a note is logged in chatter if the +corresponding option is enabled in the General Settings. diff --git a/attachment_logging/static/description/icon.png b/attachment_logging/static/description/icon.png new file mode 100644 index 00000000000..1dcc49c24f3 Binary files /dev/null and b/attachment_logging/static/description/icon.png differ diff --git a/attachment_logging/static/description/index.html b/attachment_logging/static/description/index.html new file mode 100644 index 00000000000..f1c6cd688f5 --- /dev/null +++ b/attachment_logging/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Attachment Logging

+ +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

This module shows attachment information in chatter. Following data is +displayed:

+
    +
  • User, who has created the attachment
  • +
  • Attachment creation date
  • +
+

It also allows to log attachment related actions in the record chatter.

+

Table of contents

+ +
+

Configuration

+

To enable note logging of attachment operations in record chatter:

+
    +
  • Go to “Settings > General Settings” and scroll to the “Discuss” +section.
  • +
  • Activate the “Attachment Logging” checkbox.
  • +
+

image

+
+
+

Usage

+

Create date and user are displayed next to attachments in chatter. When +attachment is added or removed a note is logged in chatter if the +corresponding option is enabled in the General Settings.

+
+
+

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

+
    +
  • Cetmix
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

This module is part of the OCA/server-tools project on GitHub.

+

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

+
+
+
+
+ + diff --git a/attachment_logging/static/src/core/common/attachment_list.xml b/attachment_logging/static/src/core/common/attachment_list.xml new file mode 100644 index 00000000000..8a751849ebe --- /dev/null +++ b/attachment_logging/static/src/core/common/attachment_list.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+ + +
+
+
+
diff --git a/attachment_logging/static/src/img/settings.png b/attachment_logging/static/src/img/settings.png new file mode 100644 index 00000000000..f9e981d3f14 Binary files /dev/null and b/attachment_logging/static/src/img/settings.png differ diff --git a/attachment_logging/tests/__init__.py b/attachment_logging/tests/__init__.py new file mode 100644 index 00000000000..77aea02d82f --- /dev/null +++ b/attachment_logging/tests/__init__.py @@ -0,0 +1 @@ +from . import test_ir_attachments diff --git a/attachment_logging/tests/test_ir_attachments.py b/attachment_logging/tests/test_ir_attachments.py new file mode 100644 index 00000000000..00352518376 --- /dev/null +++ b/attachment_logging/tests/test_ir_attachments.py @@ -0,0 +1,80 @@ +import base64 +import logging + +from odoo.tests import tagged +from odoo.tools.misc import format_datetime + +from odoo.addons.base.tests.common import TransactionCase + +_logger = logging.getLogger(__name__) + + +@tagged("-at_install", "post_install") +class TestIrAttachments(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env["res.partner"].create({"name": "Test Partner #1"}) + + @classmethod + def _create_attachment(cls): + file_content = "Hi, this files is for tests." + file_data = base64.b64encode(file_content.encode("utf-8")) + return cls.env["ir.attachment"].create( + { + "name": "tst_file.txt", + "datas": file_data, + "res_model": cls.partner._name, + "res_id": cls.partner.id, + "mimetype": "text/plain", + } + ) + + def test01_attachment_format(self): + attachment = self._create_attachment() + result = attachment._attachment_format() + self.assertTrue(result) + self.assertEqual(result[0]["create_user"], attachment.create_uid.name) + self.assertEqual( + result[0]["create_date"], + format_datetime(self.env, attachment.create_date), + ) + + def test02_post_add_create(self): + attachment = self._create_attachment() + self.env["ir.config_parameter"].sudo().set_param( + "attachment_logging.use_attachment_log", False + ) + self.partner.message_ids = [ + ( + 5, + 0, + ) + ] + attachment._post_add_create() + self.assertEqual(len(self.partner.message_ids), 0) + self.env["ir.config_parameter"].sudo().set_param( + "attachment_logging.use_attachment_log", True + ) + attachment._post_add_create() + self.assertEqual(len(self.partner.message_ids), 1) + + def test03_delete_and_notify(self): + self.env["ir.config_parameter"].sudo().set_param( + "attachment_logging.use_attachment_log", False + ) + self.partner.message_ids = [ + ( + 5, + 0, + ) + ] + attachment = self._create_attachment() + attachment._delete_and_notify() + self.assertEqual(len(self.partner.message_ids), 0) + self.env["ir.config_parameter"].sudo().set_param( + "attachment_logging.use_attachment_log", True + ) + attachment = self._create_attachment() + attachment._delete_and_notify() + self.assertEqual(len(self.partner.message_ids), 1) diff --git a/attachment_logging/views/res_config_settings_views.xml b/attachment_logging/views/res_config_settings_views.xml new file mode 100644 index 00000000000..2422dc5fa59 --- /dev/null +++ b/attachment_logging/views/res_config_settings_views.xml @@ -0,0 +1,21 @@ + + + + res.config.settings.form.view.inherited.attachment_logging + res.config.settings + + + + + + + + + + diff --git a/attachment_queue/i18n/attachment_queue.pot b/attachment_queue/i18n/attachment_queue.pot index 696a7866334..a4bb2e4ab98 100644 --- a/attachment_queue/i18n/attachment_queue.pot +++ b/attachment_queue/i18n/attachment_queue.pot @@ -188,6 +188,11 @@ msgstr "" msgid "File Content (raw)" msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_filename +msgid "File Name into the filesystem storage" +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__file_size msgid "File Size" @@ -203,6 +208,26 @@ msgstr "" msgid "File type" msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_storage_id +msgid "Filesystem Storage" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_storage_code +msgid "Filesystem Storage Code" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_url +msgid "Filesystem URL" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_url_path +msgid "Filesystem URL Path" +msgstr "" + #. module: attachment_queue #: model_terms:ir.ui.view,arch_db:attachment_queue.view_attachment_queue_search msgid "Filter on my documents" @@ -280,6 +305,11 @@ msgstr "" msgid "Indexed Content" msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__internal_url +msgid "Internal URL" +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__message_is_follower msgid "Is Follower" @@ -475,6 +505,26 @@ msgstr "" msgid "Stored Filename" msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_storage_code +msgid "" +"Technical code used to identify the storage backend into the code.This code " +"must be unique. This code is used for example to define the storage backend " +"to store the attachments via the configuration parameter " +"'ir_attachment.storage.force.database' when the module 'fs_attachment' is " +"installed." +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_url +msgid "The URL to access the file from the filesystem storage." +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__internal_url +msgid "The URL to access the file from the server." +msgstr "" + #. module: attachment_queue #: model:mail.template,subject:attachment_queue.attachment_failure_notification msgid "The attachment {{object.name}} has failed" @@ -487,11 +537,29 @@ msgid "" "data before their import in ERP or an export" msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_filename +msgid "" +"The name of the file in the filesystem storage.To preserve the mimetype and " +"the meaning of the filenamethe filename is computed from the name and the " +"extension" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_url_path +msgid "The path to access the file from the filesystem storage." +msgstr "" + #. module: attachment_queue #: model_terms:ir.ui.view,arch_db:attachment_queue.view_reschedule_attachment msgid "The selected attachments will be rescheduled." msgstr "" +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_storage_id +msgid "The storage where the file is stored." +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__type #: model_terms:ir.ui.view,arch_db:attachment_queue.view_attachment_queue_search diff --git a/attachment_queue/i18n/es.po b/attachment_queue/i18n/es.po index 7f0ec1845f4..85886513dde 100644 --- a/attachment_queue/i18n/es.po +++ b/attachment_queue/i18n/es.po @@ -216,6 +216,11 @@ msgstr "Contenido del Archivo (base64)" msgid "File Content (raw)" msgstr "Contenido del Archivo (sin procesar)" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_filename +msgid "File Name into the filesystem storage" +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__file_size msgid "File Size" @@ -231,6 +236,26 @@ msgstr "Tipo de Archivo" msgid "File type" msgstr "Tipo de archivo" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_storage_id +msgid "Filesystem Storage" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_storage_code +msgid "Filesystem Storage Code" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_url +msgid "Filesystem URL" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__fs_url_path +msgid "Filesystem URL Path" +msgstr "" + #. module: attachment_queue #: model_terms:ir.ui.view,arch_db:attachment_queue.view_attachment_queue_search msgid "Filter on my documents" @@ -308,6 +333,11 @@ msgstr "Anchura de la Imagen" msgid "Indexed Content" msgstr "Contenido Indexado" +#. module: attachment_queue +#: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__internal_url +msgid "Internal URL" +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__message_is_follower msgid "Is Follower" @@ -507,6 +537,26 @@ msgstr "" msgid "Stored Filename" msgstr "Nombre del Archivo Almacenado" +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_storage_code +msgid "" +"Technical code used to identify the storage backend into the code.This code " +"must be unique. This code is used for example to define the storage backend " +"to store the attachments via the configuration parameter " +"'ir_attachment.storage.force.database' when the module 'fs_attachment' is " +"installed." +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_url +msgid "The URL to access the file from the filesystem storage." +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__internal_url +msgid "The URL to access the file from the server." +msgstr "" + #. module: attachment_queue #: model:mail.template,subject:attachment_queue.attachment_failure_notification msgid "The attachment {{object.name}} has failed" @@ -521,11 +571,29 @@ msgstr "" "El tipo de archivo determina el método de importación que se utilizará para " "analizar y transformar los datos antes de importarlos al ERP o exportarlos" +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_filename +msgid "" +"The name of the file in the filesystem storage.To preserve the mimetype and " +"the meaning of the filenamethe filename is computed from the name and the " +"extension" +msgstr "" + +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_url_path +msgid "The path to access the file from the filesystem storage." +msgstr "" + #. module: attachment_queue #: model_terms:ir.ui.view,arch_db:attachment_queue.view_reschedule_attachment msgid "The selected attachments will be rescheduled." msgstr "Los anexos seleccionados se reprogramarán." +#. module: attachment_queue +#: model:ir.model.fields,help:attachment_queue.field_attachment_queue__fs_storage_id +msgid "The storage where the file is stored." +msgstr "" + #. module: attachment_queue #: model:ir.model.fields,field_description:attachment_queue.field_attachment_queue__type #: model_terms:ir.ui.view,arch_db:attachment_queue.view_attachment_queue_search diff --git a/attachment_queue/i18n/it.po b/attachment_queue/i18n/it.po index 7651e5bcd56..89fb94d7592 100644 --- a/attachment_queue/i18n/it.po +++ b/attachment_queue/i18n/it.po @@ -40,8 +40,8 @@ msgstr "" "\">Salce,

\n" "

l'allegato ${object.name} ha un errore con il segente messaggio : " -"
${object.state_message}

l'allegato ${object.name} ha un errore con il segente messaggio :
$" +"{object.state_message}

\n" "

`_ + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +BUSINESS NEED: This module addresses the critical need for safeguarding +Odoo instance data by enabling automated backups to a filesystem +supported by the ``fsspec`` library. Businesses often require reliable +and accessible backup solutions to ensure data integrity and recovery in +case of system failures or data loss. This module is particularly useful +in contexts where organizations need to store backups on cloud storage, +network drives, or other custom filesystems supported by ``fsspec``. + +Practical examples include: + +- Backing up Odoo data to cloud storage providers like AWS S3, Google + Cloud Storage, or Azure Blob Storage. +- Storing backups on a secure local or remote filesystem for disaster + recovery purposes. +- Automating backup processes in multi-environment setups, such as + multi-company or multi-website configurations. + +APPROACH: The module extends the backup functionality from the +``auto_backup`` module by introducing a method that allows storing the +resulting backup using an ``fsspec`` implementation. This is achieved +through the integration of the ``fs_file`` from `storage +repository `__. The module leverages the +``fsspec`` library to provide a flexible and extensible interface for +interacting with various filesystems. It automates the backup process by +exporting Odoo instance data and storing it in the specified filesystem. +Additionally, it allows users to download the backups for local storage +or further processing. + +USEFUL INFORMATION: + +- **Dependencies**: This module depends on the ``fsspec`` library, its + relevant filesystem implementations, and the ``fs_file`` addon from + OCA/storage. Ensure the required ``fsspec`` plugins are installed for + your target filesystem. + +Installation +============ + +This addon itself does not introduce any dependencies, but its +dependencies may require additional packages.:wa + +Configuration +============= + +1. **Review Documentation for Dependencies** Before configuring the + module, ensure you have reviewed the documentation for the following + modules: + +- ``fs_attachment`` +- ``fs_storage`` These modules provide the necessary setup for file + storage and attachment handling. + +2. **Configure File Storage** + +- Navigate to **Settings** > **Technical** > **FS Storage**. +- Create or select an existing storage configuration. +- Ensure the storage is properly set up and tested for accessibility. + +3. **Link Backup File field to Storage** + +- While configuring the file storage in **Settings** > **Technical** > + **FS Storage**, ensure that the ``backup_file`` from the + ``db.backup.fs.file`` model is listed under the ``Field`` field. +- This step is part of the storage configuration process. +- Save the changes after verifying the setup. + +|Example of File Storage Configuration| + +4. **Verify Configuration** + +- Perform a test backup to ensure the files are being stored in the + correct location. +- Check the logs for any errors or warnings. + +By following these steps, you will ensure that the module is properly +configured for storing backups in the desired file storage system. + +.. |Example of File Storage Configuration| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/auto_backup_fs_file/images/file_storage_configuration.png + +Usage +===== + +This module extends the functionality of the database backup system in +Odoo by introducing a new backup method: **Fs File**. This method allows +storing database backups as files using an FSSPEC implementation. + +How to Use the Module +--------------------- + +1. Configure the Backup Method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Navigate to **Settings** > **Technical** > **Database Structure** > + **Automated Backups**. +2. Create or edit a backup configuration. +3. In the **Backup Method** field, select **Fs File**. +4. Configure other fields as needed, such as the backup format and + retention settings. +5. Save the configuration. + +2. Perform a Backup +~~~~~~~~~~~~~~~~~~~ + +1. From the list of backup configurations, select the one configured + with the **Fs File** method. +2. Click the **Backup Now** button to initiate the backup process. +3. The backup will be stored as a file in the configured FSSPEC storage. + +3. View Fs File Backups +~~~~~~~~~~~~~~~~~~~~~~~ + +1. Open the backup configuration form view. +2. In the top-right corner, you will see a **Backups** stat button (if + backups exist). +3. Click the **Backups** button to view the list of Fs File backups + associated with the configuration. + +4. Manage Fs File Backups +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- In the Fs File backups list view, you can see details such as the + backup filename and associated database backup configuration. +- Use this view to manage or download backups as needed. + +Screenshots +~~~~~~~~~~~ + +- **Backup Configuration Form View** |Backup Configuration Form| + +- **Fs File Backups List View** |Fs File Backups List| + +Notes +~~~~~ + +- Ensure that the FSSPEC storage is properly configured before using the + **Fs File** method. +- This module adds a new stat button in the backup configuration form + view to quickly access Fs File backups. + +.. |Backup Configuration Form| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/auto_backup_fs_file/static/description/db_backup_form_view.png +.. |Fs File Backups List| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/auto_backup_fs_file/static/description/db_backup_fs_file_tree_view.png + +Known issues / Roadmap +====================== + +- **Folder field behavior**: The ``folder`` field on the ``db.backup`` + model specifies the backup storage directory. For records using the + ``fs_file`` method, storage is actually controlled by the ``fs_file`` + field's settings. However, since ``folder`` is currently a required + non-computed field in the ``auto_backup`` addon, modifications to sync + these two fields are not performed. Future versions may add this + synchronization support. + +- **Design limitation**: The current implementation has a design + constraint due to ``fs_storage`` addon limitations. Since storage + setting targets the ``db.backup.fs.file`` model, only one storage + backend can effectively be used. + +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 +------- + +* Binhex + +Contributors +------------ + +- Rolando Pérez Rebollo r.perez@binhex.cloud + +Other credits +------------- + +The development of this module has been financially supported by: + +- Binhex + +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. + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/auto_backup_fs_file/__init__.py b/auto_backup_fs_file/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/auto_backup_fs_file/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/auto_backup_fs_file/__manifest__.py b/auto_backup_fs_file/__manifest__.py new file mode 100644 index 00000000000..7c8490c8c9b --- /dev/null +++ b/auto_backup_fs_file/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2025 r.perez@binhex.cloud +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Auto Backup Fs File", + "summary": """Store backups using some FSSPEC implementation""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "Binhex,Odoo Community Association (OCA)", + "category": "Tools", + "website": "https://github.com/OCA/server-tools", + "depends": ["auto_backup", "fs_file", "mail"], + "development_status": "Alpha", + "data": [ + "data/mail_activity_type_data.xml", + "data/fs_storage_data.xml", + "security/ir.model.access.csv", + "views/db_backup_views.xml", + "views/db_backup_fs_file_views.xml", + ], +} diff --git a/auto_backup_fs_file/data/fs_storage_data.xml b/auto_backup_fs_file/data/fs_storage_data.xml new file mode 100644 index 00000000000..4eed67e9fb2 --- /dev/null +++ b/auto_backup_fs_file/data/fs_storage_data.xml @@ -0,0 +1,13 @@ + + + + + Odoo Filesystem Auto Backups Backend + odoofs + odoobackupfs + auto_backup_fs_file.field_db_backup_fs_file__backup_file + + diff --git a/auto_backup_fs_file/data/mail_activity_type_data.xml b/auto_backup_fs_file/data/mail_activity_type_data.xml new file mode 100644 index 00000000000..ef95e81f9c1 --- /dev/null +++ b/auto_backup_fs_file/data/mail_activity_type_data.xml @@ -0,0 +1,10 @@ + + + + + Download Backup + fa-download + db.backup.fs.file + + diff --git a/auto_backup_fs_file/i18n/auto_backup_fs_file.pot b/auto_backup_fs_file/i18n/auto_backup_fs_file.pot new file mode 100644 index 00000000000..6b3ef2b1c35 --- /dev/null +++ b/auto_backup_fs_file/i18n/auto_backup_fs_file.pot @@ -0,0 +1,313 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auto_backup_fs_file +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_ids +msgid "Activities" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "Activity State" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "Backup File" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__name +msgid "Backup Filename" +msgstr "" + +#. module: auto_backup_fs_file +#: model_terms:ir.ui.view,arch_db:auto_backup_fs_file.view_backup_conf_form +msgid "Backups" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__method +msgid "Choose the storage method for this backup." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_uid +msgid "Created by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_date +msgid "Created on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__db_backup_id +msgid "DB Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup +msgid "Database Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup_fs_file +msgid "Database Backup Files" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__display_name +msgid "Display Name" +msgstr "" + +#. module: auto_backup_fs_file +#: model:mail.activity.type,name:auto_backup_fs_file.mail_act_download_backup +msgid "Download Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields.selection,name:auto_backup_fs_file.selection__db_backup__method__fs_file +msgid "Fs File" +msgstr "" + +#. module: auto_backup_fs_file +#. odoo-python +#: code:addons/auto_backup_fs_file/models/db_backup.py:0 +#, python-format +msgid "Fs File Backup - %s" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_count +msgid "Fs File Backup Count" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.actions.act_window,name:auto_backup_fs_file.db_backup_fs_file_act_window +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_ids +#: model:ir.ui.menu,name:auto_backup_fs_file.db_backup_fs_file_menu +msgid "Fs File Backups" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__has_message +msgid "Has Message" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__id +msgid "ID" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Indicates whether the backup has exceeded its storage time." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Is Expired" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_date +msgid "Last Updated on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_ids +msgid "Messages" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__method +msgid "Method" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__responsible_id +msgid "Responsible" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__smart_search +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__smart_search +msgid "Smart Search" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "The file that contains the database backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__responsible_id +msgid "User to be notified." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: auto_backup_fs_file +#. odoo-python +#: code:addons/auto_backup_fs_file/models/db_backup.py:0 +#, python-format +msgid "" +"You must configure a FS Storage for the '%(model_description)s' model - or " +"'Backup File' - field to use the 'Fs File' backup method." +msgstr "" diff --git a/auto_backup_fs_file/i18n/es.po b/auto_backup_fs_file/i18n/es.po new file mode 100644 index 00000000000..ce977d6f5d1 --- /dev/null +++ b/auto_backup_fs_file/i18n/es.po @@ -0,0 +1,293 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auto_backup_fs_file +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-11-18 13:18+0000\n" +"PO-Revision-Date: 2025-11-18 13:18+0000\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: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_ids +msgid "Activities" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "Activity State" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "Backup File" +msgstr "Archivo de copia de seguridad" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__name +msgid "Backup Filename" +msgstr "Nombre del archivo de copia de seguridad" + +#. module: auto_backup_fs_file +#: model_terms:ir.ui.view,arch_db:auto_backup_fs_file.view_backup_conf_form +msgid "Backups" +msgstr "Copias de seguridad" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__method +msgid "Choose the storage method for this backup." +msgstr "Elija el método de almacenamiento para esta copia de seguridad." + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_uid +msgid "Created by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_date +msgid "Created on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__db_backup_id +msgid "DB Backup" +msgstr "Copia de seguridad de la base de datos" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup +msgid "Database Backup" +msgstr "Copia de seguridad de la base de datos" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup_fs_file +msgid "Database Backup Files" +msgstr "Archivos de copia de seguridad de la base de datos" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__display_name +msgid "Display Name" +msgstr "" + +#. module: auto_backup_fs_file +#: model:mail.activity.type,name:auto_backup_fs_file.mail_act_download_backup +msgid "Download Backup" +msgstr "Descargar copia de seguridad" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_follower_ids +msgid "Followers" +msgstr "Seguidores" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_partner_ids +msgid "Followers (Partners)" +msgstr "Seguidores (Contactos)" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields.selection,name:auto_backup_fs_file.selection__db_backup__method__fs_file +msgid "Fs File" +msgstr "Archivo FS" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_count +msgid "Fs File Backup Count" +msgstr "Conteo de copias de seguridad de archivos FS" + +#. module: auto_backup_fs_file +#: model:ir.actions.act_window,name:auto_backup_fs_file.db_backup_fs_file_act_window +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_ids +#: model:ir.ui.menu,name:auto_backup_fs_file.db_backup_fs_file_menu +msgid "Fs File Backups" +msgstr "Copias de seguridad de archivos FS" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__has_message +msgid "Has Message" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__id +msgid "ID" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Indicates whether the backup has exceeded its storage time." +msgstr "Indica si la copia de seguridad ha superado su tiempo de almacenamiento." + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Is Expired" +msgstr "¿Está caducado?" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_date +msgid "Last Updated on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_ids +msgid "Messages" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__method +msgid "Method" +msgstr "Método" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__responsible_id +msgid "Responsible" +msgstr "Responsable" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "The file that contains the database backup" +msgstr "El archivo que contiene la copia de seguridad de la base de datos" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__responsible_id +msgid "User to be notified." +msgstr "Usuario a ser notificado." + +#. module: auto_backup_fs_file +#. odoo-python +#: code:addons/auto_backup_fs_file/models/db_backup.py:0 +#, python-format +msgid "" +"You must configure a FS Storage for the '%(model_description)s' model - or " +"'Backup File' - field to use the 'Fs File' backup method." +msgstr "Debe configurar un almacenamiento FS para el modelo '%(model_description)s'" +" o para el campo 'Archivo de copia de seguridad' para utilizar el método de copia de seguridad 'Fs File'." diff --git a/auto_backup_fs_file/i18n/it.po b/auto_backup_fs_file/i18n/it.po new file mode 100644 index 00000000000..c165797b07a --- /dev/null +++ b/auto_backup_fs_file/i18n/it.po @@ -0,0 +1,314 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * auto_backup_fs_file +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_ids +msgid "Activities" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "Activity State" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "Backup File" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__name +msgid "Backup Filename" +msgstr "" + +#. module: auto_backup_fs_file +#: model_terms:ir.ui.view,arch_db:auto_backup_fs_file.view_backup_conf_form +msgid "Backups" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__method +msgid "Choose the storage method for this backup." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_uid +msgid "Created by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__create_date +msgid "Created on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__db_backup_id +msgid "DB Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup +msgid "Database Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model,name:auto_backup_fs_file.model_db_backup_fs_file +msgid "Database Backup Files" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__display_name +msgid "Display Name" +msgstr "" + +#. module: auto_backup_fs_file +#: model:mail.activity.type,name:auto_backup_fs_file.mail_act_download_backup +msgid "Download Backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields.selection,name:auto_backup_fs_file.selection__db_backup__method__fs_file +msgid "Fs File" +msgstr "" + +#. module: auto_backup_fs_file +#. odoo-python +#: code:addons/auto_backup_fs_file/models/db_backup.py:0 +#, python-format +msgid "Fs File Backup - %s" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_count +msgid "Fs File Backup Count" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.actions.act_window,name:auto_backup_fs_file.db_backup_fs_file_act_window +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__fs_file_backup_ids +#: model:ir.ui.menu,name:auto_backup_fs_file.db_backup_fs_file_menu +msgid "Fs File Backups" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__has_message +msgid "Has Message" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__id +msgid "ID" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Indicates whether the backup has exceeded its storage time." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__is_expired +msgid "Is Expired" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__write_date +msgid "Last Updated on" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_ids +msgid "Messages" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__method +msgid "Method" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__responsible_id +msgid "Responsible" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup__smart_search +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__smart_search +msgid "Smart Search" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__backup_file +msgid "The file that contains the database backup" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup__responsible_id +msgid "User to be notified." +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,field_description:auto_backup_fs_file.field_db_backup_fs_file__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: auto_backup_fs_file +#: model:ir.model.fields,help:auto_backup_fs_file.field_db_backup_fs_file__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: auto_backup_fs_file +#. odoo-python +#: code:addons/auto_backup_fs_file/models/db_backup.py:0 +#, python-format +msgid "" +"You must configure a FS Storage for the '%(model_description)s' model - or " +"'Backup File' - field to use the 'Fs File' backup method." +msgstr "" diff --git a/auto_backup_fs_file/models/__init__.py b/auto_backup_fs_file/models/__init__.py new file mode 100644 index 00000000000..d0cb75951a9 --- /dev/null +++ b/auto_backup_fs_file/models/__init__.py @@ -0,0 +1,2 @@ +from . import db_backup_fs_file +from . import db_backup diff --git a/auto_backup_fs_file/models/db_backup.py b/auto_backup_fs_file/models/db_backup.py new file mode 100644 index 00000000000..7e1411e80bd --- /dev/null +++ b/auto_backup_fs_file/models/db_backup.py @@ -0,0 +1,128 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from markupsafe import Markup + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from odoo.service import db + +from odoo.addons.fs_file.fields import FSFileValue + + +class DbBackup(models.Model): + _inherit = "db.backup" + + method = fields.Selection( + selection_add=[("fs_file", "Fs File")], ondelete={"fs_file": "cascade"} + ) + + fs_file_backup_ids = fields.One2many( + comodel_name="db.backup.fs.file", + inverse_name="db_backup_id", + string="Fs File Backups", + ) + + fs_file_backup_count = fields.Integer(compute="_compute_fs_file_backup_count") + + responsible_id = fields.Many2one("res.users", help="User to be notified.") + + @api.model + def _get_fs_storage(self): + """Get the fs_storage to be used for fs_file backups.""" + DbBackupFsFile = self.env["db.backup.fs.file"] + return DbBackupFsFile.fs_storage() + + def _compute_name(self): + res = super()._compute_name() + for record in self.filtered(lambda r: r.method == "fs_file"): + record.name = _("Fs File Backup - %s", record._get_fs_storage().name) + return res + + @api.depends("fs_file_backup_ids") + def _compute_fs_file_backup_count(self): + """Compute the count of fs_file backups.""" + for record in self: + record.fs_file_backup_count = len(record.fs_file_backup_ids) + + @api.constrains("method") + def _check_fs_file_backup_storage(self): + """Ensure that fs_file method has a storage configured.""" + for record in self.filtered(lambda r: r.method == "fs_file"): + if not record._get_fs_storage(): + raise ValidationError( + _( + "You must configure a FS Storage for the " + "'%(model_description)s' model - or 'Backup File' - field" + " to use the 'Fs File'" + " backup method.", + model_description=self.fs_file_backup_ids._description, + ) + ) + + def action_backup(self): + """Override the action_backup method to add the fs_file method.""" + fs_backups = self.filtered(lambda it: it.method == "fs_file") + dbname = self.env.cr.dbname + for fs_backup in fs_backups: + with fs_backup.backup_log(): + filename = self.filename( + fields.Datetime.now(), ext=fs_backup.backup_format + ) + backup = self.env["db.backup.fs.file"].create( + { + "name": filename, + "db_backup_id": fs_backup.id, + "backup_file": FSFileValue( + name=filename, + value=b"init file", + ), + } + ) + with backup.backup_file.open("wb", new_version=False) as f: + db.dump_db(dbname, f, fs_backup.backup_format) + user_to_notify = fs_backup.responsible_id or self.env.user + file_metadata = backup.read(["backup_file"])[0].get("backup_file") + base_url = ( + self.env["ir.config_parameter"].sudo().get_param("web.base.url") + ) + activity_note = Markup( + _( + "The database backup '%(backup_name)s' is ready." + " You can download it from the attachment link: " + "" + "%(download_link)s", + backup_name=backup.name, + download_link=f"{base_url}{file_metadata.get('url')}", + ) + ) + backup.activity_schedule( + "auto_backup_fs_file.mail_act_download_backup", + date_deadline=fields.Date.today(), + note=activity_note, + summary=_("Database backup is ready to download."), + user_id=user_to_notify.id, + ) + res = super().action_backup() + return res + + def action_open_fs_backups_view(self): + self.ensure_one() + action = self.env["ir.actions.actions"]._for_xml_id( + "auto_backup_fs_file.db_backup_fs_file_act_window" + ) + action["domain"] = [("db_backup_id", "=", self.id)] + return action + + def cleanup(self): + """Extend cleanup to fs_file backups.""" + for db_backup_conf in self.filtered( + lambda record: record.method == "fs_file" and record.days_to_keep + ): + with db_backup_conf.cleanup_log(): + to_delete = db_backup_conf.fs_file_backup_ids.filtered("is_expired") + for backup in to_delete: + self._get_fs_storage().fs.rm_file(backup.get_fs_storage_filename()) + to_delete.unlink() + res = super().cleanup() + return res diff --git a/auto_backup_fs_file/models/db_backup_fs_file.py b/auto_backup_fs_file/models/db_backup_fs_file.py new file mode 100644 index 00000000000..4934b400845 --- /dev/null +++ b/auto_backup_fs_file/models/db_backup_fs_file.py @@ -0,0 +1,57 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + +from odoo.addons.fs_file import fields as fs_fields + + +class DbBackupFsFile(models.Model): + _name = "db.backup.fs.file" + _inherit = ["mail.thread", "mail.activity.mixin"] + _description = "Database Backup Files" + + name = fields.Char("Backup Filename", required=True) + db_backup_id = fields.Many2one("db.backup", string="DB Backup", required=True) + backup_file = fs_fields.FSFile( + required=False, + help="The file that contains the database backup", + ) + is_expired = fields.Boolean( + compute="_compute_is_expired", + help="Indicates whether the backup has exceeded its storage time.", + ) + + def _compute_is_expired(self): + """Compute whether the backup has exceeded its storage time.""" + for record in self: + days_to_keep = record.db_backup_id.days_to_keep + if days_to_keep: + expiration_date = fields.Datetime.add( + record.create_date, days=days_to_keep + ) + record.is_expired = fields.Datetime.now() > expiration_date + else: + record.is_expired = False + + @api.model + def fs_storage(self): + FsStorage = self.env["fs.storage"] + fs_storages = FsStorage.search([]) + fs_storage = fs_storages.filtered( + lambda item: item.field_xmlids + and "auto_backup_fs_file.field_db_backup_fs_file__backup_file" + in item.field_xmlids + ) + if not fs_storage: + fs_storage = fs_storages.filtered( + lambda item: item.model_xmlids + and "auto_backup_fs_file.model_db_backup_fs_file" in item.model_xmlids + ) + if fs_storage: + return fs_storage + return False + + def get_fs_storage_filename(self): + self.ensure_one() + return self.backup_file.attachment.store_fname.split("://")[-1] diff --git a/auto_backup_fs_file/pyproject.toml b/auto_backup_fs_file/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/auto_backup_fs_file/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/auto_backup_fs_file/readme/CONFIGURE.md b/auto_backup_fs_file/readme/CONFIGURE.md new file mode 100644 index 00000000000..26b4c2ae26a --- /dev/null +++ b/auto_backup_fs_file/readme/CONFIGURE.md @@ -0,0 +1,23 @@ +1. **Review Documentation for Dependencies** + Before configuring the module, ensure you have reviewed the documentation for the following modules: + - `fs_attachment` + - `fs_storage` + These modules provide the necessary setup for file storage and attachment handling. + +2. **Configure File Storage** + - Navigate to **Settings** > **Technical** > **FS Storage**. + - Create or select an existing storage configuration. + - Ensure the storage is properly set up and tested for accessibility. + +3. **Link Backup File field to Storage** + - While configuring the file storage in **Settings** > **Technical** > **FS Storage**, ensure that the `backup_file` from the `db.backup.fs.file` model is listed under the `Field` field. + - This step is part of the storage configuration process. + - Save the changes after verifying the setup. + + ![Example of File Storage Configuration](../images/file_storage_configuration.png) + +4. **Verify Configuration** + - Perform a test backup to ensure the files are being stored in the correct location. + - Check the logs for any errors or warnings. + +By following these steps, you will ensure that the module is properly configured for storing backups in the desired file storage system. diff --git a/auto_backup_fs_file/readme/CONTEXT.md b/auto_backup_fs_file/readme/CONTEXT.md new file mode 100644 index 00000000000..fe771bb0775 --- /dev/null +++ b/auto_backup_fs_file/readme/CONTEXT.md @@ -0,0 +1,13 @@ +BUSINESS NEED: +This module addresses the critical need for safeguarding Odoo instance data by enabling automated backups to a filesystem supported by the `fsspec` library. Businesses often require reliable and accessible backup solutions to ensure data integrity and recovery in case of system failures or data loss. This module is particularly useful in contexts where organizations need to store backups on cloud storage, network drives, or other custom filesystems supported by `fsspec`. + +Practical examples include: +- Backing up Odoo data to cloud storage providers like AWS S3, Google Cloud Storage, or Azure Blob Storage. +- Storing backups on a secure local or remote filesystem for disaster recovery purposes. +- Automating backup processes in multi-environment setups, such as multi-company or multi-website configurations. + +APPROACH: +The module extends the backup functionality from the `auto_backup` module by introducing a method that allows storing the resulting backup using an `fsspec` implementation. This is achieved through the integration of the `fs_file` from [storage repository](https://github.com/OCA/storage). The module leverages the `fsspec` library to provide a flexible and extensible interface for interacting with various filesystems. It automates the backup process by exporting Odoo instance data and storing it in the specified filesystem. Additionally, it allows users to download the backups for local storage or further processing. + +USEFUL INFORMATION: +- **Dependencies**: This module depends on the `fsspec` library, its relevant filesystem implementations, and the `fs_file` addon from OCA/storage. Ensure the required `fsspec` plugins are installed for your target filesystem. diff --git a/auto_backup_fs_file/readme/CONTRIBUTORS.md b/auto_backup_fs_file/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..f8e1ad8bfa1 --- /dev/null +++ b/auto_backup_fs_file/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Rolando Pérez Rebollo diff --git a/auto_backup_fs_file/readme/CREDITS.md b/auto_backup_fs_file/readme/CREDITS.md new file mode 100644 index 00000000000..95aa18652f8 --- /dev/null +++ b/auto_backup_fs_file/readme/CREDITS.md @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +- Binhex diff --git a/auto_backup_fs_file/readme/DESCRIPTION.md b/auto_backup_fs_file/readme/DESCRIPTION.md new file mode 100644 index 00000000000..c1ea900109a --- /dev/null +++ b/auto_backup_fs_file/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module enhances the database backup functionality in Odoo by introducing support for storing backups as files using the `fsspec` library. It is designed to address the need for reliable and flexible backup solutions, enabling businesses to safeguard their data by storing backups on various filesystems, including cloud storage providers, network drives, and local secure storage. + +By integrating with the `fs_file` addon from the OCA storage repository, this module allows users to automate the backup process and store the resulting files in a configured filesystem. It provides an easy-to-use interface for configuring backup methods, managing stored backups, and ensuring data integrity for disaster recovery or multi-environment setups. diff --git a/auto_backup_fs_file/readme/INSTALL.md b/auto_backup_fs_file/readme/INSTALL.md new file mode 100644 index 00000000000..f60d5acfaa5 --- /dev/null +++ b/auto_backup_fs_file/readme/INSTALL.md @@ -0,0 +1 @@ +This addon itself does not introduce any dependencies, but its dependencies may require additional packages.:wa diff --git a/auto_backup_fs_file/readme/ROADMAP.md b/auto_backup_fs_file/readme/ROADMAP.md new file mode 100644 index 00000000000..a3a695bc2b8 --- /dev/null +++ b/auto_backup_fs_file/readme/ROADMAP.md @@ -0,0 +1,3 @@ +- **Folder field behavior**: The `folder` field on the `db.backup` model specifies the backup storage directory. For records using the `fs_file` method, storage is actually controlled by the `fs_file` field's settings. However, since `folder` is currently a required non-computed field in the `auto_backup` addon, modifications to sync these two fields are not performed. Future versions may add this synchronization support. + +- **Design limitation**: The current implementation has a design constraint due to `fs_storage` addon limitations. Since storage setting targets the `db.backup.fs.file` model, only one storage backend can effectively be used. diff --git a/auto_backup_fs_file/readme/USAGE.md b/auto_backup_fs_file/readme/USAGE.md new file mode 100644 index 00000000000..b1b2cc0a190 --- /dev/null +++ b/auto_backup_fs_file/readme/USAGE.md @@ -0,0 +1,36 @@ +This module extends the functionality of the database backup system in Odoo by introducing a new backup method: **Fs File**. This method allows storing database backups as files using an FSSPEC implementation. + +## How to Use the Module + +### 1. Configure the Backup Method +1. Navigate to **Settings** > **Technical** > **Database Structure** > **Automated Backups**. +2. Create or edit a backup configuration. +3. In the **Backup Method** field, select **Fs File**. +4. Configure other fields as needed, such as the backup format and retention settings. +5. Save the configuration. + +### 2. Perform a Backup +1. From the list of backup configurations, select the one configured with the **Fs File** method. +2. Click the **Backup Now** button to initiate the backup process. +3. The backup will be stored as a file in the configured FSSPEC storage. + +### 3. View Fs File Backups +1. Open the backup configuration form view. +2. In the top-right corner, you will see a **Backups** stat button (if backups exist). +3. Click the **Backups** button to view the list of Fs File backups associated with the configuration. + +### 4. Manage Fs File Backups +- In the Fs File backups list view, you can see details such as the backup filename and associated database backup configuration. +- Use this view to manage or download backups as needed. + +### Screenshots +- **Backup Configuration Form View** + ![Backup Configuration Form](../static/description/db_backup_form_view.png) + +- **Fs File Backups List View** + ![Fs File Backups List](../static/description/db_backup_fs_file_tree_view.png) + +### Notes +- Ensure that the FSSPEC storage is properly configured before using the **Fs File** method. +- This module adds a new stat button in the backup configuration form view to quickly access Fs File backups. + diff --git a/auto_backup_fs_file/security/ir.model.access.csv b/auto_backup_fs_file/security/ir.model.access.csv new file mode 100644 index 00000000000..9ababe18d50 --- /dev/null +++ b/auto_backup_fs_file/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_db_backup_fs_file_read,Read db.backup fs.file,model_db_backup_fs_file,base.group_erp_manager,1,0,0,0 +access_db_backup_fs_file_write,Write db.backup fs.file,model_db_backup_fs_file,base.group_system,1,1,1,1 diff --git a/auto_backup_fs_file/static/description/db_backup_form_view.png b/auto_backup_fs_file/static/description/db_backup_form_view.png new file mode 100644 index 00000000000..98881da236a Binary files /dev/null and b/auto_backup_fs_file/static/description/db_backup_form_view.png differ diff --git a/auto_backup_fs_file/static/description/db_backup_fs_file_tree_view.png b/auto_backup_fs_file/static/description/db_backup_fs_file_tree_view.png new file mode 100644 index 00000000000..ca37b316188 Binary files /dev/null and b/auto_backup_fs_file/static/description/db_backup_fs_file_tree_view.png differ diff --git a/auto_backup_fs_file/static/description/file_storage_configuration.png b/auto_backup_fs_file/static/description/file_storage_configuration.png new file mode 100644 index 00000000000..5bb8f8ddf34 Binary files /dev/null and b/auto_backup_fs_file/static/description/file_storage_configuration.png differ diff --git a/auto_backup_fs_file/static/description/icon.png b/auto_backup_fs_file/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/auto_backup_fs_file/static/description/icon.png differ diff --git a/auto_backup_fs_file/static/description/index.html b/auto_backup_fs_file/static/description/index.html new file mode 100644 index 00000000000..967556011f1 --- /dev/null +++ b/auto_backup_fs_file/static/description/index.html @@ -0,0 +1,633 @@ + + + + + +README.rst + + + +

+ + + +Odoo Community Association + +
+

Auto Backup Fs File

+ +

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

+

This module enhances the database backup functionality in Odoo by +introducing support for storing backups as files using the fsspec +library. It is designed to address the need for reliable and flexible +backup solutions, enabling businesses to safeguard their data by storing +backups on various filesystems, including cloud storage providers, +network drives, and local secure storage.

+

By integrating with the fs_file addon from the OCA storage +repository, this module allows users to automate the backup process and +store the resulting files in a configured filesystem. It provides an +easy-to-use interface for configuring backup methods, managing stored +backups, and ensuring data integrity for disaster recovery or +multi-environment setups.

+
+

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

+

BUSINESS NEED: This module addresses the critical need for safeguarding +Odoo instance data by enabling automated backups to a filesystem +supported by the fsspec library. Businesses often require reliable +and accessible backup solutions to ensure data integrity and recovery in +case of system failures or data loss. This module is particularly useful +in contexts where organizations need to store backups on cloud storage, +network drives, or other custom filesystems supported by fsspec.

+

Practical examples include:

+
    +
  • Backing up Odoo data to cloud storage providers like AWS S3, Google +Cloud Storage, or Azure Blob Storage.
  • +
  • Storing backups on a secure local or remote filesystem for disaster +recovery purposes.
  • +
  • Automating backup processes in multi-environment setups, such as +multi-company or multi-website configurations.
  • +
+

APPROACH: The module extends the backup functionality from the +auto_backup module by introducing a method that allows storing the +resulting backup using an fsspec implementation. This is achieved +through the integration of the fs_file from storage +repository. The module leverages the +fsspec library to provide a flexible and extensible interface for +interacting with various filesystems. It automates the backup process by +exporting Odoo instance data and storing it in the specified filesystem. +Additionally, it allows users to download the backups for local storage +or further processing.

+

USEFUL INFORMATION:

+
    +
  • Dependencies: This module depends on the fsspec library, its +relevant filesystem implementations, and the fs_file addon from +OCA/storage. Ensure the required fsspec plugins are installed for +your target filesystem.
  • +
+
+
+

Installation

+

This addon itself does not introduce any dependencies, but its +dependencies may require additional packages.:wa

+
+
+

Configuration

+
    +
  1. Review Documentation for Dependencies Before configuring the +module, ensure you have reviewed the documentation for the following +modules:
  2. +
+
    +
  • fs_attachment
  • +
  • fs_storage These modules provide the necessary setup for file +storage and attachment handling.
  • +
+
    +
  1. Configure File Storage
  2. +
+
    +
  • Navigate to Settings > Technical > FS Storage.
  • +
  • Create or select an existing storage configuration.
  • +
  • Ensure the storage is properly set up and tested for accessibility.
  • +
+
    +
  1. Link Backup File field to Storage
  2. +
+
    +
  • While configuring the file storage in Settings > Technical > +FS Storage, ensure that the backup_file from the +db.backup.fs.file model is listed under the Field field.
  • +
  • This step is part of the storage configuration process.
  • +
  • Save the changes after verifying the setup.
  • +
+

Example of File Storage Configuration

+
    +
  1. Verify Configuration
  2. +
+
    +
  • Perform a test backup to ensure the files are being stored in the +correct location.
  • +
  • Check the logs for any errors or warnings.
  • +
+

By following these steps, you will ensure that the module is properly +configured for storing backups in the desired file storage system.

+
+
+

Usage

+

This module extends the functionality of the database backup system in +Odoo by introducing a new backup method: Fs File. This method allows +storing database backups as files using an FSSPEC implementation.

+
+

How to Use the Module

+
+

1. Configure the Backup Method

+
    +
  1. Navigate to Settings > Technical > Database Structure > +Automated Backups.
  2. +
  3. Create or edit a backup configuration.
  4. +
  5. In the Backup Method field, select Fs File.
  6. +
  7. Configure other fields as needed, such as the backup format and +retention settings.
  8. +
  9. Save the configuration.
  10. +
+
+
+

2. Perform a Backup

+
    +
  1. From the list of backup configurations, select the one configured +with the Fs File method.
  2. +
  3. Click the Backup Now button to initiate the backup process.
  4. +
  5. The backup will be stored as a file in the configured FSSPEC storage.
  6. +
+
+
+

3. View Fs File Backups

+
    +
  1. Open the backup configuration form view.
  2. +
  3. In the top-right corner, you will see a Backups stat button (if +backups exist).
  4. +
  5. Click the Backups button to view the list of Fs File backups +associated with the configuration.
  6. +
+
+
+

4. Manage Fs File Backups

+
    +
  • In the Fs File backups list view, you can see details such as the +backup filename and associated database backup configuration.
  • +
  • Use this view to manage or download backups as needed.
  • +
+
+
+

Screenshots

+
    +
  • Backup Configuration Form View Backup Configuration Form
  • +
  • Fs File Backups List View Fs File Backups List
  • +
+
+
+

Notes

+
    +
  • Ensure that the FSSPEC storage is properly configured before using the +Fs File method.
  • +
  • This module adds a new stat button in the backup configuration form +view to quickly access Fs File backups.
  • +
+
+
+
+
+

Known issues / Roadmap

+
    +
  • Folder field behavior: The folder field on the db.backup +model specifies the backup storage directory. For records using the +fs_file method, storage is actually controlled by the fs_file +field’s settings. However, since folder is currently a required +non-computed field in the auto_backup addon, modifications to sync +these two fields are not performed. Future versions may add this +synchronization support.
  • +
  • Design limitation: The current implementation has a design +constraint due to fs_storage addon limitations. Since storage +setting targets the db.backup.fs.file model, only one storage +backend can effectively be used.
  • +
+
+
+

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

+
    +
  • Binhex
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been financially supported by:

+
    +
  • Binhex
  • +
+
+
+

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.

+

This module is part of the OCA/server-tools project on GitHub.

+

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

+
+
+
+
+ + diff --git a/auto_backup_fs_file/tests/__init__.py b/auto_backup_fs_file/tests/__init__.py new file mode 100644 index 00000000000..0f334ca0fa9 --- /dev/null +++ b/auto_backup_fs_file/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_auto_backup_fs_file diff --git a/auto_backup_fs_file/tests/test_auto_backup_fs_file.py b/auto_backup_fs_file/tests/test_auto_backup_fs_file.py new file mode 100644 index 00000000000..d169e8e6132 --- /dev/null +++ b/auto_backup_fs_file/tests/test_auto_backup_fs_file.py @@ -0,0 +1,123 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later[](https://www.gnu.org/licenses/agpl). + +import io + +from odoo import fields +from odoo.exceptions import ValidationError +from odoo.service import db +from odoo.tests import tagged + +from odoo.addons.base.tests.common import BaseCommon + + +@tagged("post_install", "-at_install") +class TestAutoBackupFsFile(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.DbBackup = cls.env["db.backup"] + cls.DbBackupFsFile = cls.env["db.backup.fs.file"] + cls.FsStorage = cls.env["fs.storage"] + + cls.env.ref("auto_backup_fs_file.fs_storage_auto_backup").unlink() + + # Create a test FS Storage + cls.test_storage = cls.FsStorage.create( + { + "name": "Test Storage", + "protocol": "memory", # Use in-memory for testing + "code": "mem_dir", + "directory_path": "/tmp/", + } + ) + + def setUp(self): + super().setUp() + # Patch db.dump_db to avoid actual DB dumping (active for the entire test) + self.patch( + db, + "dump_db", + lambda dbname, stream, backup_format: io.BytesIO(b"fake_backup_data"), + ) + + def _create_backup_config(self): + # Create a test backup configuration with fs_file method + return self.DbBackup.create( + { + "method": "fs_file", + "backup_format": "zip", + "days_to_keep": 7, + "responsible_id": self.env.user.id, + } + ) + + def _action_backup(self, backup_config): + backup_config.action_backup() + + def test_ordinary_flow(self): + """Test the ordinary flow of creating a backup configuration and performing + backups.""" + # Create backup configuration, field not linked to storage yet + with self.assertRaises(ValidationError): + self._create_backup_config() + + self.test_storage.field_xmlids = ( + "auto_backup_fs_file.field_db_backup_fs_file__backup_file" + ) + backup_config = self._create_backup_config() + self.assertEqual( + backup_config.name, + f"Fs File Backup - {backup_config._get_fs_storage().name}", + ) + + # Test computation of fs_file_backup_count + self.assertEqual(backup_config.fs_file_backup_count, 0) + + # Test backup generation and activity creation + self._action_backup( + backup_config + ) # No need for _action_backup_with_time_freeze + self.assertEqual(backup_config.fs_file_backup_count, 1) + + # Check activity scheduled + activity = self.env["mail.activity"].search( + [ + ("res_model", "=", "db.backup.fs.file"), + ("res_id", "=", backup_config.fs_file_backup_ids.id), + ( + "activity_type_id", + "=", + self.env.ref("auto_backup_fs_file.mail_act_download_backup").id, + ), + ] + ) + self.assertTrue(activity) + self.assertEqual(activity.user_id, self.env.user) + self.assertFalse( + backup_config.fs_file_backup_ids.is_expired + ) # Without active mock, not expired + backup_config.cleanup() + self.assertEqual(backup_config.fs_file_backup_count, 1) + + # Get the fs_backup for expiry testing + fs_backup = backup_config.fs_file_backup_ids + + # Compute the expiration date + computed_now = fields.Datetime.add( + fs_backup.create_date, days=backup_config.days_to_keep, seconds=10 + ) + + def fake_now(): + return computed_now + + # Use self.patch to mock ONLY Datetime.now() for the duration of the test + self.patch(fields.Datetime, "now", fake_now) + fs_backup.invalidate_recordset(["is_expired"]) + + self.assertTrue( + fs_backup.is_expired + ) # Triggers _compute_is_expired with mocked now + backup_config.cleanup() # Will use the computed is_expired + + self.assertEqual(backup_config.fs_file_backup_count, 0) diff --git a/auto_backup_fs_file/views/db_backup_fs_file_views.xml b/auto_backup_fs_file/views/db_backup_fs_file_views.xml new file mode 100644 index 00000000000..e1652283de5 --- /dev/null +++ b/auto_backup_fs_file/views/db_backup_fs_file_views.xml @@ -0,0 +1,63 @@ + + + + + + db.backup.fs.file.form.view + db.backup.fs.file + +
+
+ + + + + + + + +
+ + + +
+ + + + + + db.backup.fs.file.search.view + db.backup.fs.file + + + + + + + + + db.backup.fs.file.tree.view + db.backup.fs.file + + + + + + + + + + + Fs File Backups + db.backup.fs.file + + + + Fs File Backups + + + + + + diff --git a/auto_backup_fs_file/views/db_backup_views.xml b/auto_backup_fs_file/views/db_backup_views.xml new file mode 100644 index 00000000000..1bbe336b90e --- /dev/null +++ b/auto_backup_fs_file/views/db_backup_views.xml @@ -0,0 +1,44 @@ + + + + + + db.backup + + + +
+ +
+
+ + + + +
+ + + + db.backup + + + + + + + + +
diff --git a/base_name_search_improved/i18n/base_name_search_improved.pot b/base_name_search_improved/i18n/base_name_search_improved.pot index e6223889c85..3e71760def2 100644 --- a/base_name_search_improved/i18n/base_name_search_improved.pot +++ b/base_name_search_improved/i18n/base_name_search_improved.pot @@ -225,6 +225,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -476,6 +479,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/ca.po b/base_name_search_improved/i18n/ca.po index 35b929c326c..81d68080cef 100644 --- a/base_name_search_improved/i18n/ca.po +++ b/base_name_search_improved/i18n/ca.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/de.po b/base_name_search_improved/i18n/de.po index 78e49b9e2c2..2ff1623f867 100644 --- a/base_name_search_improved/i18n/de.po +++ b/base_name_search_improved/i18n/de.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/es.po b/base_name_search_improved/i18n/es.po index e1052438417..a8c5d029998 100644 --- a/base_name_search_improved/i18n/es.po +++ b/base_name_search_improved/i18n/es.po @@ -266,6 +266,9 @@ msgstr "¿Búsqueda inteligente por nombre activada?" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -517,6 +520,9 @@ msgstr "¿Búsqueda inteligente por nombre activada?" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/es_ES.po b/base_name_search_improved/i18n/es_ES.po index b59ef214d6a..e12a4eb8053 100644 --- a/base_name_search_improved/i18n/es_ES.po +++ b/base_name_search_improved/i18n/es_ES.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/eu.po b/base_name_search_improved/i18n/eu.po index 290c7ceac02..f33e5d170f3 100644 --- a/base_name_search_improved/i18n/eu.po +++ b/base_name_search_improved/i18n/eu.po @@ -238,6 +238,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -489,6 +492,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/fi.po b/base_name_search_improved/i18n/fi.po index 81e3151aa44..2e9108c6a71 100644 --- a/base_name_search_improved/i18n/fi.po +++ b/base_name_search_improved/i18n/fi.po @@ -238,6 +238,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -489,6 +492,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/fr.po b/base_name_search_improved/i18n/fr.po index 934cb90eaa4..0c0ad956860 100644 --- a/base_name_search_improved/i18n/fr.po +++ b/base_name_search_improved/i18n/fr.po @@ -238,6 +238,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -489,6 +492,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/hr.po b/base_name_search_improved/i18n/hr.po index 4513ace1b22..9c56cbf3c32 100644 --- a/base_name_search_improved/i18n/hr.po +++ b/base_name_search_improved/i18n/hr.po @@ -239,6 +239,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -490,6 +493,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/hr_HR.po b/base_name_search_improved/i18n/hr_HR.po index 7014ed71651..efa9b24065d 100644 --- a/base_name_search_improved/i18n/hr_HR.po +++ b/base_name_search_improved/i18n/hr_HR.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/it.po b/base_name_search_improved/i18n/it.po index a4c9d4b76b8..e2d8a99830f 100644 --- a/base_name_search_improved/i18n/it.po +++ b/base_name_search_improved/i18n/it.po @@ -264,6 +264,9 @@ msgstr "Ricerca nome intelligente abilitata?" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -515,6 +518,9 @@ msgstr "Ricerca nome intelligente abilitata?" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/nb_NO.po b/base_name_search_improved/i18n/nb_NO.po index f4ed0d73f05..e7ed77b8cf2 100644 --- a/base_name_search_improved/i18n/nb_NO.po +++ b/base_name_search_improved/i18n/nb_NO.po @@ -239,6 +239,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -490,6 +493,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/nl.po b/base_name_search_improved/i18n/nl.po index 0d4f169510f..9e500841e61 100644 --- a/base_name_search_improved/i18n/nl.po +++ b/base_name_search_improved/i18n/nl.po @@ -238,6 +238,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -489,6 +492,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/pt_BR.po b/base_name_search_improved/i18n/pt_BR.po index ad996fe458e..4be63f91fc7 100644 --- a/base_name_search_improved/i18n/pt_BR.po +++ b/base_name_search_improved/i18n/pt_BR.po @@ -12,8 +12,8 @@ msgstr "" "POT-Creation-Date: 2017-10-28 11:05+0000\n" "PO-Revision-Date: 2017-10-28 11:05+0000\n" "Last-Translator: Armando Vulcano Junior , 2017\n" -"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/" -"teams/23907/pt_BR/)\n" +"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/teams/" +"23907/pt_BR/)\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -241,6 +241,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -492,6 +495,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/sl.po b/base_name_search_improved/i18n/sl.po index 3491f4a0ff8..34af1522d46 100644 --- a/base_name_search_improved/i18n/sl.po +++ b/base_name_search_improved/i18n/sl.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/tr.po b/base_name_search_improved/i18n/tr.po index 3d298dac423..a35b990d187 100644 --- a/base_name_search_improved/i18n/tr.po +++ b/base_name_search_improved/i18n/tr.po @@ -240,6 +240,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -491,6 +494,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/tr_TR.po b/base_name_search_improved/i18n/tr_TR.po index 0da83495a91..163987b3425 100644 --- a/base_name_search_improved/i18n/tr_TR.po +++ b/base_name_search_improved/i18n/tr_TR.po @@ -239,6 +239,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -490,6 +493,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/base_name_search_improved/i18n/zh_CN.po b/base_name_search_improved/i18n/zh_CN.po index d2aeeeabca2..fe9e3828c5e 100644 --- a/base_name_search_improved/i18n/zh_CN.po +++ b/base_name_search_improved/i18n/zh_CN.po @@ -239,6 +239,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_discuss_voice_metadata__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_fetchmail_server__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_format_address_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_file_gc__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_storage__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_fs_test_connection__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_google_gmail_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_html_field_history_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_iap_account__smart_search @@ -490,6 +493,9 @@ msgstr "" #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_resource_resource__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sequence_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_config__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_mixin__smart_search +#: model:ir.model.fields,field_description:base_name_search_improved.field_server_env_techname_mixin__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_composer__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend__smart_search #: model:ir.model.fields,field_description:base_name_search_improved.field_sms_resend_recipient__smart_search diff --git a/oca_dependencies.txt b/oca_dependencies.txt new file mode 100644 index 00000000000..fa780e25de5 --- /dev/null +++ b/oca_dependencies.txt @@ -0,0 +1 @@ +storage diff --git a/setup/_metapackage/pyproject.toml b/setup/_metapackage/pyproject.toml index b44c570a4e9..4ea8ac45dbe 100644 --- a/setup/_metapackage/pyproject.toml +++ b/setup/_metapackage/pyproject.toml @@ -1,10 +1,12 @@ [project] name = "odoo-addons-oca-server-tools" -version = "17.0.20251206.1" +version = "17.0.20260125.0" dependencies = [ + "odoo-addon-attachment_logging>=17.0dev,<17.1dev", "odoo-addon-attachment_queue>=17.0dev,<17.1dev", "odoo-addon-auditlog>=17.0dev,<17.1dev", "odoo-addon-auto_backup>=17.0dev,<17.1dev", + "odoo-addon-auto_backup_fs_file>=17.0dev,<17.1dev", "odoo-addon-base_cron_exclusion>=17.0dev,<17.1dev", "odoo-addon-base_exception>=17.0dev,<17.1dev", "odoo-addon-base_fontawesome>=17.0dev,<17.1dev",