""" Silique (https://www.silique.fr) Copyright (C) 2022-2026 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ from typing import Any, List, Optional from json import dumps from tiramisu import groups from tiramisu.error import PropertiesOptionError, ConfigError from rougail.error import ExtensionError from .i18n import _ from .__version__ import __version__ class RougailOutputJson: output_name = "json" def __init__( self, config: "Config", *, rougailconfig: "RougailConfig" = None, user_data_errors: Optional[list] = None, user_data_warnings: Optional[list] = None, true_config: "Config" = None, **kwargs, ) -> None: if rougailconfig is None: from rougail import RougailConfig rougailconfig = RougailConfig rougailconfig["step.output"] = self.output_name if rougailconfig["step.output"] != self.output_name: raise ExtensionError( _('the "step.output" is not set to "{0}"').format(self.output_name) ) self.rougailconfig = rougailconfig self.config = config if true_config: self.true_config = true_config else: self.true_config = config try: groups.namespace self.support_namespace = True except AttributeError: self.support_namespace = False if user_data_errors: self.errors = user_data_errors else: self.errors = [] if user_data_warnings: self.warnings = user_data_warnings else: self.warnings = [] def run(self) -> None: ret = self.exporter() if isinstance(self.dico, str): value = self.dico else: value = dumps(self.dico, ensure_ascii=False, indent=2) return ret, value def print(self) -> str: ret, data = self.run() print(data) return ret def exporter(self) -> None: self.dico = {} self.manage_warnings() if not self.manage_errors(): return False if not self.config.isoptiondescription(): self.dico = self.config.value.get() return True self.parse_family( self.config, self.dico, None, ) return self.manage_errors() def manage_warnings(self) -> None: if not self.warnings: return warnings = [] for w in self.warnings: if isinstance(w, dict): msg, opt = next(iter(w.items())) warnings.append(_('{0}: {1}').format(opt.path, msg)) else: warnings.append(w) self.dico["_warnings"] = warnings def manage_errors(self) -> bool: if not self.errors: return True errors = [] for e in self.errors: if isinstance(e, dict): msg, opt = next(iter(e.items())) errors.append(_('{0}: {1}').format(opt.path, msg)) else: errors.append(e) self.dico["_errors"] = errors #self.manage_warnings() return False def parse_family( self, conf, child, namespace, ): for option in conf: if option.isoptiondescription(): if option.isleadership(): parent = [] self.parse_sequence( option, parent, ) else: if namespace is None and self.support_namespace and option.group_type() is groups.namespace: subnamespace = option.name() else: subnamespace = namespace parent = {} self.parse_family(option, parent, subnamespace) child[option.name()] = parent else: child[option.name()] = option.value.get() def parse_sequence( self, conf, parent, ): leader, *followers = list(conf) leader_values = leader.value.get() for idx, leader_value in enumerate(leader_values): leader_dict = {leader.name(): leader_value} parent.append(leader_dict) for follower in list(followers): if follower.index() != idx: continue followers.remove(follower) leader_dict[follower.name()] = follower.value.get() RougailOutput = RougailOutputJson __all__ = ("RougailOutputJson",)