rougail-output-display/src/rougail/output_display/util.py

277 lines
9.5 KiB
Python
Raw Normal View History

2025-12-02 13:59:33 +01:00
"""
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 <http://www.gnu.org/licenses/>.
"""
from typing import Any, Optional
2025-12-03 21:49:02 +01:00
# from tiramisu import owners
2025-12-02 13:59:33 +01:00
from rougail.utils import undefined
2025-12-03 21:49:02 +01:00
from .i18n import _
2025-12-02 13:59:33 +01:00
class CommonOutput:
def __init__(
self,
2025-12-03 21:49:02 +01:00
rougailconfig,
2025-12-02 13:59:33 +01:00
) -> None:
2025-12-03 21:49:02 +01:00
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
2025-12-02 13:59:33 +01:00
def header(self):
raise NotImplementedError()
2025-12-03 21:49:02 +01:00
#
# 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()
2025-12-02 13:59:33 +01:00
2025-12-03 21:49:02 +01:00
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)
2025-12-02 13:59:33 +01:00
2025-12-03 21:49:02 +01:00
def _parse_error_warning(self, tree, error, display, level, default_color):
2025-12-02 13:59:33 +01:00
if isinstance(error, list):
for err in error:
2025-12-03 21:49:02 +01:00
self._parse_error_warning(tree, err, display, level+1, default_color)
2025-12-02 13:59:33 +01:00
elif isinstance(error, dict):
for key, value in error.items():
if key is None:
# it's variables, no more families
2025-12-03 21:49:02 +01:00
self._parse_error_warning(tree, value, display, level, default_color)
2025-12-02 13:59:33 +01:00
else:
2025-12-03 21:49:02 +01:00
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)
2025-12-02 13:59:33 +01:00
else:
2025-12-03 21:49:02 +01:00
return display(level, tree, error, default_color)
def warning_end(self):
pass
2025-12-02 13:59:33 +01:00
def add_family(
self,
family,
2025-12-03 21:49:02 +01:00
level,
2025-12-02 13:59:33 +01:00
) -> '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,
2025-12-03 21:49:02 +01:00
level + 1,
2025-12-02 13:59:33 +01:00
root_family = self.root_family,
)
2025-12-03 21:49:02 +01:00
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 = ["[]"]
2025-12-02 13:59:33 +01:00
else:
2025-12-03 21:49:02 +01:00
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)
2025-12-02 13:59:33 +01:00
else:
2025-12-03 21:49:02 +01:00
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
2025-12-02 13:59:33 +01:00
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
2025-12-03 21:49:02 +01:00
def end(self):
pass