diff --git a/plexpy/helpers.py b/plexpy/helpers.py index 0c330c86..c9982eb6 100644 --- a/plexpy/helpers.py +++ b/plexpy/helpers.py @@ -814,6 +814,7 @@ def parse_condition_logic_string(s, num_cond=0): bool_next = False open_bracket_next = True close_bracket_next = False + nest_and = False for i, x in enumerate(tokens): if open_bracket_next and x == '(': @@ -823,6 +824,7 @@ def parse_condition_logic_string(s, num_cond=0): bool_next = False open_bracket_next = True close_bracket_next = False + nest_and = False elif close_bracket_next and x == ')': stack.pop() @@ -832,6 +834,7 @@ def parse_condition_logic_string(s, num_cond=0): bool_next = True open_bracket_next = False close_bracket_next = True + nest_and = False elif cond_next and re.match(conditions_pattern, x): try: @@ -840,18 +843,33 @@ def parse_condition_logic_string(s, num_cond=0): raise ValueError('invalid condition logic') if not 0 < num <= num_cond: raise ValueError('invalid condition number in condition logic') - stack[-1].append(x) + stack[-1].append(num) + if nest_and: + stack.pop() cond_next = False bool_next = True open_bracket_next = False close_bracket_next = True + nest_and = False - elif bool_next and x in ('and', 'or') and i < len(tokens)-1: + elif bool_next and x == 'and' and i < len(tokens)-1: + stack[-1].append([]) + stack.append(stack[-1][-1]) + stack[-1].append(stack[-2].pop(-2)) stack[-1].append(x) cond_next = True bool_next = False open_bracket_next = True close_bracket_next = False + nest_and = True + + elif bool_next and x == 'or' and i < len(tokens)-1: + stack[-1].append(x) + cond_next = True + bool_next = False + open_bracket_next = True + close_bracket_next = False + nest_and = False else: raise ValueError('invalid condition logic') @@ -866,4 +884,25 @@ def nested_list_to_string(l): if isinstance(x, list): l[i] = nested_list_to_string(x) s = '(' + ' '.join(l) + ')' - return s \ No newline at end of file + return s + +def eval_logic_groups_to_bool(logic_groups, eval_conds): + first_cond = logic_groups[0] + + if isinstance(first_cond, list): + result = eval_logic_groups_to_bool(first_cond, eval_conds) + else: + result = eval_conds[first_cond] + + for op, cond in zip(logic_groups[1::2], logic_groups[2::2]): + if isinstance(cond, list): + eval_cond = eval_logic_groups_to_bool(cond, eval_conds) + else: + eval_cond = eval_conds[cond] + + if op == 'and': + result = result and eval_cond + elif op == 'or': + result = result or eval_cond + + return result \ No newline at end of file diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index 779a6fb0..0e3dd7b3 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -205,7 +205,6 @@ def notify_custom_conditions(notifier_id=None, parameters=None): try: # Parse and validate the custom conditions logic logic_groups = helpers.parse_condition_logic_string(custom_conditions_logic, len(custom_conditions)) - logic_string = helpers.nested_list_to_string(logic_groups) except ValueError as e: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom condition logic '%s': %s." % (custom_conditions_logic, e)) @@ -291,7 +290,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None): # Format and evaluate the logic string try: - evaluated_logic = bool(eval(logic_string.format(*evaluated_conditions))) + evaluated_logic = helpers.eval_logic_groups_to_bool(logic_groups, evaluated_conditions) except Exception as e: logger.error(u"PlexPy NotificationHandler :: Unable to evaluate custom condition logic: %s." % e) return False