Skip to content

Commit

Permalink
feat(raw-study): add validators to validate geographic trimming filte…
Browse files Browse the repository at this point in the history
…ring
  • Loading branch information
laurent-laporte-pro committed Apr 17, 2024
1 parent e977b51 commit 594459f
Showing 1 changed file with 77 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import typing as t

_ALL_FILTERING = ["hourly", "daily", "weekly", "monthly", "annual"]


def extract_filtering(v: t.Any) -> t.Sequence[str]:
"""
Extract filtering values from a comma-separated list of values.
"""

if v is None:
values = set()
elif isinstance(v, str):
values = {x.strip() for x in v.lower().split(",")} if v else set()
elif isinstance(v, (list, tuple)):
values = set(x.strip().lower() for x in v)
else:
raise TypeError(f"Invalid type for filtering: {type(v)!r}")

try:
return sorted(values, key=lambda x: _ALL_FILTERING.index(x))
except ValueError as e:
raise ValueError(f"Invalid value for filtering: {e!s}") from None


def validate_filtering(v: t.Any) -> str:
"""
Validate the filtering field and convert it to a comma separated string.
"""

return ", ".join(extract_filtering(v))


# noinspection SpellCheckingInspection
def validate_colors(values: t.MutableMapping[str, t.Any]) -> t.Mapping[str, t.Any]:
"""
Validate ``color_rgb``, ``color_r``, ``color_g``, ``color_b`` and convert them to ``color_rgb``.
"""

def _pop_any(dictionary: t.MutableMapping[str, t.Any], *keys: str) -> t.Any:
"""Save as `pop` but for multiple keys. Return the first found value."""
return next((dictionary.pop(key, None) for key in keys if key in dictionary), None)

color_r = _pop_any(values, "color_r", "colorr")
color_g = _pop_any(values, "color_g", "colorg")
color_b = _pop_any(values, "color_b", "colorb")
if color_r is not None and color_g is not None and color_b is not None:
values["color_rgb"] = color_r, color_g, color_b
return values


def validate_color_rgb(v: t.Any) -> str:
"""
Validate RGB color field and convert it to color code.
Accepts:
- a string in the format "#RRGGBB"
- a string in the format "rgb(R, G, B)"
- a string in the format "R, G, B"
- a list or tuple of 3 integers
"""

if isinstance(v, str):
if v.startswith("#"):
r = int(v[1:3], 16)
g = int(v[3:5], 16)
b = int(v[5:7], 16)
elif v.startswith("rgb("):
r, g, b = [int(c) for c in v[4:-1].split(",")]
else:
r, g, b = [int(c) for c in v.split(",")]
elif isinstance(v, (list, tuple)):
r, g, b = map(int, v)
else:
raise TypeError(f"Invalid type for 'color_rgb': {type(v)}")

return f"#{r:02X}{g:02X}{b:02X}"

0 comments on commit 594459f

Please sign in to comment.