diff --git a/addons/cetmix_tower_yaml/README.rst b/addons/cetmix_tower_yaml/README.rst deleted file mode 100644 index 51d73cf..0000000 --- a/addons/cetmix_tower_yaml/README.rst +++ /dev/null @@ -1,152 +0,0 @@ -================= -Cetmix Tower YAML -================= - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:96e8f3f1df3ab25b952a9534d0914149740cc036b62efe2c7795f9d2d9636177 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |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-cetmix%2Fcetmix--tower-lightgray.png?logo=github - :target: https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower_yaml - :alt: cetmix/cetmix-tower - -|badge1| |badge2| |badge3| - -This module implements YAML format data import/export for `Cetmix -Tower `__. - -Please refer to the `official -documentation `__ for detailed information. - -**Table of contents** - -.. contents:: - :local: - -Configuration -============= - -Please refer to the `official -documentation `__ for detailed configuration -instructions. - -Usage -===== - -Please refer to the `official -documentation `__ for detailed usage -instructions. - -Changelog -========= - -16.0.2.0.1 (2025-10-29) ------------------------ - -- Features: Improve the way secrets are listed in the YAML import - widget. (5010) - -16.0.1.4.2 (2025-10-06) ------------------------ - -- Bugfixes: Add the missing 'create' function decorator (4980) - -16.0.1.4.1 (2025-08-26) ------------------------ - -- Bugfixes: Make selection values lowercase to simplify their - management. (4896) - -16.0.1.3.0 (2025-07-30) ------------------------ - -- Features: Optional behaviour when file uploaded by command already - exists on the server. (4740) - -16.0.1.1.4 (2025-07-08) ------------------------ - -- Bugfixes: Fix missing model names in YAML exports when exporting - multiple commands with flight plans (4820) - -16.0.1.1.3 (2025-07-07) ------------------------ - -- Bugfixes: Import servers with ``Password`` ssh authentication mode - (4812) - -16.0.1.1.1 (2025-06-23) ------------------------ - -- Features: YAML code optimisation (4728) - -16.0.1.1.0 (2025-06-20) ------------------------ - -- Features: Export/import scheduled tasks to/from YAML. (4650) - -16.0.1.0.5 (2025-05-21) ------------------------ - -- Features: Export/import secret values related to Server. (4696) - -16.0.1.0.4 (2025-05-16) ------------------------ - -- Features: Export/import servers and files to/from YAML. (4670) - -16.0.1.0.3 (2025-05-09) ------------------------ - -- Bugfixes: Non-critical issues and performance improvements. (4663) - -16.0.1.0.2 (2025-04-30) ------------------------ - -- Features: User groups are visible without developer mode. (4642) - -16.0.1.0.1 (2025-04-21) ------------------------ - -- Features: Export additional fields for shortcuts, variables and - options. Add action menu to export keys/secrets. (4602) - -16.0.1.0.0 ----------- - -Release for Odoo 16.0 - -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 - -Maintainers ------------ - -This module is part of the `cetmix/cetmix-tower `_ project on GitHub. - -You are welcome to contribute. diff --git a/addons/cetmix_tower_yaml/__init__.py b/addons/cetmix_tower_yaml/__init__.py deleted file mode 100644 index aee8895..0000000 --- a/addons/cetmix_tower_yaml/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import models -from . import wizards diff --git a/addons/cetmix_tower_yaml/__manifest__.py b/addons/cetmix_tower_yaml/__manifest__.py deleted file mode 100644 index a96cc96..0000000 --- a/addons/cetmix_tower_yaml/__manifest__.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright Cetmix OÜ 2024 -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -{ - "name": "Cetmix Tower YAML", - "summary": "Cetmix Tower YAML export/import", - "version": "16.0.2.0.3", - "development_status": "Beta", - "category": "Productivity", - "website": "https://tower.cetmix.com", - "author": "Cetmix", - "license": "AGPL-3", - "installable": True, - "depends": ["cetmix_tower_server"], - "external_dependencies": {"python": ["pyyaml"]}, - "data": [ - "security/cetmix_tower_yaml_groups.xml", - "security/cx_tower_yaml_wizard_access_rules.xml", - "security/ir.model.access.csv", - "views/cx_tower_command_view.xml", - "views/cx_tower_file_template_view.xml", - "views/cx_tower_plan_view.xml", - "views/cx_tower_server_template_view.xml", - "views/cx_tower_server_view.xml", - "views/cx_tower_variable_view.xml", - "views/cx_tower_variable_value_view.xml", - "views/cx_tower_os_view.xml", - "views/cx_tower_tag_view.xml", - "views/cx_tower_shortcut_view.xml", - "views/cx_tower_scheduled_task_view.xml", - "views/cx_tower_key_view.xml", - "views/cx_tower_yaml_manifest_template_views.xml", - "views/cx_tower_yaml_manifest_author_views.xml", - "wizards/cx_tower_yaml_export_wiz.xml", - "wizards/cx_tower_yaml_export_wiz_download.xml", - "wizards/cx_tower_yaml_import_wiz_upload.xml", - "wizards/cx_tower_yaml_import_wiz.xml", - "views/menuitems.xml", - ], - "demo": [ - "demo/demo_data.xml", - ], -} diff --git a/addons/cetmix_tower_yaml/demo/demo_data.xml b/addons/cetmix_tower_yaml/demo/demo_data.xml deleted file mode 100644 index 40f8de5..0000000 --- a/addons/cetmix_tower_yaml/demo/demo_data.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/addons/cetmix_tower_yaml/i18n/cetmix_tower_yaml.pot b/addons/cetmix_tower_yaml/i18n/cetmix_tower_yaml.pot deleted file mode 100644 index 8de30e5..0000000 --- a/addons/cetmix_tower_yaml/i18n/cetmix_tower_yaml.pot +++ /dev/null @@ -1,1017 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * cetmix_tower_yaml -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_export -msgid "" -"\n" -" Export data to YAML.\n" -" " -msgstr "" - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_import -msgid "" -"\n" -" Import data from YAML.\n" -" " -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "'%s' is not a valid model" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#, python-format -msgid "'invalid_model' is not a valid model" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Important: To maintain data consistency, the following\n" -" model records will always be updated if they exist in Odoo:" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__add_manifest -msgid "Add Manifest" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "" -"Add entire child record definitions to the exported YAML file. Otherwise " -"only references to child records will be added." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__file_prefix -msgid "" -"Add prefix to the exported YAML file name when this template is selected" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:res.groups,name:cetmix_tower_yaml.group_export -#: model:res.groups,name:cetmix_tower_yaml.group_import -msgid "Allow" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_author_string -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Author" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.constraint,message:cetmix_tower_yaml.constraint_cx_tower_yaml_manifest_author_yaml_manifest_author_name_uniq -msgid "Author name must be unique." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_author_ids -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__author_ids -msgid "Authors" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_command -msgid "Cetmix Tower Command" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_file -msgid "Cetmix Tower File" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_file_template -msgid "Cetmix Tower File Template" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan -msgid "Cetmix Tower Flight Plan" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line -msgid "Cetmix Tower Flight Plan Line" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line_action -msgid "Cetmix Tower Flight Plan Line Action" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_key -msgid "Cetmix Tower Key/Secret Storage" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_os -msgid "Cetmix Tower Operating System" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_key_value -msgid "Cetmix Tower Secret Value Storage" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server -msgid "Cetmix Tower Server" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_log -msgid "Cetmix Tower Server Log" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_template -msgid "Cetmix Tower Server Template" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_shortcut -msgid "Cetmix Tower Shortcut" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_tag -msgid "Cetmix Tower Tag" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable -msgid "Cetmix Tower Variable" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_option -msgid "Cetmix Tower Variable Options" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_value -msgid "Cetmix Tower Variable Values" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz_download -msgid "Cetmix Tower YAML Export File Download" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz -msgid "Cetmix Tower YAML Export Wizard" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz -msgid "Cetmix Tower YAML Import Wizard" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz_upload -msgid "Cetmix Tower YAML Import Wizard Upload" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_mixin -msgid "Cetmix Tower YAML rendering mixin" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_download_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Close" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Code preview" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_author_string -msgid "Comma-separated list" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__create -msgid "Create a new record" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__create_uid -msgid "Created by" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__create_date -msgid "Created on" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_currency -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_currency -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__currency -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Currency" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__currency -msgid "Currency for pricing information." -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "Currency is required when price is specified" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Custom" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license_text -msgid "Custom license text when license type is Custom." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_description -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_description -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Description" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Detailed description (optional)" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__display_name -msgid "Display Name" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Error creating record '%(reference)s' in model '%(model)s': %(error)s" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Error updating record %(reference)s: %(error)s" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Euro" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Existing record will be updated with the new data. Related records, present in the YAML code, will be updated too.\n" -" If any of those related records doesn't exist, it will be created automatically." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "Explode Child Records" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_command_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_file_template_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_key_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_os_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_plan_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_scheduled_task_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_server_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_server_template_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_shortcut_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_tag_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_variable_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_variable_value_export_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "Export YAML" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "Failed to convert dictionary to YAML: %(error)s" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "" -"Failed to encode YAML content. Please ensure all characters are UTF-8 " -"compatible." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__file_name -msgid "File Name" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "File is empty" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "File is not a valid base64-encoded file" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__file_prefix -msgid "File prefix" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Following secrets are used in the code:
%(secrets)s" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Generate YAML file" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__id -msgid "ID" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__if_record_exists -msgid "If Record Exists" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Import" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_yaml_import_wiz_upload -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_cetmix_tower_yaml_import -msgid "Import YAML" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Import result: %(model)s" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Information" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Invalid YAML file" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Key/Secrets" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl____last_update -msgid "Last Modified on" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__write_date -msgid "Last Updated on" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_name -msgid "Leave this field blank if you don't want to create a manifest" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_license -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_license -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_license_text -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license_text -msgid "License Text" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License and pricing" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_license_text -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License text" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "License text is required for a custom license" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license -msgid "License used for the code snippet." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__author_ids -msgid "List of author names to include in the YAML manifest." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__secret_list -msgid "List of secrets present in the YAML file (formatted as HTML list)" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Manifest" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_manifest_author_action -msgid "Manifest Authors" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_template_id -msgid "Manifest Template" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_manifest_template -msgid "Manifest Templates" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Model '%s' does not support YAML import" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#, python-format -msgid "Model 'command_run_wizard' does not support YAML import" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_names -msgid "Model Names" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_names -msgid "Models to create records in" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__name -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Name" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__name -msgid "Name of the manifest template." -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No YAML code is present." -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No model or records selected" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "No records were created or updated" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No valid records selected" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "OSs" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__preview_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__preview_code -msgid "Preview Code" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Preview code" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_price -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_price -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Price" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -msgid "Process" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Provide Custom License Text when License is set to 'Custom'." -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Record Import" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Record model is missing for record %s" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Record reference is missing" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Records of the following models were created or updated: %(models)s" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "Remove Empty x2m Field Values" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "" -"Remove empty Many2one, Many2many and One2many field values from the exported" -" YAML file." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_scheduled_task -msgid "Scheduled Task" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__secret_list -msgid "Secret List" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Select a pre-defined template" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Select a template to auto-populate manifest fields" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_summary -msgid "Short summary that includes core information. 160 symbols max" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Short summary, 160 symbols max" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__skip -msgid "Skip record" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_name -msgid "Snippet Name" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_file_name -msgid "Snippet file name without extension, eg 'my_snippet'" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_summary -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_summary -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Summary" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Tags" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "This may overwrite existing records. Proceed?" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"To create new entities instead of updating existing ones, remove or modify\n" -" the reference field in the YAML code for those entities." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__preview_code -msgid "Toggle to show or hide YAML code preview" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "US Dollar" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__update -msgid "Update existing record" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_version -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Use the Major.Minor.Patch format, e.g. 1.2.3" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Values must be a dictionary" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Variable Options" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Variables" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_version -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_version -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__version -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Version" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__version -msgid "Version in Major.Minor.Patch format, e.g. 1.0.0" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "Version must be in format Major.Minor.Patch, e.g. 1.2.3" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Version must be in the Major.Minor.Patch format, e.g. 1.2.3" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_website -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_website -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__website -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Website" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__website -msgid "Website URL for the manifest." -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__if_record_exists -msgid "What to do if record with the same reference already exists" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Wrong value for 'access_level' key: %(acv)s" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "YAML" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.module.category,name:cetmix_tower_yaml.ir_module_category_tower_yaml_export -msgid "YAML Export" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_settings_root -msgid "YAML Export/Import" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_file_name -msgid "YAML File Name" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.module.category,name:cetmix_tower_yaml.ir_module_category_tower_yaml_import -msgid "YAML Import" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_manifest_author -msgid "YAML Manifest Author" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_yaml_manifest_author -msgid "YAML Manifest Authors" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_manifest_tmpl -msgid "YAML Manifest Template" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_yaml_manifest_template -msgid "YAML Manifest Templates" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML file cannot be decoded properly" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML file doesn't contain any records" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "" -"YAML version is higher than version supported by your Cetmix Tower instance." -" %(code_version)s > %(tower_version)s" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key_value__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_scheduled_task__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_shortcut__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin__yaml_code -msgid "Yaml Code" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__yaml_file -msgid "Yaml File" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file_name -msgid "Yaml File Name" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Yaml file doesn't contain valid data" -msgstr "" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "You are not allowed to create records from YAML" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "You must be a member of the \"YAML/Export\" group to export data as YAML." -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "my_snippet.yaml" -msgstr "" diff --git a/addons/cetmix_tower_yaml/i18n/hr.po b/addons/cetmix_tower_yaml/i18n/hr.po deleted file mode 100644 index 4283e6a..0000000 --- a/addons/cetmix_tower_yaml/i18n/hr.po +++ /dev/null @@ -1,587 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * cetmix_tower_yaml -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-03-06 09:11+0000\n" -"Last-Translator: Bole \n" -"Language-Team: Croatian \n" -"Language: hr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Weblate 5.10.3-dev\n" - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_export -msgid "" -"\n" -" Export data to YAML.\n" -" " -msgstr "" -"\n" -" Izvoz podataka u YAML.\n" -" " - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_import -msgid "" -"\n" -" Import data from YAML.\n" -" " -msgstr "" -"\n" -" Uvoz podataka iz YAML.\n" -" " - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Important: To maintain data consistency, the following " -"model records will always be updated if they exist in Odoo:" -msgstr "" -"Važno: Za održavanje konsistencije podataka, sljedeći " -"zapisi modela će uvijek biti ažurirani ako postoje u Odoo:" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "" -"Add entire child record definitions to the exported YAML file. Otherwise " -"only references to child records will be added." -msgstr "" -"Dodaj sve podređene definicije podataka u izveženu YAML datoteku. Inače će " -"biti dodane samo reference na podređene zapise." - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_command -msgid "Cetmix Tower Command" -msgstr "Cetmix Tower Naredba" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan -msgid "Cetmix Tower Flight Plan" -msgstr "Cetmix Tower Plan Leta" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line -msgid "Cetmix Tower Flight Plan Line" -msgstr "Cetmix Tower Stavka plana leta" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line_action -msgid "Cetmix Tower Flight Plan Line Action" -msgstr "Cetmix Tower Akcija stavke plana leta" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_os -msgid "Cetmix Tower Operating System" -msgstr "Cetmix Tower Operativni sistem" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_log -msgid "Cetmix Tower Server Log" -msgstr "Cetmix Tower Log servera" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_template -msgid "Cetmix Tower Server Template" -msgstr "Cetmix Tower Predložak servera" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_tag -msgid "Cetmix Tower Tag" -msgstr "Cetmix Tower Oznaka" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable -msgid "Cetmix Tower Variable" -msgstr "Cetmix Tower Varijabla" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_option -msgid "Cetmix Tower Variable Options" -msgstr "Cetmix Tower Opcija varijable" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_value -msgid "Cetmix Tower Variable Values" -msgstr "Cetmix Tower Vrijednosti varijabli" - -#. module: cetmix_tower_yaml -#: model:ir.module.category,name:cetmix_tower_yaml.ir_module_category_tower_yaml -msgid "Cetmix Tower YAML" -msgstr "Cetmix Tower YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz_download -msgid "Cetmix Tower YAML Export File Download" -msgstr "Cetmix Tower YAML preuzimanje izvežene datoteke" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz -msgid "Cetmix Tower YAML Export Wizard" -msgstr "Cetmix Tower YAML Čarobnjak za izvoz" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz -msgid "Cetmix Tower YAML Import Wizard" -msgstr "Cetmix Tower YAML Čarobnjak za uvoz" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz_upload -msgid "Cetmix Tower YAML Import Wizard Upload" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_mixin -msgid "Cetmix Tower YAML rendering mixin" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_key -msgid "Cetmix Tower private key storage" -msgstr "Cetmix Tower Pohrana privatnih ključeva" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_download_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Close" -msgstr "Zatvori" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__comment -msgid "Comment" -msgstr "Komentar" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__comment -msgid "Comment to be added to the beginning of exported YAML file" -msgstr "Komentar koje će biti dodan na početku izvežene YAML datoteke" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Create New Record" -msgstr "Kreiraj novi zapis" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_uid -msgid "Created by" -msgstr "Kreirao" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_date -msgid "Created on" -msgstr "Kreirano" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_file_template -msgid "Cx Tower File Template" -msgstr "CxTower Predložak datoteke" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin__display_name -msgid "Display Name" -msgstr "Naziv" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Existing record will be updated with the new data. Related records, present in the YAML code, will be updated too.\n" -" If any of those related records doesn't exist, it will be created automatically." -msgstr "" -"Postojeći zapis će biti ažuriran sa novim podacima. Povezani zapisi, " -"prisutni u YAML kodu, će također biti ažurirani.\n" -" Ukoliko neki od " -"povezanih zapisa ne postoji, biti će kreiran automatski." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "Explode Child Records" -msgstr "Proširi podređene zapise" - -#. module: cetmix_tower_yaml -#: model:res.groups,name:cetmix_tower_yaml.group_export -msgid "Export" -msgstr "Izvoz" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -msgid "Export YAML" -msgstr "Izvoz YAML" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "Failed to convert dictionary to YAML: %(error)s" -msgstr "Neuspjelo pretvaranje dictionary u YAML: %(error)s" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "" -"Failed to encode YAML content. Please ensure all characters are UTF-8 " -"compatible." -msgstr "" -"Neuspjelo kreiranje YAML sadržaja. Molimo provjerite jesu li svi znakovi UTF-" -"8 kompatabilni." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__file_name -msgid "File Name" -msgstr "Naziv datoteke" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "File is not a valid base64-encoded file" -msgstr "Datoteka nije ispravno base64 kodirana" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Generate YAML file" -msgstr "Generiraj YAML datoteku" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin__id -msgid "ID" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__update_existing_record -msgid "" -"If enabled, existing records will be updated with the new data. Otherwise, " -"new records will be created." -msgstr "" -"Ako je označeno, postojeći zapisi će biti ažurirani sa novim podacima. " -"Inače, novi zapisi će biti kreirani." - -#. module: cetmix_tower_yaml -#: model:res.groups,name:cetmix_tower_yaml.group_import -msgid "Import" -msgstr "Uvoz" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_yaml_import_wiz_upload -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_cetmix_tower_yaml_import -msgid "Import YAML" -msgstr "Uvoz YAML" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Invalid YAML file" -msgstr "Neispravna YAML datoteka" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Invalid model specified in the YAML file" -msgstr "Neispravan model naveden u YAML datoteci" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin____last_update -msgid "Last Modified on" -msgstr "Zadnje modificirano" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_uid -msgid "Last Updated by" -msgstr "Zadnji ažurirao" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_date -msgid "Last Updated on" -msgstr "Zadnje ažurirano" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_description -msgid "Model" -msgstr "" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_name -msgid "Model Name" -msgstr "Naziv modela" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Model does not support YAML import" -msgstr "Model ne podržava YAML uvoz" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_name -msgid "Model to create records in" -msgstr "Model u kojem će podaci biti kreirani" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No YAML code is present." -msgstr "YAML kod nije dostupan." - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "No model for import is specified in the YAML file" -msgstr "Model za uvoz nije naveden u YAML datoteci" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No model or records selected" -msgstr "Nisu odabrani zapisi ili model" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "OSs" -msgstr "" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Open Existing Record" -msgstr "Otvori postojeći zapis" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -msgid "Process" -msgstr "U procesu" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__record_id -msgid "Record" -msgstr "Zapis" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__record_id -msgid "Record ID to update" -msgstr "ID zapisa za ažuriranje" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "Remove Empty x2m Field Values" -msgstr "Ukloni prazne x2m vrijednosti polja" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "" -"Remove empty Many2one, Many2many and One2many field values from the exported" -" YAML file." -msgstr "" -"Ukloni prazne Many2one, Many2many i One2many vrijednosti polja iz izvežene " -"YAML datoteke." - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Tags" -msgstr "Oznake" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "This will create a new record. Proceed?" -msgstr "Ovo će kreirati novi zapis. Nastaviti?" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "This will overwrite the existing record. Proceed?" -msgstr "Ovo će prepisati preko postojećeg zapisa. Nastaviti?" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"To create new entities instead of updating existing ones, remove or modify " -"the reference field in the YAML code for those entities." -msgstr "" -"Za kreiranje novih entiteta umjesto ažuriranja postojećih, uklonite ili " -"modificirajte reference polje u YAML kodu za te zapise." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__update_existing_record -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Update Existing Record" -msgstr "Ažuriraj postojeći zapis" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Values must be a dictionary" -msgstr "Vrijednosti moraju biti dictionary" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Variables" -msgstr "Varijable" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Wrong value for 'access_level' key: %(acv)s" -msgstr "Pogrešna vrijednost za ključ 'access_level': %(acv)s" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -msgid "YAML" -msgstr "" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML file cannot be decoded properly" -msgstr "YAML datoteku nije moguće pročitati ili dekodirati" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "" -"YAML file version is not supported. You may need to update the Cetmix Tower " -"Yaml module." -msgstr "" -"Verzija YAML datoteke nije podržana. Možda morate ažurirati Cetmix Tower " -"Yaml modul." - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "" -"YAML version is higher than version supported by your Cetmix Tower instance." -" %(code_version)s > %(tower_version)s" -msgstr "" -"YAML verzija je viša od verzije podržane na vašoj Cetmix Tower instanci. " -"%(code_version)s>%(tower_version)s" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin__yaml_code -msgid "Yaml Code" -msgstr "YAML kod" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__yaml_file -msgid "Yaml File" -msgstr "YAML datoteka" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file_name -msgid "Yaml File Name" -msgstr "YAML naziv datoteke" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Yaml file doesn't contain valid data" -msgstr "Yaml datoteka ne sadrži valjane podatke" - -#. module: cetmix_tower_yaml -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "You are not allowed to create records from YAML" -msgstr "Nije vam dozvoljeno kreiranje zapisa pomoću YAML datoteka" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -msgid "You must be a member of the \"YAML/Export\" group to export data as YAML." -msgstr "Morate bit član \"YAML/Izvoz\" grupe za izvoz podataka u YAML." diff --git a/addons/cetmix_tower_yaml/i18n/it.po b/addons/cetmix_tower_yaml/i18n/it.po deleted file mode 100644 index 7442838..0000000 --- a/addons/cetmix_tower_yaml/i18n/it.po +++ /dev/null @@ -1,1069 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * cetmix_tower_yaml -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2025-11-14 09:22+0100\n" -"Last-Translator: \n" -"Language-Team: Italian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Language: it\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 2.3\n" - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_export -msgid "" -"\n" -" Export data to YAML.\n" -" " -msgstr "" -"\n" -" Esporta dati a YAML.\n" -" " - -#. module: cetmix_tower_yaml -#: model:res.groups,comment:cetmix_tower_yaml.group_import -msgid "" -"\n" -" Import data from YAML.\n" -" " -msgstr "" -"\n" -" Importa dati da YAML.\n" -" " - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "'%s' is not a valid model" -msgstr "'%s' non è un modello valido" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#, python-format -msgid "'invalid_model' is not a valid model" -msgstr "'invalid_model' non è un modello valido" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Important: To maintain data consistency, the following\n" -" model records will always be updated if they exist in Odoo:" -msgstr "Importante: per mantenere la consistenza dei dati, i recod del modello seguenti verranno sempre aggiornati se esistono in Odoo:" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__add_manifest -msgid "Add Manifest" -msgstr "Aggiungi manifest" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "Add entire child record definitions to the exported YAML file. Otherwise only references to child records will be added." -msgstr "Aggiungere le definizioni di tutti i record figli allo YAML esportato. Altrimenti solo i riferimenti ai record figli verranno aggiunti." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__file_prefix -msgid "Add prefix to the exported YAML file name when this template is selected" -msgstr "Aggiungi prefisso al nome file YAML esportato quando è selezionato questo modello" - -#. module: cetmix_tower_yaml -#: model:res.groups,name:cetmix_tower_yaml.group_export -#: model:res.groups,name:cetmix_tower_yaml.group_import -msgid "Allow" -msgstr "Consenti" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_author_string -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Author" -msgstr "Autore" - -#. module: cetmix_tower_yaml -#: model:ir.model.constraint,message:cetmix_tower_yaml.constraint_cx_tower_yaml_manifest_author_yaml_manifest_author_name_uniq -msgid "Author name must be unique." -msgstr "il nome autore deve essere univoco." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_author_ids -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__author_ids -msgid "Authors" -msgstr "Autori" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_command -msgid "Cetmix Tower Command" -msgstr "Comando Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_file -msgid "Cetmix Tower File" -msgstr "File Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_file_template -msgid "Cetmix Tower File Template" -msgstr "Modello file Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan -msgid "Cetmix Tower Flight Plan" -msgstr "Piano di volo Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line -msgid "Cetmix Tower Flight Plan Line" -msgstr "Riga piano di volo Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_plan_line_action -msgid "Cetmix Tower Flight Plan Line Action" -msgstr "Azione riga piano di volo Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_key -msgid "Cetmix Tower Key/Secret Storage" -msgstr "Archivio chiave/segreto Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_os -msgid "Cetmix Tower Operating System" -msgstr "Sistema operativo Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_key_value -msgid "Cetmix Tower Secret Value Storage" -msgstr "Archivio valore segreto Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server -msgid "Cetmix Tower Server" -msgstr "Server Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_log -msgid "Cetmix Tower Server Log" -msgstr "Registro server Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_server_template -msgid "Cetmix Tower Server Template" -msgstr "Modello server Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_shortcut -msgid "Cetmix Tower Shortcut" -msgstr "Scorciatoia Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_tag -msgid "Cetmix Tower Tag" -msgstr "Etichetta Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable -msgid "Cetmix Tower Variable" -msgstr "Variabile Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_option -msgid "Cetmix Tower Variable Options" -msgstr "Opzioni variabile Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_variable_value -msgid "Cetmix Tower Variable Values" -msgstr "Valori variabile Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz_download -msgid "Cetmix Tower YAML Export File Download" -msgstr "Scarico file esportazione YAML Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_export_wiz -msgid "Cetmix Tower YAML Export Wizard" -msgstr "Procedura guidata esportazione YAML Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz -msgid "Cetmix Tower YAML Import Wizard" -msgstr "Procedura guidata importazione YAML Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_import_wiz_upload -msgid "Cetmix Tower YAML Import Wizard Upload" -msgstr "Aggiornamento procedura guidata importazione YAML Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_mixin -msgid "Cetmix Tower YAML rendering mixin" -msgstr "Mixin compilazione YAML Cetmix Tower" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_download_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Close" -msgstr "Chiudi" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Code preview" -msgstr "Anteprima codice" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_author_string -msgid "Comma-separated list" -msgstr "Elenco separato da virgola" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__create -msgid "Create a new record" -msgstr "Crea un nuovo record" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__create_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__create_uid -msgid "Created by" -msgstr "Creato da" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__create_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__create_date -msgid "Created on" -msgstr "Creato il" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_currency -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_currency -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__currency -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Currency" -msgstr "Valuta" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__currency -msgid "Currency for pricing information." -msgstr "Valuta per le informazioni di prezzo." - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "Currency is required when price is specified" -msgstr "La valuta è richiesta quando è indicato il prezzo" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Custom" -msgstr "Personalizzato" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license_text -msgid "Custom license text when license type is Custom." -msgstr "Testo licenza personalizzata quantdo il tipo licenza è personalizzato." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_description -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_description -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Description" -msgstr "Descrizione" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Detailed description (optional)" -msgstr "Descrizione dettagliata (opzionale)" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__display_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__display_name -msgid "Display Name" -msgstr "Nome visualizzato" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Error creating record '%(reference)s' in model '%(model)s': %(error)s" -msgstr "Errore durante la creazione del record '%(reference)s' nel modello '%(model)s': %(error)s" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Error updating record %(reference)s: %(error)s" -msgstr "Errore durante l'aggiornamento del record %(reference)s: %(error)s" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Euro" -msgstr "Euro" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"Existing record will be updated with the new data. Related records, present in the YAML code, will be updated too.\n" -" If any of those related records doesn't exist, it will be created automatically." -msgstr "" -"Il record esistente verrà aggiornato con i dati sucessivi. Anche il record relativo, presente nel record YAML, verrà aggiornato.\n" -" Se uno dei record collegati non esiste, verrà creato automaticamente." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__explode_child_records -msgid "Explode Child Records" -msgstr "Esplodi record figli" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_command_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_file_template_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_key_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_os_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_plan_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_scheduled_task_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_server_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_server_template_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_shortcut_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_tag_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_variable_export_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_variable_value_export_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "Export YAML" -msgstr "Esporta YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "Failed to convert dictionary to YAML: %(error)s" -msgstr "Conversione dizionario in YAML fallita: %(error)s" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "Failed to encode YAML content. Please ensure all characters are UTF-8 compatible." -msgstr "Codifica contenuto YAML fallita. Assicurarsi che tutti i caratteri sia compatibili UTF-8." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__file_name -msgid "File Name" -msgstr "Nome file" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "File is not a valid base64-encoded file" -msgstr "Il file non è un file codificato in base64 valido" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__file_prefix -msgid "File prefix" -msgstr "Prefisso file" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Following secrets are used in the code:
%(secrets)s" -msgstr "I seguenti segreti vengono utilizzati nel codice:
%(secrets)s" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Generate YAML file" -msgstr "Genera file YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__id -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__id -msgid "ID" -msgstr "ID" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__if_record_exists -msgid "If Record Exists" -msgstr "Se esiste il record" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Import" -msgstr "Importa" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_cx_tower_yaml_import_wiz_upload -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_cetmix_tower_yaml_import -msgid "Import YAML" -msgstr "Importa YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Import result: %(model)s" -msgstr "Importa risultato: %(model)s" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Information" -msgstr "Informazione" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Invalid YAML file" -msgstr "File YAML non valido" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Key/Secrets" -msgstr "Chiavi/segreti" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author____last_update -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__write_uid -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__write_uid -msgid "Last Updated by" -msgstr "Ultimo aggiornamento di" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__write_date -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__write_date -msgid "Last Updated on" -msgstr "Ultimo aggiornamento il" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_name -msgid "Leave this field blank if you don't want to create a manifest" -msgstr "Lasciare questo campo vuoto se non si vuole creare un manifest" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_license -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_license -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License" -msgstr "Licenza" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_license_text -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license_text -msgid "License Text" -msgstr "Testo licenza" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License and pricing" -msgstr "Licenza e prezzo" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_license_text -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "License text" -msgstr "Testo licenza" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "License text is required for a custom license" -msgstr "Il testo licenza è richiesto per una licenza personalizzata" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__license -msgid "License used for the code snippet." -msgstr "Licenza usata per l'esempio di codice." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__author_ids -msgid "List of author names to include in the YAML manifest." -msgstr "Elenco dei nomi degli autori da includere nel manifesto YAML." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__secret_list -msgid "List of secrets present in the YAML file (formatted as HTML list)" -msgstr "Elenco dei segreti presenti nel file YAML (formattati come una elenco HTML)" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Manifest" -msgstr "Manifest" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_manifest_author_action -msgid "Manifest Authors" -msgstr "Autori manifest" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_template_id -msgid "Manifest Template" -msgstr "Modello manifest" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_manifest_template -msgid "Manifest Templates" -msgstr "Modelli manifest" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Model '%s' does not support YAML import" -msgstr "Il modello '%s' non supporta l'importazione YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#, python-format -msgid "Model 'command_run_wizard' does not support YAML import" -msgstr "Il modello 'command_run_wizard' non supporta l'importazione YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_names -msgid "Model Names" -msgstr "Nomi modello" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__model_names -msgid "Models to create records in" -msgstr "Modelli in cui creare i record" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_author__name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__name -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Name" -msgstr "Nome" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__name -msgid "Name of the manifest template." -msgstr "Nome del modello manifest." - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No YAML code is present." -msgstr "Codice YAML non presente." - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No model or records selected" -msgstr "Nessun modello o record selezionato" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "No records were created or updated" -msgstr "Nessun record è stato creato o aggiornato" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "No valid records selected" -msgstr "Nessun record valido selezionato" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "OSs" -msgstr "SO" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__preview_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__preview_code -msgid "Preview Code" -msgstr "Anteprima codice" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Preview code" -msgstr "Anteprima codice" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_price -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_price -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Price" -msgstr "Prezzo" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_upload_view_form -msgid "Process" -msgstr "Processo" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Provide Custom License Text when License is set to 'Custom'." -msgstr "Fornisce un testo licenza personalizzato quando la licenza è impostata a \"Personalizzata\"." - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Record Import" -msgstr "Importa record" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Record model is missing for record %s" -msgstr "Manca il modello di record per il record %s" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Record reference is missing" -msgstr "Manca il riferimento al record" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#, python-format -msgid "Records of the following models were created or updated: %(models)s" -msgstr "Sono stati creati o aggiornati i record dei seguenti modelli: %(models)s" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "Remove Empty x2m Field Values" -msgstr "Rimozione dei valori campo x2m vuoti" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__remove_empty_values -msgid "Remove empty Many2one, Many2many and One2many field values from the exported YAML file." -msgstr "Rimozione dei valori campi Many2one, Many2many e One2many vuoti dal file YAML esportato." - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_scheduled_task -msgid "Scheduled Task" -msgstr "Lavoro schedulato" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__secret_list -msgid "Secret List" -msgstr "Elenco segreto" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Select a pre-defined template" -msgstr "Seleziona un modello predefinito" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Select a template to auto-populate manifest fields" -msgstr "Seleziona un modello per compilare automaticamente i campi del manifest" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_summary -msgid "Short summary that includes core information. 160 symbols max" -msgstr "Sommario breve che include le informazioni principali. Massimo 160 caratteri" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Short summary, 160 symbols max" -msgstr "Sommario breve, massimo 160 caratteri" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__skip -msgid "Skip record" -msgstr "Salta record" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_name -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_name -msgid "Snippet Name" -msgstr "Nome snippet" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_file_name -msgid "Snippet file name without extension, eg 'my_snippet'" -msgstr "Nome del file dello snippet senza estensione, es. 'my_snippet'" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_summary -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_summary -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Summary" -msgstr "Sommario" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Tags" -msgstr "Etichette" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "This may overwrite existing records. Proceed?" -msgstr "Questo potrebbe sovrascrivere i record esistenti. Procedere?" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "" -"To create new entities instead of updating existing ones, remove or modify\n" -" the reference field in the YAML code for those entities." -msgstr "Per creare nuove entità anziché aggiornare le esistenti, rimuovere o modificare il campo reference nel codice YAML per quelle entità." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__preview_code -msgid "Toggle to show or hide YAML code preview" -msgstr "Azionare per visualizzare o nascondere l'anteprima del codice YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "US Dollar" -msgstr "Dollaro USA" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields.selection,name:cetmix_tower_yaml.selection__cx_tower_yaml_import_wiz__if_record_exists__update -msgid "Update existing record" -msgstr "Aggiorna record esistente" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_version -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "Use the Major.Minor.Patch format, e.g. 1.2.3" -msgstr "Usare il formato Major.Minor.Patch, es. 1.2.3" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Values must be a dictionary" -msgstr "I valori devono essere un dizionario" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Variable Options" -msgstr "Opzioni variabile" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Variables" -msgstr "Variabili" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_version -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_version -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__version -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Version" -msgstr "Versione" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__version -msgid "Version in Major.Minor.Patch format, e.g. 1.0.0" -msgstr "Versione nel formato Major.Minor.Patch, es. 1.0.0" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_export_wiz.py:0 -#, python-format -msgid "Version must be in format Major.Minor.Patch, e.g. 1.2.3" -msgstr "La versione deve essere nel formato Major.Minor.Patch, es. 1.2.3" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py:0 -#, python-format -msgid "Version must be in the Major.Minor.Patch format, e.g. 1.2.3" -msgstr "La versione deve essere nel formato Major.Minor.Patch, es. 1.2.3" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__manifest_website -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__manifest_website -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__website -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_import_wiz_view_form -msgid "Website" -msgstr "Sito web" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_manifest_tmpl__website -msgid "Website URL for the manifest." -msgstr "URL sito web per il manifest." - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,help:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__if_record_exists -msgid "What to do if record with the same reference already exists" -msgstr "Cosa fare se esiste già un record con lo stesso riferimento" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#: code:addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py:0 -#, python-format -msgid "Wrong value for 'access_level' key: %(acv)s" -msgstr "Valore errato per la chiave 'access_level': %(acv)s" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "YAML" -msgstr "YAML" - -#. module: cetmix_tower_yaml -#: model:ir.module.category,name:cetmix_tower_yaml.ir_module_category_tower_yaml_export -msgid "YAML Export" -msgstr "Esporta YAML" - -#. module: cetmix_tower_yaml -#: model:ir.ui.menu,name:cetmix_tower_yaml.menu_yaml_settings_root -msgid "YAML Export/Import" -msgstr "Esporta/Importa YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_file_name -msgid "YAML File Name" -msgstr "Nome file YAML" - -#. module: cetmix_tower_yaml -#: model:ir.module.category,name:cetmix_tower_yaml.ir_module_category_tower_yaml_import -msgid "YAML Import" -msgstr "Importa YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_manifest_author -msgid "YAML Manifest Author" -msgstr "Autore manifest YAML" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_yaml_manifest_author -msgid "YAML Manifest Authors" -msgstr "Autori manifest YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model,name:cetmix_tower_yaml.model_cx_tower_yaml_manifest_tmpl -msgid "YAML Manifest Template" -msgstr "Modello manifest YAML" - -#. module: cetmix_tower_yaml -#: model:ir.actions.act_window,name:cetmix_tower_yaml.action_yaml_manifest_template -msgid "YAML Manifest Templates" -msgstr "Modelli manifest YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML file cannot be decoded properly" -msgstr "Il file YAML non può essere decodificato in modo corretto" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML file doesn't contain any records" -msgstr "Il file YAML non contiene nessun record" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "YAML version is higher than version supported by your Cetmix Tower instance. %(code_version)s > %(tower_version)s" -msgstr "La versione YAML è successiva a quella supportata dalla tua istanza Cetmix Tower. %(code_version)s > %(tower_version)s" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_command__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_file_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_key_value__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_os__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_plan_line_action__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_scheduled_task__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_log__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_server_template__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_shortcut__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_tag__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_option__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_variable_value__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz__yaml_code -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_mixin__yaml_code -msgid "Yaml Code" -msgstr "Codice YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_import_wiz_upload__yaml_file -msgid "Yaml File" -msgstr "File YAML" - -#. module: cetmix_tower_yaml -#: model:ir.model.fields,field_description:cetmix_tower_yaml.field_cx_tower_yaml_export_wiz_download__yaml_file_name -msgid "Yaml File Name" -msgstr "Nome file YAML" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py:0 -#: code:addons/cetmix_tower_yaml/wizards/cx_tower_yaml_import_wiz_upload.py:0 -#, python-format -msgid "Yaml file doesn't contain valid data" -msgstr "Il file YAML non contiene dati validi" - -#. module: cetmix_tower_yaml -#. odoo-python -#: code:addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py:0 -#, python-format -msgid "You are not allowed to create records from YAML" -msgstr "Non si è autorizzati a creare record da YAML" - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_command_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_file_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_plan_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_template_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_server_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_shortcut_view_form -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.view_cx_tower_scheduled_task_view_form -msgid "You must be a member of the \"YAML/Export\" group to export data as YAML." -msgstr "Bisogna appartenere al gruppo \"YAML/Export\" per esportare dati in YAML." - -#. module: cetmix_tower_yaml -#: model_terms:ir.ui.view,arch_db:cetmix_tower_yaml.cx_tower_yaml_export_wiz_view_form -msgid "my_snippet.yaml" -msgstr "my_snippet.yaml" - -#~ msgid "" -#~ "After import, please check and provide secret values if needed for the " -#~ "following secrets: %(secrets)s" -#~ msgstr "" -#~ "Dopo l'importazione, controllare e fornire i valori segreti, se " -#~ "necessario, per i seguenti segreti: %(secrets)s" - -#~ msgid "Comment" -#~ msgstr "Commento" - -#~ msgid "Comment to be added to the beginning of exported YAML file" -#~ msgstr "Commento da aggiungere all'inizio del file YAML esportato" - -#~ msgid "Cetmix Tower YAML" -#~ msgstr "YAML Cetmix Tower" - -#~ msgid "Cetmix Tower private key storage" -#~ msgstr "Deposito chiave privata Cetmix Tower" - -#~ msgid "" -#~ "If enabled, existing records will be updated with the new data. " -#~ "Otherwise, new records will be created." -#~ msgstr "" -#~ "Se abilitata, i record esistenti verranno aggiornati con i nuovi dati. " -#~ "altrimenti, verranno creati nuovi record." - -#~ msgid "Invalid model specified in the YAML file" -#~ msgstr "Modello non valido indicato nel file YAML" - -#~ msgid "Model" -#~ msgstr "Modello" - -#~ msgid "Open Existing Record" -#~ msgstr "Apri record esistente" - -#~ msgid "Record" -#~ msgstr "Record" - -#~ msgid "This will create a new record. Proceed?" -#~ msgstr "Questo creerà un nuovo record. Procedere?" - -#~ msgid "" -#~ "YAML file version is not supported. You may need to update the Cetmix " -#~ "Tower Yaml module." -#~ msgstr "" -#~ "La versione del file YAML non è supportata. Bisogna aggiornare il modulo " -#~ "YAML Cetmix Tower." - -#~ msgid "cx.tower.yaml.import.wiz" -#~ msgstr "cx.tower.yaml.import.wiz" - -#~ msgid "Add entire related record data instead of just a reference" -#~ msgstr "" -#~ "Aggiungere tutti i dati del record correlato invece di un solo riferimento" - -#~ msgid "Explode" -#~ msgstr "Esplodi" diff --git a/addons/cetmix_tower_yaml/migrations/16.0.1.4.1/post-migration.py b/addons/cetmix_tower_yaml/migrations/16.0.1.4.1/post-migration.py deleted file mode 100644 index 8238759..0000000 --- a/addons/cetmix_tower_yaml/migrations/16.0.1.4.1/post-migration.py +++ /dev/null @@ -1,19 +0,0 @@ -def migrate(cr, version): - """ - Normalize existing license values to lowercase. - Runs only on upgrade (version != False). - """ - if not version: - return - # Skip rows already lowercase for efficiency - cr.execute( - """ - UPDATE cx_tower_yaml_manifest_tmpl - SET license = LOWER(TRIM(license)) - WHERE license IS NOT NULL - AND ( - license <> LOWER(license) - OR license <> TRIM(license) - ) - """ - ) diff --git a/addons/cetmix_tower_yaml/models/__init__.py b/addons/cetmix_tower_yaml/models/__init__.py deleted file mode 100644 index 9d7745e..0000000 --- a/addons/cetmix_tower_yaml/models/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from . import cx_tower_yaml_mixin -from . import cx_tower_command -from . import cx_tower_file_template -from . import cx_tower_tag -from . import cx_tower_plan -from . import cx_tower_plan_line -from . import cx_tower_plan_line_action -from . import cx_tower_variable -from . import cx_tower_variable_option -from . import cx_tower_variable_value -from . import cx_tower_os -from . import cx_tower_server_template -from . import cx_tower_key -from . import cx_tower_key_value -from . import cx_tower_server_log -from . import cx_tower_shortcut -from . import cx_tower_scheduled_task -from . import cx_tower_file -from . import cx_tower_server -from . import cx_tower_yaml_manifest_template -from . import cx_tower_yaml_manifest_author diff --git a/addons/cetmix_tower_yaml/models/cx_tower_command.py b/addons/cetmix_tower_yaml/models/cx_tower_command.py deleted file mode 100644 index 7a02e39..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_command.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerCommand(models.Model): - _name = "cx.tower.command" - _inherit = ["cx.tower.command", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "access_level", - "name", - "action", - "allow_parallel_run", - "note", - "os_ids", - "tag_ids", - "path", - "file_template_id", - "flight_plan_id", - "code", - "server_status", - "variable_ids", - "secret_ids", - "no_split_for_sudo", - "if_file_exists", - "disconnect_file", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_file.py b/addons/cetmix_tower_yaml/models/cx_tower_file.py deleted file mode 100644 index 983fa40..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_file.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerFile(models.Model): - _name = "cx.tower.file" - _inherit = ["cx.tower.file", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "source", - "file_type", - "server_dir", - "code", - "file", - "variable_ids", - "secret_ids", - "template_id", - "keep_when_deleted", - "auto_sync", - "auto_sync_interval", - "sync_date_next", - "sync_date_last", - "server_response", - ] - return res - - def _post_create_write(self, op_type="write"): - # Do not pull/push files if they are being created from YAML - if self.env.context.get("from_yaml"): - return - super()._post_create_write(op_type) - - def _prepare_record_for_yaml(self): - """ - Override to drop file `code` when the source is 'server'. - """ - record_dict = super()._prepare_record_for_yaml() - - if record_dict.get("source") == "server": - record_dict["code"] = False - - return record_dict diff --git a/addons/cetmix_tower_yaml/models/cx_tower_file_template.py b/addons/cetmix_tower_yaml/models/cx_tower_file_template.py deleted file mode 100644 index 12572df..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_file_template.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerFileTemplate(models.Model): - _name = "cx.tower.file.template" - _inherit = ["cx.tower.file.template", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "source", - "file_type", - "server_dir", - "file_name", - "keep_when_deleted", - "tag_ids", - "note", - "code", - "variable_ids", - "secret_ids", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_jet_action.py b/addons/cetmix_tower_yaml/models/cx_tower_jet_action.py deleted file mode 100644 index 2af9459..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_jet_action.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerJetAction(models.Model): - _name = "cx.tower.jet.action" - _inherit = [ - "cx.tower.jet.action", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "note", - "priority", - "access_level", - "state_from_id", - "state_transit_id", - "state_to_id", - "state_error_id", - "plan_id", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_jet_state.py b/addons/cetmix_tower_yaml/models/cx_tower_jet_state.py deleted file mode 100644 index f4b6801..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_jet_state.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerJetState(models.Model): - _name = "cx.tower.jet.state" - _inherit = [ - "cx.tower.jet.state", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "sequence", - "access_level", - "color", - "note", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_jet_template.py b/addons/cetmix_tower_yaml/models/cx_tower_jet_template.py deleted file mode 100644 index 3dca470..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_jet_template.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerJetTemplate(models.Model): - _name = "cx.tower.jet.template" - _inherit = [ - "cx.tower.jet.template", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "note", - "tag_ids", - "limit_per_server", - "show_in_create_wizard", - "plan_install_id", - "plan_uninstall_id", - "plan_clone_same_server_id", - "plan_clone_different_server_id", - "variable_value_ids", - "action_ids", - "template_requires_ids", - "waypoint_template_ids", - "server_log_ids", - "scheduled_task_ids", - ] - return res - - def _get_deferred_x2m_import_fields(self): - """Return x2m child records resolved after the main import pass.""" - return { - "template_requires_ids": { - "child_model": "cx.tower.jet.template.dependency", - "deferred_field": "template_required_id", - "target_model": "cx.tower.jet.template", - } - } diff --git a/addons/cetmix_tower_yaml/models/cx_tower_jet_template_dependency.py b/addons/cetmix_tower_yaml/models/cx_tower_jet_template_dependency.py deleted file mode 100644 index da00652..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_jet_template_dependency.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerJetTemplateDependency(models.Model): - _name = "cx.tower.jet.template.dependency" - _inherit = [ - "cx.tower.jet.template.dependency", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "template_required_id", - "state_required_id", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_jet_waypoint_template.py b/addons/cetmix_tower_yaml/models/cx_tower_jet_waypoint_template.py deleted file mode 100644 index f9dfd73..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_jet_waypoint_template.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerJetWaypointTemplate(models.Model): - _name = "cx.tower.jet.waypoint.template" - _inherit = [ - "cx.tower.jet.waypoint.template", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "sequence", - "access_level", - "jet_template_id", - "plan_create_id", - "plan_arrive_id", - "plan_leave_id", - "plan_delete_id", - "note", - ] - return res - - def _get_deferred_m2o_import_fields(self): - """Return m2o waypoint-template fields resolved after import.""" - return { - "jet_template_id": "cx.tower.jet.template", - } diff --git a/addons/cetmix_tower_yaml/models/cx_tower_key.py b/addons/cetmix_tower_yaml/models/cx_tower_key.py deleted file mode 100644 index 80797f6..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_key.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerKey(models.Model): - _name = "cx.tower.key" - _inherit = [ - "cx.tower.key", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "key_type", - "note", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_key_value.py b/addons/cetmix_tower_yaml/models/cx_tower_key_value.py deleted file mode 100644 index f2a6b91..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_key_value.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerKeyValue(models.Model): - _name = "cx.tower.key.value" - _inherit = [ - "cx.tower.key.value", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "key_id", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_os.py b/addons/cetmix_tower_yaml/models/cx_tower_os.py deleted file mode 100644 index 5706768..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_os.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerOs(models.Model): - _name = "cx.tower.os" - _inherit = [ - "cx.tower.os", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "color", - "parent_id", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_plan.py b/addons/cetmix_tower_yaml/models/cx_tower_plan.py deleted file mode 100644 index b2cd039..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_plan.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerPlan(models.Model): - _name = "cx.tower.plan" - _inherit = ["cx.tower.plan", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "access_level", - "allow_parallel_run", - "color", - "tag_ids", - "note", - "on_error_action", - "custom_exit_code", - "line_ids", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_plan_line.py b/addons/cetmix_tower_yaml/models/cx_tower_plan_line.py deleted file mode 100644 index b28a997..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_plan_line.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerPlanLine(models.Model): - _name = "cx.tower.plan.line" - _inherit = ["cx.tower.plan.line", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "sequence", - "condition", - "use_sudo", - "path", - "command_id", - "action_ids", - "variable_ids", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_plan_line_action.py b/addons/cetmix_tower_yaml/models/cx_tower_plan_line_action.py deleted file mode 100644 index ce3e36d..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_plan_line_action.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerPlanLineAction(models.Model): - _name = "cx.tower.plan.line.action" - _inherit = ["cx.tower.plan.line.action", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "sequence", - "condition", - "value_char", - "action", - "custom_exit_code", - "variable_value_ids", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task.py b/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task.py deleted file mode 100644 index 9f7c820..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerScheduledTask(models.Model): - _name = "cx.tower.scheduled.task" - _inherit = ["cx.tower.scheduled.task", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "sequence", - "action", - "command_id", - "plan_id", - "interval_number", - "interval_type", - "next_call", - "last_call", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task_cv.py b/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task_cv.py deleted file mode 100644 index 688d752..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_scheduled_task_cv.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerScheduledTaskCv(models.Model): - _name = "cx.tower.scheduled.task.cv" - _inherit = [ - "cx.tower.scheduled.task.cv", - "cx.tower.yaml.mixin", - "cx.tower.reference.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += ["variable_value_id"] - return res - - def _post_process_yaml_dict_values(self, values): - """Populate required child fields from the linked variable value.""" - res = super()._post_process_yaml_dict_values(values) - variable_value_id = res.get("variable_value_id") - if variable_value_id: - variable_value = self.env["cx.tower.variable.value"].browse( - variable_value_id - ) - if variable_value.exists(): - res.update( - { - "name": variable_value.name, - "variable_id": variable_value.variable_id.id, - "option_id": variable_value.option_id.id or False, - "value_char": variable_value.value_char, - } - ) - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_server.py b/addons/cetmix_tower_yaml/models/cx_tower_server.py deleted file mode 100644 index 0633077..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_server.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerServer(models.Model): - _name = "cx.tower.server" - _inherit = [ - "cx.tower.server", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "ip_v4_address", - "ip_v6_address", - "skip_host_key", - "color", - "os_id", - "tag_ids", - "url", - "note", - "ssh_port", - "ssh_username", - "ssh_key_id", - "ssh_auth_mode", - "use_sudo", - "variable_value_ids", - "secret_ids", - "server_log_ids", - "shortcut_ids", - "scheduled_task_ids", - "plan_delete_id", - "file_ids", - "command_ids", - "plan_ids", - ] - return res - - def _get_force_x2m_resolve_models(self): - res = super()._get_force_x2m_resolve_models() - - # This is useful to avoid duplicating existing plans - res += [ - "cx.tower.shortcut", - "cx.tower.scheduled.task", - "cx.tower.command", - "cx.tower.plan", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_server_log.py b/addons/cetmix_tower_yaml/models/cx_tower_server_log.py deleted file mode 100644 index 34ff785..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_server_log.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerServerLog(models.Model): - _name = "cx.tower.server.log" - _inherit = [ - "cx.tower.server.log", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "log_type", - "command_id", - "use_sudo", - "file_template_id", - "file_id", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_server_template.py b/addons/cetmix_tower_yaml/models/cx_tower_server_template.py deleted file mode 100644 index 1390a06..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_server_template.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerServerTemplate(models.Model): - _name = "cx.tower.server.template" - _inherit = [ - "cx.tower.server.template", - "cx.tower.yaml.mixin", - ] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "color", - "os_id", - "tag_ids", - "note", - "ssh_port", - "ssh_username", - "ssh_key_id", - "ssh_auth_mode", - "use_sudo", - "variable_value_ids", - "server_log_ids", - "shortcut_ids", - "scheduled_task_ids", - "flight_plan_id", - "plan_delete_id", - ] - return res - - def _get_force_x2m_resolve_models(self): - res = super()._get_force_x2m_resolve_models() - - # Add Flight Plan in order to always try to use existing one - # This is useful to avoid duplicating existing plans - res += ["cx.tower.plan", "cx.tower.shortcut", "cx.tower.scheduled.task"] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_shortcut.py b/addons/cetmix_tower_yaml/models/cx_tower_shortcut.py deleted file mode 100644 index 51a2120..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_shortcut.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerShortcut(models.Model): - _name = "cx.tower.shortcut" - _inherit = ["cx.tower.shortcut", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "sequence", - "access_level", - "action", - "command_id", - "use_sudo", - "plan_id", - "note", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_tag.py b/addons/cetmix_tower_yaml/models/cx_tower_tag.py deleted file mode 100644 index d1fc446..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_tag.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerTag(models.Model): - _name = "cx.tower.tag" - _inherit = ["cx.tower.tag", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "color", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_variable.py b/addons/cetmix_tower_yaml/models/cx_tower_variable.py deleted file mode 100644 index 0a80468..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_variable.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerVariable(models.Model): - _name = "cx.tower.variable" - _inherit = ["cx.tower.variable", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "name", - "access_level", - "variable_type", - "option_ids", - "applied_expression", - "validation_pattern", - "validation_message", - "note", - "tag_ids", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_variable_option.py b/addons/cetmix_tower_yaml/models/cx_tower_variable_option.py deleted file mode 100644 index 81b3835..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_variable_option.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerVariableOption(models.Model): - _name = "cx.tower.variable.option" - _inherit = ["cx.tower.variable.option", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "sequence", - "access_level", - "name", - "value_char", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_variable_value.py b/addons/cetmix_tower_yaml/models/cx_tower_variable_value.py deleted file mode 100644 index 947d860..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_variable_value.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models - - -class CxTowerVariableValue(models.Model): - _name = "cx.tower.variable.value" - _inherit = ["cx.tower.variable.value", "cx.tower.yaml.mixin"] - - def _get_fields_for_yaml(self): - res = super()._get_fields_for_yaml() - res += [ - "sequence", - "access_level", - "variable_id", - "value_char", - "variable_ids", - "required", - ] - return res diff --git a/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_author.py b/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_author.py deleted file mode 100644 index e2dbbb5..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_author.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - - -from odoo import fields, models - - -class CxTowerYamlManifestAuthor(models.Model): - """Author of a YAML manifest (can be one or many).""" - - _name = "cx.tower.yaml.manifest.author" - - _sql_constraints = [ - ( - "yaml_manifest_author_name_uniq", - "unique(name)", - "Author name must be unique.", - ) - ] - _description = "YAML Manifest Author" - _order = "name" - - name = fields.Char(required=True, translate=False) diff --git a/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py b/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py deleted file mode 100644 index f0f3d57..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_yaml_manifest_template.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -import re - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class CxTowerYamlManifestTemplate(models.Model): - """Pre-defined YAML manifest template storing common metadata - such as authors, website, license, and currency for reuse - during YAML exports.""" - - _name = "cx.tower.yaml.manifest.tmpl" - _description = "YAML Manifest Template" - _order = "name" - - name = fields.Char( - required=True, - help="Name of the manifest template.", - ) - website = fields.Char(help="Website URL for the manifest.") - - author_ids = fields.Many2many( - "cx.tower.yaml.manifest.author", - string="Authors", - help="List of author names to include in the YAML manifest.", - ) - - license = fields.Selection( - selection=lambda self: self._selection_license(), - help="License used for the code snippet.", - ) - license_text = fields.Text( - help="Custom license text when license type is Custom.", - ) - - currency = fields.Selection( - selection=lambda self: self._selection_currency(), - help="Currency for pricing information.", - ) - - version = fields.Char( - help="Version in Major.Minor.Patch format, e.g. 1.0.0", - default="1.0.0", - ) - - file_prefix = fields.Char( - string="File prefix", - help="Add prefix to the exported YAML file name when this template is selected", - ) - - @api.model - def _selection_license(self): - """Return available license options for manifest.""" - return [ - ("agpl-3", "AGPL-3"), - ("lgpl-3", "LGPL-3"), - ("mit", "MIT"), - ("custom", _("Custom")), - ] - - @api.model - def _selection_currency(self): - """Return available currency options for manifest pricing.""" - return [ - ("EUR", _("Euro")), - ("USD", _("US Dollar")), - ] - - @api.constrains("license", "license_text") - def _check_license_text_for_custom(self): - """Ensure that custom license text is provided when license is 'custom'.""" - for rec in self: - if rec.license == "custom" and not (rec.license_text or "").strip(): - raise ValidationError( - _("Provide Custom License Text when License is set to 'Custom'.") - ) - - @api.constrains("version") - def _check_version_format(self): - """Ensure the template version follows the x.y.z semantic format. - - The version must consist of three non-negative integers (major, minor, patch) - separated by dots—for example, “1.2.3”. Raises a ValidationError otherwise. - """ - semver = re.compile(r"^\d+\.\d+\.\d+$") - for rec in self: - if rec.version and not semver.match(rec.version): - raise ValidationError( - _("Version must be in the Major.Minor.Patch format, e.g. 1.2.3") - ) diff --git a/addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py b/addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py deleted file mode 100644 index c089e83..0000000 --- a/addons/cetmix_tower_yaml/models/cx_tower_yaml_mixin.py +++ /dev/null @@ -1,577 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import logging - -import yaml - -from odoo import _, api, fields, models -from odoo.exceptions import AccessError, ValidationError - -_logger = logging.getLogger(__name__) - - -class CustomDumper(yaml.Dumper): - """Custom dumper to ensures code - is properly dumped in YAML - """ - - def represent_scalar(self, tag, value, style=None): - if isinstance(value, str) and "\n" in value: - style = "|" - return super().represent_scalar(tag, value, style) - - -class YamlExportCollector: - """ - Collector for YAML export. - Tracks unique records by their (model_name, reference) tuple to avoid duplicates. - """ - - def __init__(self): - """ - Initialize the collector. - """ - self.added_references = set() - - def add(self, key): - """ - Add a record to the collector if its reference is unique. - :param key: tuple, key of the record - """ - if key and key not in self.added_references: - self.added_references.add(key) - - def is_added(self, key): - """ - Check by (model, reference) tuple. - :param key: tuple, key of the record - :return: bool - """ - return key in self.added_references - - -class CxTowerYamlMixin(models.AbstractModel): - """Used to implement YAML rendering functions. - Inherit in your model in case you want to YAML instance of the records. - """ - - _name = "cx.tower.yaml.mixin" - _description = "Cetmix Tower YAML rendering mixin" - - # File format version in order to track compatibility - CETMIX_TOWER_YAML_VERSION = 1 - - # TO_YAML_* used to convert from Odoo field values to YAML - TO_YAML_ACCESS_LEVEL = {"1": "user", "2": "manager", "3": "root"} - - # TO_TOWER_* used to convert from YAML field values to Tower ones - TO_TOWER_ACCESS_LEVEL = {"user": "1", "manager": "2", "root": "3"} - - yaml_code = fields.Text( - compute="_compute_yaml_code", - inverse="_inverse_yaml_code", - groups="cetmix_tower_yaml.group_export,cetmix_tower_yaml.group_import", - ) - - def _compute_yaml_code(self): - """Compute YAML code based on model record data""" - - # This is used for the file name. - # Eg cx.tower.command record will have 'command_' prefix. - for record in self: - # We are reading field list for each record - # because list of fields can differ from record to record - record.yaml_code = self._convert_dict_to_yaml( - record._prepare_record_for_yaml() - ) - - def _inverse_yaml_code(self): - """Compose record based on provided YAML""" - for record in self: - if record.yaml_code: - record_yaml_dict = yaml.safe_load(record.yaml_code) - record_vals = record._post_process_yaml_dict_values(record_yaml_dict) - record.update(record_vals) - - @api.constrains("yaml_code") - def _check_yaml_code_write_access(self): - """ - Check if user has access to create records from YAML. - This is checked only when user already has access to export YAML. - Otherwise, the field is not accessible due to security group. - """ - if self.env.user.has_group("cetmix_tower_yaml.group_export") and ( - not self.env.user.has_group("cetmix_tower_yaml.group_import") - and not self.env.user._is_superuser() - ): - raise AccessError(_("You are not allowed to create records from YAML")) - - @api.model_create_multi - def create(self, vals_list): - # Handle validation error when field values are not valid - try: - return super().create(vals_list) - except ValueError as e: - raise ValidationError(str(e)) from e - - def write(self, vals): - # Handle validation error when field values are not valid - try: - return super().write(vals) - except ValueError as e: - raise ValidationError(str(e)) from e - - def action_open_yaml_export_wizard(self): - """Open YAML export wizard""" - - return { - "type": "ir.actions.act_window", - "res_model": "cx.tower.yaml.export.wiz", - "view_mode": "form", - "target": "new", - } - - def _convert_dict_to_yaml(self, values): - """Converts Python dictionary to YAML string. - - This is a helper function that is designed to be used - by any models that need to convert a dictionary to YAML. - - Args: - values (Dict): Dictionary containing data - to be converted to YAML format - Returns: - Text: YAML string - Raises: - ValidationError: If values is not a dictionary - or YAML conversion fails - """ - if not isinstance(values, dict): - raise ValidationError(_("Values must be a dictionary")) - try: - yaml_code = yaml.dump( - values, - Dumper=CustomDumper, - default_flow_style=False, - sort_keys=False, - ) - return yaml_code - except (yaml.YAMLError, UnicodeEncodeError) as e: - raise ValidationError( - _( - "Failed to convert dictionary" " to YAML: %(error)s", - error=str(e), - ) - ) from e - - def _prepare_record_for_yaml(self): - """Reads and processes current record before converting it to YAML - - Returns: - dict: values ready for YAML conversion - """ - self.ensure_one() - yaml_keys = self._get_fields_for_yaml() - record_dict = self.read(fields=yaml_keys)[0] - return self._post_process_record_values(record_dict) - - def _get_fields_for_yaml(self): - """Get ist of field to be present in YAML - - Set 'no_yaml_service_fields' context key to skip - service fields creation (cetmix_tower_yaml_version, cetmix_tower_model) - - Returns: - list(): list of fields to be used as YAML keys - """ - return ["reference"] - - def _get_force_x2m_resolve_models(self): - """List of models that will always try to be resolved - when referenced in x2m related fields. - - This is useful for models that should always use existing records - instead of creating new ones when referenced in x2m related fields. - Such as variables or tags. - - Returns: - List: list of models that will always try to be resolved - """ - return [ - "cx.tower.variable", - "cx.tower.variable.option", - "cx.tower.tag", - "cx.tower.os", - "cx.tower.key", - ] - - def _post_process_record_values(self, values): - """Post process record values - before converting them to YAML - - Args: - values (dict): values returned by 'read' method - - Context: - explode_related_record: if set will return entire record dictionary - not just a reference - remove_empty_values: if set will remove empty values from the record - - Returns: - dict(): processed values - """ - collector = self._context.get("yaml_collector") - ref = values.get("reference") - collector_key = (self._name, ref) if ref else None - - if collector and collector_key and collector.is_added(collector_key): - return {"reference": ref} - - # We don't need id because we are not using it - values.pop("id", None) - - # Add YAML format version and model - if not self._context.get("no_yaml_service_fields"): - model_name = self._name.replace("cx.tower.", "").replace(".", "_") - model_values = { - "cetmix_tower_model": model_name, - } - else: - model_values = {} - - # Parse access level - access_level = values.pop("access_level", None) - if access_level: - model_values.update( - {"access_level": self.TO_YAML_ACCESS_LEVEL[access_level]} - ) - - values = {**model_values, **values} - # Copy values to avoid modifying the original values - new_values = values.copy() - - # Check if we need to return a record dict or just a reference - # Use context value first, revert to the record setting if not defined - explode_related_record = self._context.get("explode_related_record") - - # Check if we need to remove empty values - # Currently only x2m fields are supported - remove_empty_values = self._context.get("remove_empty_values") - - # Post process m2o and x2m fields - for key, value in values.items(): - # IMPORTANT: Odoo naming patterns must be followed for related fields. - # This is why we are checking for the field name ending here. - # Further checks for the field type are done - # in _process_relation_field_value() - if key.endswith("_id") or key.endswith("_ids"): - if not value and remove_empty_values: - del new_values[key] - else: - processed_value = self.with_context( - explode_related_record=explode_related_record - )._process_relation_field_value(key, value, record_mode=True) - new_values.update({key: processed_value}) - - if collector and collector_key: - collector.add(collector_key) - - return new_values - - def _post_process_yaml_dict_values(self, values): - """Post process dictionary values generated from YAML code - - Args: - values (dict): Dictionary generated from YAML - - Returns: - dict(): Post-processed values - """ - - # Remove model data because it is not a field - if "cetmix_tower_model" in values: - values.pop("cetmix_tower_model") - - # Parse access level - if "access_level" in values: - values_access_level = values["access_level"] - access_level = self.TO_TOWER_ACCESS_LEVEL.get(values_access_level) - if access_level: - values.update({"access_level": access_level}) - else: - raise ValidationError( - _( - "Wrong value for 'access_level' key: %(acv)s", - acv=values_access_level, - ) - ) - - # Leave supported keys only - supported_keys = self._get_fields_for_yaml() - filtered_values = {k: v for k, v in values.items() if k in supported_keys} - - # Post process m2o fields - for key, value in filtered_values.items(): - # IMPORTANT: Odoo naming patterns must be followed for related fields. - # This is why we are checking for the field name ending here. - # Further checks for the field type are done - # in _process_relation_field_value() - if key.endswith("_id") or key.endswith("_ids"): - processed_value = self.with_context( - explode_related_record=True - )._process_relation_field_value(key, value, record_mode=False) - filtered_values.update({key: processed_value}) - - return filtered_values - - def _process_relation_field_value(self, field, value, record_mode=False): - """Post process One2many, Many2many or Many2one value - - Args: - field (Char): Field the value belongs to - value (Char): Value to process - record_mode (Bool): If True process value as a record value - else process value as a YAML value - Context: - explode_related_record: if set will return entire record dictionary - not just a reference - Returns: - dict() or Char: record dictionary if fetch_record else reference - """ - # Step 1: Return False if the value is not set or the field is not found - if not value: - return False - - field_obj = self._fields.get(field) - if not field_obj: - return False - - # Step 2: Return False if the field type doesn't match - # or comodel is not defined - field_type = field_obj.type - if ( - field_type not in ["one2many", "many2many", "many2one"] - or not field_obj.comodel_name - ): - return False - - comodel = self.env[field_obj.comodel_name] - explode_related_record = self._context.get("explode_related_record") - - # Step 3: process value based on the field type - if field_type == "many2one": - return self._process_m2o_value( - comodel, value, explode_related_record, record_mode - ) - if field_type in ["one2many", "many2many"]: - return self._process_x2m_values( - comodel, field_type, value, explode_related_record, record_mode - ) - - # Step 4: fall back if field type is not supported - return False - - def _process_m2o_value( - self, comodel, value, explode_related_record, record_mode=False - ): - """Post process many2one value - Args: - comodel (BaseClass): Model the value belongs to - value (Char): Value to process - explode_related_record (Bool): If True return entire record dict - instead of a reference - record_mode (Bool): If True process value as a record value - else process value as a YAML value - - Returns: - dict() or Char: record dictionary if fetch_record else reference - """ - - # -- (Record -> YAML) - if record_mode: - # Retrieve the record based on the ID provided in the value - record = comodel.browse(value[0]) - - # If the context specifies to explode the related record, - # return its dictionary representation - if explode_related_record: - return ( - record.with_context( - no_yaml_service_fields=True - )._prepare_record_for_yaml() - if record - else False - ) - - # Otherwise, return just the reference (or False if record does not exist) - return record.reference if record else False - - # -- (YAML -> Record) - # Step 1: Process value in normal mode - record = False - - # If the value is a string, it is treated as a reference - if isinstance(value, str): - reference = value - - # If the value is a dictionary, extract the reference from it - elif isinstance(value, dict): - reference = value.get("reference") - - record = self._update_or_create_related_record( - comodel, reference, value, create_immediately=True - ) - else: - return False - - # Step 2: Final fallback: attempt to retrieve the record by reference if set, - # return its ID or False - if not record and reference: - record = comodel.get_by_reference(reference) - return record.id if record else False - - def _process_x2m_values( - self, comodel, field_type, values, explode_related_record, record_mode=False - ): - """Post process many2many value - Args: - comodel (BaseClass): Model the value belongs to - field_type (Char): Field type - values (list()): Values to process - explode_related_record (Bool): If True return entire record dict - instead of a reference - record_mode (Bool): If True process value as a record value - else process value as a YAML value - - Returns: - dict() or Char: record dictionary if fetch_record else reference - """ - - # -- (Record -> YAML) - if record_mode: - record_list = [] - for value in values: - # Retrieve the record based on the ID provided in the value - record = comodel.browse(value) - - # If the context specifies to explode the related record, - # return its dictionary representation - if explode_related_record: - record_list.append( - record.with_context( - no_yaml_service_fields=True - )._prepare_record_for_yaml() - if record - else False - ) - - # Otherwise, return just the reference - # (or False if record does not exist) - else: - record_list.append(record.reference if record else False) - - return record_list - - # -- (YAML -> Record) - # Step 1: Process value in normal mode - record_ids = [] - - for value in values: - record = False - # If the value is a string, it is treated as a reference - if isinstance(value, str): - reference = value - - # If the value is a dictionary, extract the reference from it - elif isinstance(value, dict): - reference = value.get("reference") - record = self._update_or_create_related_record( - comodel, - reference, - value, - create_immediately=field_type == "many2many", - ) - - # Step 2: Final fallback: attempt to retrieve the record by reference - # Return record ID or False if reference is not defined - if not record and reference: - record = comodel.get_by_reference(reference) - - # Save record data - if record: - record_ids.append( - record if isinstance(record, tuple) else (4, record.id) - ) - - return record_ids - - def _update_or_create_related_record( - self, model, reference, values, create_immediately=False - ): - """Update related record with provided values or create a new one - - Args: - model (BaseModel): Related record model - values (dict()): Values to update existing/create new record - reference (Char): Record reference - create_immediately (Bool): If True create a new record immediately. - Used for Many2one fields. - - Context: - force_create_related_record (Bool): If True, create a new record - even if reference is provided. - - Returns: - record: Existing record or new record tuple - """ - - # If reference is found, retrieve the corresponding record - if reference and ( - model._name in self._get_force_x2m_resolve_models() - or not self._context.get("force_create_related_record") - ): - record = model.get_by_reference(reference) - # If the record exists, update it with the values from the dictionary - if record: - # Remove reference from values to avoid possible consequences - values.pop("reference", None) - record.with_context(from_yaml=True).write( - record._post_process_yaml_dict_values(values) - ) - - # If the record does not exist, create a new one - else: - if create_immediately: - record = model.with_context(from_yaml=True).create( - model._post_process_yaml_dict_values(values) - ) - else: - # Use "Create" service command tuple - record = (0, 0, model._post_process_yaml_dict_values(values)) - - # If there's no reference but value is a dict, create a new record - else: - if create_immediately: - # Only 'reference' provided, no other data: do not create, - # just log warning - if set(values.keys()) == {"reference"}: - _logger.warning( - "Attempted to import a record for model '%s' with reference " - "'%s', but only the 'reference' field was provided. " - "It is possible that this record has already been imported. " - "Creation will be skipped.", - model._name, - reference, - ) - return False - - record = model.with_context(from_yaml=True).create( - model._post_process_yaml_dict_values(values) - ) - else: - # Use "Create" service command tuple - record = (0, 0, model._post_process_yaml_dict_values(values)) - - # Return the record's ID if it exists, otherwise return False - return record or False diff --git a/addons/cetmix_tower_yaml/pyproject.toml b/addons/cetmix_tower_yaml/pyproject.toml deleted file mode 100644 index 4231d0c..0000000 --- a/addons/cetmix_tower_yaml/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build-system] -requires = ["whool"] -build-backend = "whool.buildapi" diff --git a/addons/cetmix_tower_yaml/readme/CONFIGURE.md b/addons/cetmix_tower_yaml/readme/CONFIGURE.md deleted file mode 100644 index 8c717e5..0000000 --- a/addons/cetmix_tower_yaml/readme/CONFIGURE.md +++ /dev/null @@ -1 +0,0 @@ -Please refer to the [official documentation](https://cetmix.com/tower) for detailed configuration instructions. diff --git a/addons/cetmix_tower_yaml/readme/DESCRIPTION.md b/addons/cetmix_tower_yaml/readme/DESCRIPTION.md deleted file mode 100644 index 2f07eba..0000000 --- a/addons/cetmix_tower_yaml/readme/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ -This module implements YAML format data import/export for [Cetmix Tower](https://cetmix.com/tower). - -Please refer to the [official documentation](https://cetmix.com/tower) for detailed information. diff --git a/addons/cetmix_tower_yaml/readme/HISTORY.md b/addons/cetmix_tower_yaml/readme/HISTORY.md deleted file mode 100644 index a9e2000..0000000 --- a/addons/cetmix_tower_yaml/readme/HISTORY.md +++ /dev/null @@ -1,69 +0,0 @@ -## 16.0.2.0.1 (2025-10-29) - -- Features: Improve the way secrets are listed in the YAML import widget. (5010) - - -## 16.0.1.4.2 (2025-10-06) - -- Bugfixes: Add the missing 'create' function decorator (4980) - - -## 16.0.1.4.1 (2025-08-26) - -- Bugfixes: Make selection values lowercase to simplify their management. (4896) - - -## 16.0.1.3.0 (2025-07-30) - -- Features: Optional behaviour when file uploaded by command already exists on the server. (4740) - - -## 16.0.1.1.4 (2025-07-08) - -- Bugfixes: Fix missing model names in YAML exports when exporting multiple commands with flight plans (4820) - - -## 16.0.1.1.3 (2025-07-07) - -- Bugfixes: Import servers with `Password` ssh authentication mode (4812) - - -## 16.0.1.1.1 (2025-06-23) - -- Features: YAML code optimisation (4728) - - -## 16.0.1.1.0 (2025-06-20) - -- Features: Export/import scheduled tasks to/from YAML. (4650) - - -## 16.0.1.0.5 (2025-05-21) - -- Features: Export/import secret values related to Server. (4696) - - -## 16.0.1.0.4 (2025-05-16) - -- Features: Export/import servers and files to/from YAML. (4670) - - -## 16.0.1.0.3 (2025-05-09) - -- Bugfixes: Non-critical issues and performance improvements. (4663) - - -## 16.0.1.0.2 (2025-04-30) - -- Features: User groups are visible without developer mode. (4642) - - -## 16.0.1.0.1 (2025-04-21) - -- Features: Export additional fields for shortcuts, variables and options. - Add action menu to export keys/secrets. (4602) - - -## 16.0.1.0.0 - -Release for Odoo 16.0 diff --git a/addons/cetmix_tower_yaml/readme/USAGE.md b/addons/cetmix_tower_yaml/readme/USAGE.md deleted file mode 100644 index 901f5a6..0000000 --- a/addons/cetmix_tower_yaml/readme/USAGE.md +++ /dev/null @@ -1 +0,0 @@ -Please refer to the [official documentation](https://cetmix.com/tower) for detailed usage instructions. diff --git a/addons/cetmix_tower_yaml/readme/newsfragments/.gitkeep b/addons/cetmix_tower_yaml/readme/newsfragments/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/addons/cetmix_tower_yaml/security/cetmix_tower_yaml_groups.xml b/addons/cetmix_tower_yaml/security/cetmix_tower_yaml_groups.xml deleted file mode 100644 index 3ff6ff0..0000000 --- a/addons/cetmix_tower_yaml/security/cetmix_tower_yaml_groups.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - YAML Export - - - - - YAML Import - - - - Allow - - - Export data to YAML. - - - - - Allow - - - Import data from YAML. - - - - diff --git a/addons/cetmix_tower_yaml/security/cx_tower_yaml_wizard_access_rules.xml b/addons/cetmix_tower_yaml/security/cx_tower_yaml_wizard_access_rules.xml deleted file mode 100644 index 97c3308..0000000 --- a/addons/cetmix_tower_yaml/security/cx_tower_yaml_wizard_access_rules.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - Creator only - - - [('create_uid', '=', user.id)] - - - - - Creator only - - - [('create_uid', '=', user.id)] - - - - - Creator only - - - [('create_uid', '=', user.id)] - - - - - Creator only - - - [('create_uid', '=', user.id)] - - - diff --git a/addons/cetmix_tower_yaml/security/ir.model.access.csv b/addons/cetmix_tower_yaml/security/ir.model.access.csv deleted file mode 100644 index bb6e5dd..0000000 --- a/addons/cetmix_tower_yaml/security/ir.model.access.csv +++ /dev/null @@ -1,9 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_yaml_export_wizard,Export YAML,model_cx_tower_yaml_export_wiz,group_export,1,1,1,1 -access_yaml_export_wizard_download,Export YAML File,model_cx_tower_yaml_export_wiz_download,group_export,1,1,1,1 -access_yaml_import_wizard_upload,Import YAML,model_cx_tower_yaml_import_wiz_upload,group_import,1,1,1,1 -access_yaml_import_wizard,Import YAML,model_cx_tower_yaml_import_wiz,group_import,1,1,1,1 -access_manifest_tmpl_read_export,Manifest tmpl read (export),model_cx_tower_yaml_manifest_tmpl,cetmix_tower_yaml.group_export,1,0,0,0 -access_manifest_tmpl_admin,Manifest tmpl admin,model_cx_tower_yaml_manifest_tmpl,cetmix_tower_server.group_root,1,1,1,1 -access_manifest_author_read_export,Manifest author read (export),model_cx_tower_yaml_manifest_author,cetmix_tower_yaml.group_export,1,0,0,0 -access_manifest_author_admin,Manifest author admin,model_cx_tower_yaml_manifest_author,cetmix_tower_server.group_root,1,1,1,1 diff --git a/addons/cetmix_tower_yaml/static/description/icon.png b/addons/cetmix_tower_yaml/static/description/icon.png deleted file mode 100644 index 2507f55..0000000 Binary files a/addons/cetmix_tower_yaml/static/description/icon.png and /dev/null differ diff --git a/addons/cetmix_tower_yaml/static/description/index.html b/addons/cetmix_tower_yaml/static/description/index.html deleted file mode 100644 index e12b94a..0000000 --- a/addons/cetmix_tower_yaml/static/description/index.html +++ /dev/null @@ -1,534 +0,0 @@ - - - - - -Cetmix Tower YAML - - - -
-

Cetmix Tower YAML

- - -

Beta License: AGPL-3 cetmix/cetmix-tower

-

This module implements YAML format data import/export for Cetmix -Tower.

-

Please refer to the official -documentation for detailed information.

-

Table of contents

- -
-

Configuration

-

Please refer to the official -documentation for detailed configuration -instructions.

-
-
-

Usage

-

Please refer to the official -documentation for detailed usage -instructions.

-
-
-

Changelog

-
-

16.0.2.0.1 (2025-10-29)

-
    -
  • Features: Improve the way secrets are listed in the YAML import -widget. (5010)
  • -
-
-
-

16.0.1.4.2 (2025-10-06)

-
    -
  • Bugfixes: Add the missing ‘create’ function decorator (4980)
  • -
-
-
-

16.0.1.4.1 (2025-08-26)

-
    -
  • Bugfixes: Make selection values lowercase to simplify their -management. (4896)
  • -
-
-
-

16.0.1.3.0 (2025-07-30)

-
    -
  • Features: Optional behaviour when file uploaded by command already -exists on the server. (4740)
  • -
-
-
-

16.0.1.1.4 (2025-07-08)

-
    -
  • Bugfixes: Fix missing model names in YAML exports when exporting -multiple commands with flight plans (4820)
  • -
-
-
-

16.0.1.1.3 (2025-07-07)

-
    -
  • Bugfixes: Import servers with Password ssh authentication mode -(4812)
  • -
-
-
-

16.0.1.1.1 (2025-06-23)

-
    -
  • Features: YAML code optimisation (4728)
  • -
-
-
-

16.0.1.1.0 (2025-06-20)

-
    -
  • Features: Export/import scheduled tasks to/from YAML. (4650)
  • -
-
-
-

16.0.1.0.5 (2025-05-21)

-
    -
  • Features: Export/import secret values related to Server. (4696)
  • -
-
-
-

16.0.1.0.4 (2025-05-16)

-
    -
  • Features: Export/import servers and files to/from YAML. (4670)
  • -
-
-
-

16.0.1.0.3 (2025-05-09)

-
    -
  • Bugfixes: Non-critical issues and performance improvements. (4663)
  • -
-
-
-

16.0.1.0.2 (2025-04-30)

-
    -
  • Features: User groups are visible without developer mode. (4642)
  • -
-
-
-

16.0.1.0.1 (2025-04-21)

-
    -
  • Features: Export additional fields for shortcuts, variables and -options. Add action menu to export keys/secrets. (4602)
  • -
-
-
-

16.0.1.0.0

-

Release for Odoo 16.0

-
-
-
-

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

Maintainers

-

This module is part of the cetmix/cetmix-tower project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/addons/cetmix_tower_yaml/tests/__init__.py b/addons/cetmix_tower_yaml/tests/__init__.py deleted file mode 100644 index b5e1e10..0000000 --- a/addons/cetmix_tower_yaml/tests/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from . import test_command -from . import test_tower_yaml_mixin -from . import test_file_template -from . import test_plan -from . import test_yaml_export_wizard -from . import test_yaml_import_wizard -from . import test_server_log -from . import test_server_yaml diff --git a/addons/cetmix_tower_yaml/tests/test_command.py b/addons/cetmix_tower_yaml/tests/test_command.py deleted file mode 100644 index bb4257f..0000000 --- a/addons/cetmix_tower_yaml/tests/test_command.py +++ /dev/null @@ -1,347 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import yaml - -from odoo.exceptions import ValidationError -from odoo.tests import TransactionCase - - -class TestTowerCommand(TransactionCase): - @classmethod - def setUpClass(cls, *args, **kwargs): - super().setUpClass(*args, **kwargs) - - cls.Command = cls.env["cx.tower.command"] - - # Expected YAML content of the test command - cls.command_test_yaml = """cetmix_tower_model: command -access_level: manager -reference: test_yaml_in_tests -name: Test YAML -action: ssh_command -allow_parallel_run: false -note: |- - Test YAML command conversion. - Ensure all fields are rendered properly. -os_ids: false -tag_ids: false -path: false -file_template_id: false -flight_plan_id: false -code: |- - cd /home/{{ tower.server.ssh_username }} \\ - && ls -lha -server_status: false -variable_ids: false -secret_ids: false -no_split_for_sudo: false -if_file_exists: skip -disconnect_file: false -""" - - # YAML content translated into Python dict - cls.command_test_yaml_dict = yaml.safe_load(cls.command_test_yaml) - - def test_yaml_from_command(self): - """Test if YAML is generated properly from a command""" - - # -- 0 -- - # Create test command - # Test command - command_test = self.Command.create( - { - "name": "Test YAML", - "reference": "test_yaml_in_tests", - "action": "ssh_command", - "code": """cd /home/{{ tower.server.ssh_username }} \\ -&& ls -lha""", - "note": """Test YAML command conversion. -Ensure all fields are rendered properly.""", - } - ) - - # -- 1 -- - # Check it YAML generated by the command matches - # YAML from the template file - self.assertEqual( - command_test.yaml_code, - self.command_test_yaml, - "YAML generated from command doesn't match template file one", - ) - - # -- 2 -- - # Check if YAML key values match Cetmix Tower ones - - self.assertEqual( - command_test.access_level, - self.Command.TO_TOWER_ACCESS_LEVEL[ - self.command_test_yaml_dict["access_level"] - ], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.action, - self.command_test_yaml_dict["action"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.allow_parallel_run, - self.command_test_yaml_dict["allow_parallel_run"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.code, - self.command_test_yaml_dict["code"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.name, - self.command_test_yaml_dict["name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.note, - self.command_test_yaml_dict["note"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.path, - self.command_test_yaml_dict["path"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.reference, - self.command_test_yaml_dict["reference"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.if_file_exists, - self.command_test_yaml_dict["if_file_exists"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command_test.disconnect_file, - self.command_test_yaml_dict["disconnect_file"], - "YAML value doesn't match Cetmix Tower one", - ) - - def test_command_from_yaml(self): - """Test if YAML is generated properly from a command""" - - def test_yaml(command): - """Checks if yaml values are inserted correctly - - Args: - command(cx.tower.command): _description_ - """ - self.assertEqual( - command.access_level, - self.Command.TO_TOWER_ACCESS_LEVEL[ - self.command_test_yaml_dict["access_level"] - ], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.action, - self.command_test_yaml_dict["action"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.allow_parallel_run, - self.command_test_yaml_dict["allow_parallel_run"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.code, - self.command_test_yaml_dict["code"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.name, - self.command_test_yaml_dict["name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.note, - self.command_test_yaml_dict["note"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.path, - self.command_test_yaml_dict["path"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.reference, - self.command_test_yaml_dict["reference"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.if_file_exists, - self.command_test_yaml_dict["if_file_exists"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - command.disconnect_file, - self.command_test_yaml_dict["disconnect_file"], - "YAML value doesn't match Cetmix Tower one", - ) - - # Create test command - command_test = self.Command.create( - {"name": "New Command", "action": "python_code"} - ) - - # -- 1 -- - # Insert YAML into the command and - # check if YAML key values match Cetmix Tower ones - command_test.yaml_code = self.command_test_yaml - test_yaml(command_test) - - # -- 2 -- - # Insert some non supported keys and ensure nothing bad happens - yaml_with_non_supported_keys = """access_level: manager -action: ssh_command -doge: wow -memes: much nice! -allow_parallel_run: false -cetmix_tower_model: command -code: |- - cd /home/{{ tower.server.ssh_username }} \\ - && ls -lha -file_template_id: false -flight_plan_id: false -name: Test YAML -note: |- - Test YAML command conversion. - Ensure all fields are rendered properly. -path: false -reference: test_yaml_in_tests -tag_ids: false -""" - command_test.yaml_code = yaml_with_non_supported_keys - test_yaml(command_test) - - # -- 3 -- - # Insert non existing selection field value and exception is raised - yaml_with_non_supported_keys = """access_level: manager -action: non_existing_action -doge: wow -memes: much nice! -allow_parallel_run: false -cetmix_tower_model: command -code: |- - cd /home/{{ tower.server.ssh_username }} \\ - && ls -lha -file_template_id: false -flight_plan_id: false -name: Test YAML -note: |- - Test YAML command conversion. - Ensure all fields are rendered properly. -path: false -reference: test_yaml_in_tests -tag_ids: false -""" - with self.assertRaises(ValidationError) as e: - command_test.yaml_code = yaml_with_non_supported_keys - self.assertIn("non_existing_action", str(e.exception)) - self.assertEqual( - str(e), - "Wrong value for cx.tower.command.action: 'non_existing_action'", - "Exception message doesn't match", - ) - - def test_command_with_action_file_template(self): - """Test command with 'File from template' action""" - yaml_with_reference = """cetmix_tower_model: command -access_level: manager -reference: such_much_test_command -name: Such Much Command -action: file_using_template -allow_parallel_run: false -note: Just a note -os_ids: false -tag_ids: false -path: false -file_template_id: my_custom_test_template -flight_plan_id: false -code: false -server_status: false -variable_ids: false -secret_ids: false -no_split_for_sudo: false -if_file_exists: skip -disconnect_file: false -""" - # Add file template - file_template = self.env["cx.tower.file.template"].create( - { - "name": "Such much demo", - "reference": "my_custom_test_template", - "file_name": "much_logs.txt", - "server_dir": "/var/log/my/files", - "source": "tower", - "file_type": "text", - "note": "Hey!", - "keep_when_deleted": False, - } - ) - command_with_template = self.Command.create( - { - "name": "Such Much Command", - "reference": "such_much_test_command", - "action": "file_using_template", - "note": "Just a note", - "file_template_id": file_template.id, - } - ) - - # -- 1 -- - # Check if final YAML composed correctly - self.assertEqual( - command_with_template.yaml_code, - yaml_with_reference, - "YAML is not composed correctly", - ) - - # -- 2 -- - # Explode related record and check the YAML - yaml_with_reference_exploded = """cetmix_tower_model: command -access_level: manager -reference: such_much_test_command -name: Such Much Command -action: file_using_template -allow_parallel_run: false -note: Just a note -os_ids: false -tag_ids: false -path: false -file_template_id: - reference: my_custom_test_template - name: Such much demo - source: tower - file_type: text - server_dir: /var/log/my/files - file_name: much_logs.txt - keep_when_deleted: false - tag_ids: false - note: Hey! - code: false - variable_ids: false - secret_ids: false -flight_plan_id: false -code: false -server_status: false -variable_ids: false -secret_ids: false -no_split_for_sudo: false -if_file_exists: skip -disconnect_file: false -""" - command_with_template.invalidate_recordset(["yaml_code"]) - self.assertEqual( - command_with_template.with_context(explode_related_record=True).yaml_code, - yaml_with_reference_exploded, - "YAML is not composed correctly", - ) diff --git a/addons/cetmix_tower_yaml/tests/test_file_template.py b/addons/cetmix_tower_yaml/tests/test_file_template.py deleted file mode 100644 index 097cb76..0000000 --- a/addons/cetmix_tower_yaml/tests/test_file_template.py +++ /dev/null @@ -1,320 +0,0 @@ -import yaml - -from odoo.tests import TransactionCase - - -class TestTowerFileTemplate(TransactionCase): - @classmethod - def setUpClass(cls, *args, **kwargs): - super().setUpClass(*args, **kwargs) - - cls.FileTemplate = cls.env["cx.tower.file.template"] - - # Expected YAML content of the test file template - cls.file_template_test_yaml = """cetmix_tower_model: file_template -reference: dockerfile_unit_test -name: Dockerfile Test -source: tower -file_type: text -server_dir: /opt -file_name: Dockerfile -keep_when_deleted: true -tag_ids: false -note: |- - Used to build Odoo addons image. - Depends on Odoo core image. -code: |- - FROM odoo:{{ odoo_test_version }} - # Install git-aggregator and tools for requirements generation - RUN pip3 install --upgrade pip && pip install manifestoo setuptools-odoo git-aggregator - # Let's go! - USER odoo -variable_ids: false -secret_ids: false -""" # noqa - - # Expected YAML content of the test file template - # without empty x2mvalues - cls.file_template_test_yaml_no_empty_values = """cetmix_tower_model: file_template -reference: dockerfile_unit_test -name: Dockerfile Test -source: tower -file_type: text -server_dir: /opt -file_name: Dockerfile -keep_when_deleted: true -note: |- - Used to build Odoo addons image. - Depends on Odoo core image. -code: |- - FROM odoo:{{ odoo_test_version }} - # Install git-aggregator and tools for requirements generation - RUN pip3 install --upgrade pip && pip install manifestoo setuptools-odoo git-aggregator - # Let's go! - USER odoo -""" # noqa - - # YAML content translated into Python dict - cls.file_template_test_yaml_dict = yaml.safe_load(cls.file_template_test_yaml) - cls.file_template_test_yaml_dict_no_empty_values = yaml.safe_load( - cls.file_template_test_yaml_no_empty_values - ) - - def test_yaml_from_file_template(self): - """Test if YAML is generated properly from a file""" - - # -- 0 -- - # Create test file - # Test file - file_template_test = self.FileTemplate.create( - { - "name": "Dockerfile Test", - "reference": "dockerfile_unit_test", - "file_name": "Dockerfile", - "server_dir": "/opt", - "source": "tower", - "keep_when_deleted": True, - "file_type": "text", - "code": """FROM odoo:{{ odoo_test_version }} -# Install git-aggregator and tools for requirements generation -RUN pip3 install --upgrade pip && pip install manifestoo setuptools-odoo git-aggregator -# Let's go! -USER odoo""", - "note": """Used to build Odoo addons image. -Depends on Odoo core image.""", - } - ) - - # -- 1 -- - # Check it YAML generated by the file matches - # YAML from the template file - - self.assertEqual( - file_template_test.yaml_code, - self.file_template_test_yaml, - "YAML generated from file doesn't match template file one", - ) - - # -- 2 -- - # Check if YAML key values match Cetmix Tower ones - - self.assertEqual( - file_template_test.source, - self.file_template_test_yaml_dict["source"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.file_name, - self.file_template_test_yaml_dict["file_name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.code, - self.file_template_test_yaml_dict["code"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.name, - self.file_template_test_yaml_dict["name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.note, - self.file_template_test_yaml_dict["note"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.server_dir, - self.file_template_test_yaml_dict["server_dir"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.reference, - self.file_template_test_yaml_dict["reference"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.file_type, - self.file_template_test_yaml_dict["file_type"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.keep_when_deleted, - self.file_template_test_yaml_dict["keep_when_deleted"], - "YAML value doesn't match Cetmix Tower one", - ) - - def test_yaml_from_file_template_no_empty_values(self): - """Test if YAML is generated properly from a file""" - - # -- 0 -- - # Create test file - # Test file - file_template_test = self.FileTemplate.with_context( - remove_empty_values=True - ).create( - { - "name": "Dockerfile Test", - "reference": "dockerfile_unit_test", - "file_name": "Dockerfile", - "server_dir": "/opt", - "source": "tower", - "keep_when_deleted": True, - "file_type": "text", - "code": """FROM odoo:{{ odoo_test_version }} -# Install git-aggregator and tools for requirements generation -RUN pip3 install --upgrade pip && pip install manifestoo setuptools-odoo git-aggregator -# Let's go! -USER odoo""", - "note": """Used to build Odoo addons image. -Depends on Odoo core image.""", - } - ) - - # -- 1 -- - # Check it YAML generated by the file matches - # YAML from the template file - - self.assertEqual( - file_template_test.yaml_code, - self.file_template_test_yaml_no_empty_values, - "YAML generated from file doesn't match template file one", - ) - - # -- 2 -- - # Check if YAML key values match Cetmix Tower ones - - self.assertEqual( - file_template_test.source, - self.file_template_test_yaml_dict_no_empty_values["source"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.file_name, - self.file_template_test_yaml_dict_no_empty_values["file_name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.code, - self.file_template_test_yaml_dict_no_empty_values["code"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.name, - self.file_template_test_yaml_dict_no_empty_values["name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.note, - self.file_template_test_yaml_dict_no_empty_values["note"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.server_dir, - self.file_template_test_yaml_dict_no_empty_values["server_dir"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.reference, - self.file_template_test_yaml_dict_no_empty_values["reference"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.file_type, - self.file_template_test_yaml_dict_no_empty_values["file_type"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template_test.keep_when_deleted, - self.file_template_test_yaml_dict_no_empty_values["keep_when_deleted"], - "YAML value doesn't match Cetmix Tower one", - ) - - def test_file_template_from_yaml(self): - """Test if YAML is generated properly from a file""" - - def test_yaml(file_template): - """Checks if yaml values are inserted correctly - - Args: - file_template (cx.tower.file.template): File template - """ - self.assertEqual( - file_template.source, - self.file_template_test_yaml_dict["source"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.file_name, - self.file_template_test_yaml_dict["file_name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.code, - self.file_template_test_yaml_dict["code"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.name, - self.file_template_test_yaml_dict["name"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.note, - self.file_template_test_yaml_dict["note"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.server_dir, - self.file_template_test_yaml_dict["server_dir"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.reference, - self.file_template_test_yaml_dict["reference"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.file_type, - self.file_template_test_yaml_dict["file_type"], - "YAML value doesn't match Cetmix Tower one", - ) - self.assertEqual( - file_template.keep_when_deleted, - self.file_template_test_yaml_dict["keep_when_deleted"], - "YAML value doesn't match Cetmix Tower one", - ) - - # Create test file template - file_template_test = self.FileTemplate.create({"name": "New file template"}) - - # -- 1 -- - # Insert YAML into the file and - # check if YAML key values match Cetmix Tower ones - file_template_test.yaml_code = self.file_template_test_yaml - test_yaml(file_template_test) - - # -- 2 -- - # Insert some non supported keys and ensure nothing bad happens - yaml_with_non_supported_keys = """cetmix_tower_model: file_template -code: |- - FROM odoo:{{ odoo_test_version }} - # Install git-aggregator and tools for requirements generation - RUN pip3 install --upgrade pip && pip install manifestoo setuptools-odoo git-aggregator - # Let's go! - USER odoo -doge: SoMuch style! -file_name: Dockerfile -file_type: text -keep_when_deleted: true -name: Dockerfile Test -note: |- - Used to build Odoo addons image. - Depends on Odoo core image. -reference: dockerfile_unit_test -server_dir: /opt -source: tower -tag_ids: false -""" # noqa - file_template_test.yaml_code = yaml_with_non_supported_keys - test_yaml(file_template_test) diff --git a/addons/cetmix_tower_yaml/tests/test_plan.py b/addons/cetmix_tower_yaml/tests/test_plan.py deleted file mode 100644 index 4d9ec43..0000000 --- a/addons/cetmix_tower_yaml/tests/test_plan.py +++ /dev/null @@ -1,179 +0,0 @@ -from odoo.tests import TransactionCase - - -class TestTowerPlan(TransactionCase): - @classmethod - def setUpClass(cls, *args, **kwargs): - super().setUpClass(*args, **kwargs) - - cls.Plan = cls.env["cx.tower.plan"] - - def test_plan_create_from_yaml(self): - """Test plan creation from YAML.""" - - plan_yaml = """cetmix_tower_model: plan -access_level: manager -reference: test_plan_from_yaml -name: 'Test Plan From Yaml' -allow_parallel_run: false -color: 0 -tag_ids: -- reference: doge_test_plan_tag - name: Doge Test Plan Tag - color: 1 -on_error_action: e -custom_exit_code: 0 -line_ids: -- sequence: 5 - condition: false - use_sudo: false - path: /such/much/{{ test_plan_dir }} - command_id: - access_level: manager - reference: very_much_command_test - name: Very much command - action: ssh_command - allow_parallel_run: false - note: false - code: Such much code - variable_ids: - - cetmix_tower_model: variable - reference: test_plan_dir - name: Test Plan Directory - action_ids: - - sequence: 1 - condition: == - value_char: '0' - action: n - custom_exit_code: 0 - variable_value_ids: - - cetmix_tower_model: variable_value - variable_id: - cetmix_tower_yaml_version: 1 - cetmix_tower_model: variable - reference: test_plan_branch - name: Test Plan Branch - value_char: production - - cetmix_tower_model: variable_value - variable_id: - cetmix_tower_yaml_version: 1 - cetmix_tower_model: variable - reference: test_plan_some_unique_variable - name: Test Plan Some Unique Variable - value_char: 'Final Value' - - cetmix_tower_model: plan_line_action - access_level: manager - sequence: 2 - condition: '>' - value_char: '0' - action: ec - custom_exit_code: 255 - variable_value_ids: false - variable_ids: false -""" - # -- 1 -- - # Create plan from YAML - plan_form_yaml = self.Plan.create( - {"name": "Name Placeholder", "yaml_code": plan_yaml} - ) - self.assertEqual( - plan_form_yaml.reference, - "test_plan_from_yaml", - "Reference is not set from YAML", - ) - # Name should be set from YAML - self.assertEqual( - plan_form_yaml.name, "Test Plan From Yaml", "Name is not set from YAML" - ) - - # -- 2 -- - # Check plan tags - plan_tags = plan_form_yaml.tag_ids - self.assertEqual(len(plan_tags), 1) - self.assertEqual(plan_tags.name, "Doge Test Plan Tag") - - # -- 3 -- - # Check plan lines - plan_lines = plan_form_yaml.line_ids - self.assertEqual(len(plan_lines), 1, "Line count is not 1") - self.assertFalse(plan_lines.condition, "Condition is not false") - self.assertEqual( - plan_lines.path, - "/such/much/{{ test_plan_dir }}", - "Path is not set from YAML", - ) - self.assertEqual( - plan_lines.command_id.reference, - "very_much_command_test", - "Command reference is not set from YAML", - ) - self.assertEqual( - plan_lines.command_id.name, - "Very much command", - "Command name is not set from YAML", - ) - self.assertEqual( - plan_lines.command_id.action, - "ssh_command", - "Command action is not set from YAML", - ) - self.assertFalse( - plan_lines.command_id.allow_parallel_run, - "Command allow parallel run is not set from YAML", - ) - self.assertFalse( - plan_lines.command_id.note, "Command note is not set from YAML" - ) - self.assertEqual( - plan_lines.command_id.variable_ids.mapped("reference"), - ["test_plan_dir"], - "Command variable ids is not set from YAML", - ) - self.assertEqual( - plan_lines.command_id.access_level, - "2", - "Command access level is not set from YAML", - ) - - # -- 4 -- - # Check plan line actions - plan_actions = plan_form_yaml.line_ids.action_ids - self.assertEqual(len(plan_actions), 2, "Action count is not 2") - self.assertEqual( - plan_actions[0].condition, "==", "First action condition is not equal" - ) - self.assertEqual( - plan_actions[0].value_char, "0", "First action value char is not 0" - ) - self.assertEqual(plan_actions[0].action, "n", "First action action is not n") - self.assertEqual( - plan_actions[0].custom_exit_code, - 0, - "First action custom exit code is not 0", - ) - self.assertEqual( - len(plan_actions[0].variable_value_ids), - 2, - "Number of variable value ids is not correct", - ) - self.assertEqual( - plan_actions[0].variable_value_ids.mapped("value_char"), - ["production", "Final Value"], - "Variable value chars are not correct", - ) - self.assertEqual( - plan_actions[1].condition, ">", "Second action condition is not greater" - ) - self.assertEqual( - plan_actions[1].value_char, "0", "Second action value char is not 0" - ) - self.assertEqual(plan_actions[1].action, "ec", "Second action action is not ec") - self.assertEqual( - plan_actions[1].custom_exit_code, - 255, - "Second action custom exit code is not 255", - ) - self.assertFalse( - plan_actions[1].variable_value_ids, - "Second action variable value ids is not false", - ) diff --git a/addons/cetmix_tower_yaml/tests/test_server_log.py b/addons/cetmix_tower_yaml/tests/test_server_log.py deleted file mode 100644 index 4849332..0000000 --- a/addons/cetmix_tower_yaml/tests/test_server_log.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -""" -Tests for the cx.tower.server.log model YAML export/import. - -Covers: -1. YAML export of a file-type log must include `file_id` and allow suffixes. -2. A full round-trip (export → delete → import) preserves the `file_id` relation. -3. Exporting a non-file log must include a falsy `file_id`. -4. Importing YAML with a bogus `file_id` reference raises ValidationError. -""" - -import yaml - -from odoo.tests import TransactionCase, tagged - - -@tagged("post_install", "-at_install") -class TestServerLog(TransactionCase): - """YAML export/import tests for cx.tower.server.log.""" - - @classmethod - def setUpClass(cls): - super().setUpClass() - env = cls.env - cls.File = env["cx.tower.file"] - cls.Server = env["cx.tower.server"] - cls.ServerLog = env["cx.tower.server.log"] - - # Create a file to reference from the log - cls.file = cls.File.create( - { - "name": "repos.yaml", - "reference": "reposyaml", - "source": "tower", - "file_type": "text", - "server_dir": "/tmp", - "code": "# Example\nHello, Tower!", - } - ) - - # Create a server (use password auth to satisfy constraints) - cls.server = cls.Server.create( - { - "name": "Srv-YAML-Test", - "reference": "srv_yaml_test", - "ip_v4_address": "127.0.0.1", - "ssh_username": "admin", - "ssh_port": 22, - "ssh_auth_mode": "p", - "ssh_password": "dummy", - "use_sudo": False, - } - ) - - # Create a file-type log linked to the file above - cls.log = cls.ServerLog.create( - { - "name": "Log from file", - "reference": "log_from_file", - "log_type": "file", - "file_id": cls.file.id, - "server_id": cls.server.id, - "use_sudo": False, - } - ) - - def test_yaml_export_contains_file_id(self): - """Exported YAML must include a file_id starting with the file's reference.""" - data = yaml.safe_load(self.log.yaml_code) - # Ensure file_id is present - self.assertIn("file_id", data, "`file_id` is missing from YAML export") - # Allow for auto-appended suffixes, so only check prefix - self.assertTrue( - data["file_id"].startswith(self.file.reference), - f"`file_id` value '{data['file_id']}' should start with " - f"'{self.file.reference}'", - ) - - def test_yaml_roundtrip_restores_file_id(self): - """A full export→delete→import cycle must restore the file_id relation.""" - yaml_dict = yaml.safe_load(self.log.yaml_code) - # Remove the original log - self.log.unlink() - # Recreate from YAML - vals = self.ServerLog._post_process_yaml_dict_values(yaml_dict) - restored = self.ServerLog.with_context(from_yaml=True).create(vals) - # Verify relation restored - self.assertEqual( - restored.file_id.id, - self.file.id, - "`file_id` was not restored after round-trip", - ) - - def test_yaml_export_without_file_id(self): - """Logs of non-file type should not include file_id in YAML.""" - cmd_log = self.ServerLog.create( - { - "name": "Log no file", - "reference": "log_no_file", - "log_type": "command", - "server_id": self.server.id, - "use_sudo": False, - } - ) - data = yaml.safe_load(cmd_log.yaml_code) - # key is present, but must be falsy - self.assertIn("file_id", data, "`file_id` key is missing") - self.assertFalse( - data["file_id"], - "`file_id` for non-file log must be False/empty", - ) - - def test_yaml_import_with_missing_file_reference(self): - """Missing file reference is accepted, but file_id stays empty.""" - yaml_dict = yaml.safe_load(self.log.yaml_code) - yaml_dict["file_id"] = "does_not_exist" - - vals = self.ServerLog._post_process_yaml_dict_values(yaml_dict) - new_log = self.ServerLog.with_context(from_yaml=True).create(vals) - - # Log is created, but the relation is not resolved - self.assertFalse( - new_log.file_id, - "file_id should be empty when reference cannot be resolved", - ) diff --git a/addons/cetmix_tower_yaml/tests/test_server_yaml.py b/addons/cetmix_tower_yaml/tests/test_server_yaml.py deleted file mode 100644 index 2592f39..0000000 --- a/addons/cetmix_tower_yaml/tests/test_server_yaml.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (C) 2025 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -""" -Tests for cx.tower.server YAML export/import covering command_ids and plan_ids. -""" -import yaml - -from odoo.tests import TransactionCase, tagged - - -@tagged("post_install", "-at_install") -class TestServerYAML(TransactionCase): - """YAML export/import tests for cx.tower.server with commands and plans.""" - - @classmethod - def setUpClass(cls): - super().setUpClass() - env = cls.env - cls.Server = env["cx.tower.server"] - cls.Command = env["cx.tower.command"] - cls.Plan = env["cx.tower.plan"] - - # Create a command to attach (use defaults for access_level) - cls.command = cls.Command.create( - { - "name": "Test Command", - "reference": "test_command", - "action": "ssh_command", - "allow_parallel_run": False, - } - ) - - # Create a flight plan to attach - cls.plan = cls.Plan.create( - { - "name": "Test Flight Plan", - "reference": "test_plan", - "allow_parallel_run": False, - "color": 0, - } - ) - - # Create server and link command and plan - cls.server = cls.Server.create( - { - "name": "Server YAML Test", - "reference": "srv_yaml_test", - "ip_v4_address": "127.0.0.1", - "ssh_username": "admin", - "ssh_port": 22, - "ssh_auth_mode": "p", - "ssh_password": "dummy", - "use_sudo": False, - # Link the m2m fields - "command_ids": [(6, 0, [cls.command.id])], - "plan_ids": [(6, 0, [cls.plan.id])], - } - ) - - def test_yaml_export_contains_command_and_plan(self): - """Exported YAML include command_ids and plan_ids with correct references.""" - data = yaml.safe_load(self.server.yaml_code) - # Check command_ids - self.assertIn( - "command_ids", - data, - "`command_ids` is missing from YAML export", - ) - self.assertIsInstance( - data["command_ids"], list, "`command_ids` should be a list in YAML" - ) - self.assertTrue( - data["command_ids"], - "`command_ids` list should not be empty", - ) - # Only reference should be exported - self.assertEqual( - data["command_ids"][0], - self.command.reference, - "Exported command reference does not match", - ) - - # Check plan_ids - self.assertIn( - "plan_ids", - data, - "`plan_ids` is missing from YAML export", - ) - self.assertIsInstance( - data["plan_ids"], list, "`plan_ids` should be a list in YAML" - ) - self.assertTrue( - data["plan_ids"], - "`plan_ids` list should not be empty", - ) - self.assertEqual( - data["plan_ids"][0], - self.plan.reference, - "Exported plan reference does not match", - ) - - def test_yaml_roundtrip_restores_command_and_plan(self): - """A full export→delete→import cycle must restore the m2m relations.""" - yaml_dict = yaml.safe_load(self.server.yaml_code) - # Remove original server - self.server.unlink() - # Prepare values and import - vals = self.Server._post_process_yaml_dict_values(yaml_dict) - restored = self.Server.with_context( - from_yaml=True, skip_ssh_settings_check=True - ).create(vals) - - # Verify m2m links restored - self.assertEqual( - restored.command_ids.ids, - [self.command.id], - "`command_ids` were not restored correctly", - ) - self.assertEqual( - restored.plan_ids.ids, - [self.plan.id], - "`plan_ids` were not restored correctly", - ) diff --git a/addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py b/addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py deleted file mode 100644 index bf456eb..0000000 --- a/addons/cetmix_tower_yaml/tests/test_tower_yaml_mixin.py +++ /dev/null @@ -1,525 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - - -from odoo import _ -from odoo.exceptions import AccessError, ValidationError -from odoo.tests import TransactionCase, tagged - - -class TestTowerYamlMixin(TransactionCase): - @classmethod - def setUpClass(cls, *args, **kwargs): - super().setUpClass(*args, **kwargs) - cls.Users = cls.env["res.users"].with_context(no_reset_password=True) - cls.YamlMixin = cls.env["cx.tower.yaml.mixin"] - TowerTag = cls.env["cx.tower.tag"] - cls.tag_doge = TowerTag.create({"name": "Doge", "reference": "doge"}) - cls.tag_pepe = TowerTag.create({"name": "Pepe", "reference": "pepe"}) - - def test_convert_dict_to_yaml(self): - # -- 1 -- - # Test regular flow - self.assertEqual( - self.YamlMixin._convert_dict_to_yaml({"a": 1, "b": 2}), - "a: 1\nb: 2\n", - "Dictionary was not converted to YAML correctly", - ) - - # -- 2 -- - # Test flow with exception due to wrong values - with self.assertRaises(ValidationError) as e: - self.YamlMixin._convert_dict_to_yaml("not_a_dict") - self.assertEqual( - str(e.exception), - _("Values must be a dictionary"), - "Exception message doesn't match", - ) - - def test_yaml_field_access(self): - # Create Root user with no access to the 'yaml_code field - user_root = self.Users.create( - { - "name": "Root User", - "login": "root@example.com", - "groups_id": [ - (4, self.env.ref("base.group_user").id), - (4, self.env.ref("cetmix_tower_server.group_root").id), - ], - } - ) - with self.assertRaises(AccessError): - self.tag_doge.with_user(user_root).read(["yaml_code"]) - - # Add user to the 'cetmix_tower_yaml.group_export' group - # and check if access is granted - user_root.write( - {"groups_id": [(4, self.env.ref("cetmix_tower_yaml.group_export").id)]} - ) - yaml_code = ( - self.tag_doge.with_user(user_root).read(["yaml_code"])[0].get("yaml_code") - ) - - # Modify YAML code and check if it's saved - yaml_code = yaml_code.replace("Doge", "WowDoge") - with self.assertRaises(AccessError): - self.tag_doge.with_user(user_root).write({"yaml_code": yaml_code}) - - # Add user to the 'cetmix_tower_yaml.group_import' group - # and check if access is granted - user_root.write( - {"groups_id": [(4, self.env.ref("cetmix_tower_yaml.group_import").id)]} - ) - self.tag_doge.with_user(user_root).write({"yaml_code": yaml_code}) - self.assertEqual( - self.tag_doge.with_user(user_root).yaml_code, - yaml_code, - "YAML code was not saved", - ) - - def test_post_process_record_values(self): - """Test value post processing. - We test common fields only because this method can be overridden - in models inheriting this mixin. - """ - - # Patch method to return "access_level" field too - def _get_fields_for_yaml(self): - return ["access_level", "name", "reference"] - - self.YamlMixin._patch_method("_get_fields_for_yaml", _get_fields_for_yaml) - - source_values = { - "access_level": "3", - "id": 22332, - "name": "Doge Much Like", - "reference": "such_much_doge", - } - - result_values = self.YamlMixin._post_process_record_values(source_values.copy()) - - self.assertNotIn("id", result_values, "ID must be removed") - self.assertEqual( - result_values["access_level"], - self.YamlMixin.TO_YAML_ACCESS_LEVEL[source_values["access_level"]], - "Access level is not parsed correctly", - ) - self.assertEqual( - result_values["name"], - source_values["name"], - "Other values should remain unchanged", - ) - self.assertEqual( - result_values["reference"], - source_values["reference"], - "Other values should remain unchanged", - ) - - # Restore original method - self.YamlMixin._revert_method("_get_fields_for_yaml") - - def test_post_process_yaml_dict_values(self): - """Test YAML dict value post processing. - We test common fields only because this method can be overridden - in models inheriting this mixin. - """ - - # Patch method to return "access_level" field too - def _get_fields_for_yaml(self): - return ["access_level", "name", "reference"] - - self.YamlMixin._patch_method("_get_fields_for_yaml", _get_fields_for_yaml) - - # -- 1 -- - # Test regular flow - source_values = { - "access_level": "user", - "name": "Doge Much Like", - "reference": "such_much_doge", - "some_doge_field": "some_meme", - } - - result_values = self.YamlMixin._post_process_yaml_dict_values( - source_values.copy() - ) - self.assertNotIn( - "some_doge_field", result_values, "Non listed fields must be removed" - ) - self.assertEqual( - result_values["access_level"], - self.YamlMixin.TO_TOWER_ACCESS_LEVEL[source_values["access_level"]], - "Access level is not parsed correctly", - ) - self.assertEqual( - result_values["name"], - source_values["name"], - "Other values should remain unchanged", - ) - self.assertEqual( - result_values["reference"], - source_values["reference"], - "Other values should remain unchanged", - ) - - # -- Test 2 -- - # Submit wrong value for access level - source_values.update( - { - "access_level": "doge", - } - ) - with self.assertRaises(ValidationError) as e: - result_values = self.YamlMixin._post_process_yaml_dict_values( - source_values.copy() - ) - self.assertEqual( - str(e.exception), - _( - "Wrong value for 'access_level' key: %(acv)s", - acv="doge", - ), - "Exception message doesn't match", - ) - - # Restore original method - self.YamlMixin._revert_method("_get_fields_for_yaml") - - def test_process_relation_field_value_no_explode(self): - """Test non exploded related field values. - Non exploded values represent related record with reference only. - - Covers the following child functions: - - _process_m2o_value(..) - - _process_x2m_values(..) - """ - - # We are using command with file template for that - file_template = self.env["cx.tower.file.template"].create( - {"name": "Test m2o", "reference": "test_m2o"} - ) - command = self.env["cx.tower.command"].create( - { - "name": "Command test m2o", - "action": "file_using_template", - "file_template_id": file_template.id, - "tag_ids": [(4, self.tag_doge.id), (4, self.tag_pepe.id)], - } - ) - - # -- 1 -- - # Record -> Yaml - - # -- 1.1 -- - # Many2one - result = command._process_relation_field_value( - field="file_template_id", - value=(command.file_template_id.id, command.file_template_id.name), - record_mode=True, - ) - self.assertEqual( - result, file_template.reference, "Reference was not resolved correctly" - ) - # -- 1.2 -- - # Many2many - result = command._process_relation_field_value( - field="tag_ids", - value=[self.tag_doge.id, self.tag_pepe.id], - record_mode=True, - ) - - self.assertEqual(len(result), 2, "Must be 2 references") - self.assertIn( - self.tag_doge.reference, result, "Reference was not resolved correctly" - ) - self.assertIn( - self.tag_pepe.reference, result, "Reference was not resolved correctly" - ) - - # -- 2 -- - # Yaml -> Record - - # -- 2.1. -- - # Many2one - result = command._process_relation_field_value( - field="file_template_id", value=file_template.reference, record_mode=False - ) - self.assertEqual( - result, file_template.id, "Record ID was not resolved correctly" - ) - - # -- 2.2 -- - # Many2many - result = command._process_relation_field_value( - field="tag_ids", - value=[self.tag_doge.reference, self.tag_pepe.reference], - record_mode=False, - ) - self.assertEqual(len(result), 2, "Must be 2 records") - self.assertIn( - (4, self.tag_doge.id), result, "Record ID was not resolved correctly" - ) - self.assertIn( - (4, self.tag_pepe.id), result, "Record ID was not resolved correctly" - ) - - # -- 3 -- - # Yaml with non existing reference -> Record - result = command._process_relation_field_value( - field="file_template_id", value="such_much_not_reference", record_mode=False - ) - self.assertFalse(result, "Must be 'False'") - - # -- 4 -- - # No record -> Yaml - result = command._process_relation_field_value( - field="file_template_id", - value=self.env["cx.tower.file.template"], - record_mode=True, - ) - self.assertFalse(result, "Result must be 'False'") - - def test_process_relation_field_value_explode(self): - """Test exploded related field values. - Exploded values represent related record with a child YAML structure. - - Covers the following child functions: - - _process_m2o_value(..) - - _process_x2m_values(..) - """ - - # We are using command with file template for that - file_template = self.env["cx.tower.file.template"].create( - {"name": "Test m2o", "reference": "test_m2o"} - ) - file_template_values = file_template.with_context( - no_yaml_service_fields=True - )._prepare_record_for_yaml() - tag_doge_values = self.tag_doge.with_context( - no_yaml_service_fields=True - )._prepare_record_for_yaml() - tag_pepe_values = self.tag_pepe.with_context( - no_yaml_service_fields=True - )._prepare_record_for_yaml() - command = ( - self.env["cx.tower.command"] - .create( - { - "name": "Command test m2o", - "action": "file_using_template", - "file_template_id": file_template.id, - "tag_ids": [(4, self.tag_doge.id), (4, self.tag_pepe.id)], - } - ) - .with_context(explode_related_record=True) - ) # and this is the actual trigger - - # -- 1 -- - # Record -> Yaml - - # -- 1.1 -- - # Many2one - result = command._process_relation_field_value( - field="file_template_id", - value=(command.file_template_id.id, command.file_template_id.name), - record_mode=True, - ) - self.assertEqual( - result, file_template_values, "Reference was not resolved correctly" - ) - - # -- 1.2 -- - # Many2many - result = command._process_relation_field_value( - field="tag_ids", - value=[self.tag_doge.id, self.tag_pepe.id], - record_mode=True, - ) - self.assertEqual(len(result), 2, "Must be 2 records") - self.assertIn(tag_doge_values, result, "Record ID was not resolved correctly") - self.assertIn(tag_pepe_values, result, "Record ID was not resolved correctly") - - # -- 2 -- - # Yaml -> Record - - # -- 2.1 -- - # Many2one - result = command._process_relation_field_value( - field="file_template_id", value=file_template_values, record_mode=False - ) - self.assertEqual( - result, file_template.id, "Record ID was not resolved correctly" - ) - - # -- 2.2 -- - # Many2many - result = command._process_relation_field_value( - field="tag_ids", value=[tag_doge_values, tag_pepe_values], record_mode=False - ) - self.assertEqual(len(result), 2, "Must be 2 records") - self.assertIn( - (4, self.tag_doge.id), result, "Record ID was not resolved correctly" - ) - self.assertIn( - (4, self.tag_pepe.id), result, "Record ID was not resolved correctly" - ) - # -- 3 -- - # Yaml with non existing reference -> Record - file_template_values.update( - { - "name": "Very new name", - "reference": "such_much_not_reference", - "source": "server", - "file_type": "binary", - } - ) - result = command._process_relation_field_value( - field="file_template_id", value=file_template_values, record_mode=False - ) - - # New record must be created - record = self.env["cx.tower.file.template"].browse(result) - self.assertEqual( - record.name, file_template_values["name"], "New record value doesn't match" - ) - self.assertEqual( - record.reference, - file_template_values["reference"], - "New record value doesn't match", - ) - self.assertEqual( - record.source, - file_template_values["source"], - "New record value doesn't match", - ) - self.assertEqual( - record.file_type, - file_template_values["file_type"], - "New record value doesn't match", - ) - - # -- 4 -- - # Yaml with no reference at all -> Record - values_with_no_references = { - "name": "Sorry no reference here", - "source": "tower", - "file_type": "binary", - } - result = command._process_relation_field_value( - field="file_template_id", value=values_with_no_references, record_mode=False - ) - - # New record must be created - record = self.env["cx.tower.file.template"].browse(result) - - self.assertEqual( - record.name, - values_with_no_references["name"], - "New record value doesn't match", - ) - self.assertEqual( - record.source, - values_with_no_references["source"], - "New record value doesn't match", - ) - self.assertEqual( - record.file_type, - values_with_no_references["file_type"], - "New record value doesn't match", - ) - - # -- 5 -- - # No record -> Yaml - result = command._process_relation_field_value( - field="file_template_id", - value=self.env["cx.tower.file.template"], - record_mode=True, - ) - self.assertFalse(result, "Result must be 'False'") - - def test_update_or_create_related_record(self): - """Test if related record is updated or created correctly""" - - # -- 1 -- - # Update existing values - # We are using file template for that - FileTemplateModel = self.env["cx.tower.file.template"] - file_template = self.env["cx.tower.file.template"].create( - {"name": "Test m2o", "reference": "test_m2o"} - ) - values_to_update = {"name": "Much new name"} - record = FileTemplateModel._update_or_create_related_record( - model=FileTemplateModel, - reference=file_template.reference, - values=values_to_update, - ) - self.assertEqual( - record.name, values_to_update["name"], "Value was not updated properly" - ) - self.assertEqual(record.id, file_template.id, "Same record must be updated") - - # -- 2 -- - # Reference not found. Must create a new record - values_to_update = {"name": "Doge file"} - record = FileTemplateModel._update_or_create_related_record( - model=FileTemplateModel, - reference="doge_file", - values=values_to_update, - create_immediately=True, - ) - self.assertEqual( - record.name, values_to_update["name"], "Value was not updated properly" - ) - self.assertNotEqual(record.id, file_template.id, "New record must be created") - - # -- 2 -- - # Reference not provided. Must create a new record - values_to_update = {"name": "Doge file"} - record = FileTemplateModel._update_or_create_related_record( - model=FileTemplateModel, - reference=False, - values=values_to_update, - create_immediately=True, - ) - self.assertEqual( - record.name, values_to_update["name"], "Value was not updated properly" - ) - self.assertNotEqual(record.id, file_template.id, "New record must be created") - - @tagged("post_install", "-at_install") - def test_prepare_record_truncates_code_for_server_files(self): - """Mixin must set code=False for cx.tower.file when source=='server'.""" - File = self.env["cx.tower.file"] - srv_file = File.create( - { - "name": "srv.log", - "reference": "srvlog", - "source": "server", - "file_type": "text", - "server_dir": "/tmp", - "code": "BIG DATA", - } - ) - rec = srv_file._prepare_record_for_yaml() - self.assertIn("code", rec) - self.assertFalse(rec["code"], "Expected code=False for server-sourced files") - - @tagged("post_install", "-at_install") - def test_prepare_record_keeps_code_for_tower_files(self): - """Mixin must keep code for cx.tower.file when source=='tower'.""" - File = self.env["cx.tower.file"] - tw_file = File.create( - { - "name": "local.txt", - "reference": "localtxt", - "source": "tower", - "file_type": "text", - "server_dir": "/etc", - "code": "SMALL DATA", - } - ) - rec = tw_file._prepare_record_for_yaml() - self.assertEqual( - rec["code"], - "SMALL DATA", - "Expected original code for tower-sourced files", - ) diff --git a/addons/cetmix_tower_yaml/tests/test_yaml_export_wizard.py b/addons/cetmix_tower_yaml/tests/test_yaml_export_wizard.py deleted file mode 100644 index c757a3a..0000000 --- a/addons/cetmix_tower_yaml/tests/test_yaml_export_wizard.py +++ /dev/null @@ -1,375 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import base64 - -import yaml - -from odoo.exceptions import AccessError, ValidationError - -from odoo.addons.base.tests.common import BaseCommon - - -class TestYamlExportWizard(BaseCommon): - @classmethod - def setUpClass(cls, *args, **kwargs): - super().setUpClass(*args, **kwargs) - - # Used to ensure that the file header - # is present in the YAML code - cls.file_header = """ -# This file is generated with Cetmix Tower. -# Details and documentation: https://cetmix.com/tower -""" - # Create a command - cls.TowerCommand = cls.env["cx.tower.command"] - cls.command_test_wizard = cls.TowerCommand.create( - { - "reference": "test_command_from_yaml", - "name": "Test Command From Yaml", - "code": "echo 'Test Command From Yaml'", - } - ) - cls.command_test_wizard_2 = cls.TowerCommand.create( - { - "reference": "test_command_from_yaml_2", - "name": "Test Command From Yaml 2", - "code": "echo 'Test Command From Yaml 2'", - } - ) - - # Create a flight plan - cls.FlightPlan = cls.env["cx.tower.plan"] - cls.flight_plan_test_wizard = cls.FlightPlan.create( - { - "name": "Test Flight Plan From Yaml", - "line_ids": [ - ( - 0, - 0, - { - "command_id": cls.command_test_wizard.id, - }, - ) - ], - } - ) - - # Create a server template - cls.ServerTemplate = cls.env["cx.tower.server.template"] - cls.server_template_test_wizard = cls.ServerTemplate.create( - { - "name": "Test Server Template From Yaml", - "flight_plan_id": cls.flight_plan_test_wizard.id, - } - ) - - # Create a wizard and trigger onchange - cls.YamlExportWizard = cls.env["cx.tower.yaml.export.wiz"] - cls.test_wizard = cls.YamlExportWizard.with_context( - active_model="cx.tower.server.template", - active_ids=[cls.server_template_test_wizard.id], - ).create({}) - cls.test_wizard.onchange_explode_child_records() - - def test_user_without_export_group_cannot_export(self): - """Test if user without export group cannot export""" - - # Tower manager user without export group - self.user_yaml_export = self.env["res.users"].create( - { - "name": "No Yaml Export User", - "login": "no_yaml_export_user", - "groups_id": [ - (4, self.env.ref("cetmix_tower_server.group_manager").id) - ], - } - ) - with self.assertRaises(AccessError): - self.test_wizard.with_user(self.user_yaml_export).read([]) - - def test_yaml_export_wizard_yaml_generation(self): - """Test code generation of YAML export wizard.""" - - wizard_yaml = """ -# This file is generated with Cetmix Tower. -# Details and documentation: https://cetmix.com/tower -cetmix_tower_yaml_version: 1 -records: -- cetmix_tower_model: command - access_level: manager - reference: test_command_from_yaml - name: Test Command From Yaml - action: ssh_command - allow_parallel_run: false - note: false - path: false - code: echo 'Test Command From Yaml' - server_status: false - no_split_for_sudo: false - if_file_exists: skip - disconnect_file: false -- cetmix_tower_model: command - access_level: manager - reference: test_command_from_yaml_2 - name: Test Command From Yaml 2 - action: ssh_command - allow_parallel_run: false - note: false - path: false - code: echo 'Test Command From Yaml 2' - server_status: false - no_split_for_sudo: false - if_file_exists: skip - disconnect_file: false -""" - - # -- 1 -- - # Test with two commands - context = { - "default_explode_child_records": True, - "default_remove_empty_values": True, - "active_model": "cx.tower.command", - "active_ids": [self.command_test_wizard.id, self.command_test_wizard_2.id], - } - wizard = self.YamlExportWizard.with_context(context).create({}) # pylint: disable=context-overridden # new need a new clean context - wizard.onchange_explode_child_records() - self.assertEqual(wizard.yaml_code, wizard_yaml) - - def test_yaml_export_wizard(self): - """Test the YAML export wizard.""" - - # -- 1 -- - # Test wizard action - result = self.test_wizard.action_generate_yaml_file() - self.assertEqual( - result["type"], "ir.actions.act_window", "Action should be a window" - ) - self.assertEqual( - result["res_model"], - "cx.tower.yaml.export.wiz.download", - "Result model should be the download wizard", - ) - self.assertTrue(result["res_id"], "Wizard should have been created") - - # -- 2 -- - # Ensure download wizard file name is generated - # based on the record reference - download_wizard = self.env["cx.tower.yaml.export.wiz.download"].browse( - result["res_id"] - ) - self.assertEqual( - download_wizard.yaml_file_name, - f"server_template_{self.server_template_test_wizard.reference}.yaml", - "YAML file name should be generated based on record reference", - ) - - # -- 3 -- - # Decode YAML file and check if it's valid - yaml_file_content = base64.decodebytes(download_wizard.yaml_file).decode( - "utf-8" - ) - self.assertEqual( - yaml_file_content, - self.test_wizard.yaml_code, - "YAML file content should be the same as the original YAML code", - ) - - # -- 4 -- - # Test if empty YAML code is handled correctly - self.test_wizard.yaml_code = "" - with self.assertRaises(ValidationError): - self.test_wizard.action_generate_yaml_file() - - def test_reference_object_uniqueness(self): - """ - Ensure each reference is exported as a full object only once - (other times only as ref). - """ - - # Prepare YAML export for flight_plan with two same commands - self.flight_plan_test_wizard.line_ids = [ - (0, 0, {"command_id": self.command_test_wizard.id}), - (0, 0, {"command_id": self.command_test_wizard.id}), - ] - - # Prepare YAML code - self.test_wizard.onchange_explode_child_records() - yaml_data = yaml.safe_load(self.test_wizard.yaml_code) - - # reference counters - ref_full = set() - ref_refs = set() - - # Recursively walk through the YAML data and count references - def walk(obj): - if isinstance(obj, dict): - ref = obj.get("reference") - # dict only with "reference" = ref, otherwise — full object - if ref: - if list(obj.keys()) == ["reference"]: - ref_refs.add(ref) - else: - ref_full.add(ref) - for v in obj.values(): - walk(v) - elif isinstance(obj, list): - for v in obj: - walk(v) - - # Walk through the YAML data - walk(yaml_data["records"]) - - # Each reference as a full object — only once - for ref in ref_full: - self.assertEqual( - list(ref_full).count(ref), - 1, - f"Reference '{ref}' appears as a full object more than once", - ) - # Check that no full objects appear more than once - self.assertEqual( - len(ref_full), - len(set(ref_full)), - "Some full objects appear more than once", - ) - - # Check that for each ref there is no only reference, but no full object - for ref in ref_refs: - self.assertIn( - ref, - ref_full, - f"Reference '{ref}' is used only as a reference, " - "but no full object present", - ) - - def test_export_required_model_name_in_yaml(self): - """ - Test that the model name is required in the YAML file for each record - """ - # create a command to run flight plan - command_run_flight_plan = self.TowerCommand.create( - { - "name": "Run Flight Plan", - "action": "plan", - "flight_plan_id": self.flight_plan_test_wizard.id, - } - ) - # export 2 commands: command_run_flight_plan and command_test_wizard - wizard = self.YamlExportWizard.with_context( - active_model="cx.tower.command", - active_ids=[command_run_flight_plan.id, self.command_test_wizard.id], - ).create({}) - - wizard.onchange_explode_child_records() - - yaml_data = yaml.safe_load(wizard.yaml_code) - - # check that the model name is present in the YAML file for each record - for record in yaml_data["records"]: - self.assertIn("cetmix_tower_model", record) - - def test_default_yaml_file_name_is_used(self): - """ - Wizard should pre-fill `yaml_file_name` with the auto-generated - value that ends with '.yaml' and contains the model prefix. - """ - wiz = self.YamlExportWizard.with_context( - active_model="cx.tower.command", - active_ids=[self.command_test_wizard.id], - ).create({}) - - default_name = wiz.yaml_file_name - - self.assertFalse( - default_name.endswith(".yaml"), - "Default file name must NO have .yaml suffix", - ) - self.assertIn( - "command_", - default_name, - "Default file name should include model prefix", - ) - - def test_yaml_file_name_is_auto_fixed(self): - """ - When the user assigns an invalid name, wizard should auto-sanitise - it to a safe *basename* (lowercase, underscores, no extension). - """ - wiz = self.YamlExportWizard.with_context( - active_model="cx.tower.command", - active_ids=[self.command_test_wizard.id], - ).create({}) - - # user enters a 'dirty' name with spaces, capitals, symbols - wiz.write({"yaml_file_name": "My File!@# .YAML"}) - - # write() override strips to a basename WITHOUT '.yaml' - self.assertEqual( - wiz.yaml_file_name, - "my_file", - "Wizard field must hold only the cleaned basename, without extension", - ) - - def test_action_generate_appends_extension(self): - """ - When generating the download record, the system must append - the `.yaml` extension to the sanitized basename. - """ - wiz = self.YamlExportWizard.with_context( - active_model="cx.tower.command", - active_ids=[self.command_test_wizard.id], - ).create({}) - wiz.onchange_explode_child_records() - act = wiz.action_generate_yaml_file() - download = self.env["cx.tower.yaml.export.wiz.download"].browse(act["res_id"]) - self.assertTrue(download.yaml_file_name.endswith(".yaml")) - - def test_custom_requires_text(self): - """Creating a template with license 'custom' but no text must fail""" - with self.assertRaises(ValidationError): - self.env["cx.tower.yaml.manifest.tmpl"].create( - { - "name": "Bad Manifest", - "license": "custom", - } - ) - - tmpl_ok = self.env["cx.tower.yaml.manifest.tmpl"].create( - { - "name": "Good Manifest", - "license": "custom", - "license_text": "Custom license terms", - } - ) - self.assertEqual(tmpl_ok.license, "custom") - self.assertEqual(tmpl_ok.license_text, "Custom license terms") - - with self.assertRaises(ValidationError): - self.env["cx.tower.yaml.manifest.tmpl"].create( - { - "name": "Bad Manifest 2", - "license": "custom", - "license_text": " ", - } - ) - - def test_wizard_resets_price_on_license_change(self): - """Wizard must reset price/currency when license changes away from 'custom'""" - wiz = self.YamlExportWizard.new( - { - "manifest_license": "custom", - "manifest_price": 42.0, - "manifest_currency": "EUR", - } - ) - wiz.manifest_license = "agpl-3" - wiz._onchange_manifest_license() - self.assertEqual(wiz.manifest_price, 0.0) - self.assertFalse(wiz.manifest_currency) - - wiz.manifest_price = 7.5 - wiz.manifest_currency = "USD" - wiz.manifest_license = "custom" - wiz._onchange_manifest_license() - self.assertEqual(wiz.manifest_price, 7.5) - self.assertEqual(wiz.manifest_currency, "USD") diff --git a/addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py b/addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py deleted file mode 100644 index 9441ca3..0000000 --- a/addons/cetmix_tower_yaml/tests/test_yaml_import_wizard.py +++ /dev/null @@ -1,703 +0,0 @@ -# Copyright (C) 2024 Cetmix OÜ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - - -import base64 - -import yaml - -from odoo import _ -from odoo.exceptions import ValidationError -from odoo.tests import TransactionCase -from odoo.tools import mute_logger - - -class TestTowerYamlImportWizUpload(TransactionCase): - """Test Tower YAML Import Wizard Upload""" - - @classmethod - def setUpClass(cls): - super().setUpClass() - - # Variables - cls.Variable = cls.env["cx.tower.variable"] - cls.variable_yaml_test = cls.Variable.create( - {"name": "YAML Test", "reference": "yaml_test"} - ) - cls.variable_yaml_url = cls.Variable.create( - {"name": "YAML URL", "reference": "yaml_url"} - ) - - # Tags - cls.Tag = cls.env["cx.tower.tag"] - cls.tag_yaml_test = cls.Tag.create( - {"name": "YAML Test", "reference": "yaml_test"} - ) - cls.tag_another_yaml_test = cls.Tag.create( - {"name": "Another YAML Test", "reference": "another_yaml_test"} - ) - - # Commands - cls.Command = cls.env["cx.tower.command"] - cls.command_yaml_test = cls.Command.create( - {"name": "Test Yaml Command", "reference": "test_yaml_command"} - ) - - # Flight Plan - cls.FlightPlan = cls.env["cx.tower.plan"] - cls.flight_plan_yaml_test = cls.FlightPlan.create( - { - "name": "Test Yaml Flight Plan", - "reference": "test_yaml_flight_plan", - "line_ids": [ - ( - 0, - 0, - { - "condition": False, - "use_sudo": False, - "command_id": cls.command_yaml_test.id, - }, - ), - ], - } - ) - - # Create Server Template used for testing - cls.server_template_yaml_test = cls.env["cx.tower.server.template"].create( - { - "name": "Test Server Template", - "tag_ids": [ - (4, cls.tag_yaml_test.id), - (4, cls.tag_another_yaml_test.id), - ], - "variable_value_ids": [ - ( - 0, - 0, - { - "variable_id": cls.variable_yaml_test.id, - "value_char": "Some Test Value", - }, - ), - ( - 0, - 0, - { - "variable_id": cls.variable_yaml_url.id, - "value_char": "https://cetmix.com", - }, - ), - ], - "flight_plan_id": cls.flight_plan_yaml_test.id, - } - ) - - # Server Logs - cls.ServerLog = cls.env["cx.tower.server.log"] - cls.server_log_yaml_test = cls.ServerLog.create( - { - "name": "Test Server Log", - "reference": "test_server_log", - "command_id": cls.command_yaml_test.id, - "log_type": "command", - "server_template_id": cls.server_template_yaml_test.id, - } - ) - - # Create an export wizard and generate YAML code - context = { - "active_model": "cx.tower.server.template", - "active_ids": [cls.server_template_yaml_test.id], - } - cls.export_wizard = ( - cls.env["cx.tower.yaml.export.wiz"].with_context(context).create({}) # pylint: disable=context-overridden # new need a new clean context - ) - cls.export_wizard.onchange_explode_child_records() - cls.export_wizard.action_generate_yaml_file() - cls.yaml_code = cls.export_wizard.yaml_code - cls.yaml_file = base64.b64encode(cls.yaml_code.encode("utf-8")) - - # YAML import upload wizard - cls.YamlImportWizUpload = cls.env["cx.tower.yaml.import.wiz.upload"] - cls.yaml_upload_wizard = cls.YamlImportWizUpload.create( - {"yaml_file": cls.yaml_file, "file_name": "test_yaml_file.yaml"} - ) - - # YAML import wizard - cls.import_wizard_action = cls.yaml_upload_wizard.action_import_yaml() - cls.import_wizard = cls.env[cls.import_wizard_action["res_model"]].browse( - cls.import_wizard_action["res_id"] - ) - cls.import_wizard.if_record_exists = "update" - - def test_extract_yaml_data(self): - """Test extract YAML data from file""" - - # -- 1 -- - # Test if YAML file is valid - extracted_yaml_data = self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - extracted_yaml_data, - self.yaml_code, - "YAML code is not extracted correctly", - ) - - # -- 2 -- - # Test if invalid model is handled properly - # Replace model name with invalid model - self.invalid_yaml_code = self.yaml_code.replace( - "server_template", "invalid_model" - ) - self.invalid_yaml_file = base64.b64encode( - self.invalid_yaml_code.encode("utf-8") - ) - self.yaml_upload_wizard.yaml_file = self.invalid_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _("'invalid_model' is not a valid model"), - "Exception message does not match", - ) - # -- 3 -- - # Test if non YAML supported model is handled properly - # Replace model name with non YAML supported model - self.non_yaml_supported_yaml_code = self.yaml_code.replace( - "server_template", "command_run_wizard" - ) - self.non_yaml_supported_yaml_file = base64.b64encode( - self.non_yaml_supported_yaml_code.encode("utf-8") - ) - self.yaml_upload_wizard.yaml_file = self.non_yaml_supported_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _("Model 'command_run_wizard' does not support YAML import"), - "Exception message does not match", - ) - - # -- 4 -- - # Test if YAML that is not a dictionary is handled properly - self.invalid_yaml_file = base64.b64encode(b"Invalid YAML file") - self.yaml_upload_wizard.yaml_file = self.invalid_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _("Yaml file doesn't contain valid data"), - "Exception message does not match", - ) - - # -- 5 -- - # Test if TypeError is handled properly - self.non_unicode_yaml_file = base64.b64encode(b"\x80") - self.yaml_upload_wizard.yaml_file = self.non_unicode_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _("YAML file cannot be decoded properly"), - "Exception message does not match", - ) - - # -- 6 -- - # Test if YAML file is empty - self.empty_yaml_file = "" - self.yaml_upload_wizard.yaml_file = self.empty_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _("File is empty"), - "Exception message does not match", - ) - - # -- 7 -- - # Test if YAML file with unsupported YAML version is handled properly - yaml_with_unsupported_version = self.yaml_code.replace( - f"cetmix_tower_yaml_version: {self.FlightPlan.CETMIX_TOWER_YAML_VERSION}", - f"cetmix_tower_yaml_version: {self.FlightPlan.CETMIX_TOWER_YAML_VERSION + 1}", # noqa: E501 - ) - self.unsupported_yaml_version_yaml_file = base64.b64encode( - yaml_with_unsupported_version.encode("utf-8") - ) - self.yaml_upload_wizard.yaml_file = self.unsupported_yaml_version_yaml_file - with self.assertRaises(ValidationError) as e: - self.yaml_upload_wizard._extract_yaml_data() - self.assertEqual( - str(e.exception), - _( - "YAML version is higher than version" - " supported by your Cetmix Tower instance." - " %(code_version)s > %(tower_version)s", - code_version=self.FlightPlan.CETMIX_TOWER_YAML_VERSION + 1, - tower_version=self.FlightPlan.CETMIX_TOWER_YAML_VERSION, - ), - "Exception message does not match", - ) - - # -- 8 -- - # Test YAML file with no records - self.import_wizard.yaml_code = "cetmix_tower_yaml_version: 1" - with self.assertRaises(ValidationError) as e: - self.import_wizard.action_import_yaml() - self.assertEqual( - str(e.exception), - _("YAML file doesn't contain any records"), - "Exception message does not match", - ) - - def test_action_import_yaml_skip_if_exists(self): - """Test YAML import wizard action when skipping an existing record""" - - self.import_wizard.if_record_exists = "skip" - - # Run import wizard action - import_wizard_result_action = self.import_wizard.action_import_yaml() - - # Test if action is composed properly - self.assertEqual( - import_wizard_result_action["type"], - "ir.actions.client", - "Import wizard action type is not correct", - ) - self.assertEqual( - import_wizard_result_action["tag"], - "display_notification", - "Import wizard action tag is not correct", - ) - self.assertEqual( - import_wizard_result_action["params"]["title"], - _("Record Import"), - "Import wizard action title is not correct", - ) - self.assertEqual( - import_wizard_result_action["params"]["message"], - _("No records were created or updated"), - "Import wizard action message is not correct", - ) - self.assertEqual( - import_wizard_result_action["params"]["sticky"], - True, - "Import wizard action sticky is not correct", - ) - self.assertEqual( - import_wizard_result_action["params"]["type"], - "warning", - "Import wizard action type is not correct", - ) - - def test_action_import_yaml_update_existing_record(self): - """Test YAML import wizard action when updating an existing record""" - - # -- 1 -- - # Test if new import wizard record is created properly - self.assertEqual( - self.import_wizard_action["res_model"], - "cx.tower.yaml.import.wiz", - "Import wizard action model is not correct", - ) - self.assertEqual( - self.import_wizard_action["view_mode"], - "form", - "Import wizard action view mode is not correct", - ) - - # -- 2 -- - # Modify Server Template name and variable value - self.import_wizard.yaml_code = self.import_wizard.yaml_code.replace( - "name: Test Server Template", - "name: Updated Test Server Template", - ).replace( - "value_char: Some Test Value", - "value_char: Updated Test Value", - ) - variable_value_to_update = ( - self.server_template_yaml_test.variable_value_ids.filtered( - lambda v: v.value_char == "Some Test Value" - ) - ) - - # Run import wizard action another time - import_wizard_result_action = self.import_wizard.action_import_yaml() - - # -- 3 -- - # Test if record is updated properly - self.assertEqual( - import_wizard_result_action["res_model"], - "cx.tower.server.template", - "Import wizard action model is not correct", - ) - self.assertEqual( - import_wizard_result_action["domain"], - [("id", "in", self.server_template_yaml_test.ids)], - "ID must match existing record ID", - ) - self.assertEqual( - self.server_template_yaml_test.name, - "Updated Test Server Template", - "Record is not updated properly", - ) - self.assertEqual( - variable_value_to_update.value_char, - "Updated Test Value", - "Variable value is not updated properly", - ) - - # -- 4 -- - # Test if server log remains the same - self.assertEqual( - len(self.server_template_yaml_test.server_log_ids), - 1, - "Server Log must remain the same", - ) - self.assertEqual( - self.server_log_yaml_test.id, - self.server_template_yaml_test.server_log_ids.id, - "Server Log must remain the same", - ) - - def test_action_import_yaml_create_new_record(self): - """Test YAML import wizard action when creating a new record""" - self.import_wizard.if_record_exists = "create" - with mute_logger("odoo.addons.cetmix_tower_yaml.models.cx_tower_yaml_mixin"): - import_wizard_result_action = self.import_wizard.action_import_yaml() - - # -- 1 -- - # Test if new record is created instead of updating existing one - self.assertEqual( - import_wizard_result_action["res_model"], - "cx.tower.server.template", - "Import wizard action model is not correct", - ) - self.assertNotEqual( - import_wizard_result_action["domain"], - f"[('id', '=', {self.server_template_yaml_test.ids})]", - "ID must not match existing record ID", - ) - - # -- 2 -- - # Ensure that existing flight plan is used instead of creating a new one - new_server_template = self.env[import_wizard_result_action["res_model"]].search( - import_wizard_result_action["domain"] - ) - self.assertEqual( - new_server_template.flight_plan_id, - self.flight_plan_yaml_test, - "Existing flight plan must be used", - ) - - # -- 3 -- - # Ensure that existing tags are used instead of creating new ones - for tag in self.server_template_yaml_test.tag_ids: - self.assertIn( - tag, - new_server_template.tag_ids, - "Existing tag must be used", - ) - - # -- 4 -- - # Ensure that new variable values are created - for variable_value in self.server_template_yaml_test.variable_value_ids: - self.assertNotIn( - variable_value, - new_server_template.variable_value_ids, - "New variable value must be created instead of updating existing one", - ) - - # -- 5 -- - # Test if server log is created instead of updated - for server_log in self.server_template_yaml_test.server_log_ids: - self.assertNotIn( - server_log, - new_server_template.server_log_ids, - "New Server Log must be created instead of updating existing one", - ) - - def test_extract_secret_names(self): - """Test extract secret names from YAML data""" - - # NB: this is not a real model, it's just for testing - yaml_code = """cetmix_tower_yaml_version: 1 -records: -- cetmix_tower_model: test_model - access_level: manager - reference: such_much_test_record - name: Such Much Command - action: file_using_template - allow_parallel_run: false - note: Just a note - os_ids: false - tag_ids: false - path: false - file_template_id: false - flight_plan_id: false - code: false - variable_ids: false - secret_ids: false - ssh_key_id: - reference: test_ssh_key - name: Test SSH Key - key_type: k - note: false -- cetmix_tower_model: another_test_model - reference: such_much_test_record_2 - name: Such Much Test Record 2 - note: Just a note 2 - ssh_key_id: - reference: test_ssh_key - name: Test SSH Key - key_type: k - note: false - secret_ids: - - reference: secret_2 - name: Secret 2 - key_type: s - note: false - - reference: secret_3 - name: Secret 3 - key_type: s - note: false -- cetmix_tower_model: another_test_model - reference: such_much_test_record_3 - name: Such Much Test Record 3 - note: Just a note 3 - ssh_key_id: - reference: another_ssh_key - name: Another SSH Key - sub_record: - reference: such_much_test_record_4 - name: Such Much Test Record 4 - note: Just a note 4 - secret_ids: - - reference: secret_1 - name: Secret 3 - key_type: s - note: false - - reference: secret_2 - name: Secret 4 - key_type: s - note: false - file_template_id: - reference: my_custom_test_template - name: Such much demo - source: tower - file_type: text - server_dir: /var/log/my/files - file_name: much_logs.txt - keep_when_deleted: false - tag_ids: false - note: Hey! - code: false - variable_ids: false - secret_ids: false - flight_plan_id: false - code: false - variable_ids: false - secret_ids: - - reference: secret_1 - name: Secret 1 - key_type: s - note: false - - reference: secret_2 - name: Secret 2 - key_type: s - note: false -""" - secret_list = self.env["cx.tower.yaml.import.wiz"]._extract_secret_names( - yaml.safe_load(yaml_code) - ) - # We expect 6 secrets in the list: - # 2 keys: 'Test SSH Key', 'Another SSH Key' - # 4 secrets: 'Secret 3', 'Secret 4', 'Secret 1', 'Secret 2' - self.assertEqual(len(secret_list), 6, "Secret list length is not correct") - self.assertIn("Test SSH Key", secret_list, "Key is not in the list") - self.assertIn("Another SSH Key", secret_list, "Key is not in the list") - self.assertIn("Secret 3", secret_list, "Key is not in the list") - self.assertIn("Secret 4", secret_list, "Key is not in the list") - self.assertIn("Secret 1", secret_list, "Key is not in the list") - self.assertIn("Secret 2", secret_list, "Key is not in the list") - - def test_extract_secret_names_with_key_id(self): - """Test extract secret names when secrets are nested under key_id""" - yaml_code = """cetmix_tower_yaml_version: 1 -records: -- cetmix_tower_model: test_model - reference: rec_1 - name: Test Record - secret_ids: - - key_id: - reference: secret_1 - name: Nested Secret 1 - - key_id: - reference: secret_2 - name: Nested Secret 2 - ssh_key_id: - name: SSH Key Nested -""" - secret_list = self.env["cx.tower.yaml.import.wiz"]._extract_secret_names( - yaml.safe_load(yaml_code) - ) - - # We expect 3 secrets total: - # - SSH Key Nested (from ssh_key_id) - # - Nested Secret 1 - # - Nested Secret 2 - self.assertCountEqual( - secret_list, - ["Nested Secret 1", "Nested Secret 2", "SSH Key Nested"], - "Unexpected secrets extracted for nested structure", - ) - - def test_create_records_different_models(self): - """Test create records with different models""" - - yaml_code = """cetmix_tower_yaml_version: 1 -records: -- cetmix_tower_model: command - access_level: manager - reference: much_much_command - name: Much Much Command - action: file_using_template - allow_parallel_run: false - note: Just a note - os_ids: false - tag_ids: false - path: false - file_template_id: false - flight_plan_id: false - code: false - variable_ids: false - secret_ids: false - ssh_key_id: - reference: test_ssh_key - name: Test SSH Key - key_type: k - note: false -- cetmix_tower_model: server_template - reference: wow_much_server_template - name: Wow Much Server Template - note: Just a note 2 -- cetmix_tower_model: tag - reference: such_much_tag - name: Such Much Tag -""" - # Create a new command record - self.import_wizard.if_record_exists = "update" - self.import_wizard.yaml_code = yaml_code - - action = self.import_wizard.action_import_yaml() - - # Check if action is composed properly - self.assertEqual( - action["type"], - "ir.actions.client", - "Import wizard action type is not correct", - ) - self.assertEqual( - action["tag"], - "display_notification", - "Import wizard action tag is not correct", - ) - self.assertEqual( - action["params"]["title"], - _("Record Import"), - "Import wizard action title is not correct", - ) - self.assertEqual( - action["params"]["type"], - "success", - "Import wizard action type is not correct", - ) - self.assertEqual( - action["params"]["sticky"], - True, - "Import wizard action sticky is not correct", - ) - - # Check command - self.assertTrue( - self.Command.get_by_reference("much_much_command"), - "Command must be created", - ) - - # Check server template - self.assertTrue( - self.env["cx.tower.server.template"].get_by_reference( - "wow_much_server_template" - ), - "Server template must be created", - ) - - # Check tag - self.assertTrue( - self.Tag.get_by_reference("such_much_tag"), "Tag must be created" - ) - - def test_yaml_import_server_without_password(self): - """Wizard should import server without ssh_password.""" - yaml_code = ( - "cetmix_tower_yaml_version: 1\n" - "records:\n" - "- reference: srv_nopass\n" - " cetmix_tower_model: server\n" - " name: YAML NoPass\n" - " ssh_auth_mode: p\n" - " ssh_username: root\n" - " ip_v4_address: 10.0.0.3\n" - ) - wiz = self.env["cx.tower.yaml.import.wiz"].create( - { - "yaml_code": yaml_code, - "if_record_exists": "create", - } - ) - wiz.action_import_yaml() - - srv = self.env["cx.tower.server"].get_by_reference("srv_nopass") - self.assertTrue(srv, "Server was not created") - self.assertFalse( - srv._get_secret_value("ssh_password"), - "ssh_password must stay empty after import", - ) - - def test_orm_create_server_requires_password(self): - """Creating a server via ORM/UI must fail when ssh_password is missing.""" - with self.assertRaises(ValidationError) as err: - self.env["cx.tower.server"].create( - { - "reference": "srv_ui", - "name": "UI NoPass", - "ssh_auth_mode": "p", - "ssh_username": "root", - "ip_v4_address": "10.0.0.2", - } - ) - self.assertIn("Please provide SSH password", str(err.exception)) - - def test_yaml_import_server_with_skip_ssh_check(self): - """Explicit skip_ssh_settings_check also bypasses password validation.""" - yaml_code = ( - "cetmix_tower_yaml_version: 1\n" - "records:\n" - "- reference: srv_skip\n" - " cetmix_tower_model: server\n" - " name: YAML Skip Check\n" - " ssh_auth_mode: p\n" - " ssh_username: root\n" - " ip_v4_address: 10.0.0.4\n" - ) - wiz = self.env["cx.tower.yaml.import.wiz"].create( - { - "yaml_code": yaml_code, - "if_record_exists": "create", - } - ) - wiz.with_context(skip_ssh_settings_check=True).action_import_yaml() - - srv = self.env["cx.tower.server"].get_by_reference("srv_skip") - self.assertTrue( - srv, "Server must be created when skip_ssh_settings_check is set" - ) diff --git a/addons/cetmix_tower_yaml/views/cx_tower_command_view.xml b/addons/cetmix_tower_yaml/views/cx_tower_command_view.xml deleted file mode 100644 index 08dece7..0000000 --- a/addons/cetmix_tower_yaml/views/cx_tower_command_view.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - cx.tower.command.yaml.view.form - cx.tower.command - - - - -
-

You must be a member of the "YAML/Export" group to export data as YAML.

-
-