Commit c3c8b552 authored by Floreal Cabanettes's avatar Floreal Cabanettes
Browse files

Change rules (remove excludeif, toberequiredif and add activateif, requiredif)...

Change rules (remove excludeif, toberequiredif and add activateif, requiredif) and ConditionalLinkRule model
parent 31d9dd88
......@@ -15,6 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import re
from abc import ABC, abstractmethod
from jflow.parameter import InputFile, InputFileList, InputDirectory, MultiParameter, MultiParameterList
......@@ -55,7 +57,7 @@ class LinkRule (SimpleRule):
class ConditionalLinkRule(LinkRule):
def __init__(self, user_args, wf_instance, src_arg, targets_args, conditions, all_files=None):
def __init__(self, user_args, wf_instance, src_arg, targets_args, conditions, which, all_files=None):
LinkRule.__init__(self, user_args, wf_instance, src_arg, targets_args, all_files)
self.conditions = conditions
......@@ -63,12 +65,27 @@ class ConditionalLinkRule(LinkRule):
self.check_type_argument()
# Test condition is raised:
self.condition_raised = None
self.condition_raised = False
all_raised = True
for condition in self.conditions:
if (condition[0] == "!" and str(self.user_args[src_arg]) != str(condition[1:])) or (condition[0] != "!" and
str(self.user_args[src_arg]) == str(condition)):
self.condition_raised = condition
break
c_match = re.match(r"(\w+)(!)?=(.+)", condition)
name_arg = c_match.group(1)
if name_arg == "self":
name_arg = self.parameter_name
test_val = c_match.group(3)
is_equal = c_match.group(2) is None
#TODO: considère-t-on que si on a un !valeur, si le paramètre en question pas définit => condition is raised ?
if name_arg in self.user_args:
if (not is_equal and str(self.user_args[name_arg]) != str(test_val[1:])) or (is_equal and
str(self.user_args[name_arg]) == str(test_val)):
if which == "ANY":
self.condition_raised = True
break
elif which == "ALL":
all_raised = False
break
if which == "ALL" and all_raised:
self.condition_raised = True
def check_type_argument(self):
if isinstance(self.wf_parameter, InputFile) or isinstance(self.wf_parameter, InputFileList) or \
......@@ -90,36 +107,30 @@ class Exclude(LinkRule):
raise Exception("arguments " + self.parameter_name + " and " + exclude + " are mutually excluded")
class ExcludeIf(ConditionalLinkRule):
def check(self):
if self.condition_raised is not None:
validator = Exclude(self.user_args, self.wf_instance, self.parameter_name, self.targets_args, self.all_files)
try:
validator.check()
except Exception as e:
raise Exception("Argument " + self.parameter_name + " is set to " + self.condition_raised + ": " +
str(e))
class ToBeRequired(LinkRule):
def check(self):
for require in self.targets_args:
if require not in self.user_args or (require in self.user_args and self.user_args[require] is None): # The target is not found
if require not in self.user_args or (require in self.user_args and self.user_args[require] is None): # The
# target is not found
raise Exception("the argument " + self.parameter_name + " require argument " + require +
" to be defined")
class ToBeRequiredIf(ConditionalLinkRule):
class RequiredIf(ConditionalLinkRule):
def check(self):
if self.condition_raised is not None:
validator = ToBeRequired(self.user_args, self.wf_instance, self.parameter_name, self.targets_args,
self.all_files)
try:
validator.check()
except Exception as e:
raise Exception("Argument " + self.parameter_name + " is set to " + self.condition_raised + ": " +
str(e))
if self.parameter_name not in self.user_args or not self.user_args[self.parameter_name]:
raise Exception("Argument " + self.parameter_name + " is required, due to it's required rule")
class ActivateIf(ConditionalLinkRule):
def check(self):
if not self.condition_raised:
for target in self.targets_args:
if target in self.user_args and \
str(self.user_args[target]) != str(self.wf_instance.__dict__[target]):
print("\033[93mWarning: parameter " + target + " is ignored: " + self.parameter_name +
" is set to " + str(self.user_args[self.parameter_name]) + " \033[0m")
......@@ -1263,9 +1263,8 @@ class Workflow(threading.Thread):
rules[parameter.name] = parameter.rules.split(";")
# Other parameters:
elif parameter.name in user_params and user_params[parameter.name] is not None and user_params[
parameter.name]:
parameters_used[parameter.name] = user_params[parameter.name]
else:
parameters_used[parameter.name] = user_params[parameter.name] if parameter.name in user_params else None
if parameter.rules is not None:
rules[parameter.name] = parameter.rules.split(";")
if isinstance(parameter, InputFile):
......@@ -1276,7 +1275,8 @@ class Workflow(threading.Thread):
# Check rules:
for src_arg, arg_rules in rules.items():
for arg_rule in arg_rules:
self.check_parameter_rule(arg_rule, src_arg, parameters_used, all_files)
if arg_rule != "":
self.check_parameter_rule(arg_rule, src_arg, parameters_used, all_files)
def check_parameter_rule(self, rule: str, src_arg: str, user_args: dict, all_files: list):
"""
......@@ -1300,15 +1300,17 @@ class Workflow(threading.Thread):
###############################################################
# Regexp for special rules:
conditional_link_rule = r"(.+)\?\[(.+)\]=(.+)"
conditional_link_rule = r"(.+)\?(ANY|ALL)\[(.+)\](=(.+))?"
link_rule = r"(.+)=(.+)"
is_conditional_link_rule = re.match(conditional_link_rule, rule) # Check first special rule
if is_conditional_link_rule:
# Check this special rule:
name = is_conditional_link_rule.group(1)
conditions = is_conditional_link_rule.group(2).split(",")
targets = is_conditional_link_rule.group(3).split(",")
which = is_conditional_link_rule.group(2)
conditions = is_conditional_link_rule.group(3).split(",")
targets = is_conditional_link_rule.group(5)
targets = targets.split(",") if targets is not None else None
# Get validator:
if hasattr(wf_rules, name): # Check the rule exists
......@@ -1320,11 +1322,11 @@ class Workflow(threading.Thread):
# Launch validator:
if issubclass(validator_class, j_rules.ConditionalLinkRule): # Check the rule is the same special rule
validator = validator_class(user_args, self, src_arg, targets, conditions, all_files)
validator = validator_class(user_args, self, src_arg, targets, conditions, which, all_files)
validator.check()
else:
raise Exception("Rule is not a conditional link rule: " + name)
else:
elif src_arg in user_args and user_args[src_arg] is not None and user_args[src_arg]:
is_link_rule = re.match(link_rule, rule) # Check the second special rule
if is_link_rule:
# Check this special rule:
......
......@@ -446,8 +446,8 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
// when serializing, multiple data are repeated, so build a hash to gather values from the same parameter
$.each ( $('#workflow_form').serializeArray(), function(_, kv) {
console.log(kv.name, kv.value);
if ($('#'+kv.name).length == 0 || $('#'+kv.name).is(":enabled")) { // not exists or not disabled
if ($('#'+kv.name).length == 0 || ($('#'+kv.name).is(":enabled")
&& !$('#'+kv.name).hasClass("hidden-exclude"))) { // not exists or not disabled
if (kv.value != "" && $('#'+kv.name).attr("type") == "password" ){
kv.value = rc4_encrypt(kv.value)
}
......@@ -506,7 +506,6 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
});
$this.$element.off("uploaded.wfform").on("uploaded.wfform", function() {
$this.$element.off("uploaded");
$.ajax({
url: $this.options.serverURL + '/run_workflow?' + params + 'callback=?',
dataType: "json",
......@@ -742,9 +741,11 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
*/
var _add_event_rule_to_parameter = function (parameter_name, rule, parameter_type) {
var ruleExclude = /Exclude=(.+)/;
var ruleExcludeIf = /ExcludeIf\?\[(.+)\]=(.+)/;
var ruleExcludeIf = /ExcludeIf\?(ANY|ALL)\[(.+)\]=(.+)/;
var ruleToBeRequired = /ToBeRequired=(.+)/;
var ruleToBeRequiredIf = /ToBeRequiredIf\?\[(.+)\]=(.+)/;
//var ruleToBeRequiredIf = /ToBeRequiredIf\?\[(.+)\]=(.+)/;
var ruleRequiredIf = /RequiredIf\?(ANY|ALL)\[(.+)\]/;
var ruleActivateIf = /ActivateIf\?(ANY|ALL)\[(.+)\]=(.+)/;
var match;
/**
......@@ -755,7 +756,7 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
*/
var __exclude_targets = function(change_on, excludes) {
excludes.splice(excludes.indexOf(change_on.attr("id")), 1);
var excludes_objects = $("#" + excludes.join(", #"))
var excludes_objects = $("#" + excludes.join(", #"));
if ((parameter_type != "bool" && change_on.val().length > 0) ||
(parameter_type == "bool" && change_on.is(":checked"))) {
_disable_parameters(excludes_objects)
......@@ -772,33 +773,6 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
}
}
/**
* Disable targets excludes if the conditions are raised, else re-enable them
* @param excludes: name of targets excludes parameters
* @private
*/
var __check_exclude_targets = function(excludes) {
var condition_raised = false;
var parameter_object = $("#" + parameter_name)
if (parameter_type == "str") {
condition_raised = conditions.indexOf(parameter_object.val()) > -1;
}
else if (parameter_type == "bool") {
var val = parameter_object.is(":checked").toString();
val = val[0].toUpperCase() + val.slice(1);
condition_raised = conditions.indexOf(val) > -1;
}
var excludes_objects = $("#" + excludes.join(", #"));
if (condition_raised) {
_add_excludes_by_tag(excludes, parameter_object)
_disable_parameters(excludes_objects);
}
else {
_remove_excludes_by_tag(excludes, parameter_object)
_enable_parameters(excludes_objects);
}
}
/**
* Add the required rule to the form for given targets (according to change_on input parameter)
* @param change_on
......@@ -850,7 +824,7 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
* @param targets: targets to mark required
* @private
*/
var __make_required_targets = function(change_on, targets) {
var __required_targets = function(change_on, targets) {
if (change_on.length > 0) {
if ((parameter_type != "bool" && change_on.val().length > 0) ||
(parameter_type == "bool" && change_on.is(":checked"))) {
......@@ -871,7 +845,7 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
* @param targets: targets to mark required
* @private
*/
var __check_required_targets = function(parameter_object, targets) {
/*var __check_required_targets = function(parameter_object, targets) {
var condition_raised = false;
if (parameter_type == "str") {
condition_raised = conditions.indexOf(parameter_object.val()) > -1;
......@@ -887,6 +861,91 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
else {
__remove_required_target(parameter_object, targets);
}
}*/
var __check_condition_raised = function() {
var condition_raised = false;
var all_raised = true;
for (var param in conditions_params) {
var obj_param = $("#" + param);
if (obj_param.length > 0) {
var value = obj_param.val();
if (obj_param.is("input[type=checkbox]")) {
value = obj_param.is(":checked") ? "True" : "False";
}
var c_values = conditions_params[param].values;
if ((conditions_params[param].equal && ("*" in c_values && value != "" || c_values.indexOf(value) > -1)) ||
(!conditions_params[param].equal && ("*" in c_values && value == "" || c_values.indexOf(value) == -1))) {
if (which == "ANY") {
condition_raised = true;
break;
}
}
else if (which == "ALL") {
all_raised = false;
break;
}
}
else if (which == "ALL") {
all_raised = false;
break;
}
}
if (which == "ALL" && all_raised) {
condition_raised = true;
}
return condition_raised
}
var __check_activate_targets = function(parameter_object, targets) {
var condition_raised = __check_condition_raised();
for (var t in targets) {
var target = $("#" + targets[t]);
if (target.length > 0) {
if (condition_raised) {
target.closest("div.form-group").show()
target.removeClass("hidden-exclude")
}
else {
target.closest("div.form-group").hide()
target.addClass("hidden-exclude")
}
}
}
}
var __check_required = function() {
var condition_raised = __check_condition_raised();
if (condition_raised) {
param_input.rules("add", {"required": true})
}
else {
param_input.rules("remove", "required")
}
}
var __get_conditions_params = function() {
var conditions_params = {};
var re_cond = /(\w+)(!)?=(.*)/;
for (var c in conditions) {
var condition = conditions[c];
var match = null;
if (match = condition.match(re_cond)) {
var name = match[1] != "self" ? match[1] : parameter_name
if (!(name in conditions_params)) {
conditions_params[name] = {};
conditions_params[name]["equal"] = match[2] === undefined;
}
if (!("values" in conditions_params[name]))
conditions_params[name]["values"] = []
conditions_params[name]["values"].push(match[3]);
}
}
return conditions_params;
}
//Check rule Exclude
......@@ -910,40 +969,44 @@ Handsontable.cellTypes["bootdate"] = Handsontable.BootstrapDateCell;
}
}
//Check rule ExcludeIf
else if (match = rule.match(ruleExcludeIf)) {
var conditions = match[1].split(",");
var targets = match[2].split(",");
var param_input = $("#" + parameter_name);
param_input.on("change", function() {
__check_exclude_targets(targets);
});
__check_exclude_targets(targets);
}
//Check rule ToBeRequired
else if (match = rule.match(ruleToBeRequired)) {
var targets = match[1].split(",");
var param_input = $("#" + parameter_name)
var param_input = $("#" + parameter_name);
param_input.on("change", function() {
__make_required_targets(param_input, targets);
__required_targets(param_input, targets);
})
__make_required_targets(param_input, targets);
__required_targets(param_input, targets);
}
//Check rule ToBeRequiredIf
else if (match = rule.match(ruleToBeRequiredIf)) {
var conditions = match[1].split(",");
var targets = match[2].split(",");
//Check rule ActivateIf
else if (match = rule.match(ruleActivateIf)) {
var which = match[1]
var conditions = match[2].split(",");
var conditions_params = __get_conditions_params();
var tags = "#" + Object.keys(conditions_params).join(", #");
var targets = match[3].split(",");
var param_input = $("#" + parameter_name);
param_input.on("change", function() {
__check_required_targets(param_input, targets);
})
$(tags).on("change", function() {
__check_activate_targets(param_input, targets);
});
__check_activate_targets(param_input, targets);
}
__check_required_targets(param_input, targets);
//Check rule RequiredIf
else if (match = rule.match(ruleRequiredIf)) {
var which = match[1]
var conditions = match[2].split(",");
var conditions_params = __get_conditions_params();
var tags = "#" + Object.keys(conditions_params).join(", #");
var param_input = $("#" + parameter_name);
$(tags).on("change", function() {
__check_required();
});
__check_required();
}
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment