2024-11-15 08:13:45 +01:00
|
|
|
"""
|
|
|
|
|
Silique (https://www.silique.fr)
|
2025-02-10 09:52:12 +01:00
|
|
|
Copyright (C) 2024-2025
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
"""
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
from typing import Tuple, List, Optional
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
from io import BytesIO
|
|
|
|
|
from ruamel.yaml import YAML
|
|
|
|
|
import tabulate as tabulate_module
|
|
|
|
|
from tabulate import tabulate
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
from rougail.tiramisu import normalize_family
|
|
|
|
|
from tiramisu import undefined
|
2025-11-27 22:17:17 +01:00
|
|
|
from tiramisu.error import PropertiesOptionError, display_list
|
|
|
|
|
try:
|
|
|
|
|
from tiramisu_cmdline_parser.api import gen_argument_name
|
|
|
|
|
except:
|
|
|
|
|
gen_argument_name = None
|
2025-10-14 12:58:39 +02:00
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
from .i18n import _
|
2025-11-29 22:21:06 +01:00
|
|
|
from .config import Tables, ROUGAIL_VARIABLE_TYPE
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
ENTER = "\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_yaml = YAML()
|
|
|
|
|
_yaml.indent(mapping=2, sequence=4, offset=2)
|
|
|
|
|
|
|
|
|
|
|
2025-03-02 13:38:14 +01:00
|
|
|
def dump(informations):
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Dump variable, means transform bool, ... to yaml string"""
|
|
|
|
|
with BytesIO() as ymlfh:
|
2025-03-02 13:38:14 +01:00
|
|
|
_yaml.dump(informations, ymlfh)
|
2024-11-15 08:13:45 +01:00
|
|
|
ret = ymlfh.getvalue().decode("utf-8").strip()
|
|
|
|
|
if ret.endswith("..."):
|
|
|
|
|
ret = ret[:-3].strip()
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
def to_phrase(msg, type_="variable"):
|
2025-10-15 09:44:22 +02:00
|
|
|
"""Add maj for the first character and ends with dot"""
|
2024-11-15 08:13:45 +01:00
|
|
|
if not msg:
|
|
|
|
|
# replace None to empty string
|
|
|
|
|
return ""
|
|
|
|
|
msg = str(msg).strip()
|
|
|
|
|
# a phrase must ends with a dot
|
2025-10-15 09:44:22 +02:00
|
|
|
if type_ == "variable":
|
2025-10-14 12:58:39 +02:00
|
|
|
if not msg.endswith("."):
|
|
|
|
|
msg += "."
|
2025-10-29 10:46:57 +01:00
|
|
|
elif type_ in ["family", "description"]:
|
2025-10-14 12:58:39 +02:00
|
|
|
if msg.endswith("."):
|
|
|
|
|
msg = msg[:-1]
|
|
|
|
|
else:
|
2025-10-15 09:44:22 +02:00
|
|
|
raise Exception("unknown type")
|
2024-11-15 08:13:45 +01:00
|
|
|
# and start with a maj
|
|
|
|
|
return msg[0].upper() + msg[1:]
|
|
|
|
|
|
|
|
|
|
|
2025-11-29 22:21:06 +01:00
|
|
|
class CommonTable:
|
|
|
|
|
"""Class with common function for table"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, formatter: "CommonFormatter") -> None:
|
|
|
|
|
self.formatter = formatter
|
|
|
|
|
self.clear()
|
|
|
|
|
|
|
|
|
|
def clear(self):
|
|
|
|
|
self.columns = []
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
columns = self.get_columns()
|
|
|
|
|
self.clear()
|
|
|
|
|
return columns
|
|
|
|
|
|
|
|
|
|
def add(self, informations: dict, modified_attributes: dict, force_identifiers: Optional[str]) -> tuple:
|
|
|
|
|
self.informations = informations
|
|
|
|
|
self.modified_attributes = modified_attributes
|
|
|
|
|
self.force_identifiers = force_identifiers
|
|
|
|
|
self.calculated_properties = []
|
|
|
|
|
self.set_description()
|
|
|
|
|
self.set_type()
|
|
|
|
|
self.set_choices()
|
|
|
|
|
self.set_properties()
|
|
|
|
|
self.set_default()
|
|
|
|
|
self.set_examples()
|
|
|
|
|
self.set_paths()
|
|
|
|
|
self.set_commandline()
|
|
|
|
|
self.set_environment()
|
|
|
|
|
self.set_validators()
|
|
|
|
|
self.set_tags()
|
|
|
|
|
self.columns.append(self._add())
|
|
|
|
|
|
|
|
|
|
def set_description(self):
|
|
|
|
|
if "description" in self.informations:
|
|
|
|
|
self.description = self.formatter.get_description(
|
|
|
|
|
"variable", self.informations, self.modified_attributes, self.force_identifiers,
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
self.description = None
|
|
|
|
|
self.help_ = self.formatter.convert_list_to_string("help", self.informations, self.modified_attributes)
|
|
|
|
|
|
|
|
|
|
def set_choices(self):
|
|
|
|
|
self.default_is_already_set, self.choices = self.formatter.convert_choices_to_string(
|
|
|
|
|
self.informations, self.modified_attributes
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def set_type(self):
|
|
|
|
|
self.multi = self.informations.get("multiple", True)
|
|
|
|
|
self.type = self.informations["variable_type"]
|
|
|
|
|
|
|
|
|
|
def set_default(self):
|
|
|
|
|
if "default" in self.informations:
|
|
|
|
|
self.default = self.formatter.convert_section_to_string(
|
|
|
|
|
"default", self.informations, self.modified_attributes, multi=self.multi
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
self.default = None
|
|
|
|
|
|
|
|
|
|
def set_examples(self):
|
|
|
|
|
self.examples = self.formatter.convert_section_to_string(
|
|
|
|
|
"examples", self.informations, self.modified_attributes, multi=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def set_paths(self):
|
|
|
|
|
self.paths = self.formatter.join(self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True))
|
|
|
|
|
|
|
|
|
|
def set_commandline(self):
|
|
|
|
|
if self.formatter.with_commandline and not self.informations.get('not_for_commandline', False):
|
|
|
|
|
commandlines = self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True, is_bold=False, variable_prefix="--")
|
|
|
|
|
if self.type == 'boolean':
|
|
|
|
|
for path in list(commandlines):
|
|
|
|
|
commandlines.append("--" + gen_argument_name(path[2:], False, True, False))
|
|
|
|
|
if "alternative_name" in self.informations:
|
|
|
|
|
alternative_name = self.informations["alternative_name"]
|
|
|
|
|
commandlines[0] = f"-{alternative_name}, {commandlines[0]}"
|
|
|
|
|
if self.type == 'boolean':
|
|
|
|
|
commandlines[1] = "-" + gen_argument_name(alternative_name, True, True, False) + f", {commandlines[1]}"
|
|
|
|
|
self.commandlines = self.formatter.section(_("Command line"), commandlines)
|
|
|
|
|
else:
|
|
|
|
|
self.commandlines = None
|
|
|
|
|
|
|
|
|
|
def set_environment(self):
|
|
|
|
|
if self.formatter.with_environment:
|
|
|
|
|
environments = self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True, is_bold=False, is_upper=True, variable_prefix=self.formatter.prefix)
|
|
|
|
|
self.environments = self.formatter.section(_("Environment variable"), environments)
|
|
|
|
|
else:
|
|
|
|
|
self.environments = None
|
|
|
|
|
|
|
|
|
|
def set_properties(self):
|
|
|
|
|
self.properties = self.formatter.property_to_string(
|
|
|
|
|
self.informations, self.calculated_properties, self.modified_attributes,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def set_validators(self):
|
|
|
|
|
self.validators = self.formatter.convert_section_to_string(
|
|
|
|
|
"validators", self.informations, self.modified_attributes, multi=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def set_tags(self):
|
|
|
|
|
self.tags = self.formatter.convert_section_to_string(
|
|
|
|
|
"tags", self.informations, self.modified_attributes, multi=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def get_column(self, *args):
|
|
|
|
|
contents = [arg for arg in args if arg]
|
|
|
|
|
self.formatter.columns(contents)
|
|
|
|
|
return self.formatter.join(contents)
|
|
|
|
|
|
|
|
|
|
|
2025-10-27 21:59:39 +01:00
|
|
|
class CommonFormatter:
|
|
|
|
|
"""Class with common function for formatter"""
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
enter_table = "\n"
|
|
|
|
|
# tabulate module name
|
|
|
|
|
name = None
|
|
|
|
|
|
2025-11-29 07:59:33 +01:00
|
|
|
def __init__(self, rougailconfig, support_namespace, **kwargs):
|
2024-11-15 08:13:45 +01:00
|
|
|
tabulate_module.PRESERVE_WHITESPACE = True
|
|
|
|
|
self.header_setted = False
|
2025-10-30 21:14:34 +01:00
|
|
|
self.rougailconfig = rougailconfig
|
2025-11-27 22:17:17 +01:00
|
|
|
self.support_namespace = support_namespace
|
2025-10-30 21:14:34 +01:00
|
|
|
|
|
|
|
|
def run(
|
|
|
|
|
self, informations: dict, *, dico_is_already_treated=False
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Transform to string"""
|
|
|
|
|
if informations:
|
|
|
|
|
level = self.rougailconfig["doc.title_level"]
|
|
|
|
|
self.options()
|
|
|
|
|
if self.root:
|
|
|
|
|
current = informations
|
|
|
|
|
for path in self.root.split('.'):
|
2025-11-27 22:17:17 +01:00
|
|
|
info = current[path]['informations']
|
2025-10-30 21:14:34 +01:00
|
|
|
current = current[path]["children"]
|
2025-11-27 22:17:17 +01:00
|
|
|
informations = {"informations": info, "children": current}
|
2025-10-30 21:14:34 +01:00
|
|
|
return self._run(informations, level, dico_is_already_treated)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def options(self):
|
2025-11-27 22:17:17 +01:00
|
|
|
self.with_commandline = self.rougailconfig["doc.with_commandline"]
|
|
|
|
|
self.with_environment = self.rougailconfig["doc.with_environment"]
|
|
|
|
|
if self.with_environment and not gen_argument_name:
|
|
|
|
|
raise Exception('please install tiramisu_cmdline_parser')
|
|
|
|
|
if not self.rougailconfig["main_namespace"] and self.with_environment:
|
|
|
|
|
if self.support_namespace:
|
|
|
|
|
self.prefix = ""
|
|
|
|
|
else:
|
|
|
|
|
self.prefix = self.rougailconfig["doc.environment_default_environment_name"] + "_"
|
2025-10-30 21:14:34 +01:00
|
|
|
self.with_family = not self.rougailconfig["doc.without_family"]
|
|
|
|
|
self.root = self.rougailconfig["doc.root"]
|
|
|
|
|
self.other_root_filenames = None
|
|
|
|
|
if self.root:
|
|
|
|
|
try:
|
|
|
|
|
other_root_filenames = self.rougailconfig["doc.other_root_filenames"]
|
|
|
|
|
except PropertiesOptionError:
|
|
|
|
|
pass
|
|
|
|
|
else:
|
|
|
|
|
if other_root_filenames:
|
|
|
|
|
self.other_root_filenames = dict(zip(other_root_filenames["root_path"], other_root_filenames["filename"]))
|
2025-11-29 22:21:06 +01:00
|
|
|
table_model = self.rougailconfig["doc.table_model"]
|
|
|
|
|
self.table_datas = Tables().get()[table_model](self)
|
2025-10-30 21:14:34 +01:00
|
|
|
|
|
|
|
|
def compute(self, data):
|
|
|
|
|
return "".join([d for d in data if d])
|
2024-11-15 08:13:45 +01:00
|
|
|
|
2025-10-27 21:59:39 +01:00
|
|
|
# Class you needs implement to your Formatter
|
2024-11-15 08:13:45 +01:00
|
|
|
def title(
|
|
|
|
|
self,
|
|
|
|
|
title: str,
|
|
|
|
|
level: int,
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Display family name as a title"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def join(
|
|
|
|
|
self,
|
|
|
|
|
lst: List[str],
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Display line in table from a list"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def bold(
|
|
|
|
|
self,
|
|
|
|
|
msg: str,
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Set a text to bold"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
2025-10-29 10:46:57 +01:00
|
|
|
def underline(
|
|
|
|
|
self,
|
|
|
|
|
msg: str,
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Set a text to underline"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def anchor(self,
|
|
|
|
|
path: str,
|
|
|
|
|
true_path: str,
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Set a text to a link anchor"""
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
def link_variable(self,
|
|
|
|
|
path: str,
|
2025-11-17 09:50:28 +01:00
|
|
|
true_path: str,
|
2025-10-29 10:46:57 +01:00
|
|
|
description: str,
|
|
|
|
|
filename: Optional[str],
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Set a text link to variable anchor"""
|
|
|
|
|
return path
|
|
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
def stripped(
|
|
|
|
|
self,
|
|
|
|
|
text: str,
|
|
|
|
|
) -> str:
|
|
|
|
|
"""Return stripped text (as help)"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def list(
|
|
|
|
|
self,
|
|
|
|
|
choices: list,
|
2025-11-12 19:33:56 +01:00
|
|
|
*,
|
2025-10-27 21:59:39 +01:00
|
|
|
inside_table: bool=True,
|
2025-11-12 19:33:56 +01:00
|
|
|
type_: str="variable",
|
2024-11-15 08:13:45 +01:00
|
|
|
) -> str:
|
|
|
|
|
"""Display a liste of element"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def prop(
|
|
|
|
|
self,
|
|
|
|
|
prop: str,
|
|
|
|
|
italic: bool,
|
2025-11-05 21:43:10 +01:00
|
|
|
delete: bool,
|
|
|
|
|
underline: bool,
|
2024-11-15 08:13:45 +01:00
|
|
|
) -> str:
|
|
|
|
|
"""Display property"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
def link(
|
|
|
|
|
self,
|
|
|
|
|
comment: str,
|
|
|
|
|
link: str,
|
2025-11-05 21:43:10 +01:00
|
|
|
underline: bool,
|
2024-11-15 08:13:45 +01:00
|
|
|
) -> str:
|
|
|
|
|
"""Add a link"""
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
##################
|
|
|
|
|
|
2025-10-02 08:19:18 +02:00
|
|
|
def family_informations(self) -> str:
|
2025-10-15 09:44:22 +02:00
|
|
|
return ""
|
2025-10-02 08:19:18 +02:00
|
|
|
|
|
|
|
|
def end_family_informations(self) -> str:
|
2025-11-10 14:01:45 +01:00
|
|
|
return ENTER
|
2025-10-02 08:19:18 +02:00
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
def display_paths(
|
2025-10-02 08:19:18 +02:00
|
|
|
self,
|
2025-10-14 12:58:39 +02:00
|
|
|
informations: dict,
|
|
|
|
|
modified_attributes: dict,
|
2025-10-15 09:53:54 +02:00
|
|
|
force_identifiers: Optional[str],
|
2025-10-29 10:46:57 +01:00
|
|
|
*,
|
2025-11-27 22:17:17 +01:00
|
|
|
is_variable=False,
|
|
|
|
|
variable_prefix: str="",
|
|
|
|
|
is_bold: bool=True,
|
|
|
|
|
is_upper: bool=False,
|
2025-10-02 08:19:18 +02:00
|
|
|
) -> str:
|
2025-10-14 12:58:39 +02:00
|
|
|
ret_paths = []
|
|
|
|
|
path = informations["path"]
|
2025-11-27 22:17:17 +01:00
|
|
|
if is_bold:
|
|
|
|
|
bold = self.bold
|
|
|
|
|
else:
|
|
|
|
|
def bold(value):
|
|
|
|
|
return value
|
|
|
|
|
if is_upper:
|
|
|
|
|
def upper(value):
|
|
|
|
|
return value.upper()
|
|
|
|
|
else:
|
|
|
|
|
def upper(value):
|
|
|
|
|
return value
|
2025-10-14 12:58:39 +02:00
|
|
|
if "identifiers" in modified_attributes:
|
|
|
|
|
name, previous, new = modified_attributes["identifiers"]
|
2025-10-15 09:44:22 +02:00
|
|
|
ret_paths.extend(
|
|
|
|
|
[
|
2025-11-27 22:17:17 +01:00
|
|
|
bold(self.delete(upper(variable_prefix + calc_path(path, self, identifier))))
|
2025-10-15 09:44:22 +02:00
|
|
|
for identifier in previous
|
|
|
|
|
]
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
|
|
|
|
new = []
|
|
|
|
|
if "identifiers" in informations:
|
2025-10-29 10:46:57 +01:00
|
|
|
for idx, identifier in enumerate(informations["identifiers"]):
|
2025-10-15 09:53:54 +02:00
|
|
|
if force_identifiers and identifier != force_identifiers:
|
|
|
|
|
continue
|
2025-10-14 12:58:39 +02:00
|
|
|
path_ = calc_path(path, self, identifier)
|
2025-11-27 22:17:17 +01:00
|
|
|
if variable_prefix:
|
|
|
|
|
path_ = variable_prefix + upper(path_)
|
2025-10-29 10:46:57 +01:00
|
|
|
if not idx:
|
|
|
|
|
path_ = self.anchor(path_, path)
|
2025-10-14 12:58:39 +02:00
|
|
|
if identifier in new:
|
|
|
|
|
path_ = self.underline(path_)
|
2025-11-27 22:17:17 +01:00
|
|
|
ret_paths.append(bold(path_))
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
2025-11-27 22:17:17 +01:00
|
|
|
ret_paths.append(bold(self.anchor(variable_prefix + upper(path), path)))
|
2025-10-14 12:58:39 +02:00
|
|
|
return ret_paths
|
2025-10-02 08:19:18 +02:00
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
def table_header(
|
|
|
|
|
self,
|
|
|
|
|
lst: list,
|
|
|
|
|
) -> tuple:
|
|
|
|
|
"""Manage the header of a table"""
|
|
|
|
|
return lst
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
def _run(self, dico: dict, level: int, dico_is_already_treated: bool) -> str:
|
|
|
|
|
"""Parse the dict to transform to dict"""
|
|
|
|
|
if dico_is_already_treated:
|
|
|
|
|
return "".join(dico)
|
|
|
|
|
return "".join([msg for msg in self.dict_to_dict(dico, level, init=True)])
|
|
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def dict_to_dict(
|
|
|
|
|
self,
|
|
|
|
|
dico: dict,
|
|
|
|
|
level: int,
|
|
|
|
|
*,
|
|
|
|
|
init: bool = False,
|
|
|
|
|
) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Parse the dict to transform to dict"""
|
2025-03-29 15:10:03 +01:00
|
|
|
msg = []
|
2025-02-19 08:39:44 +01:00
|
|
|
ori_level = None
|
2025-11-27 22:17:17 +01:00
|
|
|
if init and self.root:
|
|
|
|
|
if self.with_family:
|
|
|
|
|
msg.extend(self.family_to_string(dico["informations"], level, False))
|
|
|
|
|
dico = dico["children"]
|
2025-03-29 15:10:03 +01:00
|
|
|
for value in dico.values():
|
2025-10-14 12:58:39 +02:00
|
|
|
if value["type"] == "variable":
|
2025-11-29 22:21:06 +01:00
|
|
|
self.variable_to_string(value)
|
|
|
|
|
elif self.with_family:
|
|
|
|
|
if value["type"] == "namespace":
|
|
|
|
|
namespace = ori_level is None
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-11-29 22:21:06 +01:00
|
|
|
namespace = False
|
|
|
|
|
if self.table_datas.columns:
|
|
|
|
|
msg.append(self.table())
|
|
|
|
|
msg.extend(self.family_to_string(value["informations"], level, namespace))
|
|
|
|
|
msg.extend(self.dict_to_dict(value["children"], level + 1))
|
|
|
|
|
msg.append(self.end_family(level))
|
|
|
|
|
else:
|
|
|
|
|
self.dict_to_dict(
|
|
|
|
|
value["children"], level + 1,
|
|
|
|
|
)
|
|
|
|
|
if self.table_datas.columns and (init or self.with_family):
|
|
|
|
|
msg.append(self.table())
|
2024-11-15 08:13:45 +01:00
|
|
|
return msg
|
|
|
|
|
|
|
|
|
|
# FAMILY
|
2025-03-29 15:10:03 +01:00
|
|
|
def namespace_to_title(self, informations: dict, level: int) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""manage namespace family"""
|
|
|
|
|
return self.title(
|
2025-11-12 19:33:56 +01:00
|
|
|
self.get_description("family", informations, {}, None),
|
2025-03-02 13:38:14 +01:00
|
|
|
level,
|
2024-11-15 08:13:45 +01:00
|
|
|
)
|
|
|
|
|
|
2025-11-12 19:33:56 +01:00
|
|
|
def family_to_string(self, informations: dict, level: int, namespace: bool) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""manage other family type"""
|
2025-11-12 19:33:56 +01:00
|
|
|
if namespace:
|
|
|
|
|
ret = [self.namespace_to_title(informations, level)]
|
|
|
|
|
else:
|
|
|
|
|
ret = [self.title(self.get_description("family", informations, {}, None), level)]
|
2025-11-10 14:01:45 +01:00
|
|
|
fam_info = self.family_informations()
|
|
|
|
|
if fam_info:
|
2025-11-12 19:33:56 +01:00
|
|
|
ret.append(fam_info)
|
|
|
|
|
msg = self.display_paths(informations, {}, None)
|
2025-03-02 13:38:14 +01:00
|
|
|
helps = informations.get("help")
|
2024-11-15 08:13:45 +01:00
|
|
|
if helps:
|
|
|
|
|
for help_ in helps:
|
2025-11-10 14:01:45 +01:00
|
|
|
msg.append(to_phrase(help_.strip()))
|
2025-10-02 08:19:18 +02:00
|
|
|
calculated_properties = []
|
2025-11-29 22:21:06 +01:00
|
|
|
property_str = self.property_to_string(informations, calculated_properties, {})
|
2025-11-10 14:01:45 +01:00
|
|
|
if property_str:
|
|
|
|
|
msg.append(property_str)
|
2025-10-02 08:19:18 +02:00
|
|
|
if calculated_properties:
|
2025-11-12 19:33:56 +01:00
|
|
|
msg.append(self.join(calculated_properties)
|
2025-10-15 09:44:22 +02:00
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
if "identifier" in informations:
|
2025-05-11 19:13:12 +02:00
|
|
|
msg.append(
|
2025-11-12 19:33:56 +01:00
|
|
|
self.section(_("Identifiers"), informations["identifier"], type_="family")
|
2025-05-11 19:13:12 +02:00
|
|
|
)
|
2025-11-12 19:33:56 +01:00
|
|
|
starts_line = self.family_informations_starts_line()
|
|
|
|
|
ret.append(self.family_informations_ends_line().join([starts_line + m for m in msg]) + self.end_family_informations())
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
def family_informations_starts_line(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def family_informations_ends_line(self) -> str:
|
|
|
|
|
return ENTER
|
2024-11-15 08:13:45 +01:00
|
|
|
|
2025-10-02 22:18:22 +02:00
|
|
|
def end_family(self, level: int) -> str:
|
2025-10-15 09:44:22 +02:00
|
|
|
return ""
|
2025-10-02 08:19:18 +02:00
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def convert_list_to_string(
|
|
|
|
|
self, attribute: str, informations: dict, modified_attributes: dict
|
|
|
|
|
) -> str():
|
2025-10-14 12:58:39 +02:00
|
|
|
datas = []
|
|
|
|
|
if attribute in modified_attributes:
|
|
|
|
|
name, previous, new = modified_attributes[attribute]
|
|
|
|
|
for data in previous:
|
|
|
|
|
datas.append(self.delete(self.to_phrase(data)))
|
|
|
|
|
else:
|
|
|
|
|
new = []
|
|
|
|
|
if attribute in informations:
|
|
|
|
|
for data in informations[attribute]:
|
|
|
|
|
if isinstance(data, dict):
|
2025-10-15 09:44:22 +02:00
|
|
|
if attribute.endswith("s"):
|
2025-10-14 12:58:39 +02:00
|
|
|
attr = attribute[:-1]
|
|
|
|
|
else:
|
|
|
|
|
attr = attribute
|
2025-10-15 09:44:22 +02:00
|
|
|
data = data[attr].replace(
|
|
|
|
|
"{{ identifier }}", self.italic(data["identifier"])
|
|
|
|
|
)
|
2025-10-14 13:50:02 +02:00
|
|
|
data = self.to_phrase(data)
|
2025-10-14 12:58:39 +02:00
|
|
|
if data in new:
|
|
|
|
|
data = self.underline(data)
|
2025-10-14 13:50:02 +02:00
|
|
|
datas.append(data)
|
2025-10-14 12:58:39 +02:00
|
|
|
return self.stripped(self.join(datas))
|
|
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def get_description(
|
2025-10-15 09:53:54 +02:00
|
|
|
self, type_: str, informations: dict, modified_attributes: dict, force_identifiers: Optional[str]
|
2025-10-15 09:44:22 +02:00
|
|
|
) -> str():
|
2025-10-14 12:58:39 +02:00
|
|
|
def _get_description(description, identifiers, delete=False, new=[]):
|
2025-11-05 21:43:10 +01:00
|
|
|
if identifiers and "{{ identifier }}" in description:
|
2025-10-14 12:58:39 +02:00
|
|
|
if type_ == "variable":
|
2025-10-15 09:44:22 +02:00
|
|
|
identifiers_text = display_list(
|
2025-10-15 09:53:54 +02:00
|
|
|
[self.italic(i[-1]) for i in identifiers if not force_identifiers or i == force_identifiers], separator="or"
|
2025-10-15 09:44:22 +02:00
|
|
|
)
|
|
|
|
|
description = description.replace(
|
|
|
|
|
"{{ identifier }}", identifiers_text
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
|
|
|
|
d = []
|
|
|
|
|
for i in identifiers:
|
2025-10-15 09:53:54 +02:00
|
|
|
if force_identifiers and i != force_identifiers:
|
|
|
|
|
continue
|
2025-10-15 09:44:22 +02:00
|
|
|
new_description = description.replace(
|
|
|
|
|
"{{ identifier }}", self.italic(i[-1])
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
if new_description not in d:
|
|
|
|
|
d.append(self.to_phrase(new_description))
|
|
|
|
|
description = display_list(d, separator="or")
|
|
|
|
|
else:
|
|
|
|
|
description = self.to_phrase(description)
|
|
|
|
|
if description in new:
|
|
|
|
|
description = self.underline(description)
|
|
|
|
|
if delete:
|
|
|
|
|
description = self.delete(description)
|
|
|
|
|
return description
|
2025-10-15 09:44:22 +02:00
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
if "description" in modified_attributes:
|
|
|
|
|
name, previous, new = modified_attributes["description"]
|
2025-11-05 21:43:10 +01:00
|
|
|
if previous:
|
|
|
|
|
modified_description = _get_description(
|
|
|
|
|
previous[0], modified_attributes.get("identifiers", []), delete=True
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
modified_description = None
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
|
|
|
|
modified_description = None
|
|
|
|
|
new = []
|
2025-10-15 09:44:22 +02:00
|
|
|
description = _get_description(
|
|
|
|
|
informations["description"], informations.get("identifiers"), new=new
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
if modified_description:
|
|
|
|
|
if description:
|
|
|
|
|
description = self.join([modified_description, description])
|
|
|
|
|
else:
|
|
|
|
|
description = modified_description
|
|
|
|
|
if not description:
|
|
|
|
|
return None
|
|
|
|
|
return self.stripped(description)
|
|
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
# VARIABLE
|
2025-10-15 09:44:22 +02:00
|
|
|
def variable_to_string(
|
2025-11-29 22:21:06 +01:00
|
|
|
self, informations: dict, modified_attributes: dict = {}, force_identifiers: Optional[str]=None
|
2025-10-15 09:44:22 +02:00
|
|
|
) -> None:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Manage variable"""
|
2025-11-29 22:21:06 +01:00
|
|
|
self.table_datas.add(informations, modified_attributes, force_identifiers)
|
2025-10-14 12:58:39 +02:00
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def convert_section_to_string(
|
2025-11-29 22:21:06 +01:00
|
|
|
self, attribute: str, informations: dict, modified_attributes: dict, multi: bool, *, section_name: bool = True,
|
2025-10-15 09:44:22 +02:00
|
|
|
) -> str():
|
2025-10-14 12:58:39 +02:00
|
|
|
values = []
|
|
|
|
|
submessage = ""
|
|
|
|
|
if modified_attributes and attribute in modified_attributes:
|
|
|
|
|
name, previous, new = modified_attributes[attribute]
|
|
|
|
|
if isinstance(previous, list):
|
|
|
|
|
for p in previous:
|
|
|
|
|
submessage, m = self.message_to_string(p, submessage)
|
|
|
|
|
values.append(self.delete(m))
|
|
|
|
|
else:
|
|
|
|
|
submessage, old_values = self.message_to_string(previous, submessage)
|
|
|
|
|
values.append(self.delete(old_values))
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-10-14 12:58:39 +02:00
|
|
|
new = []
|
|
|
|
|
if attribute in informations:
|
|
|
|
|
old = informations[attribute]
|
|
|
|
|
name = old["name"]
|
|
|
|
|
if isinstance(old["values"], list):
|
|
|
|
|
for value in old["values"]:
|
|
|
|
|
submessage, old_value = self.message_to_string(value, submessage)
|
|
|
|
|
if value in new:
|
|
|
|
|
old_value = self.underline(old_value)
|
|
|
|
|
values.append(old_value)
|
|
|
|
|
if multi:
|
|
|
|
|
values = self.list(values)
|
|
|
|
|
else:
|
|
|
|
|
values = self.join(values)
|
|
|
|
|
elif values:
|
|
|
|
|
old_values = old["values"]
|
|
|
|
|
submessage, old_values = self.message_to_string(old_values, submessage)
|
|
|
|
|
if old["values"] in new:
|
|
|
|
|
old_values = self.underline(old_values)
|
|
|
|
|
values.append(old_values)
|
|
|
|
|
values = self.join(values)
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-10-14 12:58:39 +02:00
|
|
|
submessage, values = self.message_to_string(old["values"], submessage)
|
|
|
|
|
if old["values"] in new:
|
|
|
|
|
values = self.underline(values)
|
|
|
|
|
if values != []:
|
2025-11-29 22:21:06 +01:00
|
|
|
return self.section(name, values, submessage=submessage, section_name=section_name)
|
2025-10-14 12:58:39 +02:00
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def convert_choices_to_string(
|
2025-11-29 22:21:06 +01:00
|
|
|
self, informations: dict, modified_attributes: dict, with_default: bool = True,
|
2025-10-15 09:44:22 +02:00
|
|
|
) -> str():
|
2025-10-14 12:58:39 +02:00
|
|
|
default_is_already_set = False
|
2025-03-02 13:38:14 +01:00
|
|
|
if "choices" in informations:
|
2025-09-22 09:42:46 +02:00
|
|
|
choices = informations["choices"]
|
2025-10-14 12:58:39 +02:00
|
|
|
choices_values = choices["values"]
|
|
|
|
|
if not isinstance(choices_values, list):
|
|
|
|
|
choices_values = [choices_values]
|
|
|
|
|
default_is_a_list = False
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-10-14 12:58:39 +02:00
|
|
|
default_is_a_list = True
|
2025-10-29 10:46:57 +01:00
|
|
|
for idx, choice in enumerate(choices_values.copy()):
|
|
|
|
|
if isinstance(choice, dict):
|
|
|
|
|
choices_values[idx] = self.message_to_string(choice, None)[1]
|
2025-10-14 12:58:39 +02:00
|
|
|
if "default" in modified_attributes:
|
|
|
|
|
name, old_default, new_default = modified_attributes["default"]
|
|
|
|
|
if not old_default:
|
|
|
|
|
old_default = [None]
|
|
|
|
|
if not isinstance(old_default, list):
|
|
|
|
|
old_default = [old_default]
|
|
|
|
|
for value in old_default.copy():
|
2025-10-15 09:44:22 +02:00
|
|
|
if (
|
|
|
|
|
isinstance(value, str)
|
|
|
|
|
and value.endswith(".")
|
|
|
|
|
and value not in choices_values
|
|
|
|
|
):
|
2025-10-14 12:58:39 +02:00
|
|
|
old_default.remove(value)
|
|
|
|
|
old_default.append(value[:-1])
|
|
|
|
|
else:
|
|
|
|
|
old_default = new_default = []
|
|
|
|
|
# check if all default values are in choices (could be from a calculation)
|
|
|
|
|
if "default" in informations:
|
|
|
|
|
default = informations["default"]["values"]
|
|
|
|
|
else:
|
2025-11-29 07:59:33 +01:00
|
|
|
default = [None]
|
2025-10-14 12:58:39 +02:00
|
|
|
if not isinstance(default, list):
|
|
|
|
|
default = [default]
|
2025-10-29 10:46:57 +01:00
|
|
|
for idx, value in enumerate(default.copy()):
|
|
|
|
|
if isinstance(value, dict):
|
|
|
|
|
default[idx] = self.message_to_string(value, None)[1]
|
2025-10-14 12:58:39 +02:00
|
|
|
default_value_not_in_choices = set(default) - set(choices_values)
|
|
|
|
|
if default_value_not_in_choices:
|
|
|
|
|
default_is_changed = False
|
|
|
|
|
for val in default_value_not_in_choices.copy():
|
2025-10-15 09:44:22 +02:00
|
|
|
if (
|
|
|
|
|
isinstance(val, str)
|
|
|
|
|
and val.endswith(".")
|
|
|
|
|
and val[:-1] in choices_values
|
|
|
|
|
):
|
2025-10-14 12:58:39 +02:00
|
|
|
default.remove(val)
|
|
|
|
|
default.append(val[:-1])
|
|
|
|
|
default_is_changed = True
|
|
|
|
|
if val in new_default:
|
|
|
|
|
new_default.remove(val)
|
|
|
|
|
new_default.append(val[:-1])
|
|
|
|
|
if default_is_changed:
|
|
|
|
|
default_value_not_in_choices = set(default) - set(choices_values)
|
|
|
|
|
if default_value_not_in_choices:
|
|
|
|
|
old_default = []
|
|
|
|
|
new_default = []
|
|
|
|
|
default = []
|
|
|
|
|
else:
|
|
|
|
|
default_is_already_set = True
|
|
|
|
|
if "choices" in modified_attributes:
|
|
|
|
|
name, previous, new = modified_attributes["choices"]
|
|
|
|
|
for choice in reversed(previous):
|
2025-10-29 10:46:57 +01:00
|
|
|
if isinstance(choice, dict):
|
|
|
|
|
choice = self.message_to_string(choice, None)[1]
|
2025-11-29 22:21:06 +01:00
|
|
|
if with_default and choice in old_default:
|
2025-10-15 09:44:22 +02:00
|
|
|
choices_values.insert(
|
|
|
|
|
0, self.delete(dump(choice) + " ← " + _("(default)"))
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
|
|
|
|
choices_values.insert(0, self.delete(dump(choice)))
|
|
|
|
|
else:
|
|
|
|
|
new = []
|
|
|
|
|
for idx, val in enumerate(choices_values):
|
2025-11-29 22:21:06 +01:00
|
|
|
if with_default and val in old_default:
|
2025-10-15 09:44:22 +02:00
|
|
|
choices_values[idx] = (
|
|
|
|
|
dump(val) + " " + self.delete("← " + _("(default)"))
|
|
|
|
|
)
|
2025-11-29 22:21:06 +01:00
|
|
|
elif with_default and val in default:
|
2025-10-14 12:58:39 +02:00
|
|
|
if val in new_default:
|
|
|
|
|
if val in new:
|
2025-10-15 09:44:22 +02:00
|
|
|
choices_values[idx] = self.underline(
|
|
|
|
|
dump(val) + " " + self.bold("← " + _("(default)"))
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
2025-10-15 09:44:22 +02:00
|
|
|
choices_values[idx] = (
|
|
|
|
|
dump(val)
|
|
|
|
|
+ " "
|
|
|
|
|
+ self.underline(self.bold("← " + _("(default)")))
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
2025-10-15 09:44:22 +02:00
|
|
|
choices_values[idx] = (
|
|
|
|
|
dump(val) + " " + self.bold("← " + _("(default)"))
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
elif val in new:
|
|
|
|
|
choices_values[idx] = self.underline(dump(val))
|
|
|
|
|
# if old value and new value is a list, display a list
|
|
|
|
|
if not default_is_a_list and len(choices_values) == 1:
|
|
|
|
|
choices_values = choices_values[0]
|
|
|
|
|
return default_is_already_set, self.section(choices["name"], choices_values)
|
|
|
|
|
return default_is_already_set, None
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
# OTHERs
|
2025-10-14 12:58:39 +02:00
|
|
|
def to_phrase(self, text: str) -> str:
|
|
|
|
|
return text
|
|
|
|
|
|
2025-03-02 13:38:14 +01:00
|
|
|
def property_to_string(
|
2025-10-15 09:44:22 +02:00
|
|
|
self,
|
|
|
|
|
informations: dict,
|
|
|
|
|
calculated_properties: list,
|
|
|
|
|
modified_attributes: dict,
|
2025-11-29 22:21:06 +01:00
|
|
|
contents: str="all"
|
2025-03-02 13:38:14 +01:00
|
|
|
) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Transform properties to string"""
|
|
|
|
|
properties = []
|
2025-11-29 22:21:06 +01:00
|
|
|
modified_properties = []
|
|
|
|
|
if contents in ["all", "type"]:
|
|
|
|
|
if "type" in modified_attributes:
|
|
|
|
|
modified_properties.append(self.prop(modified_attributes["type"], italic=False, delete=True, underline=False))
|
|
|
|
|
if "multi" in modified_attributes:
|
|
|
|
|
modified_properties.append(self.prop("multiple", italic=False, delete=True, underline=False))
|
|
|
|
|
if "properties" in modified_attributes and contents in ["all", "properties"]:
|
|
|
|
|
modified_properties.extend(modified_attributes["properties"])
|
2025-10-14 12:58:39 +02:00
|
|
|
local_calculated_properties = {}
|
2025-11-29 22:21:06 +01:00
|
|
|
if modified_properties:
|
2025-10-15 09:44:22 +02:00
|
|
|
previous, new = self.get_modified_properties(
|
2025-11-29 22:21:06 +01:00
|
|
|
*modified_properties
|
2025-10-15 09:44:22 +02:00
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
for p, annotation in previous.items():
|
|
|
|
|
if p not in new:
|
2025-11-05 21:43:10 +01:00
|
|
|
properties.append(self.prop(p, italic=False, delete=True, underline=False))
|
2025-10-14 12:58:39 +02:00
|
|
|
if annotation is not None:
|
2025-11-21 08:15:00 +01:00
|
|
|
local_calculated_properties[p] = [{"annotation": annotation, "delete": True}]
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
|
|
|
|
previous = new = []
|
2025-11-29 22:21:06 +01:00
|
|
|
others = []
|
|
|
|
|
if contents in ["all", "type"] and "variable_type" in informations:
|
|
|
|
|
others.append({"name": informations["variable_type"]})
|
|
|
|
|
if informations.get("multiple"):
|
|
|
|
|
others.append({"name": "multiple"})
|
|
|
|
|
if contents in ["all", "properties"] and "properties" in informations:
|
|
|
|
|
others.extend(informations["properties"])
|
|
|
|
|
for prop in others:
|
2025-11-05 21:43:10 +01:00
|
|
|
prop_name = prop["name"]
|
|
|
|
|
if prop_name not in previous and prop_name in new:
|
|
|
|
|
underline = True
|
|
|
|
|
else:
|
|
|
|
|
underline = False
|
2025-11-29 22:21:06 +01:00
|
|
|
if "annotation" in prop:
|
|
|
|
|
italic = True
|
|
|
|
|
prop_annotation = prop["annotation"]
|
|
|
|
|
if prop_name in new and (
|
|
|
|
|
prop_name not in previous
|
|
|
|
|
or new[prop_name] != previous[prop_name]
|
|
|
|
|
):
|
|
|
|
|
underline_ = True
|
2025-11-21 08:15:00 +01:00
|
|
|
# prop_annotation = self.underline(prop_annotation)
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-11-29 22:21:06 +01:00
|
|
|
underline_ = False
|
|
|
|
|
local_calculated_properties.setdefault(prop["name"], []).append(
|
|
|
|
|
{"annotation": prop_annotation, "underline": underline_}
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
italic = False
|
|
|
|
|
properties.append(self.prop(prop_name, italic=italic, delete=False, underline=underline))
|
2025-10-14 12:58:39 +02:00
|
|
|
if local_calculated_properties:
|
2025-10-15 09:44:22 +02:00
|
|
|
for (
|
|
|
|
|
calculated_property_name,
|
|
|
|
|
calculated_property,
|
|
|
|
|
) in local_calculated_properties.items():
|
2025-11-21 08:15:00 +01:00
|
|
|
# calculated_property = calculated_property_data["annotation"]
|
|
|
|
|
data = []
|
|
|
|
|
for calc in calculated_property:
|
|
|
|
|
annotation = self.message_to_string(calc["annotation"], None)[1]
|
|
|
|
|
if calc.get("underline", False):
|
|
|
|
|
annotation = self.underline(annotation)
|
|
|
|
|
if calc.get("delete", False):
|
|
|
|
|
annotation = self.delete(annotation)
|
|
|
|
|
data.append(annotation)
|
2025-10-14 12:58:39 +02:00
|
|
|
if len(calculated_property) > 1:
|
2025-11-21 08:15:00 +01:00
|
|
|
calculated_property = self.join(data)
|
2025-10-14 12:58:39 +02:00
|
|
|
else:
|
2025-11-21 08:15:00 +01:00
|
|
|
calculated_property = data[0]
|
2025-10-14 12:58:39 +02:00
|
|
|
calculated_properties.append(
|
2025-10-15 09:44:22 +02:00
|
|
|
self.section(
|
|
|
|
|
calculated_property_name.capitalize(), calculated_property
|
|
|
|
|
)
|
2025-10-14 12:58:39 +02:00
|
|
|
)
|
2024-11-15 08:13:45 +01:00
|
|
|
if not properties:
|
2025-11-29 22:21:06 +01:00
|
|
|
return ""
|
|
|
|
|
return " ".join(properties)
|
2025-10-14 12:58:39 +02:00
|
|
|
|
2025-10-15 09:44:22 +02:00
|
|
|
def get_modified_properties(
|
|
|
|
|
self, previous: List[dict], new: List[dict]
|
|
|
|
|
) -> Tuple[dict, dict]:
|
2025-10-14 12:58:39 +02:00
|
|
|
def modified_properties_parser(dico):
|
|
|
|
|
return {d["name"]: d.get("annotation") for d in dico}
|
2025-10-15 09:44:22 +02:00
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
return modified_properties_parser(previous), modified_properties_parser(new)
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
def columns(
|
|
|
|
|
self,
|
|
|
|
|
col: List[str], # pylint: disable=unused-argument
|
|
|
|
|
) -> None:
|
|
|
|
|
"""Manage column"""
|
|
|
|
|
return
|
|
|
|
|
|
2025-11-29 22:21:06 +01:00
|
|
|
def table(self, with_header: bool = True) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Transform list to a table in string format"""
|
2025-10-14 16:42:39 +02:00
|
|
|
if with_header:
|
2025-11-29 22:21:06 +01:00
|
|
|
headers = self.table_header(self.table_datas.headers())
|
2025-10-14 16:42:39 +02:00
|
|
|
else:
|
|
|
|
|
headers = ()
|
2024-11-15 08:13:45 +01:00
|
|
|
msg = (
|
|
|
|
|
tabulate(
|
2025-11-29 22:21:06 +01:00
|
|
|
self.table_datas.get(),
|
2025-10-14 16:42:39 +02:00
|
|
|
headers=headers,
|
2024-11-20 21:12:56 +01:00
|
|
|
tablefmt=self._table_name,
|
2024-11-15 08:13:45 +01:00
|
|
|
)
|
|
|
|
|
+ "\n\n"
|
|
|
|
|
)
|
|
|
|
|
return msg
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
def message_to_string(self, msg, ret, identifiers=[]):
|
|
|
|
|
if isinstance(msg, dict):
|
|
|
|
|
if "submessage" in msg:
|
|
|
|
|
ret += msg["submessage"]
|
|
|
|
|
msg = msg["values"]
|
|
|
|
|
elif "message" in msg:
|
2025-10-29 10:46:57 +01:00
|
|
|
filename = None
|
|
|
|
|
if self.other_root_filenames:
|
|
|
|
|
path = msg["path"]["path"]
|
|
|
|
|
for root in self.other_root_filenames:
|
|
|
|
|
if path == root or path.startswith(f'{root}.'):
|
|
|
|
|
filename = self.other_root_filenames[root]
|
|
|
|
|
break
|
2025-11-17 15:46:24 +01:00
|
|
|
if "identifiers" in msg["path"]:
|
|
|
|
|
msg["identifiers"] = [msg["path"]["identifiers"]]
|
|
|
|
|
path = self.link_variable(calc_path(msg["path"], self, identifiers), msg["path"]["path"], self.get_description("variable", msg, {}, None), filename=filename)
|
2025-10-14 12:58:39 +02:00
|
|
|
msg = msg["message"].format(path)
|
2025-11-21 08:15:00 +01:00
|
|
|
elif "description" in msg:
|
|
|
|
|
if "variables" in msg:
|
|
|
|
|
paths = []
|
|
|
|
|
for variable in msg["variables"]:
|
|
|
|
|
filename = None
|
|
|
|
|
if self.other_root_filenames:
|
|
|
|
|
path = msg["path"]
|
|
|
|
|
for root in self.other_root_filenames:
|
|
|
|
|
if path == root or path.startswith(f'{root}.'):
|
|
|
|
|
filename = self.other_root_filenames[root]
|
|
|
|
|
break
|
|
|
|
|
identifiers = variable.get("identifiers")
|
|
|
|
|
path = calc_path(variable, self, identifiers)
|
|
|
|
|
paths.append(self.link_variable(path, variable["path"], self.get_description("variable", variable, {}, force_identifiers=identifiers), filename=filename))
|
|
|
|
|
msg = msg["description"].format(*paths)
|
|
|
|
|
else:
|
|
|
|
|
msg = msg["description"]
|
2025-10-14 12:58:39 +02:00
|
|
|
return ret, msg
|
|
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
def section(
|
|
|
|
|
self,
|
|
|
|
|
name: str,
|
|
|
|
|
msg: str,
|
2025-10-14 12:58:39 +02:00
|
|
|
submessage: str = "",
|
2025-11-12 19:33:56 +01:00
|
|
|
type_ = "variable",
|
2025-11-29 22:21:06 +01:00
|
|
|
section_name=True,
|
2024-11-15 08:13:45 +01:00
|
|
|
) -> str:
|
|
|
|
|
"""Return something like Name: msg"""
|
2025-10-14 12:58:39 +02:00
|
|
|
submessage, msg = self.message_to_string(msg, submessage)
|
2024-11-15 08:13:45 +01:00
|
|
|
if isinstance(msg, list):
|
|
|
|
|
if len(msg) == 1:
|
2025-10-16 20:58:39 +02:00
|
|
|
submessage, elt = self.message_to_string(msg[0], submessage)
|
2025-10-18 06:40:23 +02:00
|
|
|
if isinstance(elt, list):
|
2025-11-12 19:33:56 +01:00
|
|
|
submessage += self.list(elt, type_=type_)
|
2025-10-18 06:40:23 +02:00
|
|
|
else:
|
|
|
|
|
submessage += elt
|
2024-11-15 08:13:45 +01:00
|
|
|
else:
|
2025-10-14 12:58:39 +02:00
|
|
|
lst = []
|
|
|
|
|
for p in msg:
|
|
|
|
|
submessage, elt = self.message_to_string(p, submessage)
|
|
|
|
|
lst.append(elt)
|
2025-11-12 19:33:56 +01:00
|
|
|
submessage += self.list(lst, type_=type_)
|
2025-10-16 20:58:39 +02:00
|
|
|
msg = ""
|
2024-11-15 08:13:45 +01:00
|
|
|
if not isinstance(msg, str):
|
2025-10-14 12:58:39 +02:00
|
|
|
submessage += dump(msg)
|
|
|
|
|
else:
|
|
|
|
|
submessage += msg
|
2025-11-29 22:21:06 +01:00
|
|
|
if section_name:
|
|
|
|
|
return _("{0}: {1}").format(self.bold(name), submessage)
|
|
|
|
|
return submessage
|
2025-10-14 12:58:39 +02:00
|
|
|
|
|
|
|
|
|
2025-10-27 21:59:39 +01:00
|
|
|
def calc_path(path, formatter=None, identifiers: List[str] = None) -> str:
|
2025-10-14 12:58:39 +02:00
|
|
|
def _path_with_identifier(path, identifier):
|
|
|
|
|
identifier = normalize_family(str(identifier))
|
2025-10-27 21:59:39 +01:00
|
|
|
if formatter:
|
|
|
|
|
identifier = formatter.italic(identifier)
|
2025-10-15 09:44:22 +02:00
|
|
|
return path.replace("{{ identifier }}", identifier, 1)
|
|
|
|
|
|
2025-10-14 12:58:39 +02:00
|
|
|
if isinstance(path, dict):
|
|
|
|
|
path_ = path["path"]
|
2025-10-29 10:46:57 +01:00
|
|
|
if "identifiers" in path:
|
|
|
|
|
for identifier in path["identifiers"]:
|
|
|
|
|
path_ = _path_with_identifier(path_, identifier)
|
2025-10-14 12:58:39 +02:00
|
|
|
elif identifiers:
|
|
|
|
|
path_ = path
|
|
|
|
|
for identifier in identifiers:
|
|
|
|
|
path_ = _path_with_identifier(path_, identifier)
|
|
|
|
|
else:
|
|
|
|
|
path_ = path
|
|
|
|
|
return path_
|