Esempio n. 1
0
def edit_action_out(request, pk):
    """
    View to handle the AJAX form to edit an action (editor, conditions,
    filters, etc).
    :param request: Request object
    :param pk: Action PK
    :return: JSON response
    """

    # Try to get the workflow first
    workflow = get_workflow(request)
    if not workflow:
        return redirect('workflow:index')

    # Get the action and create the form
    try:
        action = Action.objects.filter(
            Q(workflow__user=request.user) |
            Q(workflow__shared=request.user)).distinct().get(pk=pk)
    except ObjectDoesNotExist:
        return redirect('action:index')

    # Create the form
    form = EditActionOutForm(request.POST or None, instance=action)

    # See if the action has a filter or not
    try:
        filter_condition = Condition.objects.get(
            action=action, is_filter=True
        )
    except Condition.DoesNotExist:
        filter_condition = None
    except Condition.MultipleObjectsReturned:
        return render(request, 'error.html',
                      {'message': 'Malfunction detected when retrieving filter '
                                  '(action: {0})'.format(action.id)})

    # Conditions to show in the page as well.
    conditions = Condition.objects.filter(
        action=action, is_filter=False
    ).order_by('created').values('id', 'name')

    # Boolean to find out if there is a table attached to this workflow
    has_data = ops.workflow_has_table(action.workflow)

    # Get the total number of rows in DF and those selected by filter.
    total_rows = workflow.nrows
    if filter_condition:
        action.n_selected_rows = \
            pandas_db.num_rows(action.workflow.id, filter_condition.formula)

    # Context to render the form
    context = {'filter_condition': filter_condition,
               'action': action,
               'conditions': conditions,
               'query_builder_ops': workflow.get_query_builder_ops_as_str(),
               'attribute_names': [x for x in workflow.attributes.keys()],
               'column_names': workflow.get_column_names(),
               'selected_rows': action.n_selected_rows,
               'has_data': has_data,
               'total_rows': total_rows,
               'form': form,
               'vis_scripts': PlotlyHandler.get_engine_scripts()
               }

    # Processing the request after receiving the text from the editor
    if request.method == 'POST':
        # Get the next step
        next_step = request.POST['Submit']

        if form.is_valid():
            content = form.cleaned_data.get('content', None)
            # TODO: Can we detect unused vars only for this invocation?
            # Render the content as a template and catch potential problems.
            # This seems to be only possible if dealing directly with Jinja2
            # instead of Django.
            try:
                render_template(content, {}, action)
            except Exception as e:
                # Pass the django exception to the form (fingers crossed)
                form.add_error(None, e.message)
                return render(request, 'action/edit_out.html', context)

            # Log the event
            logs.ops.put(request.user,
                         'action_update',
                         action.workflow,
                         {'id': action.id,
                          'name': action.name,
                          'workflow_id': workflow.id,
                          'workflow_name': workflow.name,
                          'content': content})

            # Text is good. Update the content of the action
            action.content = content
            action.save()

            # Closing
            if next_step == 'Save-and-close':
                return redirect('action:index')

    # Return the same form in the same page
    return render(request, 'action/edit_out.html', context=context)
Esempio n. 2
0
def edit_action_out(request, workflow, action):
    """
    View to handle the form to edit an action OUT (editor, conditions,
    filters, etc).
    :param request: Request object
    :param action: Action
    :return: HTML response
    """

    # Create the form
    form = EditActionOutForm(request.POST or None, instance=action)

    # Get the filter or None
    filter_condition = action.get_filter()

    # Conditions to show in the page.
    conditions = Condition.objects.filter(action=action,
                                          is_filter=False).order_by('created')

    # Context to render the form
    context = {
        'filter_condition':
        filter_condition,
        'action':
        action,
        'conditions':
        conditions,
        'query_builder_ops':
        workflow.get_query_builder_ops_as_str(),
        'attribute_names': [x for x in workflow.attributes.keys()],
        'column_names':
        workflow.get_column_names(),
        'selected_rows':
        filter_condition.n_rows_selected if filter_condition else -1,
        'has_data':
        ops.workflow_has_table(action.workflow),
        'total_rows':
        workflow.nrows,
        'form':
        form,
        'vis_scripts':
        PlotlyHandler.get_engine_scripts()
    }

    # Template to use
    template = 'action/md_edit_personalized_text.html'
    if action.action_type == Action.PERSONALIZED_JSON:
        template = 'action/edit_personalized_json.html'

    # Processing the request after receiving the text from the editor
    if request.method == 'GET' or not form.is_valid():
        # Return the same form in the same page
        return render(request, template, context=context)

    # Get content
    content = form.cleaned_data.get('content', None)

    # Render the content as a template and catch potential problems.
    # This seems to be only possible if dealing directly with Jinja2
    # instead of Django.
    try:
        render_template(content, {}, action)
    except Exception as e:
        # Pass the django exception to the form (fingers crossed)
        form.add_error(None, e.message)
        return render(request, template, context)

    # Log the event
    Log.objects.register(
        request.user, Log.ACTION_UPDATE, action.workflow, {
            'id': action.id,
            'name': action.name,
            'workflow_id': workflow.id,
            'workflow_name': workflow.name,
            'content': content
        })

    # Text is good. Update the content of the action
    action.set_content(content)

    # Update additional fields
    if action.action_type == Action.PERSONALIZED_JSON:
        action.target_url = form.cleaned_data['target_url']

    action.save()

    return redirect('action:index')