Team Ai
Apppublic

Underground-Digital/Workflow-Engine

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
processor.py386 linesDownload Raw Back to condition
1from collections.abc import Sequence2from typing import Any, Literal3 4from core.file import FileAttribute, file_manager5from core.variables import ArrayFileSegment6from core.workflow.entities.variable_pool import VariablePool7 8from .entities import Condition, SubCondition, SupportedComparisonOperator9 10 11class ConditionProcessor:12    def process_conditions(13        self,14        *,15        variable_pool: VariablePool,16        conditions: Sequence[Condition],17        operator: Literal["and", "or"],18    ):19        input_conditions = []20        group_results = []21 22        for condition in conditions:23            variable = variable_pool.get(condition.variable_selector)24            if variable is None:25                raise ValueError(f"Variable {condition.variable_selector} not found")26 27            if isinstance(variable, ArrayFileSegment) and condition.comparison_operator in {28                "contains",29                "not contains",30                "all of",31            }:32                # check sub conditions33                if not condition.sub_variable_condition:34                    raise ValueError("Sub variable is required")35                result = _process_sub_conditions(36                    variable=variable,37                    sub_conditions=condition.sub_variable_condition.conditions,38                    operator=condition.sub_variable_condition.logical_operator,39                )40            elif condition.comparison_operator in {41                "exists",42                "not exists",43            }:44                result = _evaluate_condition(45                    value=variable.value,46                    operator=condition.comparison_operator,47                    expected=None,48                )49            else:50                actual_value = variable.value if variable else None51                expected_value = condition.value52                if isinstance(expected_value, str):53                    expected_value = variable_pool.convert_template(expected_value).text54                input_conditions.append(55                    {56                        "actual_value": actual_value,57                        "expected_value": expected_value,58                        "comparison_operator": condition.comparison_operator,59                    }60                )61                result = _evaluate_condition(62                    value=actual_value,63                    operator=condition.comparison_operator,64                    expected=expected_value,65                )66            group_results.append(result)67 68        final_result = all(group_results) if operator == "and" else any(group_results)69        return input_conditions, group_results, final_result70 71 72def _evaluate_condition(73    *,74    operator: SupportedComparisonOperator,75    value: Any,76    expected: str | Sequence[str] | None,77) -> bool:78    match operator:79        case "contains":80            return _assert_contains(value=value, expected=expected)81        case "not contains":82            return _assert_not_contains(value=value, expected=expected)83        case "start with":84            return _assert_start_with(value=value, expected=expected)85        case "end with":86            return _assert_end_with(value=value, expected=expected)87        case "is":88            return _assert_is(value=value, expected=expected)89        case "is not":90            return _assert_is_not(value=value, expected=expected)91        case "empty":92            return _assert_empty(value=value)93        case "not empty":94            return _assert_not_empty(value=value)95        case "=":96            return _assert_equal(value=value, expected=expected)97        case "≠":98            return _assert_not_equal(value=value, expected=expected)99        case ">":100            return _assert_greater_than(value=value, expected=expected)101        case "<":102            return _assert_less_than(value=value, expected=expected)103        case "≥":104            return _assert_greater_than_or_equal(value=value, expected=expected)105        case "≤":106            return _assert_less_than_or_equal(value=value, expected=expected)107        case "null":108            return _assert_null(value=value)109        case "not null":110            return _assert_not_null(value=value)111        case "in":112            return _assert_in(value=value, expected=expected)113        case "not in":114            return _assert_not_in(value=value, expected=expected)115        case "all of" if isinstance(expected, list):116            return _assert_all_of(value=value, expected=expected)117        case "exists":118            return _assert_exists(value=value)119        case "not exists":120            return _assert_not_exists(value=value)121        case _:122            raise ValueError(f"Unsupported operator: {operator}")123 124 125def _assert_contains(*, value: Any, expected: Any) -> bool:126    if not value:127        return False128 129    if not isinstance(value, str | list):130        raise ValueError("Invalid actual value type: string or array")131 132    if expected not in value:133        return False134    return True135 136 137def _assert_not_contains(*, value: Any, expected: Any) -> bool:138    if not value:139        return True140 141    if not isinstance(value, str | list):142        raise ValueError("Invalid actual value type: string or array")143 144    if expected in value:145        return False146    return True147 148 149def _assert_start_with(*, value: Any, expected: Any) -> bool:150    if not value:151        return False152 153    if not isinstance(value, str):154        raise ValueError("Invalid actual value type: string")155 156    if not value.startswith(expected):157        return False158    return True159 160 161def _assert_end_with(*, value: Any, expected: Any) -> bool:162    if not value:163        return False164 165    if not isinstance(value, str):166        raise ValueError("Invalid actual value type: string")167 168    if not value.endswith(expected):169        return False170    return True171 172 173def _assert_is(*, value: Any, expected: Any) -> bool:174    if value is None:175        return False176 177    if not isinstance(value, str):178        raise ValueError("Invalid actual value type: string")179 180    if value != expected:181        return False182    return True183 184 185def _assert_is_not(*, value: Any, expected: Any) -> bool:186    if value is None:187        return False188 189    if not isinstance(value, str):190        raise ValueError("Invalid actual value type: string")191 192    if value == expected:193        return False194    return True195 196 197def _assert_empty(*, value: Any) -> bool:198    if not value:199        return True200    return False201 202 203def _assert_not_empty(*, value: Any) -> bool:204    if value:205        return True206    return False207 208 209def _assert_equal(*, value: Any, expected: Any) -> bool:210    if value is None:211        return False212 213    if not isinstance(value, int | float):214        raise ValueError("Invalid actual value type: number")215 216    if isinstance(value, int):217        expected = int(expected)218    else:219        expected = float(expected)220 221    if value != expected:222        return False223    return True224 225 226def _assert_not_equal(*, value: Any, expected: Any) -> bool:227    if value is None:228        return False229 230    if not isinstance(value, int | float):231        raise ValueError("Invalid actual value type: number")232 233    if isinstance(value, int):234        expected = int(expected)235    else:236        expected = float(expected)237 238    if value == expected:239        return False240    return True241 242 243def _assert_greater_than(*, value: Any, expected: Any) -> bool:244    if value is None:245        return False246 247    if not isinstance(value, int | float):248        raise ValueError("Invalid actual value type: number")249 250    if isinstance(value, int):251        expected = int(expected)252    else:253        expected = float(expected)254 255    if value <= expected:256        return False257    return True258 259 260def _assert_less_than(*, value: Any, expected: Any) -> bool:261    if value is None:262        return False263 264    if not isinstance(value, int | float):265        raise ValueError("Invalid actual value type: number")266 267    if isinstance(value, int):268        expected = int(expected)269    else:270        expected = float(expected)271 272    if value >= expected:273        return False274    return True275 276 277def _assert_greater_than_or_equal(*, value: Any, expected: Any) -> bool:278    if value is None:279        return False280 281    if not isinstance(value, int | float):282        raise ValueError("Invalid actual value type: number")283 284    if isinstance(value, int):285        expected = int(expected)286    else:287        expected = float(expected)288 289    if value < expected:290        return False291    return True292 293 294def _assert_less_than_or_equal(*, value: Any, expected: Any) -> bool:295    if value is None:296        return False297 298    if not isinstance(value, int | float):299        raise ValueError("Invalid actual value type: number")300 301    if isinstance(value, int):302        expected = int(expected)303    else:304        expected = float(expected)305 306    if value > expected:307        return False308    return True309 310 311def _assert_null(*, value: Any) -> bool:312    if value is None:313        return True314    return False315 316 317def _assert_not_null(*, value: Any) -> bool:318    if value is not None:319        return True320    return False321 322 323def _assert_in(*, value: Any, expected: Any) -> bool:324    if not value:325        return False326 327    if not isinstance(expected, list):328        raise ValueError("Invalid expected value type: array")329 330    if value not in expected:331        return False332    return True333 334 335def _assert_not_in(*, value: Any, expected: Any) -> bool:336    if not value:337        return True338 339    if not isinstance(expected, list):340        raise ValueError("Invalid expected value type: array")341 342    if value in expected:343        return False344    return True345 346 347def _assert_all_of(*, value: Any, expected: Sequence[str]) -> bool:348    if not value:349        return False350 351    if not all(item in value for item in expected):352        return False353    return True354 355 356def _assert_exists(*, value: Any) -> bool:357    return value is not None358 359 360def _assert_not_exists(*, value: Any) -> bool:361    return value is None362 363 364def _process_sub_conditions(365    variable: ArrayFileSegment,366    sub_conditions: Sequence[SubCondition],367    operator: Literal["and", "or"],368) -> bool:369    files = variable.value370    group_results = []371    for condition in sub_conditions:372        key = FileAttribute(condition.key)373        values = [file_manager.get_attr(file=file, attr=key) for file in files]374        sub_group_results = [375            _evaluate_condition(376                value=value,377                operator=condition.comparison_operator,378                expected=condition.value,379            )380            for value in values381        ]382        # Determine the result based on the presence of "not" in the comparison operator383        result = all(sub_group_results) if "not" in condition.comparison_operator else any(sub_group_results)384        group_results.append(result)385    return all(group_results) if operator == "and" else any(group_results)386