# © 2017 Akretion (http://www.akretion.com) # Sébastien BEAU # 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) parser["langs"] = lang_parsers if self.global_resolver_id: parser["resolver"] = self.global_resolver_id return parser