示例#1
0
def action_index(request):
    """
    Render the list of actions attached to a workflow.
    :param request: Request object
    :return: HTTP response with the table.
    """

    # Get the appropriate workflow object
    workflow = get_workflow(request)
    if not workflow:
        return redirect('workflow:index')

    # Get the actions
    actions = Action.objects.filter(
        workflow__id=workflow.id)

    # Context to render the template
    context = {'has_table': ops.workflow_has_table(workflow)}

    # Build the table only if there is anything to show (prevent empty table)
    qset = []
    for action in actions:
        qset.append({'id': action.id,
                     'name': action.name,
                     'description_text': action.description_text,
                     'is_out': action.is_out,
                     'is_correct': action.is_correct,
                     'modified': action.modified,
                     'serve_enabled': action.serve_enabled})

    context['table'] = ActionTable(qset, orderable=False)

    return render(request, 'action/index.html', context)
示例#2
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)
示例#3
0
def edit_action_in(request, pk):
    """
    View to handle the AJAX form to edit an action in (filter + columns).
    :param request: Request object
    :param pk: Action PK
    :return: HTTP response
    """

    # Check if the workflow is locked
    workflow = get_workflow(request)
    if not workflow:
        return redirect('workflow:index')

    if workflow.nrows == 0:
        messages.error(request,
                       'Workflow has no data. '
                       'Go to Dataops to upload data.')
        return redirect(reverse('action:index'))

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

    if action.is_out:
        # Trying to edit an incorrect action. Redirect to index
        return redirect('action:index')

    # 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)})

    # Get the number of rows in DF selected by filter.
    if filter_condition:
        filter_condition.n_rows_selected = \
            pandas_db.num_rows(action.workflow.id, filter_condition.formula)
        filter_condition.save()

    # Column names suitable to insert
    columns_selected = action.columns.filter(is_key=False).order_by('position')
    columns_to_insert = [c for c in workflow.columns.all()
                         if not c.is_key and c not in columns_selected]

    # Has key column and has no-key column
    has_no_key = action.columns.filter(is_key=False).exists()
    has_empty_description = columns_selected.filter(
        description_text=''
    ).exists()

    # Create the context info.
    ctx = {'action': action,
           'filter_condition': filter_condition,
           'selected_rows':
               filter_condition.n_rows_selected if filter_condition else -1,
           'total_rows': workflow.nrows,
           'query_builder_ops': workflow.get_query_builder_ops_as_str(),
           'has_data': ops.workflow_has_table(action.workflow),
           'key_selected': action.columns.filter(is_key=True).first(),
           'columns_to_insert': columns_to_insert,
           'column_selected_table': ColumnSelectedTable(
               columns_selected.values('id', 'name', 'description_text'),
               orderable=False,
               extra_columns=[
                   ('operations',
                    OperationsColumn(
                        verbose_name='Ops',
                        template_file=ColumnSelectedTable.ops_template,
                        template_context=lambda record: {'id': record['id'],
                                                         'aid': action.id})
                    )]
           ),
           'has_no_key': has_no_key,
           'has_empty_description': has_empty_description}

    return render(request, 'action/edit_in.html', ctx)