예제 #1
0
def serve_action_out(
    user,
    action: Action,
    user_attribute_name: str,
):
    """Serve request for an action out.

    Function that given a user and an Action Out
    searches for the appropriate data in the table with the given
    attribute name equal to the user email and returns the HTTP response.
    :param user: User object making the request
    :param action: Action to execute (action out)
    :param user_attribute_name: Column to check for email
    :return:
    """
    # For the response
    payload = {'action': action.name, 'action_id': action.id}

    # User_instance has the record used for verification
    row_values = get_row_values(action, (user_attribute_name, user.email))

    # Get the dictionary containing column names, attributes and condition
    # valuations:
    context = get_action_evaluation_context(action, row_values)
    if context is None:
        payload['error'] = (
            _('Error when evaluating conditions for user {0}').format(
                user.email, ))
        # Log the event
        Log.objects.register(user,
                             Log.ACTION_SERVED_EXECUTE,
                             workflow=action.workflow,
                             payload=payload)
        return HttpResponse(
            render_to_string('action/action_unavailable.html', {}))

    # Evaluate the action content.
    action_content = evaluate_row_action_out(action, context)

    # If the action content is empty, forget about it
    response = action_content
    if action_content is None:
        response = render_to_string('action/action_unavailable.html', {})
        payload['error'] = _('Action not enabled for user {0}').format(
            user.email, )

    # Log the event
    Log.objects.register(user,
                         Log.ACTION_SERVED_EXECUTE,
                         workflow=action.workflow,
                         payload=payload)

    # Respond the whole thing
    return HttpResponse(response)
예제 #2
0
def preview_response(request, pk, idx):
    """
    HTML request and the primary key of an action to preview one of its
    instances. The request must provide and additional parameter idx to
    denote which instance to show.

    :param request: HTML request object
    :param pk: Primary key of the an action for which to do the preview
    :param idx: Index of the reponse to preview
    :return:
    """

    # To include in the JSON response
    data = dict()

    # Action being used
    try:
        action = Action.objects.get(id=pk)
    except ObjectDoesNotExist:
        data['form_is_valid'] = True
        data['html_redirect'] = reverse('workflow:index')
        return JsonResponse(data)

    # Get the workflow to obtain row numbers
    workflow = get_workflow(request, action.workflow.id)
    if not workflow:
        data['form_is_valid'] = True
        data['html_redirect'] = reverse('workflow:index')
        return JsonResponse(data)

    # If the request has the 'action_content', update the action
    action_content = request.POST.get('action_content', None)
    if action_content:
        action.set_content(action_content)
        action.save()

    # Turn the parameter into an integer
    idx = int(idx)

    # Get the total number of items
    filter_obj = action.get_filter()
    n_items = filter_obj.n_rows_selected if filter_obj else -1
    if n_items == -1:
        n_items = workflow.nrows

    # Set the idx to a legal value just in case
    if not 1 <= idx <= n_items:
        idx = 1

    prv = idx - 1
    if prv <= 0:
        prv = n_items

    nxt = idx + 1
    if nxt > n_items:
        nxt = 1

    row_values = get_row_values(action, idx)

    # Get the dictionary containing column names, attributes and condition
    # valuations:
    context = action.get_evaluation_context(row_values)

    # Evaluate the action content.
    show_values = ''
    correct_json = True
    if action.is_out:
        action_content = evaluate_row_action_out(action, context)
        if action.action_type == Action.PERSONALIZED_JSON:
            try:
                __ = json.loads(action_content)
            except Exception:
                correct_json = False
    else:
        action_content = evaluate_row_action_in(action, context)
    if action_content is None:
        action_content = \
            _("Error while retrieving content for student {0}").format(idx)
    else:
        # Get the conditions used in the action content
        act_cond = action.get_action_conditions()
        # Get the variables/columns from the conditions
        act_vars = set().union(
            *[x.columns.all()
              for x in action.conditions.filter(name__in=act_cond)
              ]
        )
        # Sort the variables/columns  by position and get the name
        show_values = ', '.join(
            ["{0} = {1}".format(x.name, row_values[x.name]) for x in act_vars]
        )

    # See if there is prelude content in the request
    prelude = request.GET.get('subject_content', None)
    if prelude:
        prelude = evaluate_row_action_out(action, context, prelude)

    data['html_form'] = \
        render_to_string('action/includes/partial_preview.html',
                         {'action': action,
                          'action_content': action_content,
                          'index': idx,
                          'n_items': n_items,
                          'nxt': nxt,
                          'prv': prv,
                          'prelude': prelude,
                          'correct_json': correct_json,
                          'show_values': show_values},
                         request=request)

    return JsonResponse(data)
예제 #3
0
def preview_response(
    request: HttpRequest,
    pk: int,
    idx: int,
    workflow: Optional[Workflow] = None,
    action: Optional[Action] = None,
) -> JsonResponse:
    """Preview content of action.

    HTML request and the primary key of an action to preview one of its
    instances. The request must provide and additional parameter idx to
    denote which instance to show.

    :param request: HTML request object

    :param pk: Primary key of the an action for which to do the preview

    :param idx: Index of the reponse to preview

    :param action: Might have been fetched already

    :return: JsonResponse
    """
    # If the request has the 'action_content', update the action
    action_content = request.POST.get('action_content')
    if action_content:
        action.set_text_content(action_content)
        action.save()

    # Get the total number of items
    filter_obj = action.get_filter()
    n_items = filter_obj.n_rows_selected if filter_obj else workflow.nrows

    # Set the idx to a legal value just in case
    if not 1 <= idx <= n_items:
        idx = 1

    prv = idx - 1
    if prv <= 0:
        prv = n_items

    nxt = idx + 1
    if nxt > n_items:
        nxt = 1

    row_values = get_row_values(action, idx)

    # Obtain the dictionary with the condition evaluation
    condition_evaluation = action_condition_evaluation(action, row_values)
    # Get the dictionary containing column names, attributes and condition
    # valuations:
    context = get_action_evaluation_context(action, row_values,
                                            condition_evaluation)

    all_false = False
    if action.conditions.filter(is_filter=False).count():
        # If there are conditions, check if they are all false
        all_false = all(not bool_val
                        for __, bool_val in condition_evaluation.items())

    # Evaluate the action content.
    show_values = ''
    correct_json = True
    if action.is_out:
        action_content = evaluate_row_action_out(action, context)
        if action.action_type == Action.personalized_json:
            try:
                json.loads(action_content)
            except Exception:
                correct_json = False
    else:
        action_content = evaluate_row_action_in(action, context)
    if action_content is None:
        action_content = _(
            'Error while retrieving content for student {0}', ).format(idx)
    else:
        # Get the conditions used in the action content
        act_cond = action.get_used_conditions()
        # Get the variables/columns from the conditions
        act_vars = set().union(
            *[
                cond.columns.all()
                for cond in action.conditions.filter(name__in=act_cond)
            ], )
        # Sort the variables/columns  by position and get the name
        show_values = ', '.join([
            '{0} = {1}'.format(col.name, row_values[col.name])
            for col in act_vars
        ], )

    uses_plain_text = (action.action_type == Action.personalized_canvas_email
                       or action.action_type == Action.personalized_json)
    if uses_plain_text:
        action_content = escape(action_content)

    # See if there is prelude content in the request
    prelude = request.GET.get('subject_content')
    if prelude:
        prelude = evaluate_row_action_out(action, context, prelude)

    return JsonResponse({
        'html_form':
        render_to_string('action/includes/partial_preview.html', {
            'action': action,
            'action_content': action_content,
            'index': idx,
            'n_items': n_items,
            'nxt': nxt,
            'prv': prv,
            'prelude': prelude,
            'correct_json': correct_json,
            'show_values': show_values,
            'all_false': all_false,
        },
                         request=request),
    })