def walk(self, root, values, evaluate=False, include_layout=False): """Will walk the tree recursivley and yields every field node. Optionally you can yield every layout elements too. If evaluate parameter is true, then the function will only return fields which are relevant after the conditionals in the form has been evaluated. :root: Root node :values: Dictionary with values which are used for evaluating conditionals. :evaluate: Flag to indicate if evaluation should be done on conditionals :include_layout: Flag to indicate to include layout elements too. :returns: yields field elements """ if root is None: root = self._tree for child in root: if len(child) > 0: if child.tag == "if": if evaluate: try: rule = Rule(child.attrib.get('expr')) if not rule.evaluate(values): continue except TypeError: # FIXME: This error can happen if the rule # refers to values which are not contained in # the provided values dictionary. The value # might be missing because the converting of the # value failed or the value was missing at # all.(e.g the field was a selection field and # was "disabled" in a conditional. In this case # the value is not sent. (ti) <2015-04-28 16:52> continue for elem in self.walk(child, values, evaluate, include_layout): yield elem elif include_layout and child.tag in ["page", "section", "subsection"]: yield child for elem in self.walk(child, values, evaluate, include_layout): yield elem else: for elem in self.walk(child, values, evaluate, include_layout): yield elem elif child.tag == "snippet": sref = child.attrib.get('ref') if sref: snippet = self._parent.get_element('snippet', sref) for elem in self.walk(snippet, values, evaluate, include_layout): yield elem elif child.tag == "field": yield child
def required_rule(self, rules): if self.required: expr = "bool($%s)" % self.name mode = "pre" rule = Rule(expr, required_msg, mode) rule.required = True rules.append(rule)
def desired_rule(self, rules): if self.desired: expr = "bool($%s)" % self.name mode = "pre" triggers = "warning" rule = Rule(expr, desired_msg, mode, triggers) rule.desired = True rules.append(rule)
def evaluate(request): """Will return a JSON response with the result of the evaluation of the submitted formbar rule.""" rule = Rule(request.GET.get('rule')) result = rule.evaluate({}) return {"success": True, "data": result, "params": {"msg": rule.msg}}
def walk(self, root, values, evaluate=False, include_layout=False): """Will walk the tree recursivley and yields every field node. Optionally you can yield every layout elements too. If evaluate parameter is true, then the function will only return fields which are relevant after the conditionals in the form has been evaluated. :root: Root node :values: Dictionary with values which are used for evaluating conditionals. :evaluate: Flag to indicate if evaluation should be done on conditionals :include_layout: Flag to indicate to include layout elements too. :returns: yields field elements """ for child in root: if len(child) > 0: if child.tag == "if": if evaluate: try: rule = Rule(child.attrib.get('expr')) if not rule.evaluate(values): continue except TypeError: # FIXME: This error can happen if the rule # refers to values which are not contained in # the provided values dictionary. The value # might be missing because the converting of the # value failed or the value was missing at # all.(e.g the field was a selection field and # was "disabled" in a conditional. In this case # the value is not sent. (ti) <2015-04-28 16:52> continue for elem in self.walk(child, values, evaluate, include_layout): yield elem elif include_layout and child.tag in ["section", "subsection"]: yield child for elem in self.walk(child, values, evaluate, include_layout): yield elem else: for elem in self.walk(child, values, evaluate, include_layout): yield elem elif child.tag == "snippet": sref = child.attrib.get('ref') if sref: snippet = self._parent.get_element('snippet', sref) for elem in self.walk(snippet, values, evaluate, include_layout): yield elem elif child.tag == "field": yield child
def evaluate(request): """Method which will evaluate a formed rule given in the GET request. It will return a JSONResponse with the result of the evaluation.""" try: ruleexpr = request.GET.get('rule').strip() rule = Rule(ruleexpr) result = rule.evaluate({}) return JSONResponse(True, result, {"msg": rule.msg}) except: msg = "Can not evaluate rule '%s'" % ruleexpr log.error(msg) return JSONResponse(False, False, {"msg": msg})
def _build_filter_rule(self, expr_str, item): t = expr_str.split(" ") # The filter expression may reference values of the form using $ # variables. To have access to these values we extract the # values from the given item if available. # TODO: Access to the item is usally no good idea as formbar can # be used in environments where no item is available. if self._form._item: item_values = self._form._item.get_values() else: item_values = {} for x in t: # % marks the options in the selection field. It is used to # iterate over the options in the selection. I case the # options are SQLAlchemy based options the variable can be # used to access a attribute of the item. E.g. %id will # access the id of the current option item. For user defined # options "%" can be used to iterate over the user defined # options. In this case %attr will access a given attribte # in the option. A bare "%" will give the value of the # option. if x.startswith("%"): key = x.strip("%") value = "$%s" % (key or "value") # @ marks the item of the current fields form item. elif x.startswith("@"): key = x.strip("@") value = getattr(self._form._item, key) # $ special attributes of the current form. elif x.startswith("$"): tmpitem = None value = None tokens = x.split(".") if len(tokens) > 1: key = tokens[0].strip("$") attribute = ".".join(tokens[1:]) # FIXME: This is a bad assumption that there is a # user within a request. (ti) <2014-07-09 11:18> if key == "user": tmpitem = self._form._request.user else: key = tokens[0].strip("$") value = item_values.get(key) or '' if tmpitem and not value: value = getattr(tmpitem, attribute) if hasattr(value, '__call__'): value = value() else: value = None if value is not None: if isinstance(value, list): value = "[%s]" % ",".join("'%s'" % unicode(v) for v in value) expr_str = expr_str.replace(x, value) elif isinstance(value, basestring) and value.startswith("$"): expr_str = expr_str.replace(x, "%s" % unicode(value)) else: expr_str = expr_str.replace(x, "'%s'" % unicode(value)) return Rule(str(expr_str))
def get_rules(self): rules = [] # Add automatic genertated rules based on the required or # desired flag if self.required: expr = "bool($%s)" % self.name mode = "pre" rules.append(Rule(expr, required_msg, mode)) if self.desired: expr = "bool($%s)" % self.name mode = "pre" triggers = "warning" rules.append(Rule(expr, desired_msg, mode, triggers)) # Add rules added the the field. for rule in self._tree.findall('rule'): expr = rule.attrib.get('expr') msg = rule.attrib.get('msg') mode = rule.attrib.get('mode') triggers = rule.attrib.get('triggers') rules.append(Rule(expr, msg, mode, triggers)) return rules
def get_rules(self): rules = [] # Add automatic genertated rules based on the required or # desired flag self.required_rule(rules) self.desired_rule(rules) # Add rules added the the field. for rule in self.get_elements('rule'): expr = rule.attrib.get('expr') msg = rule.attrib.get('msg') mode = rule.attrib.get('mode') triggers = rule.attrib.get('triggers') rules.append(Rule(expr, msg, mode, triggers)) return rules
def _build_filter_rule(self, expr_str, item): return Rule(self.parse_expression(expr_str))