Exemplo n.º 1
0
class ActionCreateView(UserIsInstructor, generic.TemplateView):
    """Process get/post requests to create an action."""

    form_class = forms.ActionForm

    template_name = 'action/includes/partial_action_create.html'

    @method_decorator(user_passes_test(is_instructor))
    @method_decorator(ajax_required)
    @method_decorator(get_workflow())
    def get(self, request: http.HttpRequest, *args,
            **kwargs) -> http.HttpResponse:
        """Process the get requet when creating an action."""
        return services.save_action_form(
            request,
            self.form_class(workflow=kwargs.get('workflow')),
            self.template_name,
            workflow=kwargs.get('workflow'),
        )

    @method_decorator(user_passes_test(is_instructor))
    @method_decorator(ajax_required)
    @method_decorator(get_workflow())
    def post(self, request: http.HttpRequest, **kwargs) -> http.HttpResponse:
        """Process the post request when creating an action."""
        return services.save_action_form(
            request,
            self.form_class(request.POST, workflow=kwargs.get('workflow')),
            self.template_name,
            workflow=kwargs.get('workflow'),
        )
Exemplo n.º 2
0
class WorkflowAPILock(APIView):
    """Information stating if the workflow is locked.

    get: return information about the worklfow

    post: Tries to lock the workflow

    delete: unlock the workflow
    """

    serializer_class = WorkflowLockSerializer

    permission_classes = (UserIsInstructor, )

    @method_decorator(get_workflow(pf_related='columns'))
    def get(
        self,
        request: http.HttpRequest,
        pk: int,
        format=None,  # noqa: 132
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Return the serialized value of the lock property in the wflow."""
        del request, pk, format
        serializer = self.serializer_class({'lock': workflow.is_locked()})
        return Response(serializer.data, status=status.HTTP_200_OK)

    @method_decorator(get_workflow(pf_related='columns'))
    def post(
        self,
        request: http.HttpRequest,
        pk: int,
        format=None,  # noqa: 132
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Set the lock for a workflow."""
        del request, pk, format, workflow
        return Response(status=status.HTTP_201_CREATED)

    @method_decorator(get_workflow(pf_related='columns'))
    def delete(
        self,
        request: http.HttpRequest,
        pk: int,
        format=None,  # noqa: 132
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Remove the lock in a workflow."""
        del request, pk, format
        workflow.unlock()
        return Response(status=status.HTTP_200_OK)
Exemplo n.º 3
0
class ActionUpdateView(UserIsInstructor, generic.DetailView):
    """Process the Action Update view.

    @DynamicAttrs
    """

    model = models.Action
    template_name = 'action/includes/partial_action_update.html'
    context_object_name = 'action'
    form_class = forms.ActionUpdateForm

    def get_object(self, queryset=None) -> models.Action:
        """Access the Action object being manipulated."""
        act_obj = super().get_object(queryset=queryset)
        if act_obj.workflow.id != self.request.session['ontask_workflow_id']:
            raise http.Http404()

        return act_obj

    @method_decorator(user_passes_test(is_instructor))
    @method_decorator(ajax_required)
    @method_decorator(get_workflow())
    def get(self, request: http.HttpRequest, *args,
            **kwargs) -> http.HttpResponse:
        """Process the get request."""
        return services.save_action_form(
            request,
            self.form_class(instance=self.get_object(),
                            workflow=kwargs['workflow']), self.template_name)

    @method_decorator(user_passes_test(is_instructor))
    @method_decorator(ajax_required)
    @method_decorator(get_workflow())
    def post(self, request: http.HttpRequest, **kwargs) -> http.HttpResponse:
        """Process post request."""
        return services.save_action_form(
            request,
            self.form_class(
                request.POST,
                instance=self.get_object(),
                workflow=kwargs['workflow'],
            ), self.template_name)
Exemplo n.º 4
0
Arquivo: api.py Projeto: ubc/ontask_b
class TableBasicMerge(APIView):
    """Basic table merge methods.

    get:
    Retrieves the data frame attached to the workflow and returns it labeled
    as "data_frame"

    post:
    Request to merge a given data frame with the one attached to the workflow.
    """

    serializer_class = None

    permission_classes = (UserIsInstructor, )

    # Retrieve
    @method_decorator(get_workflow(pf_related='columns'))
    def get(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Process the GET request."""
        del request, wid, format
        # Try to retrieve the wflow to check for permissions
        serializer = self.serializer_class({
            'src_df':
            pandas.load_table(workflow.get_data_frame_table_name()),
            'how':
            '',
            'left_on':
            '',
            'right_on':
            ''
        })
        return Response(serializer.data)

    # Update
    @method_decorator(get_workflow(pf_related='columns'))
    def put(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Process the put request."""
        del wid, format
        # Get the dst_df
        dst_df = pandas.load_table(workflow.get_data_frame_table_name())

        serializer = self.serializer_class(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

        src_df = serializer.validated_data['src_df']
        how = serializer.validated_data['how']
        left_on = serializer.validated_data['left_on']
        right_on = serializer.validated_data['right_on']
        error = pandas.validate_merge_parameters(dst_df, src_df, how, left_on,
                                                 right_on)

        if error:
            raise APIException(error)

        # Ready to perform the MERGE
        try:
            pandas.perform_dataframe_upload_merge(
                workflow, dst_df, src_df, {
                    'how_merge': how,
                    'dst_selected_key': left_on,
                    'src_selected_key': right_on,
                    'initial_column_names': list(src_df.columns),
                    'rename_column_names': list(src_df.columns),
                    'columns_to_upload': [True] * len(list(src_df.columns))
                })
        except Exception as exc:
            raise APIException(
                _('Unable to perform merge operation: {0}').format(str(exc)))

        # Merge went through.
        return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemplo n.º 5
0
Arquivo: api.py Projeto: ubc/ontask_b
class TableBasicOps(APIView):
    """Basic class to implement the table API operations.

    Inheritance will implement two versions, one handling data frames in JSON
    format, and the other one using the pickle format in Pandas to preserve
    NaN and NaT and maintain column data types between exchanges.
    """

    # The serializer class needs to be overwritten by the subclasses.
    serializer_class = None

    permission_classes = (UserIsInstructor, )

    @method_decorator(get_workflow(pf_related='columns'))
    def override(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Override the content in the workflow.

        :param request: Received request object
        :param wid: Workflow ID
        :param format: format for the response
        :param workflow: Workflow being manipulated (set by decorator)
        """
        del wid, format
        # Try to retrieve the wflow to check for permissions
        serializer = self.serializer_class(data=request.data)
        if not serializer.is_valid():
            # Flag the error
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

        # Data received is a correct data frame.
        df = serializer.validated_data['data_frame']

        try:
            # Verify the data frame
            pandas.verify_data_frame(df)
            # Store the content in the db and...
            pandas.store_dataframe(df, workflow)
        except OnTaskDataFrameNoKey as exc:
            return Response(str(exc), status=status.HTTP_400_BAD_REQUEST)

        # Update all the counters in the conditions
        for action in workflow.actions.all():
            action.update_n_rows_selected()

        return Response(None, status=status.HTTP_201_CREATED)

    @method_decorator(get_workflow(pf_related='columns'))
    def get(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Retrieve the existing data frame."""
        del request, wid, format
        serializer = self.serializer_class({
            'data_frame':
            pandas.load_table(workflow.get_data_frame_table_name())
        })
        return Response(serializer.data)

    @method_decorator(get_workflow(pf_related='columns'))
    def post(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Create a new data frame."""
        if pandas.load_table(workflow.get_data_frame_table_name()) is not None:
            raise APIException(
                _('Post request requires workflow without a table'))
        return self.override(request,
                             wid=wid,
                             format=format,
                             workflow=workflow)

    @method_decorator(get_workflow(pf_related='columns'))
    def put(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ):
        """Process the put method to update the data frame."""
        return self.override(request,
                             wid=wid,
                             format=format,
                             workflow=workflow)

    # Delete
    @method_decorator(get_workflow(pf_related='columns'))
    def delete(
        self,
        request: http.HttpRequest,
        wid: int,
        format=None,
        workflow: Optional[models.Workflow] = None,
    ) -> http.HttpResponse:
        """Flush the data in the data frame."""
        del request, wid, format
        workflow.flush()
        return Response(status=status.HTTP_204_NO_CONTENT)