diff --git a/README.md b/README.md index ada1f86ff94..f7bb1e913ba 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ addon | version | maintainers | summary [base_technical_user](base_technical_user/) | 18.0.1.0.1 | | Add a technical user parameter on the company [base_temporary_action](base_temporary_action/) | 18.0.1.0.0 | | This addon allows to create temporary actions [base_time_window](base_time_window/) | 18.0.1.1.0 | | Base model to handle time windows -[base_view_inheritance_extension](base_view_inheritance_extension/) | 18.0.1.0.1 | | Adds more operators for view inheritance +[base_view_inheritance_extension](base_view_inheritance_extension/) | 18.0.1.0.2 | | Adds more operators for view inheritance [bus_alt_connection](bus_alt_connection/) | 18.0.1.0.0 | | Needed when using PgBouncer as a connection pooler [database_cleanup](database_cleanup/) | 18.0.1.0.2 | | Database cleanup [database_size](database_size/) | 18.0.1.0.2 | | Database Size @@ -55,6 +55,7 @@ addon | version | maintainers | summary [iap_alternative_provider](iap_alternative_provider/) | 18.0.1.0.0 | sebastienbeau | Base module for providing alternative provider for iap apps [jsonifier](jsonifier/) | 18.0.1.1.0 | | JSON-ify data for all models [mail_cleanup](mail_cleanup/) | 18.0.1.0.1 | | Mark as read or delete mails after a set time +[module_analysis](module_analysis/) | 18.0.1.0.0 | legalsylvain | Add analysis tools regarding installed modules to know which installed modules comes from Odoo Core, OCA, or are custom modules [module_auto_update](module_auto_update/) | 18.0.1.0.0 | | Automatically update Odoo modules [module_change_auto_install](module_change_auto_install/) | 18.0.1.0.3 | legalsylvain | Customize auto installables modules by configuration [onchange_helper](onchange_helper/) | 18.0.1.0.1 | | Technical module that ease execution of onchange in Python code diff --git a/autovacuum_message_attachment/i18n/autovacuum_message_attachment.pot b/autovacuum_message_attachment/i18n/autovacuum_message_attachment.pot index d3d98678909..c60de80c153 100644 --- a/autovacuum_message_attachment/i18n/autovacuum_message_attachment.pot +++ b/autovacuum_message_attachment/i18n/autovacuum_message_attachment.pot @@ -196,10 +196,13 @@ msgstr "" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/autovacuum_message_attachment/i18n/ca.po b/autovacuum_message_attachment/i18n/ca.po index 2564fd56264..eb1f74d4287 100644 --- a/autovacuum_message_attachment/i18n/ca.po +++ b/autovacuum_message_attachment/i18n/ca.po @@ -197,10 +197,13 @@ msgstr "" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/autovacuum_message_attachment/i18n/es.po b/autovacuum_message_attachment/i18n/es.po index 3b13baaceb8..7869cb251c3 100644 --- a/autovacuum_message_attachment/i18n/es.po +++ b/autovacuum_message_attachment/i18n/es.po @@ -199,10 +199,13 @@ msgstr "Todos" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/autovacuum_message_attachment/i18n/es_AR.po b/autovacuum_message_attachment/i18n/es_AR.po index 287abeac45b..3be9806528a 100644 --- a/autovacuum_message_attachment/i18n/es_AR.po +++ b/autovacuum_message_attachment/i18n/es_AR.po @@ -199,10 +199,13 @@ msgstr "Todos" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/autovacuum_message_attachment/i18n/fr.po b/autovacuum_message_attachment/i18n/fr.po index b463e3d693e..b6cd915d61a 100644 --- a/autovacuum_message_attachment/i18n/fr.po +++ b/autovacuum_message_attachment/i18n/fr.po @@ -199,10 +199,13 @@ msgstr "Tous" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/autovacuum_message_attachment/i18n/it.po b/autovacuum_message_attachment/i18n/it.po index 7212223e9c9..deeb65b82ec 100644 --- a/autovacuum_message_attachment/i18n/it.po +++ b/autovacuum_message_attachment/i18n/it.po @@ -199,10 +199,13 @@ msgstr "Tutti" #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_relation_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_model_size_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_author__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_category__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_dependency__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_module_exclusion__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type__assigned_attachment_ids +#: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_module_type_rule__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_profile__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb__assigned_attachment_ids #: model:ir.model.fields,field_description:autovacuum_message_attachment.field_ir_qweb_field__assigned_attachment_ids diff --git a/base_view_inheritance_extension/README.rst b/base_view_inheritance_extension/README.rst index 50a80b7c783..d8906b5d2b0 100644 --- a/base_view_inheritance_extension/README.rst +++ b/base_view_inheritance_extension/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ========================= Extended view inheritance ========================= @@ -7,13 +11,13 @@ Extended view inheritance !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3164c7b67a9aa830f28bff20df0f54007a2cb55ec7e67009ccae8a1a2925a4e6 + !! source digest: sha256:cb2fb0b7f832559d24b4af1f66ac9d92258ed4cb2a2f32b5b1afaa3437f7b9eb !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png :target: https://odoo-community.org/page/development-status :alt: Mature -.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github diff --git a/base_view_inheritance_extension/__manifest__.py b/base_view_inheritance_extension/__manifest__.py index 7c6e621f49b..7851b86825b 100644 --- a/base_view_inheritance_extension/__manifest__.py +++ b/base_view_inheritance_extension/__manifest__.py @@ -3,7 +3,7 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). { "name": "Extended view inheritance", - "version": "18.0.1.0.1", + "version": "18.0.1.0.2", "development_status": "Mature", "author": "Therp BV,Odoo Community Association (OCA)", "license": "LGPL-3", @@ -11,6 +11,5 @@ "summary": "Adds more operators for view inheritance", "website": "https://github.com/OCA/server-tools", "depends": ["base"], - "external_dependencies": {"python": ["astor"]}, "demo": ["demo/ir_ui_view.xml"], } diff --git a/base_view_inheritance_extension/static/description/index.html b/base_view_inheritance_extension/static/description/index.html index 458e90b699b..4f59755ca4b 100644 --- a/base_view_inheritance_extension/static/description/index.html +++ b/base_view_inheritance_extension/static/description/index.html @@ -3,7 +3,7 @@ -Extended view inheritance +README.rst -
-

Extended view inheritance

+
+ + +Odoo Community Association + +
+

Extended view inheritance

-

Mature License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

Mature License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

This module was written to make it simple to add custom operators for view inheritance.

Table of contents

@@ -387,7 +392,7 @@

Extended view inheritance

-

Usage

+

Usage

Change a python dictionary (context for example)

 <field position="attributes">
@@ -416,13 +421,13 @@ 

Usage

-

Known issues / Roadmap

+

Known issues / Roadmap

  • Support an eval attribute for our new node types.
-

Bug Tracker

+

Bug Tracker

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

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Therp BV
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -469,5 +474,6 @@

Maintainers

+
diff --git a/module_analysis/README.rst b/module_analysis/README.rst new file mode 100644 index 00000000000..a2a36a594f3 --- /dev/null +++ b/module_analysis/README.rst @@ -0,0 +1,209 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +=============== +Module Analysis +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6d7690f0d128b52d39e8d9a27516fa06af6dbb5cd9aa122b5786ab94b8c62cb1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/18.0/module_analysis + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-module_analysis + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows you to know 'how much code' is running on your Odoo +instance, group by 'Type' (Odoo Core, OCA, other...) + +This module can be usefull in the following cases : + +- To analyse the size of your technical debt, regarding your Custom + modules +- To know the ratio between Odoo / OCA and Custom modules +- To evaluate the amount to pay to odoo to upgrade your custom code, or + the induced workload + +|installed_modules_by_types| + +For that purpose, it adds new concepts + +- ``ir.module.author``, based on the value ``author`` present in the + manifest file. + +|module_authors| + +- ``ir.module.type``, populated by default with Odoo and OCA values. + +|module_types| + +Each installed modules have extra data in the 'Technical Data' tab : + +|module_form| + +.. |installed_modules_by_types| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/installed_modules_by_types.png +.. |module_authors| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/module_authors.png +.. |module_types| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/module_types.png +.. |module_form| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/module_form.png + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +To use this module, you have to install the ``pygount`` python librairy. + +``pip install pygount`` + +Configuration +============= + +- Go to Apps / Module Analysis / Modules Types Rules + +The Module types Rules are usefull to get the Type of a module, based on +it information. + +This module comes with default rules. + + |default_module_type_rules| + +You can add your custom rules to identify the modules your team have +developped for exemple, + + |add_module_type_rules| + +to update the data manually, you have to : + +- Go to 'Settings' / 'Technical' / 'Scheduled Actions' +- Run manually the action : 'Update Module Analysis' + +This will update analysis of your installed modules. + +to update the data automatically, you have to : + +- Go to 'Settings' / 'Technical' / 'Scheduled Actions' +- Configure the action 'Update Module Analysis' and activate it. (By + default, the cron is unactive and no analysis is done) + +Adding Extra data +----------------- + +If you want to analyse other data, (for exemple, having the number of +HTML files), create a custom modules and overload the module model : + +.. code:: python + + from odoo import api, fields, models + + class IrModuleModule(models.Model): + _inherit = 'ir.module.module' + + xml_documentation_qty = fields.Integer( + string='Quantity of Comments in XML Files') + + @api.model + def _get_analyse_settings(self): + res = super()._get_analyse_settings() + if not '.html' in res: + res['.html'] = {} + res['.html']['documentation'] 'xml_documentation_qty' + return res + +Exclude files and directories +----------------------------- + +Two parameters are availaible in 'Settings' / 'Technical' / 'Parameters' +'System Parameters' : + + |config_parameters| + +The list of folders and filename will be exclude from the analysis. You +can change the default settings. + +.. |default_module_type_rules| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/default_module_type_rules.png +.. |add_module_type_rules| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/add_module_type_rules.png +.. |config_parameters| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/config_parameters.png + +Usage +===== + +- Go to 'Apps' / 'Module Analysis' / 'Installed module by Types' + +Open the stats to analyse the detail of the code installed + + |analysis_pivot| + + |analysis_pie| + +.. |analysis_pivot| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/analysis_pivot.png +.. |analysis_pie| image:: https://raw.githubusercontent.com/OCA/server-tools/18.0/module_analysis/static/description/analysis_pie.png + +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 +------- + +* GRAP + +Contributors +------------ + +- Sylvain LE GAL (https://twitter.com/legalsylvain) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px + :target: https://github.com/legalsylvain + :alt: legalsylvain + +Current `maintainer `__: + +|maintainer-legalsylvain| + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/module_analysis/__init__.py b/module_analysis/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/module_analysis/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/module_analysis/__manifest__.py b/module_analysis/__manifest__.py new file mode 100644 index 00000000000..89a879f7607 --- /dev/null +++ b/module_analysis/__manifest__.py @@ -0,0 +1,32 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Module Analysis", + "summary": "Add analysis tools regarding installed modules" + " to know which installed modules comes from Odoo Core, OCA, or are" + " custom modules", + "author": "GRAP, Odoo Community Association (OCA)", + "maintainers": ["legalsylvain"], + "website": "https://github.com/OCA/server-tools", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "depends": ["base"], + "data": [ + "security/ir.model.access.csv", + "views/menu.xml", + "views/view_ir_module_author.xml", + "views/view_ir_module_type.xml", + "views/view_ir_module_type_rule.xml", + "views/view_ir_module_module.xml", + "data/ir_config_parameter.xml", + "data/ir_module_type.xml", + "data/ir_module_type_rule.xml", + "data/ir_cron.xml", + ], + "external_dependencies": { + "python": ["pygount"], + }, + "installable": True, +} diff --git a/module_analysis/data/ir_config_parameter.xml b/module_analysis/data/ir_config_parameter.xml new file mode 100644 index 00000000000..a5ab19622bc --- /dev/null +++ b/module_analysis/data/ir_config_parameter.xml @@ -0,0 +1,16 @@ + + + + + module_analysis.exclude_directories + lib,demo,test,tests,doc,description + + + module_analysis.exclude_files + __openerp__.py,__manifest__.py + + diff --git a/module_analysis/data/ir_cron.xml b/module_analysis/data/ir_cron.xml new file mode 100644 index 00000000000..5d0d100e460 --- /dev/null +++ b/module_analysis/data/ir_cron.xml @@ -0,0 +1,19 @@ + + + + + Update Module Analysis + + + code + model.cron_analyse_code() + 1 + days + + + + diff --git a/module_analysis/data/ir_module_type.xml b/module_analysis/data/ir_module_type.xml new file mode 100644 index 00000000000..3bc2193c46b --- /dev/null +++ b/module_analysis/data/ir_module_type.xml @@ -0,0 +1,14 @@ + + + + + Odoo Core + + + OCA + + diff --git a/module_analysis/data/ir_module_type_rule.xml b/module_analysis/data/ir_module_type_rule.xml new file mode 100644 index 00000000000..a789bf18371 --- /dev/null +++ b/module_analysis/data/ir_module_type_rule.xml @@ -0,0 +1,37 @@ + + + + + + 1 + [('author_ids', 'ilike', 'Odoo S.A')] + + + + 2 + [('author_ids', 'ilike', 'OpenERP SA')] + + + + 3 + [('author_ids', '=', 'Odoo SA')] + + + + 4 + [('author_ids', '=', 'Odoo')] + + + + + 100 + [('author_ids', '=', 'Odoo Community Association (OCA)')] + + + diff --git a/module_analysis/i18n/es.po b/module_analysis/i18n/es.po new file mode 100644 index 00000000000..5504ba45afa --- /dev/null +++ b/module_analysis/i18n/es.po @@ -0,0 +1,219 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * module_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-09-03 00:15+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis +msgid "Analysis" +msgstr "Análisis" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids +msgid "Authors" +msgstr "Autores" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty +msgid "CSS Code Quantity" +msgstr "Código CSS Cantidad" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Code Size" +msgstr "Código Tamaño" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name +msgid "Display Name" +msgstr "Mostrar Nombre" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id +msgid "ID" +msgstr "ID (identificación)" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids +msgid "Installed Modules" +msgstr "Módulos instalados" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty +msgid "Installed Modules Quantity" +msgstr "Cantidad de módulos instalados" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type +#: model:ir.ui.menu,name:module_analysis.menu_module_by_type +msgid "Installed Modules by Types" +msgstr "Módulos instalados por tipos" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty +msgid "JS Code Quantity" +msgstr "Cantidad Código JS" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid +msgid "Last Updated by" +msgstr "Actualizado por Última vez por" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date +msgid "Last Updated on" +msgstr "Última Actualización el" + +#. module: module_analysis +#: model:ir.model,name:module_analysis.model_ir_module_module +msgid "Module" +msgstr "Módulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain +msgid "Module Domain" +msgstr "Dominio del módulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id +msgid "Module Type" +msgstr "Tipo de Módulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id +msgid "Module type" +msgstr "Tipo de módulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids +msgid "Modules" +msgstr "Módulos" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author +#: model:ir.model,name:module_analysis.model_ir_module_author +#: model:ir.ui.menu,name:module_analysis.menu_module_authors +msgid "Modules Authors" +msgstr "Autores de los módulos" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty +msgid "Modules Quantity" +msgstr "Cantidad de módulos" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type +#: model:ir.model,name:module_analysis.model_ir_module_type +#: model:ir.ui.menu,name:module_analysis.menu_module_types +msgid "Modules Types" +msgstr "Tipos de Módulos" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule +#: model:ir.model,name:module_analysis.model_ir_module_type_rule +#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules +msgid "Modules Types Rules" +msgstr "Reglas de Tipos de Módulos" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name +msgid "Name" +msgstr "Nombre" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty +msgid "Python Code Quantity" +msgstr "Cantidad de Código Python" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Refresh Code Analysis" +msgstr "Análisis del Código de Actualización" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting +msgid "Reporting" +msgstr "Informes" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__scss_code_qty +msgid "SCSS Code Quantity" +msgstr "Código SCSS Cantidad" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence +msgid "Sequence" +msgstr "Secuencia" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings +msgid "Settings" +msgstr "Configuraciones" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search +msgid "Smart Search" +msgstr "Búsqueda inteligente" + +#. module: module_analysis +#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq +msgid "The name of the modules author should be unique per database!" +msgstr "¡El nombre del autor de los módulos debe ser único por base de datos!" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Type and Authors" +msgstr "Tipo y Autores" + +#. module: module_analysis +#: model:ir.actions.server,name:module_analysis.cron_module_analysis_ir_actions_server +msgid "Update Module Analysis" +msgstr "Análisis del Módulo de Actualización" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty +msgid "XML Code Quantity" +msgstr "Cantidad Código XML" + +#~ msgid "Last Modified on" +#~ msgstr "Última modificación el" diff --git a/module_analysis/i18n/it.po b/module_analysis/i18n/it.po new file mode 100644 index 00000000000..dd6a0242a30 --- /dev/null +++ b/module_analysis/i18n/it.po @@ -0,0 +1,225 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * module_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-05-24 12:37+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis +msgid "Analysis" +msgstr "Analisi" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids +msgid "Authors" +msgstr "Autori" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty +msgid "CSS Code Quantity" +msgstr "Quantità Codice CSS" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Code Size" +msgstr "Dimensione Codice" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id +msgid "ID" +msgstr "ID" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids +msgid "Installed Modules" +msgstr "Moduli Installati" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty +msgid "Installed Modules Quantity" +msgstr "Quantità Moduli Installati" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type +#: model:ir.ui.menu,name:module_analysis.menu_module_by_type +msgid "Installed Modules by Types" +msgstr "Moduli Installati per Tipo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty +msgid "JS Code Quantity" +msgstr "Quantità Codice JS" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: module_analysis +#: model:ir.model,name:module_analysis.model_ir_module_module +msgid "Module" +msgstr "Modulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain +msgid "Module Domain" +msgstr "Dominio modulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id +msgid "Module Type" +msgstr "Tipo Modulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id +msgid "Module type" +msgstr "Tipo Modulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids +msgid "Modules" +msgstr "Moduli" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author +#: model:ir.model,name:module_analysis.model_ir_module_author +#: model:ir.ui.menu,name:module_analysis.menu_module_authors +msgid "Modules Authors" +msgstr "Autori Moduli" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty +msgid "Modules Quantity" +msgstr "Quantità moduli" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type +#: model:ir.model,name:module_analysis.model_ir_module_type +#: model:ir.ui.menu,name:module_analysis.menu_module_types +msgid "Modules Types" +msgstr "Tipologia Moduli" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule +#: model:ir.model,name:module_analysis.model_ir_module_type_rule +#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules +msgid "Modules Types Rules" +msgstr "Regole Tipologie Moduli" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name +msgid "Name" +msgstr "Nome" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty +msgid "Python Code Quantity" +msgstr "Quantità Codice Python" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Refresh Code Analysis" +msgstr "Aggiorna Analisi Codice" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting +msgid "Reporting" +msgstr "Rendicontazione" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__scss_code_qty +msgid "SCSS Code Quantity" +msgstr "SCSS Quantità codice" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence +msgid "Sequence" +msgstr "Sequenza" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings +msgid "Settings" +msgstr "Impostazioni" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search +msgid "Smart Search" +msgstr "Ricerca intelligente" + +#. module: module_analysis +#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq +msgid "The name of the modules author should be unique per database!" +msgstr "Il nome dell'autore del modulo deve essere unico nel database!" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Type and Authors" +msgstr "Tipologia e Autori" + +#. module: module_analysis +#: model:ir.actions.server,name:module_analysis.cron_module_analysis_ir_actions_server +msgid "Update Module Analysis" +msgstr "Aggiorna analisi modulo" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty +msgid "XML Code Quantity" +msgstr "Quantità Codice XML" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" + +#~ msgid "Analyse Installed Modules" +#~ msgstr "Analizza Moduli Installati" + +#~ msgid "Update Module" +#~ msgstr "Aggiorna Modulo" diff --git a/module_analysis/i18n/module_analysis.pot b/module_analysis/i18n/module_analysis.pot new file mode 100644 index 00000000000..7215fd72751 --- /dev/null +++ b/module_analysis/i18n/module_analysis.pot @@ -0,0 +1,213 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * module_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id +msgid "Analysed Module Type" +msgstr "" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis +msgid "Analysis" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids +msgid "Authors" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty +msgid "CSS Code Quantity" +msgstr "" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Code Size" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid +msgid "Created by" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date +msgid "Created on" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name +msgid "Display Name" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id +msgid "ID" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids +msgid "Installed Modules" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty +msgid "Installed Modules Quantity" +msgstr "" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type +#: model:ir.ui.menu,name:module_analysis.menu_module_by_type +msgid "Installed Modules by Types" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty +msgid "JS Code Quantity" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date +msgid "Last Updated on" +msgstr "" + +#. module: module_analysis +#: model:ir.model,name:module_analysis.model_ir_module_module +msgid "Module" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain +msgid "Module Domain" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id +msgid "Module type" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids +msgid "Modules" +msgstr "" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author +#: model:ir.model,name:module_analysis.model_ir_module_author +#: model:ir.ui.menu,name:module_analysis.menu_module_authors +msgid "Modules Authors" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty +msgid "Modules Quantity" +msgstr "" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type +#: model:ir.model,name:module_analysis.model_ir_module_type +#: model:ir.ui.menu,name:module_analysis.menu_module_types +msgid "Modules Types" +msgstr "" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule +#: model:ir.model,name:module_analysis.model_ir_module_type_rule +#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules +msgid "Modules Types Rules" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name +msgid "Name" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty +msgid "Python Code Quantity" +msgstr "" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Refresh Code Analysis" +msgstr "" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting +msgid "Reporting" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__scss_code_qty +msgid "SCSS Code Quantity" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence +msgid "Sequence" +msgstr "" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings +msgid "Settings" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search +msgid "Smart Search" +msgstr "" + +#. module: module_analysis +#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq +msgid "The name of the modules author should be unique per database!" +msgstr "" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Type and Authors" +msgstr "" + +#. module: module_analysis +#: model:ir.actions.server,name:module_analysis.cron_module_analysis_ir_actions_server +msgid "Update Module Analysis" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty +msgid "XML Code Quantity" +msgstr "" diff --git a/module_analysis/i18n/zh_CN.po b/module_analysis/i18n/zh_CN.po new file mode 100644 index 00000000000..54c86cb80e4 --- /dev/null +++ b/module_analysis/i18n/zh_CN.po @@ -0,0 +1,225 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * module_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-08-31 06:51+0000\n" +"Last-Translator: 黎伟杰 <674416404@qq.com>\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8\n" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis +msgid "Analysis" +msgstr "分析" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids +msgid "Authors" +msgstr "作者" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty +msgid "CSS Code Quantity" +msgstr "CSS代码数量" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Code Size" +msgstr "代码大小" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid +msgid "Created by" +msgstr "创建者" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date +msgid "Created on" +msgstr "创建时间" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name +msgid "Display Name" +msgstr "显示名称" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id +msgid "ID" +msgstr "ID" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids +msgid "Installed Modules" +msgstr "已安装的模块" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty +msgid "Installed Modules Quantity" +msgstr "已安装的模块数量" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type +#: model:ir.ui.menu,name:module_analysis.menu_module_by_type +msgid "Installed Modules by Types" +msgstr "按类型安装的模块" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty +msgid "JS Code Quantity" +msgstr "JS代码数量" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid +msgid "Last Updated by" +msgstr "最后更新者" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date +msgid "Last Updated on" +msgstr "最后更新时间" + +#. module: module_analysis +#: model:ir.model,name:module_analysis.model_ir_module_module +msgid "Module" +msgstr "模块" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain +msgid "Module Domain" +msgstr "模块域" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id +msgid "Module Type" +msgstr "模块类型" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id +msgid "Module type" +msgstr "模块类型" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids +msgid "Modules" +msgstr "模块" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author +#: model:ir.model,name:module_analysis.model_ir_module_author +#: model:ir.ui.menu,name:module_analysis.menu_module_authors +msgid "Modules Authors" +msgstr "模块作者" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty +msgid "Modules Quantity" +msgstr "模块数量" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type +#: model:ir.model,name:module_analysis.model_ir_module_type +#: model:ir.ui.menu,name:module_analysis.menu_module_types +msgid "Modules Types" +msgstr "模块类型" + +#. module: module_analysis +#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule +#: model:ir.model,name:module_analysis.model_ir_module_type_rule +#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules +msgid "Modules Types Rules" +msgstr "模块类型规则" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name +msgid "Name" +msgstr "名称" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty +msgid "Python Code Quantity" +msgstr "Python代码数量" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Refresh Code Analysis" +msgstr "刷新代码分析" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting +msgid "Reporting" +msgstr "报告" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__scss_code_qty +msgid "SCSS Code Quantity" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence +msgid "Sequence" +msgstr "序列" + +#. module: module_analysis +#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings +msgid "Settings" +msgstr "设置" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search +msgid "Smart Search" +msgstr "" + +#. module: module_analysis +#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq +msgid "The name of the modules author should be unique per database!" +msgstr "模块作者的名称应该是每个数据库唯一的!" + +#. module: module_analysis +#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form +msgid "Type and Authors" +msgstr "类型和作者" + +#. module: module_analysis +#: model:ir.actions.server,name:module_analysis.cron_module_analysis_ir_actions_server +msgid "Update Module Analysis" +msgstr "" + +#. module: module_analysis +#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty +msgid "XML Code Quantity" +msgstr "XML代码数量" + +#~ msgid "Last Modified on" +#~ msgstr "最后修改时间" + +#~ msgid "Analyse Installed Modules" +#~ msgstr "分析已安装的模块" + +#~ msgid "Update Module" +#~ msgstr "更新模块" diff --git a/module_analysis/models/__init__.py b/module_analysis/models/__init__.py new file mode 100644 index 00000000000..53b968f5a88 --- /dev/null +++ b/module_analysis/models/__init__.py @@ -0,0 +1,4 @@ +from . import ir_module_author +from . import ir_module_module +from . import ir_module_type +from . import ir_module_type_rule diff --git a/module_analysis/models/ir_module_author.py b/module_analysis/models/ir_module_author.py new file mode 100644 index 00000000000..0b1e51fd6f2 --- /dev/null +++ b/module_analysis/models/ir_module_author.py @@ -0,0 +1,45 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class IrModuleAuthor(models.Model): + _name = "ir.module.author" + _description = "Modules Authors" + + name = fields.Char(required=True) + + installed_module_ids = fields.Many2many( + string="Modules", + comodel_name="ir.module.module", + relation="ir_module_module_author_rel", + ) + + installed_module_qty = fields.Integer( + string="Installed Modules Quantity", + compute="_compute_installed_module_qty", + store=True, + ) + + _sql_constraints = [ + ( + "name_uniq", + "unique(name)", + "The name of the modules author should be unique per database!", + ), + ] + + @api.depends("installed_module_ids") + def _compute_installed_module_qty(self): + for author in self: + author.installed_module_qty = len(author.installed_module_ids) + + @api.model + def _get_or_create(self, name): + authors = self.search([("name", "=", name)]) + if authors: + return authors[0] + else: + return self.create({"name": name}) diff --git a/module_analysis/models/ir_module_module.py b/module_analysis/models/ir_module_module.py new file mode 100644 index 00000000000..3a8dbd6d3cf --- /dev/null +++ b/module_analysis/models/ir_module_module.py @@ -0,0 +1,180 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging +import os +from pathlib import Path + +from pygount import SourceAnalysis + +from odoo import api, fields, models +from odoo.modules.module import get_module_path +from odoo.tools.safe_eval import safe_eval + +_logger = logging.getLogger(__name__) + + +class IrModuleModule(models.Model): + _inherit = "ir.module.module" + + author_ids = fields.Many2many( + string="Authors", + comodel_name="ir.module.author", + readonly=True, + relation="ir_module_module_author_rel", + ) + + module_type_id = fields.Many2one( + string="Analysed Module Type", comodel_name="ir.module.type", readonly=True + ) + + python_code_qty = fields.Integer(string="Python Code Quantity", readonly=True) + + xml_code_qty = fields.Integer(string="XML Code Quantity", readonly=True) + + js_code_qty = fields.Integer(string="JS Code Quantity", readonly=True) + + css_code_qty = fields.Integer(string="CSS Code Quantity", readonly=True) + scss_code_qty = fields.Integer(string="SCSS Code Quantity", readonly=True) + + # Overloadable Section + @api.model + def _get_analyse_settings(self): + """Return a dictionnary of data analysed + Overload this function if you want to analyse other data + { + 'extension': { + 'data_to_analyse': 'field_name', + }, + }, [...] + extension: extension of the file, with the '.' + data_to_analyse : possible value : code, documentation, empty, string + field_name: Odoo field name to store the analysis + """ + return { + ".py": {"code_count": "python_code_qty"}, + ".xml": {"code_count": "xml_code_qty"}, + ".js": {"code_count": "js_code_qty"}, + ".css": {"code_count": "css_code_qty"}, + ".scss": {"code_count": "scss_code_qty"}, + } + + @api.model + def _get_clean_analyse_values(self): + """List of fields to unset when a module is uninstalled""" + return { + "author_ids": [(6, 0, [])], + "module_type_id": False, + "python_code_qty": False, + "xml_code_qty": 0, + "js_code_qty": 0, + "css_code_qty": 0, + "scss_code_qty": 0, + } + + @api.model + def _get_module_encoding(self, file_ext): + return "utf-8" + + def write(self, vals): + res = super().write(vals) + if vals.get("state", False) == "uninstalled" and "module_analysis" not in [ + x.name for x in self + ]: + self.write(self._get_clean_analyse_values()) + return res + + # Public Section + def button_analyse_code(self): + self._analyse_code() + + @api.model + def cron_analyse_code(self, domain=None): + if domain is None: + domain = [("state", "=", "installed")] + self.search(domain)._analyse_code() + + # Custom Section + def _analyse_code(self): + IrModuleAuthor = self.env["ir.module.author"] + IrModuleTypeRule = self.env["ir.module.type.rule"] + rules = IrModuleTypeRule.search([]) + + cfg = self.env["ir.config_parameter"] + val = cfg.get_param("module_analysis.exclude_directories", "") + exclude_directories = [x.strip() for x in val.split(",") if x.strip()] + val = cfg.get_param("module_analysis.exclude_files", "") + exclude_files = [x.strip() for x in val.split(",") if x.strip()] + + for module in self: + _logger.info(f"Analysing Code for module {module.name} ...") + + # Update Authors, based on manifest key + authors = [] + if module.author and module.author[0] == "[": + author_txt_list = safe_eval(module.author) + else: + author_txt_list = (module.author and module.author.split(",")) or [] + + author_txt_list = [x.strip() for x in author_txt_list] + author_txt_list = [x for x in author_txt_list if x] + for author_txt in author_txt_list: + authors.append(IrModuleAuthor._get_or_create(author_txt)) + + author_ids = [x.id for x in authors] + module.author_ids = author_ids + + # Update Module Type, based on rules + module_type_id = rules._get_module_type_id_from_module(module) + module.module_type_id = module_type_id + + # Get Path of module folder and parse the code + module_path = get_module_path(module.name) + + # Get Files + analysed_datas = self._get_analyse_data_dict() + file_extensions = analysed_datas.keys() + file_list = self._get_files_to_analyse( + module_path, file_extensions, exclude_directories, exclude_files + ) + + for file_path, file_ext in file_list: + file_res = SourceAnalysis.from_file( + file_path, "", encoding=self._get_module_encoding(file_ext) + ) + for k, v in analysed_datas.get(file_ext).items(): + v["value"] += getattr(file_res, k) + + # Update the module with the datas + values = {} + for analyses in analysed_datas.values(): + for v in analyses.values(): + values[v["field"]] = v["value"] + module.write(values) + + @api.model + def _get_files_to_analyse( + self, path, file_extensions, exclude_directories, exclude_files + ): + res = [] + if not path: + return res + for root, _, files in os.walk(path, followlinks=True): + if set(Path(root).relative_to(path).parts) & set(exclude_directories): + continue + for name in files: + if name in exclude_files: + continue + filename, file_extension = os.path.splitext(name) + if file_extension in file_extensions: + res.append((os.path.join(root, name), file_extension)) + return res + + @api.model + def _get_analyse_data_dict(self): + res_dict = self._get_analyse_settings().copy() + for analyse_dict in res_dict.values(): + for analyse_type, v in analyse_dict.items(): + analyse_dict[analyse_type] = {"field": v, "value": 0} + return res_dict diff --git a/module_analysis/models/ir_module_type.py b/module_analysis/models/ir_module_type.py new file mode 100644 index 00000000000..de804d0b3fd --- /dev/null +++ b/module_analysis/models/ir_module_type.py @@ -0,0 +1,30 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class IrModuleType(models.Model): + _name = "ir.module.type" + _description = "Modules Types" + _order = "sequence" + + name = fields.Char(required=True) + + sequence = fields.Integer() + + installed_module_ids = fields.One2many( + string="Installed Modules", + comodel_name="ir.module.module", + inverse_name="module_type_id", + ) + + installed_module_qty = fields.Integer( + string="Modules Quantity", compute="_compute_installed_module_qty", store=True + ) + + @api.depends("installed_module_ids.module_type_id") + def _compute_installed_module_qty(self): + for module_type in self: + module_type.installed_module_qty = len(module_type.installed_module_ids) diff --git a/module_analysis/models/ir_module_type_rule.py b/module_analysis/models/ir_module_type_rule.py new file mode 100644 index 00000000000..e3f24db9789 --- /dev/null +++ b/module_analysis/models/ir_module_type_rule.py @@ -0,0 +1,29 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models +from odoo.tools.safe_eval import safe_eval + + +class IrModuleTypeRule(models.Model): + _name = "ir.module.type.rule" + _description = "Modules Types Rules" + _order = "sequence" + + sequence = fields.Integer() + + module_domain = fields.Char(required=True, default="[]") + + module_type_id = fields.Many2one( + string="Module type", comodel_name="ir.module.type", required=True + ) + + def _get_module_type_id_from_module(self, module): + IrModuleModule = self.env["ir.module.module"] + for rule in self: + domain = safe_eval(rule.module_domain) + domain.append(("id", "=", module.id)) + if IrModuleModule.search(domain): + return rule.module_type_id.id + return False diff --git a/module_analysis/pyproject.toml b/module_analysis/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/module_analysis/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/module_analysis/readme/CONFIGURE.md b/module_analysis/readme/CONFIGURE.md new file mode 100644 index 00000000000..5f3457ec8bb --- /dev/null +++ b/module_analysis/readme/CONFIGURE.md @@ -0,0 +1,59 @@ +- Go to Apps / Module Analysis / Modules Types Rules + +The Module types Rules are usefull to get the Type of a module, based on +it information. + +This module comes with default rules. + +> ![default_module_type_rules](../static/description/default_module_type_rules.png) + +You can add your custom rules to identify the modules your team have +developped for exemple, + +> ![add_module_type_rules](../static/description/add_module_type_rules.png) + +to update the data manually, you have to : + +- Go to 'Settings' / 'Technical' / 'Scheduled Actions' +- Run manually the action : 'Update Module Analysis' + +This will update analysis of your installed modules. + +to update the data automatically, you have to : + +- Go to 'Settings' / 'Technical' / 'Scheduled Actions' +- Configure the action 'Update Module Analysis' and activate it. (By + default, the cron is unactive and no analysis is done) + +## Adding Extra data + +If you want to analyse other data, (for exemple, having the number of +HTML files), create a custom modules and overload the module model : + +``` python +from odoo import api, fields, models + +class IrModuleModule(models.Model): + _inherit = 'ir.module.module' + + xml_documentation_qty = fields.Integer( + string='Quantity of Comments in XML Files') + + @api.model + def _get_analyse_settings(self): + res = super()._get_analyse_settings() + if not '.html' in res: + res['.html'] = {} + res['.html']['documentation'] 'xml_documentation_qty' + return res +``` + +## Exclude files and directories + +Two parameters are availaible in 'Settings' / 'Technical' / 'Parameters' +'System Parameters' : + +> ![config_parameters](../static/description/config_parameters.png) + +The list of folders and filename will be exclude from the analysis. You +can change the default settings. diff --git a/module_analysis/readme/CONTRIBUTORS.md b/module_analysis/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..18c1c87e0f0 --- /dev/null +++ b/module_analysis/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Sylvain LE GAL () diff --git a/module_analysis/readme/DESCRIPTION.md b/module_analysis/readme/DESCRIPTION.md new file mode 100644 index 00000000000..8680a2fef6d --- /dev/null +++ b/module_analysis/readme/DESCRIPTION.md @@ -0,0 +1,27 @@ +This module allows you to know 'how much code' is running on your Odoo +instance, group by 'Type' (Odoo Core, OCA, other...) + +This module can be usefull in the following cases : + +- To analyse the size of your technical debt, regarding your Custom + modules +- To know the ratio between Odoo / OCA and Custom modules +- To evaluate the amount to pay to odoo to upgrade your custom code, or + the induced workload + +![installed_modules_by_types](../static/description/installed_modules_by_types.png) + +For that purpose, it adds new concepts + +- `ir.module.author`, based on the value `author` present in the + manifest file. + +![module_authors](../static/description/module_authors.png) + +- `ir.module.type`, populated by default with Odoo and OCA values. + +![module_types](../static/description/module_types.png) + +Each installed modules have extra data in the 'Technical Data' tab : + +![module_form](../static/description/module_form.png) diff --git a/module_analysis/readme/INSTALL.md b/module_analysis/readme/INSTALL.md new file mode 100644 index 00000000000..8de34622099 --- /dev/null +++ b/module_analysis/readme/INSTALL.md @@ -0,0 +1,3 @@ +To use this module, you have to install the `pygount` python librairy. + +`pip install pygount` diff --git a/module_analysis/readme/USAGE.md b/module_analysis/readme/USAGE.md new file mode 100644 index 00000000000..1cc8428ba17 --- /dev/null +++ b/module_analysis/readme/USAGE.md @@ -0,0 +1,7 @@ +- Go to 'Apps' / 'Module Analysis' / 'Installed module by Types' + +Open the stats to analyse the detail of the code installed + +> ![analysis_pivot](../static/description/analysis_pivot.png) +> +> ![analysis_pie](../static/description/analysis_pie.png) diff --git a/module_analysis/security/ir.model.access.csv b/module_analysis/security/ir.model.access.csv new file mode 100644 index 00000000000..af10dbde22f --- /dev/null +++ b/module_analysis/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_ir_module_author_manager,ir_module_author_manager,model_ir_module_author,base.group_system,1,1,1,1 +access_ir_module_type_manager,ir_module_type_manager,model_ir_module_type,base.group_system,1,1,1,1 +access_ir_module_type_rule_manager,ir_module_type_rule_manager,model_ir_module_type_rule,base.group_system,1,1,1,1 diff --git a/module_analysis/static/description/add_module_type_rules.png b/module_analysis/static/description/add_module_type_rules.png new file mode 100644 index 00000000000..b9c97074e0b Binary files /dev/null and b/module_analysis/static/description/add_module_type_rules.png differ diff --git a/module_analysis/static/description/analysis_pie.png b/module_analysis/static/description/analysis_pie.png new file mode 100644 index 00000000000..1ed7f867d71 Binary files /dev/null and b/module_analysis/static/description/analysis_pie.png differ diff --git a/module_analysis/static/description/analysis_pivot.png b/module_analysis/static/description/analysis_pivot.png new file mode 100644 index 00000000000..376f008d24f Binary files /dev/null and b/module_analysis/static/description/analysis_pivot.png differ diff --git a/module_analysis/static/description/config_parameters.png b/module_analysis/static/description/config_parameters.png new file mode 100644 index 00000000000..b11538a8afb Binary files /dev/null and b/module_analysis/static/description/config_parameters.png differ diff --git a/module_analysis/static/description/default_module_type_rules.png b/module_analysis/static/description/default_module_type_rules.png new file mode 100644 index 00000000000..d3ee1b4774d Binary files /dev/null and b/module_analysis/static/description/default_module_type_rules.png differ diff --git a/module_analysis/static/description/icon.png b/module_analysis/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/module_analysis/static/description/icon.png differ diff --git a/module_analysis/static/description/index.html b/module_analysis/static/description/index.html new file mode 100644 index 00000000000..ce23286aa71 --- /dev/null +++ b/module_analysis/static/description/index.html @@ -0,0 +1,534 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Module Analysis

+ +

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

+

This module allows you to know ‘how much code’ is running on your Odoo +instance, group by ‘Type’ (Odoo Core, OCA, other…)

+

This module can be usefull in the following cases :

+
    +
  • To analyse the size of your technical debt, regarding your Custom +modules
  • +
  • To know the ratio between Odoo / OCA and Custom modules
  • +
  • To evaluate the amount to pay to odoo to upgrade your custom code, or +the induced workload
  • +
+

installed_modules_by_types

+

For that purpose, it adds new concepts

+
    +
  • ir.module.author, based on the value author present in the +manifest file.
  • +
+

module_authors

+
    +
  • ir.module.type, populated by default with Odoo and OCA values.
  • +
+

module_types

+

Each installed modules have extra data in the ‘Technical Data’ tab :

+

module_form

+

Table of contents

+ +
+

Installation

+

To use this module, you have to install the pygount python librairy.

+

pip install pygount

+
+
+

Configuration

+
    +
  • Go to Apps / Module Analysis / Modules Types Rules
  • +
+

The Module types Rules are usefull to get the Type of a module, based on +it information.

+

This module comes with default rules.

+
+default_module_type_rules
+

You can add your custom rules to identify the modules your team have +developped for exemple,

+
+add_module_type_rules
+

to update the data manually, you have to :

+
    +
  • Go to ‘Settings’ / ‘Technical’ / ‘Scheduled Actions’
  • +
  • Run manually the action : ‘Update Module Analysis’
  • +
+

This will update analysis of your installed modules.

+

to update the data automatically, you have to :

+
    +
  • Go to ‘Settings’ / ‘Technical’ / ‘Scheduled Actions’
  • +
  • Configure the action ‘Update Module Analysis’ and activate it. (By +default, the cron is unactive and no analysis is done)
  • +
+
+

Adding Extra data

+

If you want to analyse other data, (for exemple, having the number of +HTML files), create a custom modules and overload the module model :

+
+from odoo import api, fields, models
+
+class IrModuleModule(models.Model):
+   _inherit = 'ir.module.module'
+
+   xml_documentation_qty = fields.Integer(
+      string='Quantity of Comments in XML Files')
+
+  @api.model
+  def _get_analyse_settings(self):
+      res = super()._get_analyse_settings()
+      if not '.html' in res:
+          res['.html'] = {}
+      res['.html']['documentation'] 'xml_documentation_qty'
+      return res
+
+
+
+

Exclude files and directories

+

Two parameters are availaible in ‘Settings’ / ‘Technical’ / ‘Parameters’ +‘System Parameters’ :

+
+config_parameters
+

The list of folders and filename will be exclude from the analysis. You +can change the default settings.

+
+
+
+

Usage

+
    +
  • Go to ‘Apps’ / ‘Module Analysis’ / ‘Installed module by Types’
  • +
+

Open the stats to analyse the detail of the code installed

+
+

analysis_pivot

+

analysis_pie

+
+
+
+

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

+
    +
  • GRAP
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

legalsylvain

+

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

+

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

+
+
+
+
+ + diff --git a/module_analysis/static/description/installed_modules_by_types.png b/module_analysis/static/description/installed_modules_by_types.png new file mode 100644 index 00000000000..7e08867c0f8 Binary files /dev/null and b/module_analysis/static/description/installed_modules_by_types.png differ diff --git a/module_analysis/static/description/module_authors.png b/module_analysis/static/description/module_authors.png new file mode 100644 index 00000000000..0f04a8c3ca4 Binary files /dev/null and b/module_analysis/static/description/module_authors.png differ diff --git a/module_analysis/static/description/module_form.png b/module_analysis/static/description/module_form.png new file mode 100644 index 00000000000..12cef616d4c Binary files /dev/null and b/module_analysis/static/description/module_form.png differ diff --git a/module_analysis/static/description/module_types.png b/module_analysis/static/description/module_types.png new file mode 100644 index 00000000000..7df84ee0d44 Binary files /dev/null and b/module_analysis/static/description/module_types.png differ diff --git a/module_analysis/tests/__init__.py b/module_analysis/tests/__init__.py new file mode 100644 index 00000000000..d9b96c4fa5a --- /dev/null +++ b/module_analysis/tests/__init__.py @@ -0,0 +1 @@ +from . import test_module diff --git a/module_analysis/tests/test_module.py b/module_analysis/tests/test_module.py new file mode 100644 index 00000000000..eab6e94299b --- /dev/null +++ b/module_analysis/tests/test_module.py @@ -0,0 +1,45 @@ +# Copyright (C) 2019-Today: GRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests.common import TransactionCase + + +class TestModule(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.IrModuleModule = cls.env["ir.module.module"] + # Remove lib because it breaks tests in case of installation of modules with + # pip + cls.env["ir.config_parameter"].set_param( + "module_analysis.exclude_directories", "demo,test,tests,doc,description" + ) + + def test_installed_modules(self): + installed_modules = self.IrModuleModule.search( + [("state", "=", "installed"), ("name", "not like", "_test")] + ) + for module in installed_modules: + module.button_analyse_code() + self.assertTrue( + ( + module.python_code_qty > 0 + or module.xml_code_qty > 0 + or module.js_code_qty > 0 + or module.css_code_qty > 0 + or module.scss_code_qty > 0 + or module.module_type_id + ), + f"module {module.name} doesn't have code analysed defined, " + "whereas it is installed.", + ) + + def test_uninstalled_modules(self): + uninstalled_modules = self.IrModuleModule.search([("state", "!=", "installed")]) + for module in uninstalled_modules: + self.assertTrue( + module.python_code_qty == 0, + f"module {module.name} has python lines defined, " + "whereas it is not installed.", + ) diff --git a/module_analysis/views/menu.xml b/module_analysis/views/menu.xml new file mode 100644 index 00000000000..97c90634930 --- /dev/null +++ b/module_analysis/views/menu.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/module_analysis/views/view_ir_module_author.xml b/module_analysis/views/view_ir_module_author.xml new file mode 100644 index 00000000000..f74d91d615d --- /dev/null +++ b/module_analysis/views/view_ir_module_author.xml @@ -0,0 +1,50 @@ + + + + + ir.module.author + +
+ +
+
+
+

+ +

+
+ + + +
+
+
+
+ + ir.module.author + + + + + + + + + Modules Authors + ir.actions.act_window + ir.module.author + list,form + + +
diff --git a/module_analysis/views/view_ir_module_module.xml b/module_analysis/views/view_ir_module_module.xml new file mode 100644 index 00000000000..a4818c06b41 --- /dev/null +++ b/module_analysis/views/view_ir_module_module.xml @@ -0,0 +1,69 @@ + + + + + ir.module.module + + + +