""" Silique (https://www.silique.fr) Copyright (C) 2022-2025 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.error import PropertiesOptionError, ConfigError from rougail.error import ExtentionError 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, ) -> 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 ExtentionError( _('the "step.output" is not set to "{0}"').format(self.output_name) ) self.rougailconfig = rougailconfig self.config = config if user_data_errors: self.errors = user_data_errors else: self.errors = [] if user_data_warnings: self.warnings = user_data_warnings else: self.warnings = [] self.is_mandatory = self.rougailconfig["json.mandatory"] self.get = self.rougailconfig["json.get"] self.dico = {} 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: if self.is_mandatory: ori_properties = self.config.property.exportation() self.config.property.read_write() self.mandatory() self.config.property.importation(ori_properties) if self.manage_errors(): return False self.manage_warnings() if self.get: config = self.config.option(self.get) if not config.isoptiondescription(): self.dico = config.value.get() return True else: config = self.config self.parse_family( config, self.dico, ) return True def mandatory(self): title = False options_with_error = [] try: mandatories = self.config.value.mandatory() except (ConfigError, PropertiesOptionError) as err: self.errors.append(_("Error in config: {0}").format(err)) return except ValueError as err: self.errors.append(str(err)) return for option in mandatories: try: option.value.get() if not title: self.errors.append( _("The following variables are mandatory but have no value:") ) title = True self.errors.append(f" - {option.description()}") except PropertiesOptionError: options_with_error.append(option) if not title: for idx, option in enumerate(options_with_error): if not idx: self.errors.append( _( "The following variables are inaccessible but are empty and mandatory :" ) ) self.errors.append(f" - {option.description()}") def manage_warnings(self) -> None: if self.warnings: self.dico["_warnings"] = self.warnings def manage_errors(self) -> bool: if not self.errors: return False self.dico = {"_errors": self.errors} self.manage_warnings() return True def parse_family( self, conf, child, ): for option in conf: if option.isoptiondescription(): if option.isleadership(): parent = [] self.parse_leadership( option, parent, ) else: parent = {} self.parse_family(option, parent) child[option.name()] = parent else: child[option.name()] = option.value.get() def parse_leadership( 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",)