server-tools/base_jsonify/models/ir_export.py

109 lines
3.3 KiB
Python

# © 2017 Akretion (http://www.akretion.com)
# Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from collections import OrderedDict
from odoo import fields, models
def partition(l, accessor): # -> Dict
result = {}
for item in l:
key = accessor(item)
if key not in result:
result[key] = []
result[key].append(item)
return result
def update_dict(data, fields, options):
"""Contruct a tree of fields.
Example:
{
"name": True,
"resource": True,
}
Order of keys is important.
"""
field = fields[0]
if len(fields) == 1:
if field == ".id":
field = "id"
data[field] = (True, options)
else:
if field not in data:
data[field] = (False, OrderedDict())
update_dict(data[field][1], fields[1:], options)
def convert_dict(dict_parser):
"""Convert dict returned by update_dict to list consistent w/ Odoo API.
The list is composed of strings (field names or aliases) or tuples.
"""
parser = []
for field, value in dict_parser.items():
if value[0] is True: # is a leaf
parser.append(field_dict(field, value[1]))
else:
parser.append((field_dict(field), convert_dict(value[1])))
return parser
def field_dict(field, options=None):
result = {"name": field.split(":")[0]}
if len(field.split(":")) > 1:
result["alias"] = field.split(":")[1]
for option in options or {}:
if options[option]:
result[option] = options[option]
return result
class IrExport(models.Model):
_inherit = "ir.exports"
language_agnostic = fields.Boolean(
default=False,
string="Language Agnostic",
help="If set, will set the lang to False when exporting lines without lang,"
" otherwise it uses the lang in the given context to export these fields",
)
global_resolver_id = fields.Many2one(
comodel_name="ir.exports.resolver",
string="Custom global resolver",
domain="[('type', '=', 'global')]",
help="If set, will apply the global resolver to the result",
)
def get_json_parser(self):
"""Creates a parser from ir.exports record and return it.
The final parser can be used to "jsonify" records of ir.export's model.
"""
self.ensure_one()
parser = {"language_agnostic": self.language_agnostic}
lang_to_lines = partition(self.export_fields, lambda l: l.lang_id.code)
lang_parsers = {}
for lang in lang_to_lines:
dict_parser = OrderedDict()
for line in lang_to_lines[lang]:
names = line.name.split("/")
if line.alias:
names = line.alias.split("/")
options = {"resolver": line.resolver_id, "function": line.function}
update_dict(dict_parser, names, options)
lang_parsers[lang] = convert_dict(dict_parser)
if list(lang_parsers.keys()) == [False]:
parser["fields"] = lang_parsers[False]
else:
parser["langs"] = lang_parsers
if self.global_resolver_id:
parser["resolver"] = self.global_resolver_id
return parser