def run_json_list_action(
    req: HttpRequest,
    workflow: Workflow,
    action: Action,
) -> HttpResponse:
    """Request data to send JSON objects.

    Form asking for token and export wf

    :param req: HTTP request (GET)
    :param workflow: workflow being processed
    :param action: Action begin run
    :return: HTTP response
    """
    # Get the payload from the session, and if not, use the given one
    action_info = JSONListPayload({'action_id': action.id})

    # Create the form to ask for the email subject and other information
    form = JSONListActionForm(req.POST or None, form_info=action_info)

    if req.method == 'POST' and form.is_valid():
        # Log the event
        log_item = Log.objects.register(
            req.user, Log.SCHEDULE_JSON_EXECUTE, action.workflow, {
                'action': action.name,
                'action_id': action.id,
                'exported_workflow': action_info['export_wf'],
                'status': 'Preparing to execute',
                'target_url': action.target_url
            })

        # Update the last_execution_log
        action.last_executed_log = log_item
        action.save()

        # Send the objects
        run_task.delay(req.user.id, log_item.id, action_info.get_store())

        # Reset object to carry action info throughout dialogs
        set_action_payload(req.session)
        req.session.save()

        # Successful processing.
        return render(req, 'action/action_done.html', {
            'log_id': log_item.id,
            'download': action_info['export_wf']
        })

    # Render the form
    return render(
        req, 'action/request_json_list_data.html', {
            'action': action,
            'num_msgs': action.get_rows_selected(),
            'form': form,
            'valuerange': range(2),
            'rows_all_false': action.get_row_all_false_count()
        })
示例#2
0
def run_json_action(
    req: HttpRequest,
    workflow: Workflow,
    action: Action,
) -> HttpResponse:
    """Request data to send JSON objects.

    Form asking for token, item_column and if an item confirmation step is
    needed

    :param req: HTTP request (GET)
    :param workflow: workflow being processed
    :param action: Action begin run
    :return: HTTP response
    """
    # Get the payload from the session, and if not, use the given one
    action_info = get_or_set_action_info(
        req.session,
        JSONPayload,
        initial_values={
            'action_id': action.id,
            'prev_url': reverse('action:run', kwargs={'pk': action.id}),
            'post_url': reverse('action:json_done')
        },
    )

    # Create the form to ask for the email subject and other information
    form = JSONActionForm(req.POST or None,
                          column_names=[
                              col.name
                              for col in workflow.columns.filter(is_key=True)
                          ],
                          form_info=action_info)

    if req.method == 'POST' and form.is_valid():
        if action_info['confirm_items']:
            # Add information to the session object to execute the next pages
            action_info['button_label'] = ugettext('Send')
            action_info['valuerange'] = 2
            action_info['step'] = 2
            set_action_payload(req.session, action_info.get_store())

            return redirect('action:item_filter')

        # Go straight to the final step.
        return run_json_done(req, action_info=action_info, workflow=workflow)

    # Render the form
    return render(
        req, 'action/request_json_data.html', {
            'action': action,
            'num_msgs': action.get_rows_selected(),
            'form': form,
            'valuerange': range(2),
            'rows_all_false': action.get_row_all_false_count()
        })
示例#3
0
    def get_render_context(
        action: models.Action,
        form: Optional[Type[forms.ModelForm]] = None,
        form_filter: Optional[condition_forms.FilterForm] = None,
    ) -> Dict:
        """Get the initial context to render the response."""
        filter_condition = action.get_filter()
        return {
            # Workflow elements
            'attribute_names':
            [attr for attr in list(action.workflow.attributes.keys())],
            'columns':
            action.workflow.columns.all(),
            'has_data':
            action.workflow.has_table(),
            'total_rows':
            action.workflow.nrows,

            # Action Elements
            'action':
            action,
            'form':
            form,
            'form_filter':
            form_filter,
            'filter_condition':
            filter_condition,
            'selected_rows':
            filter_condition.n_rows_selected if filter_condition else -1,
            'is_email_report':
            action.action_type == models.Action.EMAIL_REPORT,
            'is_report': (action.action_type == models.Action.EMAIL_REPORT
                          or action.action_type == models.Action.JSON_REPORT),
            'is_personalized_text':
            (action.action_type == models.Action.PERSONALIZED_TEXT),
            'is_rubric':
            action.action_type == models.Action.RUBRIC_TEXT,
            'is_survey':
            action.action_type == models.Action.SURVEY,
            'all_false_conditions':
            any(cond.n_rows_selected == 0 for cond in action.conditions.all()),
            'rows_all_false':
            action.get_row_all_false_count(),

            # Page elements
            'load_summernote':
            (action.action_type == models.Action.PERSONALIZED_TEXT
             or action.action_type == models.Action.EMAIL_REPORT
             or action.action_type == models.Action.RUBRIC_TEXT),
            'query_builder_ops':
            action.workflow.get_query_builder_ops_as_str(),
            'vis_scripts':
            PlotlyHandler.get_engine_scripts()
        }
示例#4
0
def edit_action_rubric(
    request: HttpRequest,
    workflow: Workflow,
    action: Action,
) -> HttpResponse:
    """Edit action out.

    :param request: Request object
    :param workflow: The workflow with the action
    :param action: Action
    :return: HTML response
    """
    # Create the form
    form = EditActionOutForm(request.POST or None, instance=action)

    form_filter = FilterForm(request.POST or None,
                             instance=action.get_filter(),
                             action=action)

    # Processing the request after receiving the text from the editor
    if request.method == 'POST' and form.is_valid() and form_filter.is_valid():
        # Get content
        text_content = form.cleaned_data.get('text_content')

        # Render the content as a template and catch potential problems.
        if text_renders_correctly(text_content, action, form):
            # Log the event
            action.log(request.user, Log.ACTION_UPDATE)

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

            if request.POST['Submit'] == 'Submit':
                return redirect(request.get_full_path())

            return redirect('action:index')

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

    criteria = action.column_condition_pair.all()

    if not _verify_criteria_loas(criteria):
        messages.error(request, _('Inconsistent LOA in rubric criteria'))
        return redirect(reverse('action:index'))

    columns_to_insert_qs = action.workflow.columns.exclude(
        column_condition_pair__action=action, ).exclude(
            is_key=True, ).distinct().order_by('position')
    if criteria:
        columns_to_insert = [
            column for column in columns_to_insert_qs
            if set(column.categories) == set(criteria[0].column.categories)
        ]
    else:
        columns_to_insert = [
            column for column in columns_to_insert_qs if column.categories
        ]

    # This is a GET request or a faulty POST request
    context = {
        'form':
        form,
        'form_filter':
        form_filter,
        'filter_condition':
        filter_condition,
        'action':
        action,
        'load_summernote':
        Action.LOAD_SUMMERNOTE[action.action_type],
        'query_builder_ops':
        action.workflow.get_query_builder_ops_as_str(),
        'attribute_names':
        [attr for attr in list(action.workflow.attributes.keys())],
        'columns':
        action.workflow.columns.all(),
        'selected_rows':
        filter_condition.n_rows_selected if filter_condition else -1,
        'has_data':
        action.workflow.has_table(),
        'is_send_list': (action.action_type == Action.SEND_LIST
                         or action.action_type == Action.SEND_LIST_JSON),
        'is_personalized_text':
        action.action_type == Action.PERSONALIZED_TEXT,
        'is_rubric_cell':
        action.action_type == Action.RUBRIC_TEXT,
        'rows_all_false':
        action.get_row_all_false_count(),
        'total_rows':
        action.workflow.nrows,
        'all_false_conditions':
        False,
        'columns_to_insert':
        columns_to_insert,
        'vis_scripts':
        PlotlyHandler.get_engine_scripts()
    }

    # Get additional context to render the page depending on the action type
    if criteria:
        _create_rubric_table(request, action, criteria, context)

    # Return the same form in the same page
    return render(request, 'action/edit_rubric.html', context=context)
示例#5
0
def run_canvas_email_action(
    req: WSGIRequest,
    workflow: Workflow,
    action: Action,
) -> HttpResponse:
    """Request data to send JSON objects.

    Form asking for subject, item column (contains ids to select unique users),
    confirm items (add extra step to drop items), export workflow and
    target_rul (if needed).

    :param req: HTTP request (GET)
    :param workflow: workflow being processed
    :param action: Action begin run
    :return: HTTP response
    """
    # Get the payload from the session, and if not, use the given one
    action_info = get_or_set_action_info(
        req.session,
        CanvasEmailPayload,
        initial_values={
            'action_id': action.id,
            'prev_url': reverse('action:run', kwargs={'pk': action.id}),
            'post_url': reverse('action:canvas_email_done'),
        },
    )

    # Create the form to ask for the email subject and other information
    form = CanvasEmailActionForm(
        req.POST or None,
        column_names=[
            col.name for col in workflow.columns.filter(is_key=True)
        ],
        action=action,
        form_info=action_info)

    if req.method == 'POST' and form.is_valid():
        # Request is a POST and is valid

        if action_info['confirm_items']:
            # Create a dictionary in the session to carry over all the
            # information to execute the next pages
            action_info['button_label'] = ugettext('Send')
            action_info['valuerange'] = 2
            action_info['step'] = 2
            set_action_payload(req.session, action_info.get_store())
            continue_url = 'action:item_filter'
        else:
            continue_url = 'action:canvas_email_done'

        # Check for the CANVAS token and proceed to the continue_url
        return canvas_get_or_set_oauth_token(req, action_info['target_url'],
                                             continue_url)

    # Render the form
    return render(
        req, 'action/request_canvas_email_data.html', {
            'action': action,
            'num_msgs': action.get_rows_selected(),
            'form': form,
            'valuerange': range(2),
            'rows_all_false': action.get_row_all_false_count()
        })
def edit_action_out(
    request: HttpRequest,
    workflow: Workflow,
    action: Action,
) -> HttpResponse:
    """Edit action out.

    :param request: Request object
    :param workflow: The workflow with the action
    :param action: Action
    :return: HTML response
    """
    # Create the form
    form = EditActionOutForm(request.POST or None, instance=action)

    form_filter = FilterForm(request.POST or None,
                             instance=action.get_filter(),
                             action=action)

    # Processing the request after receiving the text from the editor
    if request.method == 'POST' and form.is_valid() and form_filter.is_valid():
        # Get content
        text_content = form.cleaned_data.get('text_content')

        # Render the content as a template and catch potential problems.
        if _text_renders_correctly(text_content, action, form):
            # 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': text_content
                })

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

            # If it is a JSON action, store the target_url
            if (action.action_type == Action.personalized_json
                    or action.action_type == Action.send_list_json):
                # Update the target_url field
                action.target_url = form.cleaned_data['target_url']

            action.save()

            if request.POST['Submit'] == 'Submit':
                return redirect(request.get_full_path())

            return redirect('action:index')

    # This is a GET request or a faulty POST request

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

    # Context to render the form
    context = {
        'filter_condition':
        filter_condition,
        'action':
        action,
        'load_summernote': (action.action_type == Action.personalized_text
                            or action.action_type == Action.send_list),
        'conditions':
        action.conditions.filter(is_filter=False),
        'other_conditions':
        Condition.objects.filter(
            action__workflow=workflow,
            is_filter=False,
        ).exclude(action=action),
        'query_builder_ops':
        workflow.get_query_builder_ops_as_str(),
        'attribute_names': [attr for attr in list(workflow.attributes.keys())],
        'columns':
        workflow.columns.all(),
        'stat_columns':
        workflow.columns.filter(is_key=False),
        'selected_rows':
        filter_condition.n_rows_selected if filter_condition else -1,
        'has_data':
        action.workflow.has_table(),
        'is_send_list': (action.action_type == Action.send_list
                         or action.action_type == Action.send_list_json),
        'all_false_conditions':
        any(cond.n_rows_selected == 0 for cond in action.conditions.all()),
        'rows_all_false':
        action.get_row_all_false_count(),
        'total_rows':
        workflow.nrows,
        'form':
        form,
        'form_filter':
        form_filter,
        'vis_scripts':
        PlotlyHandler.get_engine_scripts(),
    }

    # Return the same form in the same page
    return render(request, 'action/edit_out.html', context=context)