""" 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, Optional # from tiramisu import owners from rougail.utils import undefined from .i18n import _ class CommonOutput: def __init__( self, rougailconfig, ) -> None: self.set_config(rougailconfig) self.variable_default_enable = False self.variable_hidden_enable = False self.value_modified_enable = False self.value_unmodified_enable = False self.value_default_enable = False def set_config(self, rougailconfig): pass def run(self, nodes): if nodes.children: root = self.parse(nodes) return self._run(root) return 0, '' def parse(self, node, parent=None, level=0): if node.hidden: self.variable_hidden_enable = True color = self.variable_hidden_color else: if node.hidden != None: self.variable_default_enable = True color = self.variable_normal_color family_output = self.colorize( [ { "value": node.description, "color": color, "loaded_from": None, } ] ) subparent = self.get_parent(parent, family_output, level) for child in node.children: if child["type"] == "node": self.parse(child["node"], subparent, level+1) else: if child["hidden"]: self.variable_hidden_enable = True variable_color = self.variable_hidden_color else: self.variable_default_enable = True variable_color = self.variable_normal_color if child["values"][0]["is_default"]: self.value_unmodified_enable = True color = self.value_unmodified_color else: self.value_modified_enable = True color = self.value_modified_color child["values"][0]["color"] = color if len(child["values"]) > 1: self.value_default_enable = True value = self.colorize( child["values"], ) description = self.colorize( [ { "value": child["description"], "color": variable_color, "loaded_from": None, } ] ) self.add_variable(subparent, description, value, child["icon"], level+1) return subparent def header(self): raise NotImplementedError() # # def display_errors( # self, # tree, # errors, # ) -> None: # errors_dict = {} # for error in errors: # self.error_warn_to_dict(error, errors_dict, self.msg_to_error) # self.parse_error_warning(tree, errors_dict, self.display_error) # return self.pouet(tree) # self.error_end() # # def display_warnings( # self, # warnings_dict, # warnings, # ) -> None: ###### self.parse_error_warning(tree, warnings_dict, self.display_warning) ## self.warning_end() def error_warn_to_dict(self, error, errors_dict, level): if isinstance(error, dict): for msg, subconfig in error.items(): description = subconfig.option.impl_get_display_name(subconfig) self.subconfig_to_dict(subconfig, errors_dict).setdefault(None, {}).setdefault(description, []).append((msg, level)) else: errors_dict.setdefault(None, []).append(error) # # def msg_to_error(self, msg): # return msg # # def msg_to_warning(self, msg): # return msg def subconfig_to_dict(self, subconfig: "Subconfig", errors_dict: dict) -> dict: #FIXME a tester : mandatories dans une arborescence (voir si ca n'ecrase pas) parents = [] parent = subconfig while True: parent = parent.parent if parent is None: break parents.insert(0, parent) current_dict = errors_dict for child in parents[1:]: description = child.option.impl_get_display_name(child) current_dict = current_dict.setdefault(description, {}) return current_dict def parse_error_warning(self, tree, error, display, default_color, level=0): self._parse_error_warning(tree, error, display, level, default_color) return self.display(tree) def _parse_error_warning(self, tree, error, display, level, default_color): if isinstance(error, list): for err in error: self._parse_error_warning(tree, err, display, level+1, default_color) elif isinstance(error, dict): for key, value in error.items(): if key is None: # it's variables, no more families self._parse_error_warning(tree, value, display, level, default_color) else: if isinstance(value, list) and len(value) == 1: self._parse_error_warning(tree, (key, *value[0]), display, level+1, default_color) else: sub_tree = self._parse_error_warning(tree, key, display, level+1, default_color) self._parse_error_warning(sub_tree, value, display, level+1, default_color) else: return display(level, tree, error, default_color) def warning_end(self): pass def add_family( self, family, level, ) -> 'OutputFamily': properties = family.property.get() if "hidden" in properties: self.root_family.variable_hidden_enable = True color = self.variable_hidden_color else: self.root_family.variable_default_enable = True color = None family_output = self.colorize( [ { "value": family.description(), "color": color, "loaded_from": None, } ] ) return self.__class__( family_output, self.get_tree(), self.root, level + 1, root_family = self.root_family, ) def colorize( self, values, option=None, ) -> str: multi = False ret = [] default = [] empty_multi = False for idx, data in enumerate(values): value = data["value"] if isinstance(value, list): multi = True if not value: empty_multi = True value = ["[]"] else: value = [value] for vidx, val in enumerate(value): if len(ret) == vidx: ret.append("") default.append(False) if idx: if not default[vidx]: if ret[vidx]: ret[vidx] += " " ret[vidx] += "(" default[vidx] = True else: ret[vidx] += " " ret[vidx] += ":hourglass_flowing_sand: " if option: val = self.convert_value( option, val, ) color = data.get("color", self.value_default_color) if color is not None: ret[vidx] += self.set_color(color, val) else: ret[vidx] += val loaded_from = data["loaded_from"] if loaded_from: ret[vidx] += f" ◀ {loaded_from}" for idx in range(len(ret)): if default[idx]: ret[idx] += ")" if not multi or empty_multi: if not ret: return "" return ret[0] return ret def get_subconfig_with_default_value(self, config): default_owner = config.owner.default() if default_owner == owners.default: return self.root.config if not self.root.config_owner_is_path: meta_config = self.root.config while True: meta_config = meta_config.parent() if not meta_config.owner.isdefault(): break else: meta_config = self.root.metaconfig for child in default_owner.split(".")[1:]: meta_config = meta_config.config(child) return meta_config def end(self): pass