示例#1
0
    def create(self, request, *args, **kwargs):
        owner = _get_owner(request)
        survey = utils.publish_xlsform(request, owner)

        if isinstance(survey, XForm):
            xform = XForm.objects.get(pk=survey.pk)
            # The XForm has been created, but `publish_xlsform` relies on
            # `onadata.apps.main.forms.QuickConverter`, which uses standard
            # Django forms and only recognizes the `xls_file`, `xls_url`,
            # `dropbox_xls_url`, and `text_xls_form` fields.
            # Use the DRF serializer to update the XForm with values for other
            # fields.
            serializer = XFormSerializer(
                xform,
                data=request.data,
                context={'request': request},
                partial=True
            )
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)

            return Response(serializer.data, status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#2
0
    def forms(self, request, **kwargs):
        """Add a form to a project or list forms for the project.

        The request key `xls_file` holds the XLSForm file object.
        """
        project = get_object_or_404(Project, pk=kwargs.get('pk'))
        if request.method.upper() == 'POST':
            survey = utils.publish_project_xform(request, project)

            if isinstance(survey, XForm):
                xform = XForm.objects.get(pk=survey.pk)
                serializer = XFormSerializer(xform,
                                             context={'request': request})

                return Response(serializer.data,
                                status=status.HTTP_201_CREATED)

            return Response(survey, status=status.HTTP_400_BAD_REQUEST)

        xforms = XForm.objects.filter(project=project)
        serializer = XFormSerializer(xforms,
                                     context={'request': request},
                                     many=True)

        return Response(serializer.data)
示例#3
0
    def test_manager_can_update_xform(self):
        self._publish_xls_form_to_project()
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        self._login_user_and_profile(extra_post_data=alice_data)
        view = XFormViewSet.as_view({'put': 'update'})
        description = 'DESCRIPTION'
        request = self.factory.get('/', **self.extra)
        xfs = XFormSerializer(instance=self.xform,
                              context={'request': request})
        data = json.loads(JSONRenderer().render(xfs.data))
        data.update({'public': True, 'description': description})

        self.assertFalse(self.xform.shared)

        # Remove key:value pairs where the value is None.
        # More info: https://code.djangoproject.com/ticket/30024
        data.pop('enketo_preview_url')
        data.pop('last_submission_time')

        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.xform.id)
        self.assertEqual(response.status_code, 404)
        self.assertFalse(self.xform.shared)

        role.ManagerRole.add(self.user, self.xform)
        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.xform.id)

        self.xform.refresh_from_db()
        self.assertTrue(self.xform.shared)
        self.assertEqual(self.xform.description, description)
        self.assertEqual(response.data['public'], True)
        self.assertEqual(response.data['description'], description)
    def test_manager_can_update_xform(self):
        self._publish_xls_form_to_project()
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        self._login_user_and_profile(extra_post_data=alice_data)
        view = XFormViewSet.as_view({'put': 'update'})
        description = 'DESCRIPTION'
        request = self.factory.get('/', **self.extra)
        xfs = XFormSerializer(instance=self.xform,
                              context={'request': request})
        data = json.loads(JSONRenderer().render(xfs.data))
        data.update({'public': True, 'description': description})

        self.assertFalse(self.xform.shared)

        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.xform.id)
        self.assertEqual(response.status_code, 404)
        self.assertFalse(self.xform.shared)

        role.ManagerRole.add(self.user, self.xform)
        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.xform.id)

        self.xform.refresh_from_db()
        self.assertTrue(self.xform.shared)
        self.assertEqual(self.xform.description, description)
        self.assertEqual(response.data['public'], True)
        self.assertEqual(response.data['description'], description)
示例#5
0
    def forms(self, request, **kwargs):
        """Add a form to a project or list forms for the project.

        The request key `xls_file` holds the XLSForm file object.
        """
        project = self.object = self.get_object()
        if request.method.upper() == 'POST':
            survey = utils.publish_project_xform(request, project)

            if isinstance(survey, XForm):
                if 'formid' in request.data:
                    serializer_cls = XFormSerializer
                else:
                    serializer_cls = XFormCreateSerializer

                serializer = serializer_cls(survey,
                                            context={'request': request})

                published_by_formbuilder = request.data.get(
                    'published_by_formbuilder'
                )
                if str_to_bool(published_by_formbuilder):
                    MetaData.published_by_formbuilder(survey, 'True')

                return Response(serializer.data,
                                status=status.HTTP_201_CREATED)

            return Response(survey, status=status.HTTP_400_BAD_REQUEST)

        xforms = XForm.objects.filter(project=project)
        serializer = XFormSerializer(xforms, context={'request': request},
                                     many=True)

        return Response(serializer.data)
示例#6
0
    def clone(self, request, *args, **kwargs):
        self.object = self.get_object()
        data = {
            'xform': self.object.pk,
            'username': request.DATA.get('username')
        }
        serializer = CloneXFormSerializer(data=data)
        if serializer.is_valid():
            clone_to_user = User.objects.get(username=data['username'])
            if not request.user.has_perm('can_add_xform',
                                         clone_to_user.profile):
                raise exceptions.PermissionDenied(
                    detail=_(u"User %(user)s has no permission to add "
                             "xforms to account %(account)s" % {
                                 'user': request.user.username,
                                 'account': data['username']
                             }))
            xform = serializer.save()
            serializer = XFormSerializer(xform.cloned_form,
                                         context={'request': request})

            return Response(data=serializer.data,
                            status=status.HTTP_201_CREATED)

        return Response(data=serializer.errors,
                        status=status.HTTP_400_BAD_REQUEST)
示例#7
0
    def form_details(self, request, *args, **kwargs):
        dataview = self.get_object()
        xform = dataview.xform
        serializer = XFormSerializer(xform, context={'request': request})

        return Response(data=serializer.data,
                        content_type="application/json")
示例#8
0
    def test_forms_endpoint_with_metadata(self):
        date_modified = self.xform.date_modified
        for data_type in ['supporting_doc', 'media', 'source']:
            self._add_form_metadata(self.xform, data_type,
                                    self.data_value, self.path)
            self.xform.reload()
            self.assertNotEqual(date_modified, self.xform.date_modified)

        # /forms
        view = XFormViewSet.as_view({
            'get': 'retrieve'
        })
        formid = self.xform.pk
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 200)
        data = XFormSerializer(self.xform, context={'request': request}).data
        self.assertEqual(response.data, data)

        # /projects/[pk]/forms
        view = ProjectViewSet.as_view({
            'get': 'forms'
        })
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=self.project.pk)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [data])
示例#9
0
    def clone(self, request, *args, **kwargs):
        self.object = self.get_object()
        data = {
            'xform': self.object.pk,
            'username': request.data.get('username')
        }
        project = request.data.get('project_id')
        if project:
            data['project'] = project
        serializer = CloneXFormSerializer(data=data)
        if serializer.is_valid():
            clone_to_user = User.objects.get(username=data['username'])
            if not request.user.has_perm('can_add_xform',
                                         clone_to_user.profile):
                raise exceptions.PermissionDenied(
                    detail=_(u"User %(user)s has no permission to add "
                             "xforms to account %(account)s" % {
                                 'user': request.user.username,
                                 'account': data['username']
                             }))
            try:
                xform = serializer.save()
            except IntegrityError:
                raise ParseError(
                    'A clone with the same id_string has already been created')
            serializer = XFormSerializer(xform.cloned_form,
                                         context={'request': request})

            return Response(data=serializer.data,
                            status=status.HTTP_201_CREATED)

        return Response(data=serializer.errors,
                        status=status.HTTP_400_BAD_REQUEST)
示例#10
0
    def test_deleted_dataview_not_in_forms_list(self):
        self._create_dataview()
        get_form_request = self.factory.get('/', **self.extra)

        xform_serializer = XFormSerializer(
            self.xform, context={'request': get_form_request})

        self.assertIsNotNone(xform_serializer.data['data_views'])

        request = self.factory.delete('/', **self.extra)
        response = self.view(request, pk=self.data_view.pk)
        self.assertEquals(response.status_code, 204)

        xform_serializer = XFormSerializer(
            self.xform, context={'request': get_form_request})

        self.assertEquals(xform_serializer.data['data_views'], [])
示例#11
0
def _try_update_xlsform(request, xform, owner):
    survey = \
        utils.publish_xlsform(request, owner, xform.id_string, xform.project)

    if isinstance(survey, XForm):
        serializer = XFormSerializer(xform, context={'request': request})

        return Response(serializer.data, status=status.HTTP_200_OK)

    return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#12
0
 def test_forms_endpoint_with_metadata(self):
     for data_type in ['supporting_doc', 'media', 'source']:
         self._add_form_metadata(self.xform, data_type, self.data_value,
                                 self.path)
     # /forms
     view = XFormViewSet.as_view({'get': 'retrieve'})
     formid = self.xform.pk
     request = self.factory.get('/', **self.extra)
     response = view(request, pk=formid)
     self.assertEqual(response.status_code, 200)
     data = XFormSerializer(self.xform, context={'request': request}).data
     self.assertEqual(response.data, data)
示例#13
0
    def create(self, request, *args, **kwargs):
        owner = _get_owner(request)
        survey = utils.publish_xlsform(request, owner)

        if isinstance(survey, XForm):
            xform = XForm.objects.get(pk=survey.pk)
            # The XForm has been created, but `publish_xlsform` relies on
            # `onadata.apps.main.forms.QuickConverter`, which uses standard
            # Django forms and only recognizes the `xls_file`, `xls_url`,
            # `dropbox_xls_url`, and `text_xls_form` fields.
            # Use the DRF serializer to update the XForm with values for other
            # fields.
            serializer = XFormSerializer(xform,
                                         data=request.data,
                                         context={'request': request},
                                         partial=True)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            # noti = xform.logs.create(source=request.user, type=7, title="new Kobo form",
            #                          organization=request.organization,
            #                         description="new kobo form {0} created by {1}".
            #                         format(xform.title, request.user.username))
            # result = {}
            # result['description'] = noti.description
            # result['url'] = noti.get_absolute_url()
            # ChannelGroup("notify-0").send({"text":json.dumps(result)})
            # if noti.organization:
            #     ChannelGroup("notify-{}".format(noti.organization.id)).send({"text":json.dumps(result)})
            headers = self.get_success_headers(serializer.data)

            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#14
0
    def create(self, request, *args, **kwargs):
        owner = _get_owner(request)
        survey = utils.publish_xlsform(request, owner)

        if isinstance(survey, XForm):
            xform = XForm.objects.get(pk=survey.pk)
            # The XForm has been created, but `publish_xlsform` relies on
            # `onadata.apps.main.forms.QuickConverter`, which uses standard
            # Django forms and only recognizes the `xls_file`, `xls_url`,
            # `dropbox_xls_url`, and `text_xls_form` fields.
            # Use the DRF serializer to update the XForm with values for other
            # fields.
            serializer = XFormSerializer(xform,
                                         data=request.data,
                                         context={'request': request},
                                         partial=True)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)

            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#15
0
    def create(self, request, *args, **kwargs):
        owner = _get_owner(request)
        survey = utils.publish_xlsform(request, owner)

        if isinstance(survey, XForm):
            xform = XForm.objects.get(pk=survey.pk)
            serializer = XFormSerializer(xform, context={'request': request})
            headers = self.get_success_headers(serializer.data)

            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(survey, status=status.HTTP_400_BAD_REQUEST)
 def test_xform_serializer_none(self):
     data = {
         'title': u'',
         'owner': None,
         'public': False,
         'public_data': False,
         'require_auth': False,
         'description': u'',
         'downloadable': False,
         'allows_sms': False,
         'uuid': u'',
         'instances_with_geopoints': False,
         'num_of_submissions': 0
     }
     self.assertEqual(data, XFormSerializer(None).data)
示例#17
0
def _try_update_xlsform(request, xform, owner):
    if xform.instances.count() > 0:
        data = _(u"Cannot update the xls file in a form that has"
                 u" submissions")
        return Response(data, status=status.HTTP_400_BAD_REQUEST)

    survey = \
        utils.publish_xlsform(request, owner, xform.id_string)

    if isinstance(survey, XForm):
        serializer = XFormSerializer(xform, context={'request': request})

        return Response(serializer.data, status=status.HTTP_200_OK)

    return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#18
0
 def test_xform_serializer_none(self):
     data = {
         'title': '',
         'public': False,
         'public_data': False,
         'require_auth': False,
         'description': '',
         'downloadable': False,
         'uuid': '',
         'instances_with_geopoints': False,
         'num_of_submissions': 0,
         'has_kpi_hooks': False,
         'kpi_asset_uid': '',
     }
     self.assertEqual(data, XFormSerializer(None).data)
示例#19
0
    def test_form_tags(self):
        self._publish_xls_form_to_project()
        view = XFormViewSet.as_view({
            'get': 'labels',
            'post': 'labels',
            'delete': 'labels'
        })
        list_view = XFormViewSet.as_view({
            'get': 'list',
        })
        formid = self.xform.pk

        # no tags
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.data, [])

        # add tag "hello"
        request = self.factory.post('/', data={"tags": "hello"}, **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response.data, [u'hello'])

        # check filter by tag
        request = self.factory.get('/', data={"tags": "hello"}, **self.extra)
        self.form_data = XFormSerializer(self.xform,
                                         context={
                                             'request': request
                                         }).data
        response = list_view(request, pk=formid)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [self.form_data])

        request = self.factory.get('/', data={"tags": "goodbye"}, **self.extra)
        response = list_view(request, pk=formid)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.data, [])

        # remove tag "hello"
        request = self.factory.delete('/',
                                      data={"tags": "hello"},
                                      **self.extra)
        response = view(request, pk=formid, label='hello')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.data, [])
示例#20
0
    def create_async(self, request, *args, **kwargs):
        """ Temporary Endpoint for Async form creation """
        resp = headers = {}
        resp_code = status.HTTP_400_BAD_REQUEST

        if request.method == 'GET':
            self.etag_data = '{}'.format(timezone.now())
            survey = tasks.get_async_status(
                request.query_params.get('job_uuid'))

            if 'pk' in survey:
                xform = XForm.objects.get(pk=survey.get('pk'))
                serializer = XFormSerializer(xform,
                                             context={'request': request})
                headers = self.get_success_headers(serializer.data)
                resp = serializer.data
                resp_code = status.HTTP_201_CREATED
            else:
                resp_code = status.HTTP_202_ACCEPTED
                resp.update(survey)
        else:
            try:
                owner = _get_owner(request)
            except ValidationError as e:
                return Response({'message': e.messages[0]},
                                status=status.HTTP_400_BAD_REQUEST)

            fname = request.FILES.get('xls_file').name
            resp.update({
                u'job_uuid':
                tasks.publish_xlsform_async.delay(
                    request.user, request.POST, owner,
                    ({
                        'name': fname,
                        'data': request.FILES.get('xls_file').read()
                    } if isinstance(request.FILES.get('xls_file'),
                                    InMemoryUploadedFile) else
                     {
                         'name':
                         fname,
                         'path':
                         request.FILES.get('xls_file').temporary_file_path()
                     })).task_id
            })
            resp_code = status.HTTP_202_ACCEPTED

        return Response(data=resp, status=resp_code, headers=headers)
示例#21
0
def _try_update_xlsform(request, xform, owner):
    survey = \
        utils.publish_xlsform(request, owner, xform.id_string, xform.project)

    if isinstance(survey, XForm):
        serializer = XFormSerializer(
            xform, context={'request': request})

        # send form update notification
        send_message(
            instance_id=xform.id, target_id=xform.id,
            target_type=XFORM, user=request.user or owner,
            message_verb=FORM_UPDATED)

        return Response(serializer.data, status=status.HTTP_200_OK)

    return Response(survey, status=status.HTTP_400_BAD_REQUEST)
示例#22
0
    def test_owner_role(self):
        self._publish_xls_form_to_project()
        self._make_submissions()
        view = XFormViewSet.as_view({
            'get': 'retrieve',
            'put': 'update',
            'delete': 'destroy'
        })
        data_view = DataViewSet.as_view({'get': 'list'})
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        self._login_user_and_profile(extra_post_data=alice_data)
        formid = self.xform.pk

        request = self.factory.get('/', **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 404)

        response = data_view(request, pk=formid)
        self.assertEqual(response.status_code, 404)

        role.OwnerRole.add(self.user, self.xform)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 200)

        response = data_view(request, pk=formid)
        self.assertEqual(response.status_code, 200)

        xfs = XFormSerializer(instance=self.xform,
                              context={'request': request})
        data = json.loads(JSONRenderer().render(xfs.data))
        data.update({'public': True, 'description': "Some description"})

        # Remove key:value pairs where the value is None.
        # More info: https://code.djangoproject.com/ticket/30024
        data.pop('enketo_preview_url')
        data.pop('last_submission_time')

        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 200)

        request = self.factory.delete('/', **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 204)