""" Silique (https://www.silique.fr) Copyright (C) 2022-2024 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 rich.tree import Tree from rich.console import Console from rich.table import Table from rich.panel import Panel from tiramisu import undefined from ...i18n import _ class Formater: name = 'console' level = 10 variable_hidden_color = 'orange1' variable_advanced_color = 'bright_blue' variable_advanced_and_modified_color = 'red1' value_unmodified_color = 'gold1' value_default_color = 'green' def __init__(self, rougailconfig: 'RougailConfig', ) -> None: self.console = Console(force_terminal=True) self.rougailconfig = rougailconfig self.read_write = self.rougailconfig['exporter.read_write'] self.show_secrets = self.rougailconfig['exporter.show_secrets'] self.out = [] def header(self): header_variable = 'Variable\n' #header_variable += f'[{self.variable_advanced_color}]Variable non documentée[/{self.variable_advanced_color}]\n' #header_variable += f'[{self.variable_advanced_and_modified_color}]Variable non documentée mais modifiée[/{self.variable_advanced_and_modified_color}]' header_variable += f'[{self.variable_advanced_color}]{_("Undocumented variable")}[/{self.variable_advanced_color}]\n' header_variable += f'[{self.variable_advanced_and_modified_color}]{_("Undocumented but modified variable")}[/{self.variable_advanced_and_modified_color}]' if not self.read_write: #header_variable += f'\n[{self.variable_hidden_color}]Variable non modifiable[/{self.variable_hidden_color}]' header_variable += f'\n[{self.variable_hidden_color}]{_("Unmodifiable variable")}[/{self.variable_hidden_color}]' #header_value = f'[{self.value_unmodified_color}]Valeur par défaut[/{self.value_unmodified_color}]\n' #header_value += 'Valeur modifiée\n' #header_value += f'([{self.value_default_color}]Valeur par défaut originale[/{self.value_default_color}])' header_value = f'[{self.value_unmodified_color}]{_("Default value")}[/{self.value_unmodified_color}]\n' header_value += _('Modified value') + '\n' header_value += f'([{self.value_default_color}]{_("Original default value")}[/{self.value_default_color}])' header = Table.grid(padding=1, collapse_padding=True) header.pad_edge = False header.add_row(header_variable, header_value) self.out.append(Panel.fit(header, title=_("Caption"))) def errors(self, errors, ) -> None: tree = Tree(":stop_sign: ERRORS", guide_style="bold bright_red", ) for error in errors: tree.add(error) self.out.append(tree) def warnings(self, warnings: list, ) -> None: tree = Tree(":warning: WARNINGS") for warning in warnings: tree.add(warning) self.out.append(tree) def root(self) -> None: self.output = OutputFamily(_("Variables:"), None, self, no_icon=True, ) return self.output def end(self): self.out.append(self.output.tree) def print(self): for out in self.out: self.console.print(out) class OutputFamily: def __init__(self, family, parent, root, *, is_leader: bool=False, no_icon: bool=False ) -> None: if parent is None: tree = Tree else: tree = parent.add if is_leader: self.tree = tree(f":notebook: {family} :", guide_style="bold bright_blue", ) elif no_icon: self.tree = tree(f"{family}", guide_style="bold bright_blue", ) else: self.tree = tree(f":open_file_folder: {family}", guide_style="bold bright_blue", ) self.root = root # # def parse_option(self, # option, # value, # variables, # ): # if '.' in line: # # it's a dict # family, variable = line.split('.', 1) # current_path = parent_path # if current_path: # current_path += '.' # current_path += family # if for_doc: # if 'hidden' in self.conf.option(current_path).property.get() or family_hidden: # family_hidden = True # family = f'[orange1]{family}[/orange1]' # elif 'advanced' in self.conf.option(current_path).property.get(): # family = f'[bright_blue]{family}[/bright_blue]' # if '.' not in variable and self.conf.option(full_path.rsplit('.', 1)[0]).isleadership(): # dico.setdefault(family, []) # leadership = True # else: # dico.setdefault(family, {}) # leadership = False # self.parse_option(full_path, # variable, # value, # ) # elif leadership: # # it's a leadership # for idx, val in enumerate(value): # dic = {k.rsplit('.', 1)[-1]: v for k, v in val.items()} # if for_doc: # leader = True # for k, v in val.items(): # if leader: # is_default = self.conf.option(k).owner.isdefault() # properties = self.conf.option(k).property.get() # else: # is_default = self.conf.option(k, idx).owner.isdefault() # properties = self.conf.option(k, idx).property.get() # if self.conf.option(k).type() == _('password') and not self.args.show_secrets: # v = "*" * 10 # subpath = k.rsplit('.', 1)[-1] # if 'hidden' in properties or family_hidden: # subpath = f'[orange1]{subpath}[/orange1]' # elif 'advanced' in properties: # if isdefault: # subpath = f'[bright_blue]{subpath}[/bright_blue]' # else: # subpath = f'[red1]{subpath}[/red1]' # if is_default: # v = '[gold1]' + str(v) + '[/gold1]' # dico.append(f'{subpath}: {v}') # leader = False # else: # dico.append(dic) # else: # # it's a variable # self.parse_variable(option, value) # def add_family(self, option, ) -> None: properties = option.property.get() if 'hidden' in properties: color = self.root.variable_hidden_color elif 'advanced' in properties: color = self.root.variable_advanced_color else: color = None return OutputFamily(self.colorize(None, option.name(), color, None, ), self.tree, self.root, ) def add_variable(self, option, value: Any=undefined, leader_index: Optional[int]=None ): properties = option.property.get() variable_color = None if option.owner.isdefault(): if 'hidden' in properties: variable_color = self.root.variable_hidden_color elif 'advanced' in properties: variable_color = self.root.variable_advanced_color color = self.root.value_unmodified_color default_value = None else: if 'hidden' in properties: variable_color = self.root.variable_hidden_color elif 'advanced' in properties: variable_color = self.root.variable_advanced_and_modified_color color = None default_value = option.value.default() if leader_index is not None and len(default_value) > leader_index: default_value = default_value[leader_index] if value is undefined: value = option.value.get() key = self.colorize(None, option.name(), variable_color, None, ) value = self.colorize(option, value, color, default_value, ) if isinstance(value, list): subtree = self.tree.add(f":notebook: {key} :", guide_style="bold bright_blue", ) for val in value: subtree.add(str(val)) else: self.tree.add(f":notebook: {key}: {value}") def colorize(self, option, value, color: str, default_value, ) -> str: if isinstance(value, list): if default_value is None: default_value = [] len_value = len(value) len_default_value = len(default_value) len_values = max(len_value, len_default_value) ret = [] for idx in range(len_values): if idx < len_value: val = value[idx] else: val = '' if idx < len_default_value: if val: val += ' ' default = default_value[idx] else: default = None ret.append(self.colorize(option, val, color, default, )) return ret if option and value is not None: value = self.convert_value(option, value, ) else: value = str(value) if color is not None: ret = f'[{color}]{value}[/{color}]' else: ret = value if default_value and 'force_store_value' not in option.property.get(): default_value_color = self.root.value_default_color ret += f' ([{default_value_color}]{default_value}[/{default_value_color}])' return ret def convert_value(self, option, value, ): if not self.root.show_secrets and option.type() == 'password': return "*" * 10 return str(value)