Exemple #1
0
def evaluate_row(action, row_idx):
    """
    Given an action and a row index, evaluate the content of the action for
    that index. The evaluation depends on the action type.

    Given an action object and a row index:
    1) Access the attached workflow
    2) Obtain the row of data from the appropriate data frame
    3) Process further depending on the type of action

    :param action: Action object
    :param row_idx: Row index to use for evaluation
    :return HTML content resulting from the evaluation
    """

    # Step 1: Get the workflow to access the data. No need to check for
    # locking information as it has been checked upstream.
    workflow = Workflow.objects.get(pk=action.workflow.id)

    # Step 2: Get the row of data from the DB
    try:
        cond_filter = Condition.objects.get(action__id=action.id,
                                            is_filter=True)
    except ObjectDoesNotExist:
        cond_filter = None

    # If row_idx is an integer, get the data by index, otherwise, by key
    if isinstance(row_idx, int):
        row_values = ops.get_table_row_by_index(workflow,
                                                cond_filter,
                                                row_idx)
    else:
        row_values = pandas_db.get_table_row_by_key(workflow,
                                                    cond_filter,
                                                    row_idx)
    if row_values is None:
        # No rows satisfy the given condition
        return None

    # Invoke the appropriate function depending on the action type
    if action.is_out:
        return evaluate_row_out(action, row_values)

    return evaluate_row_in(action, row_values)
Exemple #2
0
def get_row_values(action, row_idx):
    """
    Given an action and a row index, obtain the appropriate row of values
    from the data frame.

    :param action: Action object
    :param row_idx: Row index to use for evaluation
    :return Dictionary with the data row
    """

    # Step 1: Get the row of data from the DB
    cond_filter = action.get_filter()

    # If row_idx is an integer, get the data by index, otherwise, by key
    if isinstance(row_idx, int):
        result = ops.get_table_row_by_index(action.workflow, cond_filter,
                                            row_idx)
    else:
        result = pandas_db.get_table_row_by_key(action.workflow, cond_filter,
                                                row_idx)
    return result
def evaluate_row(action, row_idx):
    """
    Given an action object and a row index:
    1) Access the attached workflow
    2) Obtain the row of data from the appropriate data frame
    3) Evaluate the conditions with respect to the values in the row
    4) Create a context with the result of evaluating the conditions,
       attributes and column names to values
    5) Run the template with the context
    6) Return the resulting object (HTML?)

    :param action: Action object with pointers to conditions, filter,
                   workflow, etc.
    :param row_idx: Either an integer (row index), or a pair key=value to
           filter
    :return: None to flag an error
    """

    # Step 1: Get the workflow to access the data. No need to check for
    # locking information as it has been checked upstream.
    workflow = Workflow.objects.get(pk=action.workflow.id)

    # Step 2: Get the row of data from the DB
    try:
        cond_filter = Condition.objects.get(action__id=action.id,
                                            is_filter=True)
    except ObjectDoesNotExist:
        cond_filter = None

    # If row_idx is an integer, get the data by index, otherwise, by key
    if isinstance(row_idx, int):
        row_values = ops.get_table_row_by_index(workflow, cond_filter, row_idx)
    else:
        row_values = pandas_db.get_table_row_by_key(workflow, cond_filter,
                                                    row_idx)
    if row_values is None:
        # No rows satisfy the given condition
        return None

    # Step 3: Evaluate all the conditions
    condition_eval = {}
    condition_anomalies = []
    for condition in Condition.objects.filter(action__id=action.id).values(
            'name', 'is_filter', 'formula'):
        if condition['is_filter']:
            # Filter can be skipped in this stage
            continue

        # Evaluate the condition
        try:
            condition_eval[condition['name']] = \
                dataops.formula_evaluation.evaluate_top_node(
                    condition['formula'],
                    row_values
                )
        except OntaskException as e:
            condition_anomalies.append(e.value)

    # If any of the variables was incorrectly evaluated, we replace the
    # content and replace it by something noting this anomaly
    if condition_anomalies:
        return render_to_string('action/incorrect_preview.html',
                                {'missing_values': condition_anomalies})

    # Step 4: Create the context with the attributes, the evaluation of the
    # conditions and the values of the columns.
    attributes = workflow.attributes
    context = dict(dict(row_values, **condition_eval), **attributes)

    # Step 5: run the template with the given context
    # First create the template with the string stored in the action
    try:
        result = render_template(action.content, context, action)
    except TemplateSyntaxError as e:
        return render_to_string('action/syntax_error.html', {'msg': e.message})

    # Render the text
    return result