mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
form: reorder Options
This commit is contained in:
parent
5351698230
commit
9c238f00c3
1 changed files with 293 additions and 295 deletions
|
@ -377,107 +377,52 @@ class BaseOption:
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayTextOption(BaseOption):
|
||||||
|
argument_type = "display_text"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
||||||
|
):
|
||||||
|
super().__init__(question, context, hooks)
|
||||||
|
|
||||||
|
self.optional = True
|
||||||
|
self.readonly = True
|
||||||
|
self.style = question.get(
|
||||||
|
"style", "info" if question["type"] == "alert" else ""
|
||||||
|
)
|
||||||
|
|
||||||
|
def _format_text_for_user_input_in_cli(self):
|
||||||
|
text = _value_for_locale(self.ask)
|
||||||
|
|
||||||
|
if self.style in ["success", "info", "warning", "danger"]:
|
||||||
|
color = {
|
||||||
|
"success": "green",
|
||||||
|
"info": "cyan",
|
||||||
|
"warning": "yellow",
|
||||||
|
"danger": "red",
|
||||||
|
}
|
||||||
|
prompt = m18n.g(self.style) if self.style != "danger" else m18n.n("danger")
|
||||||
|
return colorize(prompt, color[self.style]) + f" {text}"
|
||||||
|
else:
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
class ButtonOption(BaseOption):
|
||||||
|
argument_type = "button"
|
||||||
|
enabled = None
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
||||||
|
):
|
||||||
|
super().__init__(question, context, hooks)
|
||||||
|
self.enabled = question.get("enabled", None)
|
||||||
|
|
||||||
|
|
||||||
class StringOption(BaseOption):
|
class StringOption(BaseOption):
|
||||||
argument_type = "string"
|
argument_type = "string"
|
||||||
default_value = ""
|
default_value = ""
|
||||||
|
|
||||||
|
|
||||||
class EmailOption(StringOption):
|
|
||||||
pattern = {
|
|
||||||
"regexp": r"^.+@.+",
|
|
||||||
"error": "config_validate_email", # i18n: config_validate_email
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class URLOption(StringOption):
|
|
||||||
pattern = {
|
|
||||||
"regexp": r"^https?://.*$",
|
|
||||||
"error": "config_validate_url", # i18n: config_validate_url
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class DateOption(StringOption):
|
|
||||||
pattern = {
|
|
||||||
"regexp": r"^\d{4}-\d\d-\d\d$",
|
|
||||||
"error": "config_validate_date", # i18n: config_validate_date
|
|
||||||
}
|
|
||||||
|
|
||||||
def _prevalidate(self):
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
super()._prevalidate()
|
|
||||||
|
|
||||||
if self.value not in [None, ""]:
|
|
||||||
try:
|
|
||||||
datetime.strptime(self.value, "%Y-%m-%d")
|
|
||||||
except ValueError:
|
|
||||||
raise YunohostValidationError("config_validate_date")
|
|
||||||
|
|
||||||
|
|
||||||
class TimeOption(StringOption):
|
|
||||||
pattern = {
|
|
||||||
"regexp": r"^(?:\d|[01]\d|2[0-3]):[0-5]\d$",
|
|
||||||
"error": "config_validate_time", # i18n: config_validate_time
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ColorOption(StringOption):
|
|
||||||
pattern = {
|
|
||||||
"regexp": r"^#[ABCDEFabcdef\d]{3,6}$",
|
|
||||||
"error": "config_validate_color", # i18n: config_validate_color
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TagsOption(BaseOption):
|
|
||||||
argument_type = "tags"
|
|
||||||
default_value = ""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def humanize(value, option={}):
|
|
||||||
if isinstance(value, list):
|
|
||||||
return ",".join(str(v) for v in value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def normalize(value, option={}):
|
|
||||||
if isinstance(value, list):
|
|
||||||
return ",".join(str(v) for v in value)
|
|
||||||
if isinstance(value, str):
|
|
||||||
value = value.strip()
|
|
||||||
return value
|
|
||||||
|
|
||||||
def _prevalidate(self):
|
|
||||||
values = self.value
|
|
||||||
if isinstance(values, str):
|
|
||||||
values = values.split(",")
|
|
||||||
elif values is None:
|
|
||||||
values = []
|
|
||||||
|
|
||||||
if not isinstance(values, list):
|
|
||||||
if self.choices:
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_choice_invalid",
|
|
||||||
name=self.name,
|
|
||||||
value=self.value,
|
|
||||||
choices=", ".join(str(choice) for choice in self.choices),
|
|
||||||
)
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_invalid",
|
|
||||||
name=self.name,
|
|
||||||
error=f"'{str(self.value)}' is not a list",
|
|
||||||
)
|
|
||||||
|
|
||||||
for value in values:
|
|
||||||
self.value = value
|
|
||||||
super()._prevalidate()
|
|
||||||
self.value = values
|
|
||||||
|
|
||||||
def _post_parse_value(self):
|
|
||||||
if isinstance(self.value, list):
|
|
||||||
self.value = ",".join(self.value)
|
|
||||||
return super()._post_parse_value()
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordOption(BaseOption):
|
class PasswordOption(BaseOption):
|
||||||
hide_user_input_in_prompt = True
|
hide_user_input_in_prompt = True
|
||||||
argument_type = "password"
|
argument_type = "password"
|
||||||
|
@ -509,35 +454,64 @@ class PasswordOption(BaseOption):
|
||||||
assert_password_is_strong_enough("user", self.value)
|
assert_password_is_strong_enough("user", self.value)
|
||||||
|
|
||||||
|
|
||||||
class WebPathOption(BaseOption):
|
class ColorOption(StringOption):
|
||||||
argument_type = "path"
|
pattern = {
|
||||||
default_value = ""
|
"regexp": r"^#[ABCDEFabcdef\d]{3,6}$",
|
||||||
|
"error": "config_validate_color", # i18n: config_validate_color
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class NumberOption(BaseOption):
|
||||||
|
argument_type = "number"
|
||||||
|
default_value = None
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
||||||
|
):
|
||||||
|
super().__init__(question, context, hooks)
|
||||||
|
self.min = question.get("min", None)
|
||||||
|
self.max = question.get("max", None)
|
||||||
|
self.step = question.get("step", None)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def normalize(value, option={}):
|
def normalize(value, option={}):
|
||||||
|
if isinstance(value, int):
|
||||||
|
return value
|
||||||
|
|
||||||
|
if isinstance(value, str):
|
||||||
|
value = value.strip()
|
||||||
|
|
||||||
|
if isinstance(value, str) and value.isdigit():
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
if value in [None, ""]:
|
||||||
|
return None
|
||||||
|
|
||||||
option = option.__dict__ if isinstance(option, BaseOption) else option
|
option = option.__dict__ if isinstance(option, BaseOption) else option
|
||||||
|
|
||||||
if not isinstance(value, str):
|
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(
|
||||||
"app_argument_invalid",
|
"app_argument_invalid",
|
||||||
name=option.get("name"),
|
name=option.get("name"),
|
||||||
error="Argument for path should be a string.",
|
error=m18n.n("invalid_number"),
|
||||||
)
|
)
|
||||||
|
|
||||||
if not value.strip():
|
def _prevalidate(self):
|
||||||
if option.get("optional"):
|
super()._prevalidate()
|
||||||
return ""
|
if self.value in [None, ""]:
|
||||||
# Hmpf here we could just have a "else" case
|
return
|
||||||
# but we also want WebPathOption.normalize("") to return "/"
|
|
||||||
# (i.e. if no option is provided, hence .get("optional") is None
|
if self.min is not None and int(self.value) < self.min:
|
||||||
elif option.get("optional") is False:
|
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(
|
||||||
"app_argument_invalid",
|
"app_argument_invalid",
|
||||||
name=option.get("name"),
|
name=self.name,
|
||||||
error="Option is mandatory",
|
error=m18n.n("invalid_number_min", min=self.min),
|
||||||
)
|
)
|
||||||
|
|
||||||
return "/" + value.strip().strip(" /")
|
if self.max is not None and int(self.value) > self.max:
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_invalid",
|
||||||
|
name=self.name,
|
||||||
|
error=m18n.n("invalid_number_max", max=self.max),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BooleanOption(BaseOption):
|
class BooleanOption(BaseOption):
|
||||||
|
@ -630,6 +604,191 @@ class BooleanOption(BaseOption):
|
||||||
return getattr(self, key, default)
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
|
class DateOption(StringOption):
|
||||||
|
pattern = {
|
||||||
|
"regexp": r"^\d{4}-\d\d-\d\d$",
|
||||||
|
"error": "config_validate_date", # i18n: config_validate_date
|
||||||
|
}
|
||||||
|
|
||||||
|
def _prevalidate(self):
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
super()._prevalidate()
|
||||||
|
|
||||||
|
if self.value not in [None, ""]:
|
||||||
|
try:
|
||||||
|
datetime.strptime(self.value, "%Y-%m-%d")
|
||||||
|
except ValueError:
|
||||||
|
raise YunohostValidationError("config_validate_date")
|
||||||
|
|
||||||
|
|
||||||
|
class TimeOption(StringOption):
|
||||||
|
pattern = {
|
||||||
|
"regexp": r"^(?:\d|[01]\d|2[0-3]):[0-5]\d$",
|
||||||
|
"error": "config_validate_time", # i18n: config_validate_time
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EmailOption(StringOption):
|
||||||
|
pattern = {
|
||||||
|
"regexp": r"^.+@.+",
|
||||||
|
"error": "config_validate_email", # i18n: config_validate_email
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WebPathOption(BaseOption):
|
||||||
|
argument_type = "path"
|
||||||
|
default_value = ""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def normalize(value, option={}):
|
||||||
|
option = option.__dict__ if isinstance(option, BaseOption) else option
|
||||||
|
|
||||||
|
if not isinstance(value, str):
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_invalid",
|
||||||
|
name=option.get("name"),
|
||||||
|
error="Argument for path should be a string.",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not value.strip():
|
||||||
|
if option.get("optional"):
|
||||||
|
return ""
|
||||||
|
# Hmpf here we could just have a "else" case
|
||||||
|
# but we also want WebPathOption.normalize("") to return "/"
|
||||||
|
# (i.e. if no option is provided, hence .get("optional") is None
|
||||||
|
elif option.get("optional") is False:
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_invalid",
|
||||||
|
name=option.get("name"),
|
||||||
|
error="Option is mandatory",
|
||||||
|
)
|
||||||
|
|
||||||
|
return "/" + value.strip().strip(" /")
|
||||||
|
|
||||||
|
|
||||||
|
class URLOption(StringOption):
|
||||||
|
pattern = {
|
||||||
|
"regexp": r"^https?://.*$",
|
||||||
|
"error": "config_validate_url", # i18n: config_validate_url
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FileOption(BaseOption):
|
||||||
|
argument_type = "file"
|
||||||
|
upload_dirs: List[str] = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def clean_upload_dirs(cls):
|
||||||
|
# Delete files uploaded from API
|
||||||
|
for upload_dir in cls.upload_dirs:
|
||||||
|
if os.path.exists(upload_dir):
|
||||||
|
shutil.rmtree(upload_dir)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
||||||
|
):
|
||||||
|
super().__init__(question, context, hooks)
|
||||||
|
self.accept = question.get("accept", "")
|
||||||
|
|
||||||
|
def _prevalidate(self):
|
||||||
|
if self.value is None:
|
||||||
|
self.value = self.current_value
|
||||||
|
|
||||||
|
super()._prevalidate()
|
||||||
|
|
||||||
|
# Validation should have already failed if required
|
||||||
|
if self.value in [None, ""]:
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
if Moulinette.interface.type != "api":
|
||||||
|
if not os.path.exists(str(self.value)) or not os.path.isfile(
|
||||||
|
str(self.value)
|
||||||
|
):
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_invalid",
|
||||||
|
name=self.name,
|
||||||
|
error=m18n.n("file_does_not_exist", path=str(self.value)),
|
||||||
|
)
|
||||||
|
|
||||||
|
def _post_parse_value(self):
|
||||||
|
from base64 import b64decode
|
||||||
|
|
||||||
|
if not self.value:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
upload_dir = tempfile.mkdtemp(prefix="ynh_filequestion_")
|
||||||
|
_, file_path = tempfile.mkstemp(dir=upload_dir)
|
||||||
|
|
||||||
|
FileOption.upload_dirs += [upload_dir]
|
||||||
|
|
||||||
|
logger.debug(f"Saving file {self.name} for file question into {file_path}")
|
||||||
|
|
||||||
|
def is_file_path(s):
|
||||||
|
return isinstance(s, str) and s.startswith("/") and os.path.exists(s)
|
||||||
|
|
||||||
|
if Moulinette.interface.type != "api" or is_file_path(self.value):
|
||||||
|
content = read_file(str(self.value), file_mode="rb")
|
||||||
|
else:
|
||||||
|
content = b64decode(self.value)
|
||||||
|
|
||||||
|
write_to_file(file_path, content, file_mode="wb")
|
||||||
|
|
||||||
|
self.value = file_path
|
||||||
|
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
class TagsOption(BaseOption):
|
||||||
|
argument_type = "tags"
|
||||||
|
default_value = ""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def humanize(value, option={}):
|
||||||
|
if isinstance(value, list):
|
||||||
|
return ",".join(str(v) for v in value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def normalize(value, option={}):
|
||||||
|
if isinstance(value, list):
|
||||||
|
return ",".join(str(v) for v in value)
|
||||||
|
if isinstance(value, str):
|
||||||
|
value = value.strip()
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _prevalidate(self):
|
||||||
|
values = self.value
|
||||||
|
if isinstance(values, str):
|
||||||
|
values = values.split(",")
|
||||||
|
elif values is None:
|
||||||
|
values = []
|
||||||
|
|
||||||
|
if not isinstance(values, list):
|
||||||
|
if self.choices:
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_choice_invalid",
|
||||||
|
name=self.name,
|
||||||
|
value=self.value,
|
||||||
|
choices=", ".join(str(choice) for choice in self.choices),
|
||||||
|
)
|
||||||
|
raise YunohostValidationError(
|
||||||
|
"app_argument_invalid",
|
||||||
|
name=self.name,
|
||||||
|
error=f"'{str(self.value)}' is not a list",
|
||||||
|
)
|
||||||
|
|
||||||
|
for value in values:
|
||||||
|
self.value = value
|
||||||
|
super()._prevalidate()
|
||||||
|
self.value = values
|
||||||
|
|
||||||
|
def _post_parse_value(self):
|
||||||
|
if isinstance(self.value, list):
|
||||||
|
self.value = ",".join(self.value)
|
||||||
|
return super()._post_parse_value()
|
||||||
|
|
||||||
|
|
||||||
class DomainOption(BaseOption):
|
class DomainOption(BaseOption):
|
||||||
argument_type = "domain"
|
argument_type = "domain"
|
||||||
|
|
||||||
|
@ -747,189 +906,30 @@ class GroupOption(BaseOption):
|
||||||
self.default = "all_users"
|
self.default = "all_users"
|
||||||
|
|
||||||
|
|
||||||
class NumberOption(BaseOption):
|
|
||||||
argument_type = "number"
|
|
||||||
default_value = None
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
|
||||||
):
|
|
||||||
super().__init__(question, context, hooks)
|
|
||||||
self.min = question.get("min", None)
|
|
||||||
self.max = question.get("max", None)
|
|
||||||
self.step = question.get("step", None)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def normalize(value, option={}):
|
|
||||||
if isinstance(value, int):
|
|
||||||
return value
|
|
||||||
|
|
||||||
if isinstance(value, str):
|
|
||||||
value = value.strip()
|
|
||||||
|
|
||||||
if isinstance(value, str) and value.isdigit():
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
if value in [None, ""]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
option = option.__dict__ if isinstance(option, BaseOption) else option
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_invalid",
|
|
||||||
name=option.get("name"),
|
|
||||||
error=m18n.n("invalid_number"),
|
|
||||||
)
|
|
||||||
|
|
||||||
def _prevalidate(self):
|
|
||||||
super()._prevalidate()
|
|
||||||
if self.value in [None, ""]:
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.min is not None and int(self.value) < self.min:
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_invalid",
|
|
||||||
name=self.name,
|
|
||||||
error=m18n.n("invalid_number_min", min=self.min),
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.max is not None and int(self.value) > self.max:
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_invalid",
|
|
||||||
name=self.name,
|
|
||||||
error=m18n.n("invalid_number_max", max=self.max),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DisplayTextOption(BaseOption):
|
|
||||||
argument_type = "display_text"
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
|
||||||
):
|
|
||||||
super().__init__(question, context, hooks)
|
|
||||||
|
|
||||||
self.optional = True
|
|
||||||
self.readonly = True
|
|
||||||
self.style = question.get(
|
|
||||||
"style", "info" if question["type"] == "alert" else ""
|
|
||||||
)
|
|
||||||
|
|
||||||
def _format_text_for_user_input_in_cli(self):
|
|
||||||
text = _value_for_locale(self.ask)
|
|
||||||
|
|
||||||
if self.style in ["success", "info", "warning", "danger"]:
|
|
||||||
color = {
|
|
||||||
"success": "green",
|
|
||||||
"info": "cyan",
|
|
||||||
"warning": "yellow",
|
|
||||||
"danger": "red",
|
|
||||||
}
|
|
||||||
prompt = m18n.g(self.style) if self.style != "danger" else m18n.n("danger")
|
|
||||||
return colorize(prompt, color[self.style]) + f" {text}"
|
|
||||||
else:
|
|
||||||
return text
|
|
||||||
|
|
||||||
|
|
||||||
class FileOption(BaseOption):
|
|
||||||
argument_type = "file"
|
|
||||||
upload_dirs: List[str] = []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def clean_upload_dirs(cls):
|
|
||||||
# Delete files uploaded from API
|
|
||||||
for upload_dir in cls.upload_dirs:
|
|
||||||
if os.path.exists(upload_dir):
|
|
||||||
shutil.rmtree(upload_dir)
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
|
||||||
):
|
|
||||||
super().__init__(question, context, hooks)
|
|
||||||
self.accept = question.get("accept", "")
|
|
||||||
|
|
||||||
def _prevalidate(self):
|
|
||||||
if self.value is None:
|
|
||||||
self.value = self.current_value
|
|
||||||
|
|
||||||
super()._prevalidate()
|
|
||||||
|
|
||||||
# Validation should have already failed if required
|
|
||||||
if self.value in [None, ""]:
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
if Moulinette.interface.type != "api":
|
|
||||||
if not os.path.exists(str(self.value)) or not os.path.isfile(
|
|
||||||
str(self.value)
|
|
||||||
):
|
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_argument_invalid",
|
|
||||||
name=self.name,
|
|
||||||
error=m18n.n("file_does_not_exist", path=str(self.value)),
|
|
||||||
)
|
|
||||||
|
|
||||||
def _post_parse_value(self):
|
|
||||||
from base64 import b64decode
|
|
||||||
|
|
||||||
if not self.value:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
upload_dir = tempfile.mkdtemp(prefix="ynh_filequestion_")
|
|
||||||
_, file_path = tempfile.mkstemp(dir=upload_dir)
|
|
||||||
|
|
||||||
FileOption.upload_dirs += [upload_dir]
|
|
||||||
|
|
||||||
logger.debug(f"Saving file {self.name} for file question into {file_path}")
|
|
||||||
|
|
||||||
def is_file_path(s):
|
|
||||||
return isinstance(s, str) and s.startswith("/") and os.path.exists(s)
|
|
||||||
|
|
||||||
if Moulinette.interface.type != "api" or is_file_path(self.value):
|
|
||||||
content = read_file(str(self.value), file_mode="rb")
|
|
||||||
else:
|
|
||||||
content = b64decode(self.value)
|
|
||||||
|
|
||||||
write_to_file(file_path, content, file_mode="wb")
|
|
||||||
|
|
||||||
self.value = file_path
|
|
||||||
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
|
|
||||||
class ButtonOption(BaseOption):
|
|
||||||
argument_type = "button"
|
|
||||||
enabled = None
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
|
|
||||||
):
|
|
||||||
super().__init__(question, context, hooks)
|
|
||||||
self.enabled = question.get("enabled", None)
|
|
||||||
|
|
||||||
|
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
|
"display_text": DisplayTextOption,
|
||||||
|
"markdown": DisplayTextOption,
|
||||||
|
"alert": DisplayTextOption,
|
||||||
|
"button": ButtonOption,
|
||||||
"string": StringOption,
|
"string": StringOption,
|
||||||
"text": StringOption,
|
"text": StringOption,
|
||||||
"select": StringOption,
|
|
||||||
"tags": TagsOption,
|
|
||||||
"email": EmailOption,
|
|
||||||
"url": URLOption,
|
|
||||||
"date": DateOption,
|
|
||||||
"time": TimeOption,
|
|
||||||
"color": ColorOption,
|
|
||||||
"password": PasswordOption,
|
"password": PasswordOption,
|
||||||
"path": WebPathOption,
|
"color": ColorOption,
|
||||||
"boolean": BooleanOption,
|
|
||||||
"domain": DomainOption,
|
|
||||||
"user": UserOption,
|
|
||||||
"group": GroupOption,
|
|
||||||
"number": NumberOption,
|
"number": NumberOption,
|
||||||
"range": NumberOption,
|
"range": NumberOption,
|
||||||
"display_text": DisplayTextOption,
|
"boolean": BooleanOption,
|
||||||
"alert": DisplayTextOption,
|
"date": DateOption,
|
||||||
"markdown": DisplayTextOption,
|
"time": TimeOption,
|
||||||
|
"email": EmailOption,
|
||||||
|
"path": WebPathOption,
|
||||||
|
"url": URLOption,
|
||||||
"file": FileOption,
|
"file": FileOption,
|
||||||
|
"select": StringOption,
|
||||||
|
"tags": TagsOption,
|
||||||
|
"domain": DomainOption,
|
||||||
"app": AppOption,
|
"app": AppOption,
|
||||||
"button": ButtonOption,
|
"user": UserOption,
|
||||||
|
"group": GroupOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -996,9 +996,7 @@ def hydrate_questions_with_choices(raw_questions: List) -> List:
|
||||||
out = []
|
out = []
|
||||||
|
|
||||||
for raw_question in raw_questions:
|
for raw_question in raw_questions:
|
||||||
question = OPTIONS[raw_question.get("type", "string")](
|
question = OPTIONS[raw_question.get("type", "string")](raw_question)
|
||||||
raw_question
|
|
||||||
)
|
|
||||||
if question.choices:
|
if question.choices:
|
||||||
raw_question["choices"] = question.choices
|
raw_question["choices"] = question.choices
|
||||||
raw_question["default"] = question.default
|
raw_question["default"] = question.default
|
||||||
|
|
Loading…
Add table
Reference in a new issue