mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
configpanel: update _ask
This commit is contained in:
parent
2c35dcbb24
commit
7a60703ef5
1 changed files with 51 additions and 44 deletions
|
@ -19,7 +19,6 @@
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import urllib.parse
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import TYPE_CHECKING, Any, Literal, Sequence, Type, Union
|
from typing import TYPE_CHECKING, Any, Literal, Sequence, Type, Union
|
||||||
|
@ -36,19 +35,19 @@ from yunohost.utils.form import (
|
||||||
BaseOption,
|
BaseOption,
|
||||||
BaseReadonlyOption,
|
BaseReadonlyOption,
|
||||||
FileOption,
|
FileOption,
|
||||||
FormModel,
|
|
||||||
OptionsModel,
|
OptionsModel,
|
||||||
OptionType,
|
OptionType,
|
||||||
Translation,
|
Translation,
|
||||||
ask_questions_and_parse_answers,
|
|
||||||
build_form,
|
build_form,
|
||||||
evaluate_simple_js_expression,
|
evaluate_simple_js_expression,
|
||||||
parse_prefilled_values,
|
parse_prefilled_values,
|
||||||
|
prompt_or_validate_form,
|
||||||
)
|
)
|
||||||
from yunohost.utils.i18n import _value_for_locale
|
from yunohost.utils.i18n import _value_for_locale
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from pydantic.fields import ModelField
|
from pydantic.fields import ModelField
|
||||||
|
from yunohost.utils.form import FormModel, Hooks
|
||||||
|
|
||||||
logger = getLogger("yunohost.configpanel")
|
logger = getLogger("yunohost.configpanel")
|
||||||
|
|
||||||
|
@ -279,7 +278,8 @@ class ConfigPanel:
|
||||||
save_mode = "full"
|
save_mode = "full"
|
||||||
filter_key: "FilterKey" = (None, None, None)
|
filter_key: "FilterKey" = (None, None, None)
|
||||||
config: Union[ConfigPanelModel, None] = None
|
config: Union[ConfigPanelModel, None] = None
|
||||||
form: Union[FormModel, None] = None
|
form: Union["FormModel", None] = None
|
||||||
|
hooks: "Hooks" = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list(cls):
|
def list(cls):
|
||||||
|
@ -602,7 +602,7 @@ class ConfigPanel:
|
||||||
|
|
||||||
def _get_config_panel(
|
def _get_config_panel(
|
||||||
self, prevalidate: bool = False
|
self, prevalidate: bool = False
|
||||||
) -> tuple[ConfigPanelModel, FormModel]:
|
) -> tuple[ConfigPanelModel, "FormModel"]:
|
||||||
raw_config = self._get_partial_raw_config()
|
raw_config = self._get_partial_raw_config()
|
||||||
config = ConfigPanelModel(**raw_config)
|
config = ConfigPanelModel(**raw_config)
|
||||||
config, raw_settings = self._get_partial_raw_settings_and_mutate_config(config)
|
config, raw_settings = self._get_partial_raw_settings_and_mutate_config(config)
|
||||||
|
@ -623,58 +623,62 @@ class ConfigPanel:
|
||||||
|
|
||||||
return (config, settings)
|
return (config, settings)
|
||||||
|
|
||||||
def _ask(self, action=None):
|
def ask(
|
||||||
|
self,
|
||||||
|
config: ConfigPanelModel,
|
||||||
|
settings: "FormModel",
|
||||||
|
prefilled_answers: dict[str, Any] = {},
|
||||||
|
action_id: Union[str, None] = None,
|
||||||
|
hooks: "Hooks" = {},
|
||||||
|
) -> "FormModel":
|
||||||
|
# FIXME could be turned into a staticmethod
|
||||||
logger.debug("Ask unanswered question and prevalidate data")
|
logger.debug("Ask unanswered question and prevalidate data")
|
||||||
|
|
||||||
if "i18n" in self.config:
|
interactive = Moulinette.interface.type == "cli" and os.isatty(1)
|
||||||
for panel, section, option in self._iterate():
|
|
||||||
if "ask" not in option:
|
|
||||||
option["ask"] = m18n.n(self.config["i18n"] + "_" + option["id"])
|
|
||||||
# auto add i18n help text if present in locales
|
|
||||||
if m18n.key_exists(self.config["i18n"] + "_" + option["id"] + "_help"):
|
|
||||||
option["help"] = m18n.n(
|
|
||||||
self.config["i18n"] + "_" + option["id"] + "_help"
|
|
||||||
)
|
|
||||||
|
|
||||||
def display_header(message):
|
if interactive:
|
||||||
"""CLI panel/section header display"""
|
config.translate()
|
||||||
if Moulinette.interface.type == "cli" and self.filter_key.count(".") < 2:
|
|
||||||
Moulinette.display(colorize(message, "purple"))
|
|
||||||
|
|
||||||
for panel, section, obj in self._iterate(["panel", "section"]):
|
for panel in config.panels:
|
||||||
if (
|
if interactive:
|
||||||
section
|
Moulinette.display(
|
||||||
and section.get("visible")
|
colorize(f"\n{'='*40}\n>>>> {panel.name}\n{'='*40}", "purple")
|
||||||
and not evaluate_simple_js_expression(
|
|
||||||
section["visible"], context=self.future_values
|
|
||||||
)
|
)
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Ugly hack to skip action section ... except when when explicitly running actions
|
# A section or option may only evaluate its conditions (`visible`
|
||||||
if not action:
|
# and `enabled`) with its panel's local context that is built
|
||||||
if section and section["is_action_section"]:
|
# prompt after prompt.
|
||||||
|
# That means that a condition can only reference options of its
|
||||||
|
# own panel and options that are previously defined.
|
||||||
|
context: dict[str, Any] = {}
|
||||||
|
|
||||||
|
for section in panel.sections:
|
||||||
|
if (
|
||||||
|
action_id is None and section.is_action_section
|
||||||
|
) or not section.is_visible(context):
|
||||||
|
# FIXME useless?
|
||||||
|
Moulinette.display("Skipping section '{panel.id}.{section.id}'…")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if panel == obj:
|
if interactive and section.name:
|
||||||
name = _value_for_locale(panel["name"])
|
Moulinette.display(colorize(f"\n# {section.name}", "purple"))
|
||||||
display_header(f"\n{'='*40}\n>>>> {name}\n{'='*40}")
|
|
||||||
else:
|
|
||||||
name = _value_for_locale(section["name"])
|
|
||||||
if name:
|
|
||||||
display_header(f"\n# {name}")
|
|
||||||
elif section:
|
|
||||||
# filter action section options in case of multiple buttons
|
# filter action section options in case of multiple buttons
|
||||||
section["options"] = [
|
options = [
|
||||||
option
|
option
|
||||||
for option in section["options"]
|
for option in section.options
|
||||||
if option.get("type", OptionType.string) != OptionType.button
|
if option.type is not OptionType.button or option.id == action_id
|
||||||
or option["id"] == action
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if panel == obj:
|
settings = prompt_or_validate_form(
|
||||||
continue
|
options,
|
||||||
|
settings,
|
||||||
|
prefilled_answers=prefilled_answers,
|
||||||
|
context=context,
|
||||||
|
hooks=hooks,
|
||||||
|
)
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
# Check and ask unanswered questions
|
# Check and ask unanswered questions
|
||||||
prefilled_answers = self.args.copy()
|
prefilled_answers = self.args.copy()
|
||||||
prefilled_answers.update(self.new_values)
|
prefilled_answers.update(self.new_values)
|
||||||
|
@ -692,6 +696,9 @@ class ConfigPanel:
|
||||||
if not question.readonly and question.value is not None
|
if not question.readonly and question.value is not None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
=======
|
||||||
|
return settings
|
||||||
|
>>>>>>> be777b928 (configpanel: update _ask)
|
||||||
|
|
||||||
def _apply(self):
|
def _apply(self):
|
||||||
logger.info("Saving the new configuration...")
|
logger.info("Saving the new configuration...")
|
||||||
|
|
Loading…
Add table
Reference in a new issue