mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
form: rework entities validators to avoid multiple calls to them
This commit is contained in:
parent
02948ad49c
commit
80dbd6dac4
1 changed files with 55 additions and 35 deletions
|
@ -44,7 +44,6 @@ from pydantic import (
|
||||||
Extra,
|
Extra,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
create_model,
|
create_model,
|
||||||
root_validator,
|
|
||||||
validator,
|
validator,
|
||||||
)
|
)
|
||||||
from pydantic.color import Color
|
from pydantic.color import Color
|
||||||
|
@ -324,7 +323,7 @@ class BaseOption(BaseModel):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
# FIXME Legacy, is `name` still needed?
|
# FIXME Legacy, is `name` still needed?
|
||||||
@validator("name", pre=True, always=True)
|
@validator("name")
|
||||||
def apply_legacy_name(cls, value: Union[str, None], values: Values) -> str:
|
def apply_legacy_name(cls, value: Union[str, None], values: Values) -> str:
|
||||||
if value is None:
|
if value is None:
|
||||||
return values["id"]
|
return values["id"]
|
||||||
|
@ -1096,21 +1095,30 @@ class DomainOption(BaseChoicesOption):
|
||||||
type: Literal[OptionType.domain] = OptionType.domain
|
type: Literal[OptionType.domain] = OptionType.domain
|
||||||
choices: Union[dict[str, str], None]
|
choices: Union[dict[str, str], None]
|
||||||
|
|
||||||
@root_validator()
|
@validator("choices", pre=True, always=True)
|
||||||
def inject_domains_choices_and_default(cls, values: Values) -> Values:
|
def inject_domains_choices(
|
||||||
|
cls, value: Union[dict[str, str], None], values: Values
|
||||||
|
) -> dict[str, str]:
|
||||||
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
from yunohost.domain import domain_list
|
from yunohost.domain import domain_list
|
||||||
|
|
||||||
data = domain_list()
|
data = domain_list()
|
||||||
values["choices"] = {
|
return {
|
||||||
domain: domain + " ★" if domain == data["main"] else domain
|
domain: domain + " ★" if domain == data["main"] else domain
|
||||||
for domain in data["domains"]
|
for domain in data["domains"]
|
||||||
}
|
}
|
||||||
|
|
||||||
if values["default"] is None:
|
@validator("default")
|
||||||
values["default"] = data["main"]
|
def inject_default(
|
||||||
|
cls, value: Union[str, None], values: Values
|
||||||
|
) -> Union[str, None]:
|
||||||
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
|
from yunohost.domain import _get_maindomain
|
||||||
|
|
||||||
return values
|
if value is None:
|
||||||
|
return _get_maindomain()
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def normalize(value, option={}):
|
def normalize(value, option={}):
|
||||||
|
@ -1131,8 +1139,11 @@ class AppOption(BaseChoicesOption):
|
||||||
add_yunohost_portal_to_choices: bool = False
|
add_yunohost_portal_to_choices: bool = False
|
||||||
filter: Union[str, None] = None
|
filter: Union[str, None] = None
|
||||||
|
|
||||||
@root_validator()
|
@validator("choices", pre=True, always=True)
|
||||||
def inject_apps_choices(cls, values: Values) -> Values:
|
def inject_apps_choices(
|
||||||
|
cls, value: Union[dict[str, str], None], values: Values
|
||||||
|
) -> dict[str, str]:
|
||||||
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
from yunohost.app import app_list
|
from yunohost.app import app_list
|
||||||
|
|
||||||
apps = app_list(full=True)["apps"]
|
apps = app_list(full=True)["apps"]
|
||||||
|
@ -1143,61 +1154,77 @@ class AppOption(BaseChoicesOption):
|
||||||
for app in apps
|
for app in apps
|
||||||
if evaluate_simple_js_expression(values["filter"], context=app)
|
if evaluate_simple_js_expression(values["filter"], context=app)
|
||||||
]
|
]
|
||||||
values["choices"] = {"_none": "---"}
|
|
||||||
|
value = {"_none": "---"}
|
||||||
|
|
||||||
if values.get("add_yunohost_portal_to_choices", False):
|
if values.get("add_yunohost_portal_to_choices", False):
|
||||||
values["choices"]["_yunohost_portal_with_public_apps"] = "YunoHost's portal with public apps"
|
value["_yunohost_portal_with_public_apps"] = "YunoHost's portal with public apps"
|
||||||
|
|
||||||
values["choices"].update(
|
value.update(
|
||||||
{
|
{
|
||||||
app["id"]: f"{app['label']} ({app.get('domain_path', app['id'])})"
|
app["id"]: f"{app['label']} ({app.get('domain_path', app['id'])})"
|
||||||
for app in apps
|
for app in apps
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return values
|
return value
|
||||||
|
|
||||||
|
|
||||||
class UserOption(BaseChoicesOption):
|
class UserOption(BaseChoicesOption):
|
||||||
type: Literal[OptionType.user] = OptionType.user
|
type: Literal[OptionType.user] = OptionType.user
|
||||||
choices: Union[dict[str, str], None]
|
choices: Union[dict[str, str], None]
|
||||||
|
|
||||||
@root_validator()
|
@validator("choices", pre=True, always=True)
|
||||||
def inject_users_choices_and_default(cls, values: dict[str, Any]) -> dict[str, Any]:
|
def inject_users_choices(
|
||||||
from yunohost.domain import _get_maindomain
|
cls, value: Union[dict[str, str], None], values: Values
|
||||||
from yunohost.user import user_info, user_list
|
) -> dict[str, str]:
|
||||||
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
|
from yunohost.user import user_list
|
||||||
|
|
||||||
values["choices"] = {
|
value = {
|
||||||
username: f"{infos['fullname']} ({infos['mail']})"
|
username: f"{infos['fullname']} ({infos['mail']})"
|
||||||
for username, infos in user_list()["users"].items()
|
for username, infos in user_list()["users"].items()
|
||||||
}
|
}
|
||||||
|
|
||||||
# FIXME keep this to test if any user, do not raise error if no admin?
|
# FIXME keep this to test if any user, do not raise error if no admin?
|
||||||
if not values["choices"]:
|
if not value:
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(
|
||||||
"app_argument_invalid",
|
"app_argument_invalid",
|
||||||
name=values["id"],
|
name=values["id"],
|
||||||
error="You should create a YunoHost user first.",
|
error="You should create a YunoHost user first.",
|
||||||
)
|
)
|
||||||
|
|
||||||
if values["default"] is None:
|
return value
|
||||||
|
|
||||||
|
@validator("default")
|
||||||
|
def inject_default(
|
||||||
|
cls, value: Union[str, None], values: Values
|
||||||
|
) -> Union[str, None]:
|
||||||
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
|
from yunohost.domain import _get_maindomain
|
||||||
|
from yunohost.user import user_info
|
||||||
|
|
||||||
|
if value is None:
|
||||||
# FIXME: this code is obsolete with the new admins group
|
# FIXME: this code is obsolete with the new admins group
|
||||||
# Should be replaced by something like "any first user we find in the admin group"
|
# Should be replaced by something like "any first user we find in the admin group"
|
||||||
root_mail = "root@%s" % _get_maindomain()
|
root_mail = "root@%s" % _get_maindomain()
|
||||||
for user in values["choices"].keys():
|
for user in values["choices"].keys():
|
||||||
if root_mail in user_info(user).get("mail-aliases", []):
|
if root_mail in user_info(user).get("mail-aliases", []):
|
||||||
values["default"] = user
|
return user
|
||||||
break
|
|
||||||
|
|
||||||
return values
|
return value
|
||||||
|
|
||||||
|
|
||||||
class GroupOption(BaseChoicesOption):
|
class GroupOption(BaseChoicesOption):
|
||||||
type: Literal[OptionType.group] = OptionType.group
|
type: Literal[OptionType.group] = OptionType.group
|
||||||
choices: Union[dict[str, str], None]
|
choices: Union[dict[str, str], None]
|
||||||
|
default: Union[Literal["visitors", "all_users", "admins"], None] = "all_users"
|
||||||
|
|
||||||
@root_validator()
|
@validator("choices", pre=True, always=True)
|
||||||
def inject_groups_choices_and_default(cls, values: Values) -> Values:
|
def inject_groups_choices(
|
||||||
|
cls, value: Union[dict[str, str], None], values: Values
|
||||||
|
) -> dict[str, str]:
|
||||||
|
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||||
from yunohost.user import user_group_list
|
from yunohost.user import user_group_list
|
||||||
|
|
||||||
groups = user_group_list(short=True, include_primary_groups=False)["groups"]
|
groups = user_group_list(short=True, include_primary_groups=False)["groups"]
|
||||||
|
@ -1212,14 +1239,7 @@ class GroupOption(BaseChoicesOption):
|
||||||
else groupname
|
else groupname
|
||||||
)
|
)
|
||||||
|
|
||||||
values["choices"] = {
|
return {groupname: _human_readable_group(groupname) for groupname in groups}
|
||||||
groupname: _human_readable_group(groupname) for groupname in groups
|
|
||||||
}
|
|
||||||
|
|
||||||
if values["default"] is None:
|
|
||||||
values["default"] = "all_users"
|
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
|
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
|
@ -1293,7 +1313,7 @@ class OptionsModel(BaseModel):
|
||||||
"id": id_,
|
"id": id_,
|
||||||
"type": option.get("type", "string"),
|
"type": option.get("type", "string"),
|
||||||
# ConfigPanel options needs to be set as optional by default
|
# ConfigPanel options needs to be set as optional by default
|
||||||
"optional": option.get("optional", optional)
|
"optional": option.get("optional", optional),
|
||||||
}
|
}
|
||||||
for id_, option in options.items()
|
for id_, option in options.items()
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Reference in a new issue