From 02cc47bbb1baed948858bd1476c85c1d7db252b4 Mon Sep 17 00:00:00 2001 From: Jordi Riera Date: Tue, 30 Dec 2014 10:11:20 -0500 Subject: [PATCH] [IMP] prototype: added helper fields and placeholders on new fields. [IMP] prototype: no more bug when no icon, commented no implemented page in the view. [IMP] prototype: better management of special cases. [IMP] prototype: prototype.py removed print statement and shadowing of "fields". [IMP] prototype -> module_prototyper [IMP] module_prototyper: gathered menuitems that is helpfull to create a prototype under the menu 'Module Prototypes' [IMP] module_prototyper: more comment and docstrings. [IMP] module_prototyper: translations. [FIX] module_prototyper: pep8 [IMP] update module_prototyper: * pump up the version of the module to 0.3 * replace ir.ui.model by ir.ui.view in generated xml views * improve pep8 compatibility of generation of models [IMP] update module_prototyper: update of README with versions. --- module_prototyper/README.rst | 4 +- .../README.rst~HEAD | 59 +- module_prototyper/__openerp__.py | 2 +- .../__openerp__.py~HEAD | 14 +- module_prototyper/i18n/fr.po | 10 +- module_prototyper/i18n/fr.po~HEAD | 338 +++++++++++ .../models/__init__.py~HEAD | 5 +- .../models/ir_model_fields.py~HEAD | 23 +- .../models/module_prototyper.py~HEAD | 556 ++++++++++++++++++ .../templates/8.0/__init__.py.template | 3 +- .../templates/8.0/__init__.py.template~HEAD | 3 +- .../templates/8.0/__openerp__.py.template | 39 +- .../8.0/__openerp__.py.template~HEAD | 44 +- .../8.0/data/model_name.xml.template | 13 +- .../8.0/data/model_name.xml.template~HEAD | 17 + .../templates/8.0/header.template | 32 +- .../templates/8.0/header.template~HEAD | 26 + .../templates/8.0/models/__init__.py.template | 7 +- .../8.0/models/__init__.py.template~HEAD | 9 + .../8.0/models/model_name.py.template | 66 +-- .../8.0/models/model_name.py.template~HEAD | 68 +++ .../8.0/views/model_menus.xml.template | 41 +- .../8.0/views/model_menus.xml.template~HEAD | 29 + .../8.0/views/model_views.xml.template | 26 +- .../8.0/views/model_views.xml.template~HEAD | 17 + .../tests/__init__.py~HEAD | 4 +- .../tests/test_prototype.py~HEAD | 36 +- .../test_prototype_module_export.py~HEAD | 9 +- .../views/ir_model_fields_view.xml~HEAD | 51 ++ .../views/module_prototyper_view.xml | 3 +- .../views/module_prototyper_view.xml~HEAD | 145 +++++ .../wizard/module_prototyper_module_export.py | 3 + .../module_prototyper_module_export.py~HEAD | 73 ++- prototype/demo/prototype.prototype.csv | 2 - prototype/i18n/fr.po | 272 --------- prototype/i18n/prototype.pot | 268 --------- prototype/models/prototype.py | 339 ----------- prototype/security/ir.model.access.csv | 2 - prototype/static/description/icon.png | Bin 14323 -> 0 bytes .../8.0/data/model_name.xml.template | 8 - .../8.0/demo/model_name.xml.template | 8 - prototype/templates/8.0/header.template | 22 - .../templates/8.0/models/__init__.py.template | 6 - .../8.0/models/model_name.py.template | 21 - .../8.0/security/ir.model.access.csv.template | 4 - .../8.0/security/model_name.xml.template | 10 - .../8.0/views/model_menus.xml.template | 24 - .../8.0/views/model_views.xml.template | 23 - prototype/tests/__init__.py | 28 - prototype/views/ir_model_fields_view.xml | 30 - prototype/views/prototype_view.xml | 103 ---- prototype/wizard/__init__.py | 22 - .../wizard/prototype_module_export_view.xml | 43 -- 53 files changed, 1543 insertions(+), 1467 deletions(-) rename prototype/README.rst => module_prototyper/README.rst~HEAD (55%) rename prototype/__openerp__.py => module_prototyper/__openerp__.py~HEAD (82%) create mode 100644 module_prototyper/i18n/fr.po~HEAD rename prototype/__init__.py => module_prototyper/models/__init__.py~HEAD (93%) rename prototype/models/ir_model_fields.py => module_prototyper/models/ir_model_fields.py~HEAD (58%) create mode 100644 module_prototyper/models/module_prototyper.py~HEAD rename prototype/templates/8.0/__init__.py.template => module_prototyper/templates/8.0/__init__.py.template~HEAD (85%) rename prototype/templates/8.0/__openerp__.py.template => module_prototyper/templates/8.0/__openerp__.py.template~HEAD (60%) create mode 100644 module_prototyper/templates/8.0/data/model_name.xml.template~HEAD create mode 100644 module_prototyper/templates/8.0/header.template~HEAD create mode 100644 module_prototyper/templates/8.0/models/__init__.py.template~HEAD create mode 100644 module_prototyper/templates/8.0/models/model_name.py.template~HEAD create mode 100644 module_prototyper/templates/8.0/views/model_menus.xml.template~HEAD create mode 100644 module_prototyper/templates/8.0/views/model_views.xml.template~HEAD rename prototype/models/__init__.py => module_prototyper/tests/__init__.py~HEAD (95%) rename prototype/tests/test_prototype.py => module_prototyper/tests/test_prototype.py~HEAD (73%) rename prototype/tests/test_prototype_module_export.py => module_prototyper/tests/test_prototype_module_export.py~HEAD (92%) create mode 100644 module_prototyper/views/ir_model_fields_view.xml~HEAD create mode 100644 module_prototyper/views/module_prototyper_view.xml~HEAD rename prototype/wizard/prototype_module_export.py => module_prototyper/wizard/module_prototyper_module_export.py~HEAD (56%) delete mode 100644 prototype/demo/prototype.prototype.csv delete mode 100644 prototype/i18n/fr.po delete mode 100644 prototype/i18n/prototype.pot delete mode 100644 prototype/models/prototype.py delete mode 100755 prototype/security/ir.model.access.csv delete mode 100644 prototype/static/description/icon.png delete mode 100644 prototype/templates/8.0/data/model_name.xml.template delete mode 100644 prototype/templates/8.0/demo/model_name.xml.template delete mode 100644 prototype/templates/8.0/header.template delete mode 100644 prototype/templates/8.0/models/__init__.py.template delete mode 100644 prototype/templates/8.0/models/model_name.py.template delete mode 100644 prototype/templates/8.0/security/ir.model.access.csv.template delete mode 100644 prototype/templates/8.0/security/model_name.xml.template delete mode 100644 prototype/templates/8.0/views/model_menus.xml.template delete mode 100644 prototype/templates/8.0/views/model_views.xml.template delete mode 100644 prototype/tests/__init__.py delete mode 100644 prototype/views/ir_model_fields_view.xml delete mode 100644 prototype/views/prototype_view.xml delete mode 100644 prototype/wizard/__init__.py delete mode 100644 prototype/wizard/prototype_module_export_view.xml diff --git a/module_prototyper/README.rst b/module_prototyper/README.rst index dad21b91c..db47f3010 100644 --- a/module_prototyper/README.rst +++ b/module_prototyper/README.rst @@ -42,8 +42,8 @@ You will get a zip file containing your module ready to be installed and complia conventions of the OCA. You can then provide the module to a developer who have to implement things like default values or onchange methods. -Roadmap -======= +Known issues / Roadmap +====================== * `#104`_ - Include controllers.py and templates.xml from scaffold. * Attach images to the prototype and export them to be used in the 'images' module manifest. diff --git a/prototype/README.rst b/module_prototyper/README.rst~HEAD similarity index 55% rename from prototype/README.rst rename to module_prototyper/README.rst~HEAD index 774e696b5..dad21b91c 100644 --- a/prototype/README.rst +++ b/module_prototyper/README.rst~HEAD @@ -42,8 +42,8 @@ You will get a zip file containing your module ready to be installed and complia conventions of the OCA. You can then provide the module to a developer who have to implement things like default values or onchange methods. -Known issues / Roadmap -====================== +Roadmap +======= * `#104`_ - Include controllers.py and templates.xml from scaffold. * Attach images to the prototype and export them to be used in the 'images' module manifest. @@ -52,7 +52,13 @@ Known issues / Roadmap .. _#104: https://github.com/OCA/server-tools/issues/104 -Please report any idea or issue to https://github.com/OCA/server-tools/issues. +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 smashing it by providing a detailed and welcomed feedback +`here `_. Credits ======= @@ -63,7 +69,9 @@ Contributors * David Arnold * Jordi Riera * Maxime Chambreuil +* El hadji Dem * Savoir-faire Linux +* Vincent Vinet Maintainer ---------- @@ -77,3 +85,48 @@ This module is maintained by the OCA. 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. To contribute to this module, please visit http://odoo-community.org. + +Versions +======== + +v0.1 +---- + +All the features are not implemented but the minimal is done. +With this version you can: + + The set up of openerp.py is covered, description, maintainer, website, name, technical name... + Views and menus can be set through odoo and gathered in prototype. The files will be automatically generated and add to the data section of the openerp.py. Be aware some advanced feature as domain or context might still missing. + Dependencies can be set throught the Dependency page + Custom fields can be added. A file by model will be generated with all the fields of the model. The init.py files are updated accordingly. Be aware that some features are not implemented yet, as the domain, the context. + +This version should be enought for: + + set up the client module + create a new field in a view. + +Features that you might expect in next version: + + better generation of fields (many2many fields, domain, context) + Generation of data and demo data files. + Security files (rules, ir.model.access.csv) + openerp's description editing README.rst and index.html + module screenshots + +v0.2 +---- + + Renamed from prototype to module_prototyper as discussed in #108 + menu in Settings that gather element used to create a prototype (menu views, views, fields) + +v0.3 +---- + Replace ir.ui.model by ir.ui.view in generated xml views + Improve pep8 compatibility of generation of models + + +Known bugs +---------- + + icon file extension might be wrong. The extension is hard coded for now. It is planned add Document as dependency to handle it. + diff --git a/module_prototyper/__openerp__.py b/module_prototyper/__openerp__.py index b9672122c..723da8057 100644 --- a/module_prototyper/__openerp__.py +++ b/module_prototyper/__openerp__.py @@ -28,7 +28,7 @@ 'website': 'http://www.savoirfairelinux.com', 'license': 'AGPL-3', 'category': 'Others', - 'summary': 'Prototype your module.', + 'summary': 'Prototype your module', 'depends': [ 'admin_technical_features', ], diff --git a/prototype/__openerp__.py b/module_prototyper/__openerp__.py~HEAD similarity index 82% rename from prototype/__openerp__.py rename to module_prototyper/__openerp__.py~HEAD index e92d48b0f..b9672122c 100644 --- a/prototype/__openerp__.py +++ b/module_prototyper/__openerp__.py~HEAD @@ -21,26 +21,26 @@ ############################################################################## { - 'name': 'Prototype', - 'version': '0.1', - 'author': 'Savoir-faire Linux', + 'name': 'Module Prototyper', + 'version': '0.3', + 'author': 'Savoir-faire Linux, Odoo Community Association (OCA)', 'maintainer': 'Savoir-faire Linux', 'website': 'http://www.savoirfairelinux.com', 'license': 'AGPL-3', 'category': 'Others', - 'summary': 'Prototype your module', + 'summary': 'Prototype your module.', 'depends': [ - 'base', 'admin_technical_features', ], 'external_dependencies': { 'python': [], }, 'data': [ - 'wizard/prototype_module_export_view.xml', - 'views/prototype_view.xml', + 'wizard/module_prototyper_module_export_view.xml', + 'views/module_prototyper_view.xml', 'views/ir_model_fields_view.xml', 'security/ir.model.access.csv', ], 'installable': True, + 'application': True, } diff --git a/module_prototyper/i18n/fr.po b/module_prototyper/i18n/fr.po index 64c6ca30a..15c519357 100644 --- a/module_prototyper/i18n/fr.po +++ b/module_prototyper/i18n/fr.po @@ -153,7 +153,7 @@ msgstr "Groupes" #. module: module_prototyper #: field:ir.model.fields,helper:0 msgid "Helper" -msgstr "Texte d'aide" +msgstr "Texte d'aider" #. module: module_prototyper #: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard @@ -189,8 +189,8 @@ msgstr "Mis à jour le" #. module: module_prototyper #: field:module_prototyper,licence:0 -msgid "License" -msgstr "Licence" +msgid "Licence" +msgstr "" #. module: module_prototyper #: field:module_prototyper,maintainer:0 @@ -230,8 +230,8 @@ msgstr "" #. module: module_prototyper #: field:ir.model.fields,notes:0 -msgid "Notes to developers" -msgstr "Notes aux développeurs" +msgid "Notes to developers." +msgstr "Notes aux développeurs." #. module: module_prototyper #: view:ir.model.fields:module_prototyper.view_ir_model_fields_form diff --git a/module_prototyper/i18n/fr.po~HEAD b/module_prototyper/i18n/fr.po~HEAD new file mode 100644 index 000000000..64c6ca30a --- /dev/null +++ b/module_prototyper/i18n/fr.po~HEAD @@ -0,0 +1,338 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * module_prototyper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-02 17:07+0000\n" +"PO-Revision-Date: 2015-01-02 12:18-0500\n" +"Last-Translator: Jordi Riera \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.5.4\n" + +#. module: module_prototyper +#: selection:module_prototyper.module.export,api_version:0 +msgid "8.0" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper.module.export,api_version:0 +msgid "API version" +msgstr "Version de l'API" + +#. module: module_prototyper +#: field:module_prototyper,right_ids:0 +msgid "Access Rights" +msgstr "Liste des contrôles d'accès" + +#. module: module_prototyper +#: field:module_prototyper,application:0 +msgid "Application" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper,author:0 +msgid "Author" +msgstr "Auteur" + +#. module: module_prototyper +#: field:module_prototyper,auto_install:0 +msgid "Auto Install" +msgstr "Installation automatique" + +#. module: module_prototyper +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Cancel" +msgstr "Annuler" + +#. module: module_prototyper +#: field:module_prototyper,category_id:0 +msgid "Category" +msgstr "Catégorie" + +#. module: module_prototyper +#: help:module_prototyper,application:0 +msgid "Check if the module is an Odoo application." +msgstr "Cocher si le module est une application Odoo." + +#. module: module_prototyper +#: help:module_prototyper,auto_install:0 +msgid "Check if the module should be install by default." +msgstr "Cocher si le module devrait être installé par défaut." + +#. module: module_prototyper +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Close" +msgstr "Fermer" + +#. module: module_prototyper +#: field:module_prototyper,create_uid:0 +#: field:module_prototyper.module.export,create_uid:0 +msgid "Created by" +msgstr "Créé par" + +#. module: module_prototyper +#: field:module_prototyper,create_date:0 +#: field:module_prototyper.module.export,create_date:0 +msgid "Created on" +msgstr "Créé le" + +#. module: module_prototyper +#: field:module_prototyper,data_ids:0 +msgid "Data filters" +msgstr "Filtres pour les données" + +#. module: module_prototyper +#: field:module_prototyper,demo_ids:0 +msgid "Demo filters" +msgstr "Filtres pour les données de démo" + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +#: field:module_prototyper,dependency_ids:0 +msgid "Dependencies" +msgstr "Dépendances" + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +#: field:module_prototyper,description:0 +msgid "Description" +msgstr "Descriptions" + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Export" +msgstr "Exporter" + +#. module: module_prototyper +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Export Complete" +msgstr "Export terminé" + +#. module: module_prototyper +#: model:ir.actions.act_window,name:module_prototyper.button_module_export_action +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Export Module" +msgstr "Exporter le module" + +#. module: module_prototyper +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Export Settings" +msgstr "Configuration de l'export" + +#. module: module_prototyper +#: model:ir.model,name:module_prototyper.model_ir_model_fields +#: model:ir.ui.menu,name:module_prototyper.ir_model_model_fields +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +#: field:module_prototyper,field_ids:0 +msgid "Fields" +msgstr "Champs" + +#. module: module_prototyper +#: field:module_prototyper.module.export,data:0 +msgid "File" +msgstr "Fichier" + +#. module: module_prototyper +#: field:module_prototyper.module.export,name:0 +msgid "File Name" +msgstr "Nom du fichier" + +#. module: module_prototyper +#: field:module_prototyper,group_ids:0 +msgid "Groups" +msgstr "Groupes" + +#. module: module_prototyper +#: field:ir.model.fields,helper:0 +msgid "Helper" +msgstr "Texte d'aide" + +#. module: module_prototyper +#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard +msgid "Here is the exported module:" +msgstr "Voici le module exporté :" + +#. module: module_prototyper +#: field:module_prototyper,id:0 field:module_prototyper.module.export,id:0 +msgid "ID" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper,icon_image:0 +msgid "Icon" +msgstr "Icône" + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +msgid "Interface" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper,write_uid:0 +#: field:module_prototyper.module.export,write_uid:0 +msgid "Last Updated by" +msgstr "Mis à jour par" + +#. module: module_prototyper +#: field:module_prototyper,write_date:0 +#: field:module_prototyper.module.export,write_date:0 +msgid "Last Updated on" +msgstr "Mis à jour le" + +#. module: module_prototyper +#: field:module_prototyper,licence:0 +msgid "License" +msgstr "Licence" + +#. module: module_prototyper +#: field:module_prototyper,maintainer:0 +msgid "Maintainer" +msgstr "Mainteneur" + +#. module: module_prototyper +#: model:ir.ui.menu,name:module_prototyper.menu_grant_menu_access +#: field:module_prototyper,menu_ids:0 +msgid "Menu Items" +msgstr "Éléments du menu" + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view +msgid "Module" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper,human_name:0 +msgid "Module Name" +msgstr "Nom du module" + +#. module: module_prototyper +#: model:ir.model,name:module_prototyper.model_module_prototyper +msgid "Module Prototyper" +msgstr "" + +#. module: module_prototyper +#: model:ir.ui.menu,name:module_prototyper.menu_module_prototyper +msgid "Module Prototypers" +msgstr "" + +#. module: module_prototyper +#: view:ir.model:module_prototyper.view_ir_model_form +msgid "Notes" +msgstr "" + +#. module: module_prototyper +#: field:ir.model.fields,notes:0 +msgid "Notes to developers" +msgstr "Notes aux développeurs" + +#. module: module_prototyper +#: view:ir.model.fields:module_prototyper.view_ir_model_fields_form +msgid "" +"Notes to help developers to understand the work or advanced features that " +"should be added, ie: onchange, etc." +msgstr "" +"Notes pour aider les développeurs à comprendre le travail effectué ou les " +"ajouts à faire. Exemple: onchanges, etc." + +#. module: module_prototyper +#: view:module_prototyper:module_prototyper.module_prototyper_base_tree_view +msgid "Prototype" +msgstr "" + +#. module: module_prototyper +#: model:ir.actions.act_window,name:module_prototyper.open_module_prototyper_list +#: model:ir.ui.menu,name:module_prototyper.menu_open_module_prototyper +msgid "Prototypes" +msgstr "" + +#. module: module_prototyper +#: field:module_prototyper,rule_ids:0 +msgid "Record Rules" +msgstr "Règles sur les enregistrements" + +#. module: module_prototyper +#: field:module_prototyper.module.export,state:0 +msgid "State" +msgstr "État" + +#. module: module_prototyper +#: field:module_prototyper,summary:0 +msgid "Summary" +msgstr "Résumé" + +#. module: module_prototyper +#: field:module_prototyper,name:0 +msgid "Technical Name" +msgstr "Nom technique" + +#. module: module_prototyper +#: view:ir.model.fields:module_prototyper.view_ir_model_fields_form +msgid "Text that will be set as the helper of the field..." +msgstr "Texte qui sera placé en tant que texte d'aide du champs." + +#. module: module_prototyper +#: help:module_prototyper,human_name:0 +msgid "" +"The Module Name will be used as the displayed name of the exported module." +msgstr "Le nom du module sera affiché en tant que nom du module exporté." + +#. module: module_prototyper +#: help:module_prototyper,icon_image:0 +msgid "" +"The icon set up here will be used as the icon for the exported module also" +msgstr "L'icône sera utilisé comme icône du module exporté." + +#. module: module_prototyper +#: help:module_prototyper,data_ids:0 +msgid "The records matching the filters will be added as data." +msgstr "" +"Les enregistrements correspondant aux critères des filtres seront exportées " +"dans le module comme données." + +#. module: module_prototyper +#: help:module_prototyper,demo_ids:0 +msgid "The records matching the filters will be added as demo data." +msgstr "" +"Les enregistrements correspondant aux critères des filtres seront exportées " +"dans le module comme données de démo." + +#. module: module_prototyper +#: help:module_prototyper,name:0 +msgid "" +"The technical name will be used to define the name of the exported module, " +"the name of the model." +msgstr "Le nom technique sera utilisé comme nom du module exporté." + +#. module: module_prototyper +#: field:module_prototyper,version:0 +msgid "Version" +msgstr "" + +#. module: module_prototyper +#: model:ir.ui.menu,name:module_prototyper.menu_action_ui_view +#: field:module_prototyper,view_ids:0 +msgid "Views" +msgstr "Vues" + +#. module: module_prototyper +#: field:module_prototyper,website:0 +msgid "Website" +msgstr "Site web" + +#. module: module_prototyper +#: selection:module_prototyper.module.export,state:0 +msgid "choose" +msgstr "choisir" + +#. module: module_prototyper +#: selection:module_prototyper.module.export,state:0 +msgid "get" +msgstr "récupérer" diff --git a/prototype/__init__.py b/module_prototyper/models/__init__.py~HEAD similarity index 93% rename from prototype/__init__.py rename to module_prototyper/models/__init__.py~HEAD index f01f7f122..eda344760 100644 --- a/prototype/__init__.py +++ b/module_prototyper/models/__init__.py~HEAD @@ -20,6 +20,7 @@ # ############################################################################## from . import ( - models, - wizard + module_prototyper, + ir_model_fields, + default_description ) diff --git a/prototype/models/ir_model_fields.py b/module_prototyper/models/ir_model_fields.py~HEAD similarity index 58% rename from prototype/models/ir_model_fields.py rename to module_prototyper/models/ir_model_fields.py~HEAD index 0330a058e..e67df14f8 100644 --- a/prototype/models/ir_model_fields.py +++ b/module_prototyper/models/ir_model_fields.py~HEAD @@ -19,10 +19,31 @@ # along with this program. If not, see . # ############################################################################## + from openerp import fields, models +from openerp.tools.translate import _ class ir_model_fields(models.Model): + """Addition of text fields to fields.""" _inherit = "ir.model.fields" - notes = fields.Text('Notes') + notes = fields.Text('Notes to developers.') + helper = fields.Text('Helper') + # TODO: Make column1 and 2 required if a model has a m2m to itself + column1 = fields.Char( + 'Column1', + help=_("name of the column referring to 'these' records in the " + "relation table"), + ) + column2 = fields.Char( + 'Column2', + help=_("name of the column referring to 'those' records in the " + "relation table"), + ) + limit = fields.Integer('Read limit', help=_("Read limit")) + client_context = fields.Char( + 'Context', + help=_("Context to use on the client side when handling the field " + "(python dictionary)"), + ) diff --git a/module_prototyper/models/module_prototyper.py~HEAD b/module_prototyper/models/module_prototyper.py~HEAD new file mode 100644 index 000000000..aa2fa0a9e --- /dev/null +++ b/module_prototyper/models/module_prototyper.py~HEAD @@ -0,0 +1,556 @@ +# -*- encoding: utf-8 -*- +# ############################################################################# +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2010 - 2014 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import base64 +import logging +import lxml.etree +import os +import re +import textwrap + +from collections import namedtuple +from datetime import date + +from jinja2 import Environment, FileSystemLoader + +from openerp import models, api, fields +from openerp.tools.safe_eval import safe_eval + +from .default_description import get_default_description +from . import licenses + +_logger = logging.getLogger(__name__) + + +class ModulePrototyper(models.Model): + """Module Prototyper gathers different information from all over the + database to build a prototype of module. + We are calling it a prototype as it will most likely need to be reviewed + by a developer to fix glitch that would sneak it during the generation of + files but also to add not supported features. + """ + _name = "module_prototyper" + _description = "Module Prototyper" + + license = fields.Selection( + [ + (licenses.GPL3, 'GPL Version 3'), + (licenses.GPL3_L, 'GPL-3 or later version'), + (licenses.LGPL3, 'LGPL-3'), + (licenses.LGPL3_L, 'LGPL-3 or later version'), + (licenses.AGPL3, 'Affero GPL-3'), + (licenses.OSI, 'Other OSI Approved Licence'), + ('Other proprietary', 'Other Proprietary') + ], + string='License', + default=licenses.AGPL3, + ) + name = fields.Char( + 'Technical Name', required=True, + help=('The technical name will be used to define the name of ' + 'the exported module, the name of the model.') + ) + category_id = fields.Many2one('ir.module.category', 'Category') + human_name = fields.Char( + 'Module Name', required=True, + help=('The Module Name will be used as the displayed name of the ' + 'exported module.') + ) + summary = fields.Char('Summary', required=True, + help=('Enter a summary of your module')) + description = fields.Text( + 'Description', + required=True, + help=('Enter the description of your module, what it does, how to ' + 'install, configure and use it, the roadmap or known issues. ' + 'The description will be exported in README.rst'), + default=get_default_description + ) + author = fields.Char('Author', required=True, help=('Enter your name')) + maintainer = fields.Char( + 'Maintainer', + help=('Enter the name of the person or organization who will ' + 'maintain this module') + ) + website = fields.Char('Website', help=('Enter the URL of your website')) + icon_image = fields.Binary( + 'Icon', + help=('The icon set up here will be used as the icon ' + 'for the exported module also') + ) + version = fields.Char( + 'Version', + size=3, + default='0.1', + help=('Enter the version of your module with 2 digits') + ) + auto_install = fields.Boolean( + 'Auto Install', + default=False, + help='Check if the module should be install by default.' + ) + application = fields.Boolean( + 'Application', + default=False, + help='Check if the module is an Odoo application.' + ) + # Relations + dependency_ids = fields.Many2many( + 'ir.module.module', 'module_prototyper_module_rel', + 'module_prototyper_id', 'module_id', + 'Dependencies', + help=('Enter the list of required modules that need to be installed ' + 'for your module to work properly') + ) + data_ids = fields.Many2many( + 'ir.filters', + 'prototype_data_rel', + 'module_prototyper_id', 'filter_id', + 'Data filters', + help="The records matching the filters will be added as data." + ) + demo_ids = fields.Many2many( + 'ir.filters', + 'prototype_demo_rel', + 'module_prototyper_id', 'filter_id', + 'Demo filters', + help="The records matching the filters will be added as demo data." + ) + field_ids = fields.Many2many( + 'ir.model.fields', 'prototype_fields_rel', + 'module_prototyper_id', 'field_id', 'Fields', + help=('Enter the list of fields that you have created or modified ' + 'and want to export in this module. New models will be ' + 'exported as long as you choose one of his fields.') + ) + menu_ids = fields.Many2many( + 'ir.ui.menu', 'prototype_menu_rel', + 'module_prototyper_id', 'menu_id', 'Menu Items', + help=('Enter the list of menu items that you have created and want ' + 'to export in this module. Related windows actions will be ' + 'exported as well.') + ) + view_ids = fields.Many2many( + 'ir.ui.view', 'prototype_view_rel', + 'module_prototyper_id', 'view_id', 'Views', + help=('Enter the list of views that you have created and want to ' + 'export in this module.') + ) + group_ids = fields.Many2many( + 'res.groups', 'prototype_groups_rel', + 'module_prototyper_id', 'group_id', 'Groups', + help=('Enter the list of groups that you have created and want to ' + 'export in this module.') + ) + right_ids = fields.Many2many( + 'ir.model.access', 'prototype_rights_rel', + 'module_prototyper_id', 'right_id', + 'Access Rights', + help=('Enter the list of access rights that you have created and ' + 'want to export in this module.') + ) + rule_ids = fields.Many2many( + 'ir.rule', 'prototype_rule_rel', + 'module_prototyper_id', 'rule_id', 'Record Rules', + help=('Enter the list of record rules that you have created and ' + 'want to export in this module.') + ) + report_ids = fields.Many2many( + 'ir.actions.report.xml', 'prototype_report_rel', + 'module_prototyper_id', 'report_id', 'Reports', + help=('Enter the list of reports that you have created and ' + 'want to export in this module.') + ) + activity_ids = fields.Many2many( + 'workflow.activity', 'prototype_wf_activity_rel', + 'module_prototyper_id', 'activity_id', 'Activities', + help=('Enter the list of workflow activities that you have created ' + 'and want to export in this module') + ) + transition_ids = fields.Many2many( + 'workflow.transition', 'prototype_wf_transition_rel', + 'module_prototyper_id', 'transition_id', 'Transitions', + help=('Enter the list of workflow transitions that you have created ' + 'and want to export in this module') + ) + + _env = None + _data_files = () + _demo_files = () + _field_descriptions = None + File_details = namedtuple('file_details', ['filename', 'filecontent']) + template_path = '{}/../templates/'.format(os.path.dirname(__file__)) + + @api.model + def set_jinja_env(self, api_version): + """Set the Jinja2 environment. + The environment will helps the system to find the templates to render. + :param api_version: string, odoo api + :return: jinja2.Environment instance. + """ + if self._env is None: + self._env = Environment( + lstrip_blocks=True, + trim_blocks=True, + loader=FileSystemLoader( + os.path.join(self.template_path, api_version) + ) + ) + return self._env + + def set_field_descriptions(self): + """Mock the list of fields into dictionary. + It allows us to add or change attributes of the fields. + + :return: None + """ + for field in self.field_ids: + field_description = {} + # This will mock a field record. + # the mock will allow us to add data or modify the data + # of the field (like for the name) with keeping all the + # attributes of the record. + field_description.update({ + attr_name: getattr(field, attr_name) + for attr_name in dir(field) + if not attr_name[0] == '_' + }) + field_description['name'] = self.unprefix(field.name) + self._field_descriptions[field] = field_description + + @api.model + def generate_files(self): + """ Generates the files from the details of the prototype. + :return: tuple + """ + assert self._env is not None, \ + 'Run set_env(api_version) before to generate files.' + + # Avoid sharing these across instances + self._data_files = [] + self._demo_files = [] + self._field_descriptions = {} + self.set_field_descriptions() + file_details = [] + file_details.extend(self.generate_models_details()) + file_details.extend(self.generate_views_details()) + file_details.extend(self.generate_menus_details()) + file_details.append(self.generate_module_init_file_details()) + file_details.extend(self.generate_data_files()) + # must be the last as the other generations might add information + # to put in the __openerp__: additional dependencies, views files, etc. + file_details.append(self.generate_module_openerp_file_details()) + if self.icon_image: + file_details.append(self.save_icon()) + + return file_details + + @api.model + def save_icon(self): + """Save the icon of the prototype as a image. + The image is used afterwards as the icon of the exported module. + + :return: FileDetails instance + """ + # TODO: The image is not always a jpg. + # 2 ways to do it: + # * find a way to detect image type from the data + # * add document as a dependency. + # The second options seems to be better, as Document is a base module. + return self.File_details( + os.path.join('static', 'description', 'icon.jpg'), + base64.b64decode(self.icon_image) + ) + + @api.model + def generate_module_openerp_file_details(self): + """Wrapper to generate the __openerp__.py file of the module.""" + return self.generate_file_details( + '__openerp__.py', + '__openerp__.py.template', + prototype=self, + data_files=self._data_files, + demo_fiels=self._demo_files, + ) + + @api.model + def generate_module_init_file_details(self): + """Wrapper to generate the __init__.py file of the module.""" + return self.generate_file_details( + '__init__.py', + '__init__.py.template', + # no import models if no work of fields in + # the prototype + models=bool(self.field_ids) + ) + + @api.model + def generate_models_details(self): + """ + Finds the models from the list of fields and generates + the __init__ file and each models files (one by class). + """ + files = [] + # TODO: doesn't work as need to find the module to import + # and it is not necessary the name of the model the fields + # belongs to. + # ie. field.cell_phone is defined in a model inheriting from + # res.partner. + # How do we find the module the field was defined in? + # dependencies = set([dep.id for dep in self.dependencies]) + + relations = {} + field_descriptions = self._field_descriptions or {} + for field in field_descriptions.itervalues(): + model = field.get('model_id') + relations.setdefault(model, []).append(field) + # dependencies.add(model.id) + + # blind update of dependencies. + # self.write({ + # 'dependencies': [(6, 0, [id_ for id_ in dependencies])] + # }) + + files.append(self.generate_models_init_details(relations.keys())) + for model, custom_fields in relations.iteritems(): + files.append(self.generate_model_details(model, custom_fields)) + + return files + + @api.model + def generate_models_init_details(self, ir_models): + """Wrapper to generate the __init__.py file in models folder.""" + return self.generate_file_details( + 'models/__init__.py', + 'models/__init__.py.template', + models=[ + self.friendly_name(ir_model.model) + for ir_model in ir_models + ] + ) + + @api.model + def generate_views_details(self): + """Wrapper to generate the views files.""" + relations = {} + for view in self.view_ids: + relations.setdefault(view.model, []).append(view) + + views_details = [] + for model, views in relations.iteritems(): + filepath = 'views/{}_view.xml'.format( + self.friendly_name(self.unprefix(model)) + ) + views_details.append( + self.generate_file_details( + filepath, + 'views/model_views.xml.template', + views=views + ) + ) + self._data_files.append(filepath) + + return views_details + + @api.model + def generate_menus_details(self): + """Wrapper to generate the menus files.""" + relations = {} + for menu in self.menu_ids: + if menu.action and menu.action.res_model: + model = self.unprefix(menu.action.res_model) + else: + model = 'ir_ui' + relations.setdefault(model, []).append(menu) + + menus_details = [] + for model_name, menus in relations.iteritems(): + model_name = self.unprefix(model_name) + filepath = 'views/{}_menus.xml'.format( + self.friendly_name(model_name) + ) + menus_details.append( + self.generate_file_details( + filepath, + 'views/model_menus.xml.template', + menus=menus, + ) + ) + self._data_files.append(filepath) + + return menus_details + + @api.model + def generate_model_details(self, model, field_descriptions): + """Wrapper to generate the python file for the model. + + :param model: ir.model record. + :param field_descriptions: list of ir.model.fields records. + :return: FileDetails instance. + """ + python_friendly_name = self.friendly_name(self.unprefix(model.model)) + return self.generate_file_details( + 'models/{}.py'.format(python_friendly_name), + 'models/model_name.py.template', + name=python_friendly_name, + model=model, + fields=field_descriptions, + ) + + @api.model + def generate_data_files(self): + """ Generate data and demo files """ + data, demo = {}, {} + filters = [ + (data, ir_filter) + for ir_filter in self.data_ids + ] + [ + (demo, ir_filter) + for ir_filter in self.demo_ids + ] + + for target, ir_filter in filters: + model = ir_filter.model_id + model_obj = self.env[model] + target.setdefault(model, model_obj.browse([])) + target[model] |= model_obj.search(safe_eval(ir_filter.domain)) + + res = [] + for prefix, model_data, file_list in [ + ('data', data, self._data_files), + ('demo', demo, self._demo_files)]: + for model_name, records in model_data.iteritems(): + fname = self.friendly_name(self.unprefix(model_name)) + filename = '{0}/{1}.xml'.format(prefix, fname) + self._data_files.append(filename) + + res.append(self.generate_file_details( + filename, + 'data/model_name.xml.template', + model=model_name, + records=records, + )) + + return res + + @classmethod + def unprefix(cls, name): + if not name: + return name + return re.sub('^x_', '', name) + + @classmethod + def is_prefixed(cls, name): + return bool(re.match('^x_', name)) + + @classmethod + def friendly_name(cls, name): + return name.replace('.', '_') + + @classmethod + def fixup_domain(cls, domain): + """ Fix a domain according to unprefixing of fields """ + res = [] + for elem in domain: + if len(elem) == 3: + elem = list(elem) + elem[0] = cls.unprefix(elem[0]) + res.append(elem) + return res + + @classmethod + def fixup_arch(cls, archstr): + doc = lxml.etree.fromstring(archstr) + for elem in doc.xpath("//*[@name]"): + elem.attrib["name"] = cls.unprefix(elem.attrib["name"]) + + for elem in doc.xpath("//*[@attrs]"): + try: + attrs = safe_eval(elem.attrib["attrs"]) + except Exception: + _logger.error("Unable to eval attribute: %s, skipping", + elem.attrib["attrs"]) + continue + + if isinstance(attrs, dict): + for key, val in attrs.iteritems(): + if isinstance(val, (list, tuple)): + attrs[key] = cls.fixup_domain(val) + elem.attrib["attrs"] = repr(attrs) + + for elem in doc.xpath("//field"): + # Make fields self-closed by removing useless whitespace + if elem.text and not elem.text.strip(): + elem.text = None + + return lxml.etree.tostring(doc) + + @api.model + def generate_file_details(self, filename, template, **kwargs): + """ generate file details from jinja2 template. + :param filename: name of the file the content is related to + :param template: path to the file to render the content + :param kwargs: arguments of the template + :return: File_details instance + """ + template = self._env.get_template(template) + # keywords used in several templates. + kwargs.update( + { + 'export_year': date.today().year, + 'author': self.author, + 'website': self.website, + 'license_text': licenses.get_license_text(self.license), + 'cr': self._cr, + # Utility functions + 'fixup_arch': self.fixup_arch, + 'is_prefixed': self.is_prefixed, + 'unprefix': self.unprefix, + 'wrap': wrap, + + } + ) + return self.File_details(filename, template.render(kwargs)) + + +# Utility functions for rendering templates +def wrap(text, **kwargs): + """ Wrap some text for inclusion in a template, returning lines + + keyword arguments available, from textwrap.TextWrapper: + + width=70 + initial_indent='' + subsequent_indent='' + expand_tabs=True + replace_whitespace=True + fix_sentence_endings=False + break_long_words=True + drop_whitespace=True + break_on_hyphens=True + """ + if not text: + return [] + wrapper = textwrap.TextWrapper(**kwargs) + # We join the lines and split them again to offer a stable api for + # the jinja2 templates, regardless of replace_whitspace=True|False + text = "\n".join(wrapper.wrap(text)) + return text.splitlines() diff --git a/module_prototyper/templates/8.0/__init__.py.template b/module_prototyper/templates/8.0/__init__.py.template index 384a9cd45..82452828d 100644 --- a/module_prototyper/templates/8.0/__init__.py.template +++ b/module_prototyper/templates/8.0/__init__.py.template @@ -1,7 +1,6 @@ {% extends "header.template" %} {% block body %} -{% if models %} - +{% if models -%} from . import models {% endif %} {% endblock %} diff --git a/prototype/templates/8.0/__init__.py.template b/module_prototyper/templates/8.0/__init__.py.template~HEAD similarity index 85% rename from prototype/templates/8.0/__init__.py.template rename to module_prototyper/templates/8.0/__init__.py.template~HEAD index 82452828d..384a9cd45 100644 --- a/prototype/templates/8.0/__init__.py.template +++ b/module_prototyper/templates/8.0/__init__.py.template~HEAD @@ -1,6 +1,7 @@ {% extends "header.template" %} {% block body %} -{% if models -%} +{% if models %} + from . import models {% endif %} {% endblock %} diff --git a/module_prototyper/templates/8.0/__openerp__.py.template b/module_prototyper/templates/8.0/__openerp__.py.template index 28f779704..23d1125cb 100644 --- a/module_prototyper/templates/8.0/__openerp__.py.template +++ b/module_prototyper/templates/8.0/__openerp__.py.template @@ -1,19 +1,17 @@ {% extends "header.template" %} {% block body %} - { - 'name': '{{ prototype.human_name }}', + 'name': '{{ prototype.name }}', 'version': '{{ prototype.version }}', 'author': '{{ prototype.author }}', 'maintainer': '{{ prototype.maintainer }}', 'website': '{{ prototype.website }}', - 'license': '{{ prototype.license }}', - + 'license': '{{ prototype.licence }}', + # Categories can be used to filter modules in modules listing - # Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml # noqa + # Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml # for the full list - {# Use with_context({}) to get english category #} - 'category': '{{ prototype.with_context({}).category_id.name }}', + 'category': '{{ prototype.category_id.name }}', 'summary': '{{ prototype.summary }}', 'description': """ {{ prototype.description }} @@ -25,36 +23,33 @@ # any module necessary for this one to work correctly 'depends': [ - {% for dependency in prototype.dependency_ids %} + {% for dependency in prototype.dependency_ids -%} '{{ dependency.name }}', - {% endfor %} - ], + {% endfor -%}], 'external_dependencies': { 'python': [], }, - + # always loaded 'data': [ - {% for data_file in data_files %} + {% for data_file in data_files -%} '{{ data_file }}', - {% endfor %} - ], + {% endfor -%}], # only loaded in demonstration mode 'demo': [ - {% for demo_file in demo_files %} - '{{ demo_file }}', - {% endfor %} - ], - + {% for demo_file in prototype.demo_ids -%} + '{{ demo_file.name }}', + {% endfor -%}], + # used for Javascript Web CLient Testing with QUnit / PhantomJS - # https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client # noqa + # https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client 'js': [], 'css': [], 'qweb': [], 'installable': True, - # Install this module automatically if all dependency have been previously - # and independently installed. Used for synergetic or glue modules. + # Install this module automatically if all dependency have been previously and independently installed. + # Used for synergetic or glue modules. 'auto_install': {{ prototype.auto_install }}, 'application': {{ prototype.application }}, } diff --git a/prototype/templates/8.0/__openerp__.py.template b/module_prototyper/templates/8.0/__openerp__.py.template~HEAD similarity index 60% rename from prototype/templates/8.0/__openerp__.py.template rename to module_prototyper/templates/8.0/__openerp__.py.template~HEAD index 64aa0c001..28f779704 100644 --- a/prototype/templates/8.0/__openerp__.py.template +++ b/module_prototyper/templates/8.0/__openerp__.py.template~HEAD @@ -1,56 +1,60 @@ {% extends "header.template" %} {% block body %} + { - 'name': '{{ prototype.name }}', + 'name': '{{ prototype.human_name }}', 'version': '{{ prototype.version }}', - 'author': '{{ prototype.author }}', 'maintainer': '{{ prototype.maintainer }}', 'website': '{{ prototype.website }}', - 'license': '{{ prototype.licence }}', - + 'license': '{{ prototype.license }}', + # Categories can be used to filter modules in modules listing - # Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml + # Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml # noqa # for the full list - 'category': '{{ prototype.category_id.name }}', + {# Use with_context({}) to get english category #} + 'category': '{{ prototype.with_context({}).category_id.name }}', 'summary': '{{ prototype.summary }}', 'description': """ {{ prototype.description }} -* Module exported by the prototype module for version 8.0. -* If you have any questions, please contact Savoir-faire Linux \ +* Module exported by the Module Prototyper module for version 8.0. +* If you have any questions, please contact Savoir-faire Linux (support@savoirfairelinux.com) """, # any module necessary for this one to work correctly 'depends': [ - {% for dependency in prototype.dependency_ids -%} + {% for dependency in prototype.dependency_ids %} '{{ dependency.name }}', - {% endfor -%}], + {% endfor %} + ], 'external_dependencies': { 'python': [], }, - + # always loaded 'data': [ - {% for data_file in data_files -%} + {% for data_file in data_files %} '{{ data_file }}', - {% endfor -%}], + {% endfor %} + ], # only loaded in demonstration mode 'demo': [ - {% for demo_file in prototype.demo_ids -%} - '{{ demo_file.name }}', - {% endfor -%}], - + {% for demo_file in demo_files %} + '{{ demo_file }}', + {% endfor %} + ], + # used for Javascript Web CLient Testing with QUnit / PhantomJS - # https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client + # https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client # noqa 'js': [], 'css': [], 'qweb': [], 'installable': True, - # Install this module automatically if all dependency have been previously and independently installed. - # Used for synergetic or glue modules. + # Install this module automatically if all dependency have been previously + # and independently installed. Used for synergetic or glue modules. 'auto_install': {{ prototype.auto_install }}, 'application': {{ prototype.application }}, } diff --git a/module_prototyper/templates/8.0/data/model_name.xml.template b/module_prototyper/templates/8.0/data/model_name.xml.template index 77335b07d..7b25f11f8 100644 --- a/module_prototyper/templates/8.0/data/model_name.xml.template +++ b/module_prototyper/templates/8.0/data/model_name.xml.template @@ -1,17 +1,8 @@ - {% for record in records %} - - {% if not loop.last %} - {% endif %} - {% endfor %} + {{ data }} + diff --git a/module_prototyper/templates/8.0/data/model_name.xml.template~HEAD b/module_prototyper/templates/8.0/data/model_name.xml.template~HEAD new file mode 100644 index 000000000..77335b07d --- /dev/null +++ b/module_prototyper/templates/8.0/data/model_name.xml.template~HEAD @@ -0,0 +1,17 @@ + + + + {% for record in records %} + + {% if not loop.last %} + + {% endif %} + {% endfor %} + + diff --git a/module_prototyper/templates/8.0/header.template b/module_prototyper/templates/8.0/header.template index 295d4d817..2e6251e7b 100644 --- a/module_prototyper/templates/8.0/header.template +++ b/module_prototyper/templates/8.0/header.template @@ -2,25 +2,21 @@ ############################################################################## # # Odoo, Open Source Management Solution -{% if author %} -# This module copyright (C) {{ export_year }} {{ author }} -{% else %} -# This module copyright (C) {{ export_year }} -{% endif %} -{% if website %} -# ({{ website }}). -{% endif %} -{% if license_text %} +# This module copyright (C) {{ export_year }} {% if author %}{{ author }}{% endif %} +# {% if website %}({{ website }}).{% endif %} # -{% for line in license_text %} -{% if line.strip() %} -# {{ line }} -{% else %} +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. # -{% endif %} -{% endfor %} -{% endif %} +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . # ############################################################################## -{% block body %} -{% endblock %} +{% block body %}{% endblock %} \ No newline at end of file diff --git a/module_prototyper/templates/8.0/header.template~HEAD b/module_prototyper/templates/8.0/header.template~HEAD new file mode 100644 index 000000000..295d4d817 --- /dev/null +++ b/module_prototyper/templates/8.0/header.template~HEAD @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Odoo, Open Source Management Solution +{% if author %} +# This module copyright (C) {{ export_year }} {{ author }} +{% else %} +# This module copyright (C) {{ export_year }} +{% endif %} +{% if website %} +# ({{ website }}). +{% endif %} +{% if license_text %} +# +{% for line in license_text %} +{% if line.strip() %} +# {{ line }} +{% else %} +# +{% endif %} +{% endfor %} +{% endif %} +# +############################################################################## +{% block body %} +{% endblock %} diff --git a/module_prototyper/templates/8.0/models/__init__.py.template b/module_prototyper/templates/8.0/models/__init__.py.template index 5513ba9b4..caf9d7c74 100644 --- a/module_prototyper/templates/8.0/models/__init__.py.template +++ b/module_prototyper/templates/8.0/models/__init__.py.template @@ -1,9 +1,6 @@ {% extends "header.template" %} {% block body %} -{% for model in models %} -{% if loop.first %} - -{% endif %} -from . import {{ unprefix(model) }} +{% for model in models -%} +from . import {{ model }} {% endfor %} {% endblock %} diff --git a/module_prototyper/templates/8.0/models/__init__.py.template~HEAD b/module_prototyper/templates/8.0/models/__init__.py.template~HEAD new file mode 100644 index 000000000..5513ba9b4 --- /dev/null +++ b/module_prototyper/templates/8.0/models/__init__.py.template~HEAD @@ -0,0 +1,9 @@ +{% extends "header.template" %} +{% block body %} +{% for model in models %} +{% if loop.first %} + +{% endif %} +from . import {{ unprefix(model) }} +{% endfor %} +{% endblock %} diff --git a/module_prototyper/templates/8.0/models/model_name.py.template b/module_prototyper/templates/8.0/models/model_name.py.template index 44a0858d1..8f8ff5378 100644 --- a/module_prototyper/templates/8.0/models/model_name.py.template +++ b/module_prototyper/templates/8.0/models/model_name.py.template @@ -1,68 +1,22 @@ {% extends "header.template" %} {% block body %} - from openerp import models, fields from openerp.tools.translate import _ -class {{ unprefix(name) }}(models.Model): - {% if model.state == 'base' and not is_prefixed(model.model) %} - _inherit = "{{ unprefix(model.model) }}" - {% else %} - _name = "{{ unprefix(model.model) }}" - {% endif %} - {% if description %} - _description = "{{ description }}" - {% endif %} +class {{ name }}(models.Model): + _inherit = "{{ inherit }}" + {% if description -%}_description = "{{ description }}"{% endif %} - {% for field in fields %} - {% for line in wrap(field.notes, replace_whitespace=False) %} - {% if line %} - # {{line}} - {% else %} - # - {% endif %} - {% endfor %} - {{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}( + {% for field in fields -%} + {% if field.notes -%}# {{ field.notes }}{% endif %} + {{ field.name }} = fields.{{ field.ttype|capitalize }}( string=_("{{ field.field_description }}"), - {% if field.selection %} - selection={{ field.selection }}, - {% endif %} - {% if field.relation %} - comodel_name="{{ unprefix(field.relation) }}", - {% endif %} - {% if field.ttype == 'one2many' %} - inverse_name="{{ unprefix(field.relation_field) }}", - {% endif %} - {% if field.column1 %} - column1="{{ field.column1 }}", - {% endif %} - {% if field.column2 %} - column1="{{ field.column2 }}", - {% endif %} required={{ field.required }}, translate={{ field.translate }}, readonly={{ field.readonly }}, - {% if field.size %} - size={{ field.size }}, - {% endif %} - {% if field.ttype in ('many2one', 'many2many', 'one2many') %} - {% if field.domain %} - domain={{ field.domain }}, - {% endif %} - {% if field.client_context %} - context={{ field.client_context }}, - {% endif %} - {% endif %} - {% if field.limit %} - limit={{ field.limit }}, - {% endif %} - {% if field.ttype == 'many2one' and field.on_delete %} - on_delete="{{ field.on_delete }}", - {% endif %} - {% if field.helper %} - help=_("{{ field.helper }}"), - {% endif %} - ) - {% endfor %} + {% if field.size -%}size={{ field.size }},{% endif %} + {% if field.helper -%}help=_("{{ field.helper }}"),{% endif %} + ){% endfor %} + {% endblock %} diff --git a/module_prototyper/templates/8.0/models/model_name.py.template~HEAD b/module_prototyper/templates/8.0/models/model_name.py.template~HEAD new file mode 100644 index 000000000..44a0858d1 --- /dev/null +++ b/module_prototyper/templates/8.0/models/model_name.py.template~HEAD @@ -0,0 +1,68 @@ +{% extends "header.template" %} +{% block body %} + +from openerp import models, fields +from openerp.tools.translate import _ + + +class {{ unprefix(name) }}(models.Model): + {% if model.state == 'base' and not is_prefixed(model.model) %} + _inherit = "{{ unprefix(model.model) }}" + {% else %} + _name = "{{ unprefix(model.model) }}" + {% endif %} + {% if description %} + _description = "{{ description }}" + {% endif %} + + {% for field in fields %} + {% for line in wrap(field.notes, replace_whitespace=False) %} + {% if line %} + # {{line}} + {% else %} + # + {% endif %} + {% endfor %} + {{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}( + string=_("{{ field.field_description }}"), + {% if field.selection %} + selection={{ field.selection }}, + {% endif %} + {% if field.relation %} + comodel_name="{{ unprefix(field.relation) }}", + {% endif %} + {% if field.ttype == 'one2many' %} + inverse_name="{{ unprefix(field.relation_field) }}", + {% endif %} + {% if field.column1 %} + column1="{{ field.column1 }}", + {% endif %} + {% if field.column2 %} + column1="{{ field.column2 }}", + {% endif %} + required={{ field.required }}, + translate={{ field.translate }}, + readonly={{ field.readonly }}, + {% if field.size %} + size={{ field.size }}, + {% endif %} + {% if field.ttype in ('many2one', 'many2many', 'one2many') %} + {% if field.domain %} + domain={{ field.domain }}, + {% endif %} + {% if field.client_context %} + context={{ field.client_context }}, + {% endif %} + {% endif %} + {% if field.limit %} + limit={{ field.limit }}, + {% endif %} + {% if field.ttype == 'many2one' and field.on_delete %} + on_delete="{{ field.on_delete }}", + {% endif %} + {% if field.helper %} + help=_("{{ field.helper }}"), + {% endif %} + ) + {% endfor %} +{% endblock %} diff --git a/module_prototyper/templates/8.0/views/model_menus.xml.template b/module_prototyper/templates/8.0/views/model_menus.xml.template index 77b327af4..642a682d8 100644 --- a/module_prototyper/templates/8.0/views/model_menus.xml.template +++ b/module_prototyper/templates/8.0/views/model_menus.xml.template @@ -1,29 +1,24 @@ - {% for menu in menus %} - - {{ unprefix(menu.action.name) }} - {{ menu.action.type }} - {{ unprefix(menu.action.res_model) }} - {{ menu.action.view_type }} - {{ menu.action.view_mode }} - {% if menu.action.help %} - {{ menu.action.help }} - - {% endif %} - + {% for menu in menus -%} + + {{ menu.action.name }} + {{ menu.action.type }} + {{ menu.action.res_model }} + {{ menu.action.view_type }} + {{ menu.action.view_mode }} + {% if menu.action.help %}{{ menu.action.help }} + {% endif %} + - - {% if not loop.last %} - - {% endif %} - {% endfor %} + + {% endfor -%} diff --git a/module_prototyper/templates/8.0/views/model_menus.xml.template~HEAD b/module_prototyper/templates/8.0/views/model_menus.xml.template~HEAD new file mode 100644 index 000000000..77b327af4 --- /dev/null +++ b/module_prototyper/templates/8.0/views/model_menus.xml.template~HEAD @@ -0,0 +1,29 @@ + + + + {% for menu in menus %} + + {{ unprefix(menu.action.name) }} + {{ menu.action.type }} + {{ unprefix(menu.action.res_model) }} + {{ menu.action.view_type }} + {{ menu.action.view_mode }} + {% if menu.action.help %} + {{ menu.action.help }} + + {% endif %} + + + + {% if not loop.last %} + + {% endif %} + {% endfor %} + + diff --git a/module_prototyper/templates/8.0/views/model_views.xml.template b/module_prototyper/templates/8.0/views/model_views.xml.template index 218ec67df..b919abea7 100644 --- a/module_prototyper/templates/8.0/views/model_views.xml.template +++ b/module_prototyper/templates/8.0/views/model_views.xml.template @@ -2,16 +2,22 @@ - {% for view in views %} - - {{ unprefix(view.name) }}.view - {{ unprefix(view.model) }} - {{ view.type }} - - - {{ fixup_arch(view.arch) }} - - + + {% for view in views -%} + + {{ view.name }}.view + {{ view.model }} + {{ view.type }} + + + {# the arch given by odoo start with an xml tag that + will break the xml tree we build. + Be careful, custom field have a x_ prefix that has to be + removed + #} + {{ view.arch|replace('"', "'")|replace("", "")|replace("'x_", "'")|replace("> ", "/>") }} + + {% endfor %} diff --git a/module_prototyper/templates/8.0/views/model_views.xml.template~HEAD b/module_prototyper/templates/8.0/views/model_views.xml.template~HEAD new file mode 100644 index 000000000..218ec67df --- /dev/null +++ b/module_prototyper/templates/8.0/views/model_views.xml.template~HEAD @@ -0,0 +1,17 @@ + + + + + {% for view in views %} + + {{ unprefix(view.name) }}.view + {{ unprefix(view.model) }} + {{ view.type }} + + + {{ fixup_arch(view.arch) }} + + + {% endfor %} + + diff --git a/prototype/models/__init__.py b/module_prototyper/tests/__init__.py~HEAD similarity index 95% rename from prototype/models/__init__.py rename to module_prototyper/tests/__init__.py~HEAD index 8c9737d2d..aff3c1c83 100644 --- a/prototype/models/__init__.py +++ b/module_prototyper/tests/__init__.py~HEAD @@ -20,6 +20,6 @@ # ############################################################################## from . import ( - prototype, - ir_model_fields + test_prototype_module_export, + test_prototype ) diff --git a/prototype/tests/test_prototype.py b/module_prototyper/tests/test_prototype.py~HEAD similarity index 73% rename from prototype/tests/test_prototype.py rename to module_prototyper/tests/test_prototype.py~HEAD index 2d082cf9e..76d3c8fdc 100644 --- a/prototype/tests/test_prototype.py +++ b/module_prototyper/tests/test_prototype.py~HEAD @@ -17,15 +17,24 @@ # along with this program. If not, see . # +import ast +import lxml.etree + +try: + import pep8 +except ImportError: + pep8 = None + from jinja2 import Environment from jinja2.exceptions import TemplateNotFound + from openerp.tests import common -class test_prototype(common.TransactionCase): +class TestModulePrototyper(common.TransactionCase): def setUp(self): - super(test_prototype, self).setUp() - self.main_model = self.env['prototype'] + super(TestModulePrototyper, self).setUp() + self.main_model = self.env['module_prototyper'] self.module_category_model = self.env['ir.module.category'] self.module_module_model = self.env['ir.module.module'] @@ -59,6 +68,27 @@ class test_prototype(common.TransactionCase): self.assertIsInstance(file_details.filename, basestring) self.assertIsInstance(file_details.filecontent, basestring) + name, contents = file_details + if name.endswith(".py"): + # We have a "coding utf-8" line in there, we need to encode + contents = contents.encode("utf-8") + ast.parse(contents) + if pep8: + checker = pep8.Checker( + name, + contents.splitlines(True)) + res = checker.check_all() + self.assertFalse( + res, + "Python file {0} has pep8 errors:\n" + "{1}\n{2}".format(name, checker.report.messages, + repr(contents)) + ) + + elif name.endswith(".xml"): + # TODO validate valid odoo xml + lxml.etree.fromstring(contents) + def test_generate_files_raise_templatenotfound_if_not_found(self): self.prototype.set_jinja_env('t_api_version') self.assertRaises( diff --git a/prototype/tests/test_prototype_module_export.py b/module_prototyper/tests/test_prototype_module_export.py~HEAD similarity index 92% rename from prototype/tests/test_prototype_module_export.py rename to module_prototyper/tests/test_prototype_module_export.py~HEAD index 87ef77e40..e58cd1b90 100644 --- a/prototype/tests/test_prototype_module_export.py +++ b/module_prototyper/tests/test_prototype_module_export.py~HEAD @@ -27,8 +27,8 @@ import StringIO class test_prototype_module_export(common.TransactionCase): def setUp(self): super(test_prototype_module_export, self).setUp() - self.main_model = self.env['prototype.module.export'] - self.prototype_model = self.env['prototype'] + self.main_model = self.env['module_prototyper.module.export'] + self.prototype_model = self.env['module_prototyper'] self.module_category_model = self.env[ 'ir.module.category' ] @@ -69,10 +69,7 @@ class test_prototype_module_export(common.TransactionCase): def test_zip_files_returns_tuple(self): """Test the method return of the method that generate the zip file.""" - file_details = ( - ('test.txt', 'generated'), - ) - ret = self.main_model.zip_files(file_details) + ret = self.main_model.zip_files(self.exporter, [self.prototype]) self.assertIsInstance(ret, tuple) self.assertIsInstance( ret.zip_file, zipfile.ZipFile diff --git a/module_prototyper/views/ir_model_fields_view.xml~HEAD b/module_prototyper/views/ir_model_fields_view.xml~HEAD new file mode 100644 index 000000000..df2df0daf --- /dev/null +++ b/module_prototyper/views/ir_model_fields_view.xml~HEAD @@ -0,0 +1,51 @@ + + + + + + view_ir_model_fields_form + ir.model.fields + + + + + + + view_ir_model_form + ir.model + + + + + + + + + + + diff --git a/module_prototyper/views/module_prototyper_view.xml b/module_prototyper/views/module_prototyper_view.xml index 424fa7d61..de6624df9 100644 --- a/module_prototyper/views/module_prototyper_view.xml +++ b/module_prototyper/views/module_prototyper_view.xml @@ -19,6 +19,8 @@ module_prototyper
+ @@ -140,6 +142,5 @@ sequence="4" groups="base.group_system"/> - diff --git a/module_prototyper/views/module_prototyper_view.xml~HEAD b/module_prototyper/views/module_prototyper_view.xml~HEAD new file mode 100644 index 000000000..424fa7d61 --- /dev/null +++ b/module_prototyper/views/module_prototyper_view.xml~HEAD @@ -0,0 +1,145 @@ + + + + + + Base tree View for module prototypes + module_prototyper + + + + + + + + + + + Base form view for module prototypes + module_prototyper + + + + +
+

+ +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + Prototypes + module_prototyper + form + tree,form + + + + + + + + + + + + + + + + +
+
diff --git a/module_prototyper/wizard/module_prototyper_module_export.py b/module_prototyper/wizard/module_prototyper_module_export.py index 560bf591c..e87fcf145 100644 --- a/module_prototyper/wizard/module_prototyper_module_export.py +++ b/module_prototyper/wizard/module_prototyper_module_export.py @@ -33,9 +33,12 @@ class PrototypeModuleExport(models.TransientModel): _name = "module_prototyper.module.export" name = fields.Char('File Name', readonly=True) + # It is implemented in order to manage previous and next versions + # of odoo api_version = fields.Selection( [ ('8.0', '8.0'), + # ('7.0', '7.0') ], 'API version', required=True, diff --git a/prototype/wizard/prototype_module_export.py b/module_prototyper/wizard/module_prototyper_module_export.py~HEAD similarity index 56% rename from prototype/wizard/prototype_module_export.py rename to module_prototyper/wizard/module_prototyper_module_export.py~HEAD index 1811d0a99..560bf591c 100644 --- a/prototype/wizard/prototype_module_export.py +++ b/module_prototyper/wizard/module_prototyper_module_export.py~HEAD @@ -7,8 +7,8 @@ # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,23 +19,23 @@ # along with this program. If not, see . # ############################################################################## + import StringIO import base64 +import os import zipfile from collections import namedtuple + from openerp import fields, models, api -class prototype_module_export(models.TransientModel): - _name = "prototype.module.export" +class PrototypeModuleExport(models.TransientModel): + _name = "module_prototyper.module.export" name = fields.Char('File Name', readonly=True) - # It is implemented in order to manage previous and next versions - # of odoo api_version = fields.Selection( [ ('8.0', '8.0'), - # ('7.0', '7.0') ], 'API version', required=True, @@ -63,30 +63,26 @@ class prototype_module_export(models.TransientModel): active_model = self._context.get('active_model') # checking if the wizard was called by a prototype. - assert active_model == 'prototype', \ - '{} has to be called from a "prototype" , not a "{}"'.format( - self, active_model - ) + msg = '{} has to be called from a "module_prototyper" , not a "{}"' + assert active_model == 'module_prototyper', msg.format( + self, active_model + ) # getting the prototype of the wizard - prototype = self.env[active_model].browse( - self._context.get('active_id') + prototypes = self.env[active_model].browse( + [self._context.get('active_id')] ) - # setting the jinja environment. - # They will help the program to find the template to render the files - # with. - prototype.set_jinja_env(wizard.api_version) + zip_details = self.zip_files(wizard, prototypes) - # generate_files ask the prototype to investigate the input - # and to generate the file templates according to it. - # zip_files, in another hand, put all the template files into a package - # ready to be saved by the user. - zip_details = self.zip_files(prototype.generate_files()) + if len(prototypes) == 1: + zip_name = prototypes[0].name + else: + zip_name = "prototyper_export" wizard.write( { - 'name': '{}.zip'.format(prototype.name), + 'name': '{}.zip'.format(zip_name), 'state': 'get', 'data': base64.encodestring(zip_details.stringIO.getvalue()) } @@ -94,7 +90,7 @@ class prototype_module_export(models.TransientModel): return { 'type': 'ir.actions.act_window', - 'res_model': 'prototype.module.export', + 'res_model': 'module_prototyper.module.export', 'view_mode': 'form', 'view_type': 'form', 'res_id': wizard.id, @@ -103,19 +99,34 @@ class prototype_module_export(models.TransientModel): } @staticmethod - def zip_files(file_details): + def zip_files(wizard, prototypes): """Takes a set of file and zips them. - :param file_details: tuple (filename, filecontent) + :param file_details: tuple (filename, file_content) :return: tuple (zip_file, stringIO) """ zip_details = namedtuple('Zip_details', ['zip_file', 'stringIO']) out = StringIO.StringIO() with zipfile.ZipFile(out, 'w') as target: - for filename, filecontent in file_details: - info = zipfile.ZipInfo(filename) - info.compress_type = zipfile.ZIP_DEFLATED - info.external_attr = 2175008768 # specifies mode 0644 - target.writestr(info, filecontent) + for prototype in prototypes: + # setting the jinja environment. + # They will help the program to find the template to render the + # files with. + prototype.set_jinja_env(wizard.api_version) + + # generate_files ask the prototype to investigate the input and + # to generate the file templates according to it. zip_files, + # in another hand, put all the template files into a package + # ready to be saved by the user. + file_details = prototype.generate_files() + for filename, file_content in file_details: + if isinstance(file_content, unicode): + file_content = file_content.encode('utf-8') + # Prefix all names with module technical name + filename = os.path.join(prototype.name, filename) + info = zipfile.ZipInfo(filename) + info.compress_type = zipfile.ZIP_DEFLATED + info.external_attr = 2175008768 # specifies mode 0644 + target.writestr(info, file_content) return zip_details(zip_file=target, stringIO=out) diff --git a/prototype/demo/prototype.prototype.csv b/prototype/demo/prototype.prototype.csv deleted file mode 100644 index c4ffea3ec..000000000 --- a/prototype/demo/prototype.prototype.csv +++ /dev/null @@ -1,2 +0,0 @@ -"id","right_ids/id","application","author","auto_install","category_id/id","create_uid/id","create_date","data_ids/id","demo_ids/id","dependency_ids/id","description","field_ids/id","group_ids/id","icon_image","write_uid/id","write_date","licence","maintainer","menu_ids/id","human_name","rule_ids/id","summary","name","version","view_ids/id","website" -"__export__.prototype_22","__export__.ir_model_access_144","False","Savoir-faire Linux","False","base.module_category_uncategorized","base.user_root","2014-12-15 21:07:09","__export__.ir_filters_31","","base.module_crm,base.module_mail,base.module_l10n_et,base.module_l10n_mx","This module is used to test the export of prototype. It uses all the features.","__export__.ir_model_fields_1238","__export__.res_groups_13","/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAC0ALQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAor5V+JLeOfHHjK8iTQ9afTradobS3S0k8tVBIDnjGW6kn1xnAFdV4S8MfFnRvDmpWlze2Fhpctq8ZXVr0n7OpXHmRsm4x7RzgkD270Aes6r8RPB+i3H2e/8Q2Ec2/y2jSTzGRumGC5K/jitd9d0iLU49Mk1WxS/kAKWrXCCVgehCZyfyr5Qs/hbcMfP1LxFodnYhA7TR3QnfaRwRGvJ7E5xxzzjFdte/Buw8V3M0+geKEk1CEKLmK6n+1BuAFdZVwSpAHY45HGMU7Mpxkt0e82uuaXe6teaVbXsMl/ZBTcW4PzRhhkEj6EdK0K8u8K+ANYg8LmDVWSy8T2F7NLaa1BL5rXG/DF5CeXViSjK+MhR04Ndz4b1PUNU0kSarpr2F/FI8E8RB2MynG+Mn7yN1B/nikSbFFFFABRTXdY0LuwVRyWY4ArPfxDoyNhtVs8+0yn+tAGlRUFte2l6pa1uYZ1HUxSBsflU9ABRRRQAUUVnza9pEDFZdTtFYcFfOXI/DNAGhRVS11TT71ttrfW8zddscoY/kDVugAooooAKKKKACiisPxZro8PaBPeKAbhsRQKe8h6fgOT+FNK7sioxcmoozPF/jmDw+TZWarcakRkqT8kIPQvjv6L/Lv5Pqer6jrM3m6jeS3BzlVY4Rf91RwP5+9U5JHlkklmkaSR2LySOeWY8kk13XhP4etqttHqGrtJDbOA0VunyvIv95j2B7Dr9K6ko01dnrxhSw0Lvc4TOD1waVWZJFkRmSRDlXViGU+oI5Fe8QeD/DtvF5aaNZFfWSIOfzbJrE1r4a6TexM+mg2FzyRsJMbH3U9PwxSVaJMcdTbs00c34Z+I13Yypba27XNoePtGMyRe7Y+8P1+terxSxzwpNC6yRuoZXU5DA9CDXztfWNzpl9NZXkRiuIThl/kQe4PY13fwy8QtHctoNw5MThpLTJ+6RyyD2Iyw+jUqtNW5omeKw0XH2kD1GuX8R+Lo9LdrOyVZrwfeLfci+vqfar3ifWDo2kPJER9plPlw57E9/wABz+VeUsT8zMxJJLMzHJJ7kmuY8wsX19d6lL5l7cSTtnIDn5V+i9BVfp6Cux0DwV9qhS71QukbDclup2kj1Y9voK6uPw5osUexdMtSPVowx/M80CPJEZopVliZo5F+66Eqw+hHNdfoXjeaB0t9WbzYTwLnHzJ/vAdR71rap4G0+5jLWGbSfsASUY+4PT8K41vDesi5Nt/ZsxfO3dj92ffd0xQB62CGUEEEHkEd6xvEHiO20KEKR5t3IMxwg449WPYVN5q+H/DavdSGT7JbqrH++QMAD6nArym7up767lurlt80rZY+noB7DoKBlnU9a1DV3JvLhmjPSFfljH/Ae/45qhgAYwBXReHPCsutL9quHaGyzhSv3pfXHoPeu3t/DGi2ybV06B/UyrvJ/Fs0CPJSAcEgHHINdHovjC+011june7tOhDnMiD/AGWPX6H866zUPBekXiMYYvskp6PDwPxXpXnuqaXc6RfNa3SjcBuV1+66+o/w7UAeu2d3Bf2sdzbSCSGQZVhU9eZeDtZbTtUW0kc/ZbptuCeFk7H8eh/CvTaBhRRRQAV5b8V7tm1HTLIH5I4nnI9yQo/QN+depV5L8VImXxDYyn7sloVH1Vzn/wBDFa0fjOrBJe2RznhbTI9Y8T2FlMAYWcySqf4lQbiPxOB+Ne+jgV4f4CuEt/GtgZGwJFkhB/2mXj+Ve4U6/wASNMe3zpeQUUUVicJ538VdMRrKy1VV/exyeQ5HdGBIz9CP/Hq83sLxtO1K0vlJzbzJLx3API/EZH416r8UblIvDEVuSN89ygAzzhcsT+g/OvIhE87LDGMvIwRR6knArrpaw1PZwetG0j1Dx/cGTWLa2ydsMO/Hux/wWsvwvYJqPiG2ilG6KPMzgjghcYH5kflV7x3GU8Rq56SWyY/Bmz/Oo/BM6w+JURiB50Lxrn14b+QNch4p6dRRRQMKKKKAOP8AiDclNNtLUHHmzbm9wo6fmQfwrhbS2N5e29qDtM8qx59MnGa7T4iRMYtOm/hV5EP1IBH/AKCa5HSZ1ttasZnICJcIWJ7DOCaBHsEEMdvBHDEoSONQqqOwHSpKKKBhXN+N7FLnw+9xj97aESKe+OjD8v5V0lYfi+dYPDF5kgNIoiUepYgUAeVtuAJQ4YcqR2I6H869osbj7Xp9tc/89olk/MA14x/F+NeveH/+Rb0v/rzi/wDQBQI0aKKKBhXFfEvR31DQEvoULS2DmQgDkxkYf8uG/wCA12tIyhlKsAVIwQehpxfK7l05unNSXQ+bkkeORJInKSIwdHXqrA5BH417X4T8Y2niG0SKV0h1JF/ewE43f7SeoP5jv6ng/GXgifRJ5L7Toml0xiWKKMtb+xHdfQ9uh9TxwOdrqenKsp6e4IrrcY1EevOFPEwTTPpTIqtf6haaZaPdXtxHBAnV3OB+HqfYV4VF4o1+GPZHrN7txgBpN2PxIrPury6v5RLeXU9zIOjTSFiPpnpWaoPqzmjl7v7z0NfxZ4kk8S6v9oCtHaQgpbxt1A7sR2J4+gAFXPAGitq3ieGdl/0awInkPbf/AAL9c/N/wH3rF0fRb/Xr4Wmnw72z+8kb7kQ9WP8ATqa9w8P6Da+HdKSxtssc7pZWHzSOerH/AA7CqqSUI8qNsRVjRp+zjuY3jzTWn0+LUI1y1sSJMf3G6n8Dg1wEUslvNHNC+yWNg6MOxHSva3RZEZHUMjAhlYZBHoa8y8R+F59Hle4tkaWwJyGHJi9m9vQ/n78p5B22g+IrXW7cAMsd2o/eQE8g+o9RWzXh4JBV1JBHKspwR9CK0U1/WETYup3WPd8n8zQB6ve39rp1s1xdzLFEvdj19gO5rjm+IZF0caaTag9fN/eY9cYxn2z+NcZPcT3cvm3M8s8nZpHLEVY0zS7vV7oW9nHuP8ch+7GPUn+nWgR6P4gs11/w0zWv7x9q3Fvj+IgZx+IJH415Xwy+xr2mxtEsLC3tIySkMaxgnvgYri/FfhSRZpNS02MujndNAo5B7so7j1H40DNHwr4oivbaOxvZQl4g2qznAmHYg/3vUV1deHcMPUVoQa3qtsgSHUblUAwFL7gPzoA9dmnit4WlmkWONRlnc4AH1rzPxT4hGtXaRW+RZQElCRjzG6bsemOB+NY11e3d8Qbu6mnx0EjkgfQdKZFbzTrK0MTyLEpeRlGQgHqe1Ahg6ivXvD//ACLel/8AXnF/6AK8gHUV6/4f/wCRb0v/AK9Iv/QBQBo0UUUDCiiigArl9W8AaBqsjTfZ3tJ25aS1bZk+64Kn8q6iimm1sVCcoO8XY84f4TRb/wB3rUoX0e3Un8wR/Kr1j8LdHgcPeXN3eEfwFhGh/BQD+tdzRVe1n3NniqzVuYr2dja6dbLbWdvHBCv3UjUKBViiioOdu+rCggEYIyKKKAOfv/BmkXztIsT2sjclrdtoP/ASCP0rJb4dpu+XVJAvo0IJ/mK7aigDlbTwFpkLBrma4uSP4WYIv5Lg/rXSW1rb2cCw20KQxL0RFwKmooAKKKKAMfU/DGlaq5lmt9k56zQnYx+vY/iDWFJ8PIS37rU5lX0kiVj+mK7WigDkrTwBp8TBrq5uLnH8GQin8uf1rpI9Ps4rFrKO3jS2ZSpjUYBBGDVmigDjl+HtmLncb2drbP8Aqto3Y9N3p+GfeuvRFijWNFCooCqo6ACnUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z","base.user_root","2014-12-26 16:11:10","AGPL-3","OCA","__export__.ir_ui_menu_96","Demo Module","__export__.ir_rule_20","Demo module for prototype","demo_module","0.1","__export__.ir_ui_view_334,__export__.ir_ui_view_333","http://www.savoirfairelinux.com" \ No newline at end of file diff --git a/prototype/i18n/fr.po b/prototype/i18n/fr.po deleted file mode 100644 index a8f862289..000000000 --- a/prototype/i18n/fr.po +++ /dev/null @@ -1,272 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * prototype -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 8.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-10-08 17:58+0000\n" -"PO-Revision-Date: 2014-10-08 14:02-0500\n" -"Last-Translator: Maxime Chambreuil \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"X-Generator: Poedit 1.5.4\n" - -#. module: prototype -#: selection:prototype.module.export,api_version:0 -msgid "7.0" -msgstr "" - -#. module: prototype -#: selection:prototype.module.export,api_version:0 -msgid "8.0" -msgstr "" - -#. module: prototype -#: field:prototype.module.export,api_version:0 -msgid "API version" -msgstr "Version de l'API" - -#. module: prototype -#: field:prototype,rights:0 -msgid "Access Rights" -msgstr "Liste des contrôles d'accès" - -#. module: prototype -#: field:prototype,author:0 -msgid "Author" -msgstr "Auteur" - -#. module: prototype -#: field:prototype,auto_install:0 -msgid "Auto Install" -msgstr "Installation automatique" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Cancel" -msgstr "Annuler" - -#. module: prototype -#: field:prototype,category_id:0 -msgid "Category" -msgstr "Catégorie" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Close" -msgstr "Fermer" - -#. module: prototype -#: field:prototype,create_uid:0 field:prototype.module.export,create_uid:0 -msgid "Created by" -msgstr "Créé par" - -#. module: prototype -#: field:prototype,create_date:0 field:prototype.module.export,create_date:0 -msgid "Created on" -msgstr "Créé le" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Data & Demo" -msgstr "Données et démo" - -#. module: prototype -#: field:prototype,data:0 -msgid "Data filters" -msgstr "Filtres pour les données" - -#. module: prototype -#: field:prototype,demo:0 -msgid "Demo filters" -msgstr "Filtres pour les données de démo" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form field:prototype,dependencies:0 -msgid "Dependencies" -msgstr "Dépendances" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form field:prototype,description:0 -msgid "Description" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export" -msgstr "Exporter" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Complete" -msgstr "Export terminé" - -#. module: prototype -#: model:ir.actions.act_window,name:prototype.button_module_export_action -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Module" -msgstr "Exporter le module" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Settings" -msgstr "Configuration de l'export" - -#. module: prototype -#: model:ir.model,name:prototype.model_ir_model_fields -#: field:prototype,fields:0 -msgid "Fields" -msgstr "Champs" - -#. module: prototype -#: field:prototype.module.export,data:0 -msgid "File" -msgstr "Fichier" - -#. module: prototype -#: field:prototype.module.export,name:0 -msgid "File Name" -msgstr "Nom du fichier" - -#. module: prototype -#: field:prototype,groups:0 -msgid "Groups" -msgstr "Groupes" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Here is the exported module:" -msgstr "Voici le module exporté :" - -#. module: prototype -#: field:prototype,id:0 field:prototype.module.export,id:0 -msgid "ID" -msgstr "" - -#. module: prototype -#: field:prototype,icon_image:0 -msgid "Icon" -msgstr "Icône" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Interface" -msgstr "" - -#. module: prototype -#: field:prototype,write_uid:0 field:prototype.module.export,write_uid:0 -msgid "Last Updated by" -msgstr "Mis à jour par" - -#. module: prototype -#: field:prototype,write_date:0 field:prototype.module.export,write_date:0 -msgid "Last Updated on" -msgstr "Mis à jour le" - -#. module: prototype -#: field:prototype,maintainer:0 -msgid "Maintainer" -msgstr "Mainteneur" - -#. module: prototype -#: field:prototype,menu:0 -msgid "Menu Items" -msgstr "Éléments du menu" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Models" -msgstr "Modèles" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Module" -msgstr "" - -#. module: prototype -#: field:prototype,human_name:0 -msgid "Module Name" -msgstr "Nom du module" - -#. module: prototype -#: view:ir.model:prototype.view_ir_model_form field:ir.model.fields,notes:0 -msgid "Notes" -msgstr "" - -#. module: prototype -#: model:ir.actions.act_window,name:prototype.open_prototype_list -#: model:ir.model,name:prototype.model_prototype -#: model:ir.ui.menu,name:prototype.menu_open_prototype -#: view:prototype:prototype.view_prototype_tree -msgid "Prototype" -msgstr "" - -#. module: prototype -#: field:prototype,rules:0 -msgid "Record Rules" -msgstr "Règles sur les enregistrements" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Security" -msgstr "Sécurité" - -#. module: prototype -#: field:prototype,summary:0 -msgid "Summary" -msgstr "Résumé" - -#. module: prototype -#: field:prototype,name:0 -msgid "Technical Name" -msgstr "Nom technique" - -#. module: prototype -#: help:prototype,data:0 -msgid "The records matching the filters will be added as data." -msgstr "" -"Les enregistrements correspondant aux critères des filtres seront exportées " -"dans le module comme données." - -#. module: prototype -#: help:prototype,demo:0 -msgid "The records matching the filters will be added as demo data." -msgstr "" -"Les enregistrements correspondant aux critères des filtres seront exportées " -"dans le module comme données de démo." - -#. module: prototype -#: field:prototype,version:0 -msgid "Version" -msgstr "" - -#. module: prototype -#: field:prototype,views:0 -msgid "Views" -msgstr "Vues" - -#. module: prototype -#: field:prototype,website:0 -msgid "Website" -msgstr "Site web" - -#. module: prototype -#: selection:prototype.module.export,state:0 -msgid "choose" -msgstr "choisir" - -#. module: prototype -#: selection:prototype.module.export,state:0 -msgid "get" -msgstr "récupérer" - -#. module: prototype -#: field:prototype.module.export,state:0 -msgid "unknown" -msgstr "inconnu" diff --git a/prototype/i18n/prototype.pot b/prototype/i18n/prototype.pot deleted file mode 100644 index de7c40cea..000000000 --- a/prototype/i18n/prototype.pot +++ /dev/null @@ -1,268 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * prototype -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 8.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-10-08 17:58+0000\n" -"PO-Revision-Date: 2014-10-08 14:00-0500\n" -"Last-Translator: Maxime Chambreuil \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"X-Generator: Poedit 1.5.4\n" - -#. module: prototype -#: selection:prototype.module.export,api_version:0 -msgid "7.0" -msgstr "" - -#. module: prototype -#: selection:prototype.module.export,api_version:0 -msgid "8.0" -msgstr "" - -#. module: prototype -#: field:prototype.module.export,api_version:0 -msgid "API version" -msgstr "" - -#. module: prototype -#: field:prototype,rights:0 -msgid "Access Rights" -msgstr "" - -#. module: prototype -#: field:prototype,author:0 -msgid "Author" -msgstr "" - -#. module: prototype -#: field:prototype,auto_install:0 -msgid "Auto Install" -msgstr "" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Cancel" -msgstr "" - -#. module: prototype -#: field:prototype,category_id:0 -msgid "Category" -msgstr "" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Close" -msgstr "" - -#. module: prototype -#: field:prototype,create_uid:0 field:prototype.module.export,create_uid:0 -msgid "Created by" -msgstr "" - -#. module: prototype -#: field:prototype,create_date:0 field:prototype.module.export,create_date:0 -msgid "Created on" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Data & Demo" -msgstr "" - -#. module: prototype -#: field:prototype,data:0 -msgid "Data filters" -msgstr "" - -#. module: prototype -#: field:prototype,demo:0 -msgid "Demo filters" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form field:prototype,dependencies:0 -msgid "Dependencies" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form field:prototype,description:0 -msgid "Description" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export" -msgstr "" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Complete" -msgstr "" - -#. module: prototype -#: model:ir.actions.act_window,name:prototype.button_module_export_action -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Module" -msgstr "" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Export Settings" -msgstr "" - -#. module: prototype -#: model:ir.model,name:prototype.model_ir_model_fields -#: field:prototype,fields:0 -msgid "Fields" -msgstr "" - -#. module: prototype -#: field:prototype.module.export,data:0 -msgid "File" -msgstr "" - -#. module: prototype -#: field:prototype.module.export,name:0 -msgid "File Name" -msgstr "" - -#. module: prototype -#: field:prototype,groups:0 -msgid "Groups" -msgstr "" - -#. module: prototype -#: view:prototype.module.export:prototype.view_module_export_wizard -msgid "Here is the exported module:" -msgstr "" - -#. module: prototype -#: field:prototype,id:0 field:prototype.module.export,id:0 -msgid "ID" -msgstr "" - -#. module: prototype -#: field:prototype,icon_image:0 -msgid "Icon" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Interface" -msgstr "" - -#. module: prototype -#: field:prototype,write_uid:0 field:prototype.module.export,write_uid:0 -msgid "Last Updated by" -msgstr "" - -#. module: prototype -#: field:prototype,write_date:0 field:prototype.module.export,write_date:0 -msgid "Last Updated on" -msgstr "" - -#. module: prototype -#: field:prototype,maintainer:0 -msgid "Maintainer" -msgstr "" - -#. module: prototype -#: field:prototype,menu:0 -msgid "Menu Items" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Models" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Module" -msgstr "" - -#. module: prototype -#: field:prototype,human_name:0 -msgid "Module Name" -msgstr "" - -#. module: prototype -#: view:ir.model:prototype.view_ir_model_form field:ir.model.fields,notes:0 -msgid "Notes" -msgstr "" - -#. module: prototype -#: model:ir.actions.act_window,name:prototype.open_prototype_list -#: model:ir.model,name:prototype.model_prototype -#: model:ir.ui.menu,name:prototype.menu_open_prototype -#: view:prototype:prototype.view_prototype_tree -msgid "Prototype" -msgstr "" - -#. module: prototype -#: field:prototype,rules:0 -msgid "Record Rules" -msgstr "" - -#. module: prototype -#: view:prototype:prototype.view_prototype_form -msgid "Security" -msgstr "" - -#. module: prototype -#: field:prototype,summary:0 -msgid "Summary" -msgstr "" - -#. module: prototype -#: field:prototype,name:0 -msgid "Technical Name" -msgstr "" - -#. module: prototype -#: help:prototype,data:0 -msgid "The records matching the filters will be added as data." -msgstr "" - -#. module: prototype -#: help:prototype,demo:0 -msgid "The records matching the filters will be added as demo data." -msgstr "" - -#. module: prototype -#: field:prototype,version:0 -msgid "Version" -msgstr "" - -#. module: prototype -#: field:prototype,views:0 -msgid "Views" -msgstr "" - -#. module: prototype -#: field:prototype,website:0 -msgid "Website" -msgstr "" - -#. module: prototype -#: selection:prototype.module.export,state:0 -msgid "choose" -msgstr "" - -#. module: prototype -#: selection:prototype.module.export,state:0 -msgid "get" -msgstr "" - -#. module: prototype -#: field:prototype.module.export,state:0 -msgid "unknown" -msgstr "" diff --git a/prototype/models/prototype.py b/prototype/models/prototype.py deleted file mode 100644 index daea937a0..000000000 --- a/prototype/models/prototype.py +++ /dev/null @@ -1,339 +0,0 @@ -# -*- encoding: utf-8 -*- -# ############################################################################# -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -import os -import re -import base64 -from datetime import date -YEAR = date.today().year - -from collections import namedtuple -from jinja2 import Environment, FileSystemLoader -from openerp import models, api, fields - - -class Prototype(models.Model): - _name = "prototype" - _description = "Prototype" - - licence = fields.Char( - 'Licence', - default='AGPL-3', - ) - name = fields.Char( - 'Technical Name', required=True, - help=('The technical name will be used to define the name of ' - 'the exported module, the name of the model.') - ) - category_id = fields.Many2one('ir.module.category', 'Category') - human_name = fields.Char( - 'Module Name', required=True, - help=('The Module Name will be used as the displayed name of the ' - 'exported module.') - ) - summary = fields.Char('Summary', required=True) - description = fields.Text('Description', required=True) - author = fields.Char('Author', required=True) - maintainer = fields.Char('Maintainer') - website = fields.Char('Website') - icon_image = fields.Binary( - 'Icon', - help=('The icon set up here will be used as the icon ' - 'for the exported module also') - ) - version = fields.Char('Version', size=3, default='0.1') - auto_install = fields.Boolean( - 'Auto Install', - default=False, - help='Check if the module should be install by default.' - ) - application = fields.Boolean( - 'Application', - default=False, - help='Check if the module is an Odoo application.' - ) - # Relations - dependency_ids = fields.Many2many( - 'ir.module.module', 'prototype_module_rel', - 'prototype_id', 'module_id', - 'Dependencies' - ) - data_ids = fields.Many2many( - 'ir.filters', - 'prototype_data_rel', - 'prototype_id', 'filter_id', - 'Data filters', - help="The records matching the filters will be added as data." - ) - demo_ids = fields.Many2many( - 'ir.filters', - 'prototype_demo_rel', - 'prototype_id', 'filter_id', - 'Demo filters', - help="The records matching the filters will be added as demo data." - ) - field_ids = fields.Many2many( - 'ir.model.fields', 'prototype_fields_rel', - 'prototype_id', 'field_id', 'Fields' - ) - menu_ids = fields.Many2many( - 'ir.ui.menu', 'prototype_menu_rel', - 'prototype_id', 'menu_id', 'Menu Items' - ) - view_ids = fields.Many2many( - 'ir.ui.view', 'prototype_view_rel', - 'prototype_id', 'view_id', 'Views' - ) - group_ids = fields.Many2many( - 'res.groups', 'prototype_groups_rel', - 'prototype_id', 'group_id', 'Groups' - ) - right_ids = fields.Many2many( - 'ir.model.access', 'prototype_rights_rel', - 'prototype_id', 'right_id', - 'Access Rights' - ) - rule_ids = fields.Many2many( - 'ir.rule', 'prototype_rule_rel', - 'prototype_id', 'rule_id', 'Record Rules' - ) - - __data_files = [] - __field_descriptions = {} - _env = None - File_details = namedtuple('file_details', ['filename', 'filecontent']) - template_path = '{}/../templates/'.format(os.path.dirname(__file__)) - - @api.model - def set_jinja_env(self, api_version): - """Set the Jinja2 environment. - The environment will helps the system to find the templates to render. - :param api_version: string, odoo api - :return: jinja2.Environment instance. - """ - if self._env is None: - self._env = Environment( - loader=FileSystemLoader( - os.path.join(self.template_path, api_version) - ) - ) - return self._env - - def set_field_descriptions(self): - """Mock the list of fields into dictionary. - It allows us to add or change attributes of the fields. - - :return: None - """ - for field in self.field_ids: - field_description = {} - # This will mock a field record. - # the mock will allow us to add data or modify the data - # of the field (like for the name) with keeping all the - # attributes of the record. - field_description.update({ - attr_name: getattr(field, attr_name) - for attr_name in dir(field) - if not attr_name[0] == '_' - }) - # custom fields start with the prefix x_. - # it has to be removed. - field_description['name'] = re.sub(r'^x_', '', field.name) - self.__field_descriptions[field] = field_description - - @api.model - def generate_files(self): - """ Generates the files from the details of the prototype. - :return: tuple - """ - assert self._env is not None, \ - 'Run set_env(api_version) before to generate files.' - - self.set_field_descriptions() - file_details = [] - file_details.extend(self.generate_models_details()) - file_details.extend(self.generate_views_details()) - file_details.extend(self.generate_menus_details()) - file_details.append(self.generate_module_init_file_details()) - # must be the last as the other generations might add information - # to put in the __openerp__: additional dependencies, views files, etc. - file_details.append(self.generate_module_openerp_file_details()) - file_details.append(self.save_icon()) - - return file_details - - @api.model - def save_icon(self): - return self.File_details( - os.path.join('static', 'description', 'icon.jpg'), - base64.b64decode(self.icon_image) - ) - - @api.model - def generate_module_openerp_file_details(self): - """Wrapper to generate the __openerp__.py file of the module.""" - return self.generate_file_details( - '__openerp__.py', - '__openerp__.py.template', - prototype=self, - data_files=self.__data_files, - ) - - @api.model - def generate_module_init_file_details(self): - """Wrapper to generate the __init__.py file of the module.""" - return self.generate_file_details( - '__init__.py', - '__init__.py.template', - # no import models if no work of fields in - # the prototype - models=bool(self.field_ids) - ) - - @api.model - def generate_models_details(self): - """Finds the models from the list of fields and generates - the __init__ file and each models files (one by class). - """ - files = [] - # TODO: doesn't work as need to find the module to import - # and it is not necessary the name of the model the fields - # belongs to. - # ie. field.cell_phone is defined in a model inheriting from - # res.partner. - # How do we find the module the field was defined in? - # dependencies = set([dep.id for dep in self.dependencies]) - - relations = {} - for field in self.__field_descriptions.itervalues(): - model = field.get('model_id') - relations.setdefault(model, []).append(field) - # dependencies.add(model.id) - - # blind update of dependencies. - # self.write({ - # 'dependencies': [(6, 0, [id_ for id_ in dependencies])] - # }) - - files.append(self.generate_models_init_details(relations.keys())) - for model, fields in relations.iteritems(): - files.append(self.generate_model_details(model, fields)) - - return files - - @api.model - def generate_models_init_details(self, ir_models): - """Wrapper to generate the __init__.py file in models folder.""" - return self.generate_file_details( - 'models/__init__.py', - 'models/__init__.py.template', - models=[ - self.friendly_name(ir_model.model) - for ir_model in ir_models - ] - ) - - @api.model - def generate_views_details(self): - """Wrapper to generate the views files.""" - relations = {} - for view in self.view_ids: - relations.setdefault(view.model, []).append(view) - - views_details = [] - for model, views in relations.iteritems(): - filepath = 'views/{}_view.xml'.format( - self.friendly_name(model) - ) - views_details.append( - self.generate_file_details( - filepath, - 'views/model_views.xml.template', - views=views - ) - ) - self.__data_files.append(filepath) - - return views_details - - @api.model - def generate_menus_details(self): - """Wrapper to generate the menus files.""" - relations = {} - for menu in self.menu_ids: - relations.setdefault(menu.action.res_model, []).append(menu) - - menus_details = [] - for model_name, menus in relations.iteritems(): - filepath = 'views/{}_menus.xml'.format( - self.friendly_name(model_name) - ) - menus_details.append( - self.generate_file_details( - filepath, - 'views/model_menus.xml.template', - menus=menus, - ) - ) - self.__data_files.append(filepath) - - return menus_details - - @api.model - def generate_model_details(self, model, field_descriptions): - """Wrapper to generate the python file for the model. - - :param model: ir.model record. - :param field_descriptions: list of ir.model.fields records. - :return: FileDetails instance. - """ - python_friendly_name = self.friendly_name(model.model) - return self.generate_file_details( - 'models/{}.py'.format(python_friendly_name), - 'models/model_name.py.template', - name=python_friendly_name, - inherit=model.model, - fields=field_descriptions, - ) - - @staticmethod - def friendly_name(name): - return name.replace('.', '_') - - @api.model - def generate_file_details(self, filename, template, **kwargs): - """ generate file details from jinja2 template. - :param filename: name of the file the content is related to - :param template: path to the file to render the content - :param kwargs: arguments of the template - :return: File_details instance - """ - template = self._env.get_template(template) - # keywords used in several templates. - kwargs.update( - { - 'export_year': YEAR, - 'author': self.author, - 'website': self.website, - 'cr': self._cr, - } - ) - return self.File_details(filename, template.render(kwargs)) diff --git a/prototype/security/ir.model.access.csv b/prototype/security/ir.model.access.csv deleted file mode 100755 index 0533abe94..000000000 --- a/prototype/security/ir.model.access.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_prototype_admin,prototype_system,model_prototype,base.group_system,1,1,1,1 diff --git a/prototype/static/description/icon.png b/prototype/static/description/icon.png deleted file mode 100644 index 6a120f9fd6225e170be28c1f523d447820beb9d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14323 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 HwG8_o``74T diff --git a/prototype/templates/8.0/data/model_name.xml.template b/prototype/templates/8.0/data/model_name.xml.template deleted file mode 100644 index 7b25f11f8..000000000 --- a/prototype/templates/8.0/data/model_name.xml.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - - {{ data }} - - - diff --git a/prototype/templates/8.0/demo/model_name.xml.template b/prototype/templates/8.0/demo/model_name.xml.template deleted file mode 100644 index 097c294f1..000000000 --- a/prototype/templates/8.0/demo/model_name.xml.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - - {{ demo }} - - - diff --git a/prototype/templates/8.0/header.template b/prototype/templates/8.0/header.template deleted file mode 100644 index 59f0f4bfd..000000000 --- a/prototype/templates/8.0/header.template +++ /dev/null @@ -1,22 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Odoo, Open Source Management Solution -# This module copyright (C) {{ export_year }} {{ author }} -# ({{ website }}). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -{% block body %}{% endblock %} \ No newline at end of file diff --git a/prototype/templates/8.0/models/__init__.py.template b/prototype/templates/8.0/models/__init__.py.template deleted file mode 100644 index caf9d7c74..000000000 --- a/prototype/templates/8.0/models/__init__.py.template +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "header.template" %} -{% block body %} -{% for model in models -%} -from . import {{ model }} -{% endfor %} -{% endblock %} diff --git a/prototype/templates/8.0/models/model_name.py.template b/prototype/templates/8.0/models/model_name.py.template deleted file mode 100644 index 503df048f..000000000 --- a/prototype/templates/8.0/models/model_name.py.template +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "header.template" %} -{% block body %} -from openerp import models, fields -from openerp.tools.translate import _ - - -class {{ name }}(models.Model): - _inherit = "{{ inherit }}" - {% if description %}_description = "{{ description }}"{% endif %} - - {% for field in fields -%} - {{ field.name }} = fields.{{ field.ttype|capitalize }}( - string=_("{{ field.field_description }}"), - required={{ field.required }}, - translate={{ field.translate }}, - readonly={{ field.readonly }}, - help=_('{{ field.notes }}'), - ) - {% endfor %} - -{% endblock %} diff --git a/prototype/templates/8.0/security/ir.model.access.csv.template b/prototype/templates/8.0/security/ir.model.access.csv.template deleted file mode 100644 index 0d2111f9d..000000000 --- a/prototype/templates/8.0/security/ir.model.access.csv.template +++ /dev/null @@ -1,4 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -{% for rule in access_rules %} -{{ rule.id }},{{ rule.name }},{{ rule.model_id.id }},{{ rule.group_id.id }},{{ rule.perm_write }},{{ rule.perm_write }},{{ rule.perm_create }},{{ rule.perm_unlink }} -{% endfor %} diff --git a/prototype/templates/8.0/security/model_name.xml.template b/prototype/templates/8.0/security/model_name.xml.template deleted file mode 100644 index 6f2d4e508..000000000 --- a/prototype/templates/8.0/security/model_name.xml.template +++ /dev/null @@ -1,10 +0,0 @@ - - - - - {{ groups }} - - {{ rules }} - - - diff --git a/prototype/templates/8.0/views/model_menus.xml.template b/prototype/templates/8.0/views/model_menus.xml.template deleted file mode 100644 index 642a682d8..000000000 --- a/prototype/templates/8.0/views/model_menus.xml.template +++ /dev/null @@ -1,24 +0,0 @@ - - - - {% for menu in menus -%} - - {{ menu.action.name }} - {{ menu.action.type }} - {{ menu.action.res_model }} - {{ menu.action.view_type }} - {{ menu.action.view_mode }} - {% if menu.action.help %}{{ menu.action.help }} - {% endif %} - - - - {% endfor -%} - - diff --git a/prototype/templates/8.0/views/model_views.xml.template b/prototype/templates/8.0/views/model_views.xml.template deleted file mode 100644 index 4eba907ba..000000000 --- a/prototype/templates/8.0/views/model_views.xml.template +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - {% for view in views %} - - {{ view.name }}.view - {{ view.model }} - {{ view.type }} - - - {# the arch given by odoo start with an xml tag that - will break the xml tree we build. - Be careful, custom field have a x_ prefix that has to be - removed - #} - {{ view.arch|replace('', '')|replace('"x_', '"') }} - - - {% endfor %} - - diff --git a/prototype/tests/__init__.py b/prototype/tests/__init__.py deleted file mode 100644 index cb0e34aff..000000000 --- a/prototype/tests/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from . import test_prototype_module_export -from . import test_prototype - -checks = [ - test_prototype_module_export, - test_prototype, -] diff --git a/prototype/views/ir_model_fields_view.xml b/prototype/views/ir_model_fields_view.xml deleted file mode 100644 index e1563449c..000000000 --- a/prototype/views/ir_model_fields_view.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - view_ir_model_fields_form - ir.model.fields - - - - - - - - view_ir_model_form - ir.model - - - - - - - - - - - diff --git a/prototype/views/prototype_view.xml b/prototype/views/prototype_view.xml deleted file mode 100644 index c68396331..000000000 --- a/prototype/views/prototype_view.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - prototype.tree - prototype - - - - - - - - - - - prototype.form - prototype - -
- - - -
-

- -

-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - Prototype - prototype - form - tree,form - - - - - -
-
diff --git a/prototype/wizard/__init__.py b/prototype/wizard/__init__.py deleted file mode 100644 index 1bb4a444c..000000000 --- a/prototype/wizard/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from . import prototype_module_export diff --git a/prototype/wizard/prototype_module_export_view.xml b/prototype/wizard/prototype_module_export_view.xml deleted file mode 100644 index e867c9af4..000000000 --- a/prototype/wizard/prototype_module_export_view.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - Export Module - prototype.module.export - -
- - - - - - - - - -
-

Export Complete

-

Here is the exported module:

-
-
-
-
-
- -
-
- - - Export Module - prototype.module.export - form - - new - - -
-