From a7ed9061afe084648969a669f0c38bf567583a08 Mon Sep 17 00:00:00 2001 From: Tibor Frank Date: Wed, 19 Apr 2023 11:15:53 +0200 Subject: C-Dash: Add regexp filtering to comparison tables Signed-off-by: Tibor Frank Change-Id: Ibe2b951859c9d775dd386dadd1bb141d74f53652 --- csit.infra.dash/app/cdash/comparisons/tables.py | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'csit.infra.dash/app/cdash/comparisons/tables.py') diff --git a/csit.infra.dash/app/cdash/comparisons/tables.py b/csit.infra.dash/app/cdash/comparisons/tables.py index 31e268c6f0..8c19d3c776 100644 --- a/csit.infra.dash/app/cdash/comparisons/tables.py +++ b/csit.infra.dash/app/cdash/comparisons/tables.py @@ -309,3 +309,65 @@ def comparison_table( ) return (title, df_cmp) + + +def filter_table_data( + store_table_data: list, + table_filter: str + ) -> list: + """Filter table data using user specified filter. + + :param store_table_data: Table data represented as a list of records. + :param table_filter: User specified filter. + :type store_table_data: list + :type table_filter: str + :returns: A new table created by filtering of table data represented as + a list of records. + :rtype: list + """ + + # Checks: + if not any((table_filter, store_table_data, )): + return store_table_data + + def _split_filter_part(filter_part: str) -> tuple: + """Split a part of filter into column name, operator and value. + A "part of filter" is a sting berween "&&" operator. + + :param filter_part: A part of filter. + :type filter_part: str + :returns: Column name, operator, value + :rtype: tuple[str, str, str|float] + """ + for operator_type in C.OPERATORS: + for operator in operator_type: + if operator in filter_part: + name_p, val_p = filter_part.split(operator, 1) + name = name_p[name_p.find("{") + 1 : name_p.rfind("}")] + val_p = val_p.strip() + if (val_p[0] == val_p[-1] and val_p[0] in ("'", '"', '`')): + value = val_p[1:-1].replace("\\" + val_p[0], val_p[0]) + else: + try: + value = float(val_p) + except ValueError: + value = val_p + + return name, operator_type[0].strip(), value + return (None, None, None) + + df = pd.DataFrame.from_records(store_table_data) + for filter_part in table_filter.split(" && "): + col_name, operator, filter_value = _split_filter_part(filter_part) + if operator == "contains": + df = df.loc[df[col_name].str.contains(filter_value, regex=True)] + elif operator in ("eq", "ne", "lt", "le", "gt", "ge"): + # These operators match pandas series operator method names. + df = df.loc[getattr(df[col_name], operator)(filter_value)] + elif operator == "datestartswith": + # This is a simplification of the front-end filtering logic, + # only works with complete fields in standard format. + # Currently not used in comparison tables. + df = df.loc[df[col_name].str.startswith(filter_value)] + + return df.to_dict("records") -- cgit 1.2.3-korg