Browse Source

[MIG] Migration to V12.0 - initial release

12.0-mig-module_prototyper
Nicolas JEUDY 5 years ago
parent
commit
cc8110e9a1
  1. 5
      module_prototyper/data/module_prototyper_api_version_data.xml
  2. 39
      module_prototyper/models/module_prototyper.py
  3. 7
      module_prototyper/templates/12.0/__init__.py.template
  4. 54
      module_prototyper/templates/12.0/__manifest__.py.template
  5. 6
      module_prototyper/templates/12.0/data/model_name.xml.template
  6. 6
      module_prototyper/templates/12.0/demo/model_name.xml.template
  7. 4
      module_prototyper/templates/12.0/header.template
  8. 9
      module_prototyper/templates/12.0/models/__init__.py.template
  9. 35
      module_prototyper/templates/12.0/models/model_name.py.template
  10. 4
      module_prototyper/templates/12.0/security/ir.model.access.csv.template
  11. 8
      module_prototyper/templates/12.0/security/model_name.xml.template
  12. 27
      module_prototyper/templates/12.0/views/model_menus.xml.template
  13. 15
      module_prototyper/templates/12.0/views/model_views.xml.template
  14. 4
      module_prototyper/tests/test_prototype.py
  15. 4
      module_prototyper/tests/test_prototype_module_export.py
  16. 6
      module_prototyper/views/module_prototyper_view.xml
  17. 14
      module_prototyper/wizard/module_prototyper_module_export.py

5
module_prototyper/data/module_prototyper_api_version_data.xml

@ -13,4 +13,9 @@
<field name="manifest_file_name">__manifest__</field> <field name="manifest_file_name">__manifest__</field>
</record> </record>
<record id="api_version_120" model="module_prototyper.api_version">
<field name="name">12.0</field>
<field name="manifest_file_name">__manifest__</field>
</record>
</odoo> </odoo>

39
module_prototyper/models/module_prototyper.py

@ -242,28 +242,6 @@ class ModulePrototyper(models.Model):
"want to export in this module." "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 _env = None
_api_version = None _api_version = None
@ -398,7 +376,7 @@ class ModulePrototyper(models.Model):
relations = {} relations = {}
field_descriptions = self._field_descriptions or {} field_descriptions = self._field_descriptions or {}
for field in field_descriptions.itervalues():
for field in list(field_descriptions.values()):
model = field.get("model_id") model = field.get("model_id")
relations.setdefault(model, []).append(field) relations.setdefault(model, []).append(field)
# dependencies.add(model.id) # dependencies.add(model.id)
@ -408,8 +386,8 @@ class ModulePrototyper(models.Model):
# 'dependencies': [(6, 0, [id_ for id_ in dependencies])] # '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_models_init_details(list(relations.keys())))
for model, custom_fields in list(relations.items()):
files.append(self.generate_model_details(model, custom_fields)) files.append(self.generate_model_details(model, custom_fields))
return files return files
@ -433,9 +411,10 @@ class ModulePrototyper(models.Model):
relations.setdefault(view.model, []).append(view) relations.setdefault(view.model, []).append(view)
views_details = [] views_details = []
for model, views in relations.iteritems():
_logger.debug(relations)
for model, views in list(relations.items()):
filepath = "views/%s_view.xml" % ( filepath = "views/%s_view.xml" % (
self.friendly_name(self.unprefix(model)),
self.friendly_name(self.unprefix(model)) if model else 'website_templates',
) )
views_details.append( views_details.append(
self.generate_file_details( self.generate_file_details(
@ -458,7 +437,7 @@ class ModulePrototyper(models.Model):
relations.setdefault(model, []).append(menu) relations.setdefault(model, []).append(menu)
menus_details = [] menus_details = []
for model_name, menus in relations.iteritems():
for model_name, menus in list(relations.items()):
model_name = self.unprefix(model_name) model_name = self.unprefix(model_name)
filepath = "views/%s_menus.xml" % (self.friendly_name(model_name),) filepath = "views/%s_menus.xml" % (self.friendly_name(model_name),)
menus_details.append( menus_details.append(
@ -506,7 +485,7 @@ class ModulePrototyper(models.Model):
("data", data, self._data_files), ("data", data, self._data_files),
("demo", demo, self._demo_files), ("demo", demo, self._demo_files),
]: ]:
for model_name, records in model_data.iteritems():
for model_name, records in list(model_data.items()):
fname = self.friendly_name(self.unprefix(model_name)) fname = self.friendly_name(self.unprefix(model_name))
filename = "%s/%s.xml" % (prefix, fname) filename = "%s/%s.xml" % (prefix, fname)
self._data_files.append(filename) self._data_files.append(filename)
@ -564,7 +543,7 @@ class ModulePrototyper(models.Model):
continue continue
if isinstance(attrs, dict): if isinstance(attrs, dict):
for key, val in attrs.iteritems():
for key, val in list(attrs.items()):
if isinstance(val, (list, tuple)): if isinstance(val, (list, tuple)):
attrs[key] = cls.fixup_domain(val) attrs[key] = cls.fixup_domain(val)
elem.attrib["attrs"] = repr(attrs) elem.attrib["attrs"] = repr(attrs)

7
module_prototyper/templates/12.0/__init__.py.template

@ -0,0 +1,7 @@
{% extends "header.template" %}
{% block body %}
{% if models %}
from . import models
{% endif %}
{% endblock %}

54
module_prototyper/templates/12.0/__manifest__.py.template

@ -0,0 +1,54 @@
{% extends "header.template" %}
{% block body %}
{
'name': '{{ prototype.human_name }}',
'version': '{{ prototype.version }}',
'author': '{{ prototype.author }}',
'maintainer': '{{ prototype.maintainer }}',
'website': '{{ prototype.website }}',
'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
# for the full list
'category': '{{ prototype.with_context({}).category_id.name }}',{# In english please! #}
'summary': '{{ prototype.summary }}',
'description': """
{{ prototype.description }}
""",
# any module necessary for this one to work correctly
'depends': [
{% for dependency in prototype.dependency_ids %}
'{{ dependency.name }}',
{% endfor %}
],
'external_dependencies': {
'python': [],
},
# always loaded
'data': [
{% for data_file in data_files %}
'{{ data_file }}',
{% endfor %}
],
# only loaded in demonstration mode
'demo': [
{% for demo_file in prototype.demo_ids %}
'{{ demo_file.name }}',
{% endfor %}
],
'js': [],
'css': [],
'qweb': [],
'installable': True,
# 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 }},
}
{% endblock %}

6
module_prototyper/templates/12.0/data/model_name.xml.template

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<odoo>
{{ data }}
</odoo>

6
module_prototyper/templates/12.0/demo/model_name.xml.template

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<odoo>
{{ demo }}
</odoo>

4
module_prototyper/templates/12.0/header.template

@ -0,0 +1,4 @@
# Copyright {{ export_year }} {% if author %}{{ author }}{% endif %} ({% if website %}({{ website }}).{% endif %})
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{% block body %}
{% endblock %}

9
module_prototyper/templates/12.0/models/__init__.py.template

@ -0,0 +1,9 @@
{% extends "header.template" %}
{% block body %}
{% for model in models %}
{% if loop.first %}
{% endif %}
from . import {{ model }}
{% endfor %}
{% endblock %}

35
module_prototyper/templates/12.0/models/model_name.py.template

@ -0,0 +1,35 @@
{% extends "header.template" %}
{% block body %}
from odoo import models, fields
from odoo.tools.translate import _
class {{ unprefix(name) }}(models.Model):
{% if model.state == 'base' %}
_name = "{{ model.model }}"
{% else %}
_inherit = "{{ model.model }}"
{% endif %}
{% if description %}
_description = "{{ description }}"
{% endif %}
{% for field in fields %}
{% for line in wrap(field.notes, replace_whitespace=False) %}
# {{line}}
{% endfor %}
{{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}(
string=_("{{ field.field_description }}"),
required={{ field.required }},
translate={{ field.translate }},
readonly={{ field.readonly }}
{% if field.size %}
size={{ field.size }},
{% endif %}
{% if field.helper %}
help=_("{{ field.helper }}"),
{% endif %}
)
{% endfor %}
{% endblock %}

4
module_prototyper/templates/12.0/security/ir.model.access.csv.template

@ -0,0 +1,4 @@
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 %}

8
module_prototyper/templates/12.0/security/model_name.xml.template

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<odoo>
{{ groups }}
{{ rules }}
</odoo>

27
module_prototyper/templates/12.0/views/model_menus.xml.template

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<odoo>
{% for menu in menus %}
<record id="action_{{ menu.action.name }}_{{ menu.action.view_type }}_view" model="{{ menu.action.type }}">
<field name="name">{{ unprefix(menu.action.name) }}</field>
<field name="type">{{ menu.action.type }}</field>
<field name="res_model">{{ unprefix(menu.action.res_model) }}</field>
<field name="view_type">{{ menu.action.view_type }}</field>
<field name="view_mode">{{ menu.action.view_mode }}</field>
{% if menu.action.help %}
<field name="help" type="html">{{ menu.action.help }}
</field>
{% endif %}
</record>
<menuitem action="action_{{ unprefix(menu.action.name) }}_{{ menu.action.view_type }}_view"
name="{{ menu.name }}"
id="menu_action_{{ unprefix(menu.name)|replace('.', '_') }}_{{ menu.action.view_type }}"
{% if menu.parent_id %}parent="{{ menu.parent_id.get_xml_id().values()[0] }}"{% endif %}
sequence="{{ menu.sequence }}"
groups="{% for group in menu.groups_id %}{{ group.get_xml_id().values()[0] }},{% endfor %}"
/>
{% if not loop.last %}
{% endif %}
{% endfor %}
</odoo>

15
module_prototyper/templates/12.0/views/model_views.xml.template

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<odoo>
<!-- TODO: put here a reminder on what to do at the first edition -->
{% for view in views %}
<record id="{{ unprefix(view.name)|replace('.', '_')}}_view" model="ir.ui.view">
<field name="name">{{ unprefix(view.name) }}.view</field>
<field name="model">{{ unprefix(view.model) }}</field>
<field name="view_type">{{ view.type }}</field>
<field name="inherit_id" ref="{{ view.inherit_id.get_xml_id().values()[0] }}"/>
<field name="arch" type="xml">
{{ fixup_arch(view.arch) }}
</field>
</record>
{% endfor %}
</odoo>

4
module_prototyper/tests/test_prototype.py

@ -66,8 +66,8 @@ class TestModulePrototyper(common.TransactionCase):
# namedtuples in tuple # namedtuples in tuple
for file_details in details: for file_details in details:
self.assertIsInstance(file_details, tuple) self.assertIsInstance(file_details, tuple)
self.assertIsInstance(file_details.filename, basestring)
self.assertIsInstance(file_details.filecontent, basestring)
self.assertIsInstance(file_details.filename, str)
self.assertIsInstance(file_details.filecontent, str)
name, contents = file_details name, contents = file_details
if name.endswith(".py"): if name.endswith(".py"):

4
module_prototyper/tests/test_prototype_module_export.py

@ -20,7 +20,7 @@
############################################################################## ##############################################################################
from odoo.tests import common from odoo.tests import common
import zipfile import zipfile
import StringIO
import io
class TestPrototypeModuleExport(common.TransactionCase): class TestPrototypeModuleExport(common.TransactionCase):
@ -70,4 +70,4 @@ class TestPrototypeModuleExport(common.TransactionCase):
self.assertIsInstance(ret, tuple) self.assertIsInstance(ret, tuple)
self.assertIsInstance(ret.zip_file, zipfile.ZipFile) self.assertIsInstance(ret.zip_file, zipfile.ZipFile)
self.assertIsInstance(ret.stringIO, StringIO.StringIO)
self.assertIsInstance(ret.stringIO, io.StringIO)

6
module_prototyper/views/module_prototyper_view.xml

@ -88,12 +88,6 @@
<label for="rule_ids"/> <label for="rule_ids"/>
<field name="rule_ids"/> <field name="rule_ids"/>
</page> </page>
<page string="Workflows">
<label for="activity_ids" />
<field name="activity_ids" />
<label for="transition_ids" />
<field name="transition_ids" />
</page>
<page string="Website"> <page string="Website">
</page> </page>
</notebook> </notebook>

14
module_prototyper/wizard/module_prototyper_module_export.py

@ -19,10 +19,10 @@
# #
############################################################################## ##############################################################################
import StringIO
import base64 import base64
import os import os
import zipfile import zipfile
from io import BytesIO, StringIO
from collections import namedtuple from collections import namedtuple
from odoo import fields, models, api from odoo import fields, models, api
@ -53,7 +53,7 @@ class PrototypeModuleExport(models.TransientModel):
Export a zip file containing the module based on the information Export a zip file containing the module based on the information
provided in the prototype, using the templates chosen in the wizard. provided in the prototype, using the templates chosen in the wizard.
""" """
if isinstance(ids, (int, long)):
if isinstance(ids, int):
ids = [ids] ids = [ids]
wizard = self.browse(ids) wizard = self.browse(ids)
@ -79,7 +79,7 @@ class PrototypeModuleExport(models.TransientModel):
{ {
"name": "%s.zip" % (zip_name,), "name": "%s.zip" % (zip_name,),
"state": "get", "state": "get",
"data": base64.encodestring(zip_details.stringIO.getvalue()),
"data": base64.encodestring(zip_details.BytesIO.getvalue()),
} }
) )
@ -99,8 +99,8 @@ class PrototypeModuleExport(models.TransientModel):
:param file_details: tuple (filename, file_content) :param file_details: tuple (filename, file_content)
:return: tuple (zip_file, stringIO) :return: tuple (zip_file, stringIO)
""" """
zip_details = namedtuple("Zip_details", ["zip_file", "stringIO"])
out = StringIO.StringIO()
zip_details = namedtuple("Zip_details", ["zip_file", "BytesIO"])
out = BytesIO()
with zipfile.ZipFile(out, "w") as target: with zipfile.ZipFile(out, "w") as target:
for prototype in prototypes: for prototype in prototypes:
@ -115,7 +115,7 @@ class PrototypeModuleExport(models.TransientModel):
# ready to be saved by the user. # ready to be saved by the user.
file_details = prototype.generate_files() file_details = prototype.generate_files()
for filename, file_content in file_details: for filename, file_content in file_details:
if isinstance(file_content, unicode):
if isinstance(file_content, str):
file_content = file_content.encode("utf-8") file_content = file_content.encode("utf-8")
# Prefix all names with module technical name # Prefix all names with module technical name
filename = os.path.join(prototype.name, filename) filename = os.path.join(prototype.name, filename)
@ -124,4 +124,4 @@ class PrototypeModuleExport(models.TransientModel):
info.external_attr = 2175008768 # specifies mode 0644 info.external_attr = 2175008768 # specifies mode 0644
target.writestr(info, file_content) target.writestr(info, file_content)
return zip_details(zip_file=target, stringIO=out)
return zip_details(zip_file=target, BytesIO=out)
Loading…
Cancel
Save