form+config: replace _parse_pre_answered method with generic function

This commit is contained in:
axolotle 2023-04-18 16:54:54 +02:00
parent a92e22b653
commit dbaea019fe
2 changed files with 33 additions and 17 deletions

View file

@ -43,6 +43,7 @@ from yunohost.utils.form import (
ask_questions_and_parse_answers, ask_questions_and_parse_answers,
build_form, build_form,
evaluate_simple_js_expression, evaluate_simple_js_expression,
parse_prefilled_values,
) )
from yunohost.utils.i18n import _value_for_locale from yunohost.utils.i18n import _value_for_locale
@ -397,7 +398,10 @@ class ConfigPanel:
# Import and parse pre-answered options # Import and parse pre-answered options
logger.debug("Import and parse pre-answered options") logger.debug("Import and parse pre-answered options")
self._parse_pre_answered(args, value, args_file) if option_id and value is not None:
self.args = {option_id: value}
else:
self.args = parse_prefilled_values(args, value, args_file)
# Read or get values and hydrate the config # Read or get values and hydrate the config
self._get_raw_settings() self._get_raw_settings()
@ -468,7 +472,7 @@ class ConfigPanel:
# Import and parse pre-answered options # Import and parse pre-answered options
logger.debug("Import and parse pre-answered options") logger.debug("Import and parse pre-answered options")
self._parse_pre_answered(args, None, args_file) self.args = parse_prefilled_values(args, args_file)
# Read or get values and hydrate the config # Read or get values and hydrate the config
self._get_raw_settings() self._get_raw_settings()
@ -678,17 +682,6 @@ class ConfigPanel:
} }
) )
def _parse_pre_answered(self, args, value, args_file):
args = urllib.parse.parse_qs(args or "", keep_blank_values=True)
self.args = {key: ",".join(value_) for key, value_ in args.items()}
if args_file:
# Import YAML / JSON file but keep --args values
self.args = {**read_yaml(args_file), **self.args}
if value is not None:
self.args = {self.filter_key.split(".")[-1]: value}
def _apply(self): def _apply(self):
logger.info("Saving the new configuration...") logger.info("Saving the new configuration...")
dir_path = os.path.dirname(os.path.realpath(self.save_path)) dir_path = os.path.dirname(os.path.realpath(self.save_path))

View file

@ -53,7 +53,7 @@ from pydantic.types import constr
from moulinette import Moulinette, m18n from moulinette import Moulinette, m18n
from moulinette.interfaces.cli import colorize from moulinette.interfaces.cli import colorize
from moulinette.utils.filesystem import read_file, write_to_file from moulinette.utils.filesystem import read_file, read_yaml, write_to_file
from yunohost.log import OperationLogger from yunohost.log import OperationLogger
from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.error import YunohostError, YunohostValidationError
from yunohost.utils.i18n import _value_for_locale from yunohost.utils.i18n import _value_for_locale
@ -1431,6 +1431,31 @@ def hydrate_option_type(raw_option: dict[str, Any]) -> dict[str, Any]:
Hooks = dict[str, Callable[[BaseInputOption], Any]] Hooks = dict[str, Callable[[BaseInputOption], Any]]
def parse_prefilled_values(
args: Union[str, None] = None,
args_file: Union[str, None] = None,
method: Literal["parse_qs", "parse_qsl"] = "parse_qs",
) -> dict[str, Any]:
"""
Retrieve form values from yaml file or query string.
"""
values: Values = {}
if args_file:
# Import YAML / JSON file
values |= read_yaml(args_file)
if args:
# FIXME See `ask_questions_and_parse_answers`
parsed = getattr(urllib.parse, method)(args, keep_blank_values=True)
if isinstance(parsed, dict): # parse_qs
# FIXME could do the following to get a list directly?
# k: None if not len(v) else (v if len(v) > 1 else v[0])
values |= {k: ",".join(v) for k, v in parsed.items()}
else:
values |= dict(parsed)
return values
def prompt_or_validate_form( def prompt_or_validate_form(
options: list[AnyOption], options: list[AnyOption],
form: FormModel, form: FormModel,
@ -1561,9 +1586,7 @@ def ask_questions_and_parse_answers(
# whereas parse.qs return list of values (which is useful for tags, etc) # whereas parse.qs return list of values (which is useful for tags, etc)
# For now, let's not migrate this piece of code to parse_qs # For now, let's not migrate this piece of code to parse_qs
# Because Aleks believes some bits of the app CI rely on overriding values (e.g. foo=foo&...&foo=bar) # Because Aleks believes some bits of the app CI rely on overriding values (e.g. foo=foo&...&foo=bar)
answers = dict( answers = parse_prefilled_values(prefilled_answers, method="parse_qsl")
urllib.parse.parse_qsl(prefilled_answers or "", keep_blank_values=True)
)
elif isinstance(prefilled_answers, Mapping): elif isinstance(prefilled_answers, Mapping):
answers = {**prefilled_answers} answers = {**prefilled_answers}
else: else: