Parse dashboard operators independently of quoted filter values

This commit is contained in:
Andras Schmelczer 2026-10-27 20:02:40 +00:00
commit 1fda2d6fc0

View file

@ -1,23 +1,32 @@
from typing import Optional, Union
import re
from typing import Optional, Union, cast
from ....views import Filter, operators
from ....views import Filter
from ....views.operators import Operator
_expression = re.compile(
r"\s*\{([^}]+)\}\s*(>=|<=|!=|=|>|<|contains\b|ge\b|le\b|lt\b|gt\b|ne\b|eq\b)\s*(.*?)\s*",
re.DOTALL,
)
_aliases = {"ge": ">=", "le": "<=", "lt": "<", "gt": ">", "ne": "!=", "eq": "="}
def get_filter_from_datatable(description: str) -> Optional[Filter]:
for operator in operators:
if operator in description:
name_part, value_part = description.split(operator, 1)
value_part = value_part.strip()
name_part = name_part[name_part.find("{") + 1 : name_part.rfind("}")]
v0 = value_part[0]
if v0 == value_part[-1] and v0 in ("'", '"', "`"):
value: Union[str, float] = value_part[1:-1].replace("\\" + v0, v0)
else:
try:
value = float(value_part)
except ValueError:
value = value_part
return Filter(property=name_part, operator=operator, value=value)
return None
match = _expression.fullmatch(description)
if match is None:
return None
name, token, raw = match.groups()
if not raw:
return None
if raw[0] in ("'", '"', "`"):
if len(raw) < 2 or raw[-1] != raw[0]:
return None
value: Union[str, float] = re.sub(r"\\([\\'\"`])", r"\1", raw[1:-1])
else:
try:
value = float(raw)
except ValueError:
value = raw
return Filter(
property=name, operator=cast(Operator, _aliases.get(token, token)), value=value
)