feat: Add support for service options weight

This commit is contained in:
Inex Code 2024-12-21 17:46:28 +03:00
parent 5218187d6d
commit 4cdc9f3e08
No known key found for this signature in database
3 changed files with 26 additions and 1 deletions

View file

@ -207,7 +207,10 @@ class Service:
if not config_items: if not config_items:
return None return None
# By the "type" field convert every dict into a ConfigItem. In the future there will be more types. # By the "type" field convert every dict into a ConfigItem. In the future there will be more types.
return [config_item_to_graphql(config_items[item]) for item in config_items] unsorted_config_items = [config_items[item] for item in config_items]
# Sort the items by their weight. If there is no weight, implicitly set it to 50.
config_items = sorted(unsorted_config_items, key=lambda x: x.get("weight", 50))
return [config_item_to_graphql(item) for item in config_items]
# TODO: fill this # TODO: fill this
@strawberry.field @strawberry.field

View file

@ -14,6 +14,7 @@ class ServiceConfigItem(ABC):
description: str description: str
widget: str widget: str
type: str type: str
weight: int
@abstractmethod @abstractmethod
def get_value(self, service_id): def get_value(self, service_id):
@ -34,6 +35,7 @@ class ServiceConfigItem(ABC):
"description": self.description, "description": self.description,
"widget": self.widget, "widget": self.widget,
"value": self.get_value(service_id), "value": self.get_value(service_id),
"weight": self.weight,
} }
@ -46,6 +48,7 @@ class StringServiceConfigItem(ServiceConfigItem):
regex: Optional[str] = None, regex: Optional[str] = None,
widget: Optional[str] = None, widget: Optional[str] = None,
allow_empty: bool = False, allow_empty: bool = False,
weight: int = 50,
): ):
if widget == "subdomain" and not regex: if widget == "subdomain" and not regex:
raise ValueError("Subdomain widget requires regex") raise ValueError("Subdomain widget requires regex")
@ -56,6 +59,7 @@ class StringServiceConfigItem(ServiceConfigItem):
self.regex = re.compile(regex) if regex else None self.regex = re.compile(regex) if regex else None
self.widget = widget if widget else "text" self.widget = widget if widget else "text"
self.allow_empty = allow_empty self.allow_empty = allow_empty
self.weight = weight
def get_value(self, service_id): def get_value(self, service_id):
with ReadUserData() as user_data: with ReadUserData() as user_data:
@ -82,6 +86,7 @@ class StringServiceConfigItem(ServiceConfigItem):
"value": self.get_value(service_id), "value": self.get_value(service_id),
"default_value": self.default_value, "default_value": self.default_value,
"regex": self.regex.pattern if self.regex else None, "regex": self.regex.pattern if self.regex else None,
"weight": self.weight,
} }
def validate_value(self, value): def validate_value(self, value):
@ -104,12 +109,14 @@ class BoolServiceConfigItem(ServiceConfigItem):
default_value: bool, default_value: bool,
description: str, description: str,
widget: Optional[str] = None, widget: Optional[str] = None,
weight: int = 50,
): ):
self.id = id self.id = id
self.type = "bool" self.type = "bool"
self.default_value = default_value self.default_value = default_value
self.description = description self.description = description
self.widget = widget if widget else "switch" self.widget = widget if widget else "switch"
self.weight = weight
def get_value(self, service_id): def get_value(self, service_id):
with ReadUserData() as user_data: with ReadUserData() as user_data:
@ -135,6 +142,7 @@ class BoolServiceConfigItem(ServiceConfigItem):
"widget": self.widget, "widget": self.widget,
"value": self.get_value(service_id), "value": self.get_value(service_id),
"default_value": self.default_value, "default_value": self.default_value,
"weight": self.weight,
} }
def validate_value(self, value): def validate_value(self, value):
@ -149,6 +157,7 @@ class EnumServiceConfigItem(ServiceConfigItem):
description: str, description: str,
options: list[str], options: list[str],
widget: Optional[str] = None, widget: Optional[str] = None,
weight: int = 50,
): ):
self.id = id self.id = id
self.type = "enum" self.type = "enum"
@ -156,6 +165,7 @@ class EnumServiceConfigItem(ServiceConfigItem):
self.description = description self.description = description
self.options = options self.options = options
self.widget = widget if widget else "select" self.widget = widget if widget else "select"
self.weight = weight
def get_value(self, service_id): def get_value(self, service_id):
with ReadUserData() as user_data: with ReadUserData() as user_data:
@ -182,6 +192,7 @@ class EnumServiceConfigItem(ServiceConfigItem):
"value": self.get_value(service_id), "value": self.get_value(service_id),
"default_value": self.default_value, "default_value": self.default_value,
"options": self.options, "options": self.options,
"weight": self.weight,
} }
def validate_value(self, value): def validate_value(self, value):
@ -200,6 +211,7 @@ class IntServiceConfigItem(ServiceConfigItem):
widget: Optional[str] = None, widget: Optional[str] = None,
min_value: Optional[int] = None, min_value: Optional[int] = None,
max_value: Optional[int] = None, max_value: Optional[int] = None,
weight: int = 50,
) -> None: ) -> None:
self.id = id self.id = id
self.type = "int" self.type = "int"
@ -208,6 +220,7 @@ class IntServiceConfigItem(ServiceConfigItem):
self.widget = widget if widget else "number" self.widget = widget if widget else "number"
self.min_value = min_value self.min_value = min_value
self.max_value = max_value self.max_value = max_value
self.weight = weight
def get_value(self, service_id): def get_value(self, service_id):
with ReadUserData() as user_data: with ReadUserData() as user_data:
@ -235,6 +248,7 @@ class IntServiceConfigItem(ServiceConfigItem):
"default_value": self.default_value, "default_value": self.default_value,
"min_value": self.min_value, "min_value": self.min_value,
"max_value": self.max_value, "max_value": self.max_value,
"weight": self.weight,
} }
def validate_value(self, value): def validate_value(self, value):

View file

@ -245,6 +245,7 @@ class SupportLevel(Enum):
def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]: def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]:
"""Create a ServiceConfigItem from JSON data.""" """Create a ServiceConfigItem from JSON data."""
weight = json_data.get("meta", {}).get("weight", 50)
if json_data["meta"]["type"] == "enable": if json_data["meta"]["type"] == "enable":
return None return None
if json_data["meta"]["type"] == "location": if json_data["meta"]["type"] == "location":
@ -257,6 +258,7 @@ def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]:
regex=json_data["meta"].get("regex"), regex=json_data["meta"].get("regex"),
widget=json_data["meta"].get("widget"), widget=json_data["meta"].get("widget"),
allow_empty=json_data["meta"].get("allowEmpty", False), allow_empty=json_data["meta"].get("allowEmpty", False),
weight=weight,
) )
if json_data["meta"]["type"] == "bool": if json_data["meta"]["type"] == "bool":
return BoolServiceConfigItem( return BoolServiceConfigItem(
@ -264,6 +266,7 @@ def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]:
default_value=json_data["default"], default_value=json_data["default"],
description=json_data["description"], description=json_data["description"],
widget=json_data["meta"].get("widget"), widget=json_data["meta"].get("widget"),
weight=weight,
) )
if json_data["meta"]["type"] == "enum": if json_data["meta"]["type"] == "enum":
return EnumServiceConfigItem( return EnumServiceConfigItem(
@ -272,6 +275,7 @@ def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]:
description=json_data["description"], description=json_data["description"],
options=json_data["meta"]["options"], options=json_data["meta"]["options"],
widget=json_data["meta"].get("widget"), widget=json_data["meta"].get("widget"),
weight=weight,
) )
if json_data["meta"]["type"] == "int": if json_data["meta"]["type"] == "int":
return IntServiceConfigItem( return IntServiceConfigItem(
@ -281,6 +285,7 @@ def config_item_from_json(json_data: dict) -> Optional[ServiceConfigItem]:
widget=json_data["meta"].get("widget"), widget=json_data["meta"].get("widget"),
min_value=json_data["meta"].get("minValue"), min_value=json_data["meta"].get("minValue"),
max_value=json_data["meta"].get("maxValue"), max_value=json_data["meta"].get("maxValue"),
weight=weight,
) )
raise ValueError("Unknown config item type") raise ValueError("Unknown config item type")
@ -493,6 +498,9 @@ class TemplatedService(Service):
subprocess.run(["systemctl", "restart", unit], check=False) subprocess.run(["systemctl", "restart", unit], check=False)
def get_configuration(self) -> dict: def get_configuration(self) -> dict:
# If there are no options, return an empty dict
if not self.config_items:
return {}
return { return {
key: self.config_items[key].as_dict(self.get_id()) key: self.config_items[key].as_dict(self.get_id())
for key in self.config_items for key in self.config_items