Esempio n. 1
0
class CommCareCaseResource(SimpleSortableResourceMixin, v0_3.CommCareCaseResource, DomainSpecificResourceMixin):
    xforms_by_name = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_name'
    ))

    xforms_by_xmlns = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_xmlns'
    ))

    child_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='child_cases'
        )
    )

    parent_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='parent_cases'
        )
    )

    domain = fields.CharField(attribute='domain')

    date_modified = fields.CharField(attribute='modified_on', default="1900-01-01")
    indexed_on = fields.CharField(attribute='inserted_at', default="1900-01-01")
    server_date_modified = fields.CharField(attribute='server_modified_on', default="1900-01-01")
    server_date_opened = fields.CharField(attribute='server_opened_on', default="1900-01-01")
    opened_by = fields.CharField(attribute='opened_by', null=True)
    closed_by = fields.CharField(attribute='closed_by', null=True)

    def obj_get(self, bundle, **kwargs):
        case_id = kwargs['pk']
        domain = kwargs['domain']
        return self.case_es(domain).get_document(case_id)

    class Meta(v0_3.CommCareCaseResource.Meta):
        max_limit = 5000
        serializer = CommCareCaseSerializer()
        ordering = ['server_date_modified', 'date_modified', 'indexed_on']
        object_class = ESCase
Esempio n. 2
0
class XFormInstanceResource(SimpleSortableResourceMixin,
                            v0_3.XFormInstanceResource,
                            DomainSpecificResourceMixin):

    # Some fields that were present when just fetching individual docs are
    # not present for e.g. devicelogs and must be allowed blank
    uiversion = fields.CharField(attribute='uiversion', blank=True, null=True)
    metadata = fields.DictField(attribute='metadata', blank=True, null=True)
    domain = fields.CharField(attribute='domain')
    app_id = fields.CharField(attribute='app_id', null=True)
    build_id = fields.CharField(attribute='build_id', null=True)

    cases = UseIfRequested(
        ToManyDocumentsField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute=lambda xform: casexml_xform.cases_referenced_by_xform(
                xform)))

    is_phone_submission = fields.BooleanField(readonly=True)

    def dehydrate_is_phone_submission(self, bundle):
        return (getattr(bundle.obj, 'openrosa_headers', None)
                and bundle.obj.openrosa_headers.get('HTTP_X_OPENROSA_VERSION'))

    # Prevent hitting Couch to md5 the attachment. However, there is no way to
    # eliminate a tastypie field defined in a parent class.
    md5 = fields.CharField(attribute='uiversion', blank=True, null=True)

    def dehydrate_md5(self, bundle):
        return 'OBSOLETED'

    def xform_es(self, domain):
        return MOCK_XFORM_ES or XFormES(domain)

    def obj_get_list(self, bundle, domain, **kwargs):
        try:
            es_query = es_search(bundle.request, domain)
        except Http400 as e:
            raise BadRequest(e.message)
        es_query['filter']['and'].append(
            {'term': {
                'doc_type': 'xforminstance'
            }})

        # Note that XFormES is used only as an ES client, for `run_query` against the proper index
        return ESQuerySet(
            payload=es_query,
            model=XFormInstance,
            es_client=self.xform_es(domain)).order_by('-received_on')

    class Meta(v0_3.XFormInstanceResource.Meta):
        ordering = ['received_on']
        list_allowed_methods = ['get']
Esempio n. 3
0
class UseIfRequestedTestResource(Resource):
    something = UseIfRequested(fields.CharField(attribute='id'))

    def __init__(self, objs):
        super(UseIfRequestedTestResource, self).__init__()
        self.objs = objs

    def obj_get_list(self):
        return self.objs

    class Meta:
        model_class = UseIfRequestedModel
Esempio n. 4
0
class CommCareCaseResource(SimpleSortableResourceMixin, v0_3.CommCareCaseResource, DomainSpecificResourceMixin):
    xforms_by_name = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_name'
    ))

    xforms_by_xmlns = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_xmlns'
    ))

    child_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='child_cases'
        )
    )

    parent_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='parent_cases'
        )
    )

    domain = fields.CharField(attribute='domain')

    # Fields that v0.2 assumed were pre-transformed but we are now operating on straight CommCareCase objects again
    date_modified = fields.CharField(attribute='modified_on', default="1900-01-01")
    server_date_modified = fields.CharField(attribute='server_modified_on', default="1900-01-01")
    server_date_opened = fields.CharField(attribute='server_opened_on', default="1900-01-01")

    def obj_get(self, bundle, **kwargs):
        case_id = kwargs['pk']
        try:
            case = CaseAccessors(kwargs['domain']).get_case(case_id)
            return case_to_es_case(case)
        except CaseNotFound:
            raise object_does_not_exist("CommCareCase", case_id)
Esempio n. 5
0
class UseIfRequestedTestResource(Resource):
    something = UseIfRequested(fields.CharField(attribute='id'))

    def __init__(self, objs):
        super(UseIfRequestedTestResource, self).__init__()
        self.objs = objs

    def obj_get_list(self):
        return self.objs

    def detail_uri_kwargs(self, bundle_or_obj):
        return {'pk': get_obj(bundle_or_obj).id}

    class Meta(object):
        model_class = UseIfRequestedModel
Esempio n. 6
0
class XFormInstanceResource(SimpleSortableResourceMixin, HqBaseResource,
                            DomainSpecificResourceMixin):
    """This version of the form resource is built of Elasticsearch data
    which gets wrapped by ``ESXFormInstance``.
    No type conversion is done e.g. dates and some fields are named differently than in the
    Python models.
    """

    id = fields.CharField(attribute='_id', readonly=True, unique=True)

    domain = fields.CharField(attribute='domain')
    form = fields.DictField(attribute='form_data')
    type = fields.CharField(attribute='type')
    version = fields.CharField(attribute='version')
    uiversion = fields.CharField(attribute='uiversion', blank=True, null=True)
    metadata = fields.DictField(attribute='metadata', blank=True, null=True)
    received_on = fields.CharField(attribute="received_on")

    app_id = fields.CharField(attribute='app_id', null=True)
    build_id = fields.CharField(attribute='build_id', null=True)
    initial_processing_complete = fields.BooleanField(
        attribute='initial_processing_complete', null=True)
    problem = fields.CharField(attribute='problem', null=True)

    archived = fields.CharField(readonly=True)

    def dehydrate_archived(self, bundle):
        return bundle.obj.is_archived

    cases = UseIfRequested(
        ToManyDocumentsField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute=lambda xform: casexml_xform.cases_referenced_by_xform(
                xform)))

    attachments = fields.DictField(readonly=True, null=True)

    def dehydrate_attachments(self, bundle):
        attachments_dict = getattr(bundle.obj, 'blobs', None)
        if not attachments_dict:
            return {}

        def _normalize_meta(meta):
            return {
                'content_type': meta.content_type,
                'length': meta.content_length,
            }

        return {
            name: _normalize_meta(meta)
            for name, meta in attachments_dict.items()
        }

    is_phone_submission = fields.BooleanField(readonly=True)

    def dehydrate_is_phone_submission(self, bundle):
        return (getattr(bundle.obj, 'openrosa_headers', None)
                and bundle.obj.openrosa_headers.get('HTTP_X_OPENROSA_VERSION'))

    def obj_get(self, bundle, **kwargs):
        instance_id = kwargs['pk']
        try:
            form = FormAccessors(kwargs['domain']).get_form(instance_id)
            es_form = form_to_es_form(form)
            if es_form:
                return es_form
            else:
                raise XFormNotFound
        except XFormNotFound:
            raise object_does_not_exist("XFormInstance", instance_id)

    def xform_es(self, domain):
        return MOCK_XFORM_ES or XFormES(domain)

    def obj_get_list(self, bundle, domain, **kwargs):
        include_archived = 'include_archived' in bundle.request.GET
        try:
            es_query = es_search(bundle.request, domain, ['include_archived'])
        except Http400 as e:
            raise BadRequest(e.message)
        if include_archived:
            es_query['filter']['and'].append({
                'or': [
                    {
                        'term': {
                            'doc_type': 'xforminstance'
                        }
                    },
                    {
                        'term': {
                            'doc_type': 'xformarchived'
                        }
                    },
                ]
            })
        else:
            es_query['filter']['and'].append(
                {'term': {
                    'doc_type': 'xforminstance'
                }})

        # Note that XFormES is used only as an ES client, for `run_query` against the proper index
        return ElasticAPIQuerySet(
            payload=es_query,
            model=ESXFormInstance,
            es_client=self.xform_es(domain)).order_by('-received_on')

    def detail_uri_kwargs(self, bundle_or_obj):
        return {'pk': get_obj(bundle_or_obj).form_id}

    class Meta(CustomResourceMeta):
        authentication = RequirePermissionAuthentication(Permissions.edit_data)
        object_class = ESXFormInstance
        list_allowed_methods = ['get']
        detail_allowed_methods = ['get']
        resource_name = 'form'
        ordering = ['received_on']
        serializer = XFormInstanceSerializer(formats=['json'])
Esempio n. 7
0
class XFormInstanceResource(SimpleSortableResourceMixin, HqBaseResource, DomainSpecificResourceMixin):
    """This version of the form resource is built of Elasticsearch data
    which gets wrapped by ``ESXFormInstance``.
    No type conversion is done e.g. dates and some fields are named differently than in the
    Python models.
    """

    id = fields.CharField(attribute='_id', readonly=True, unique=True)

    domain = fields.CharField(attribute='domain')
    form = fields.DictField(attribute='form_data')
    type = fields.CharField(attribute='type')
    version = fields.CharField(attribute='version')
    uiversion = fields.CharField(attribute='uiversion', blank=True, null=True)
    metadata = fields.DictField(attribute='metadata', blank=True, null=True)
    received_on = fields.CharField(attribute="received_on")
    edited_on = fields.CharField(attribute="edited_on", null=True)
    server_modified_on = fields.CharField(attribute="server_modified_on")
    indexed_on = fields.CharField(attribute='inserted_at')

    app_id = fields.CharField(attribute='app_id', null=True)
    build_id = fields.CharField(attribute='build_id', null=True)
    initial_processing_complete = fields.BooleanField(
        attribute='initial_processing_complete', null=True)
    problem = fields.CharField(attribute='problem', null=True)

    archived = fields.CharField(readonly=True)

    def dehydrate_archived(self, bundle):
        return bundle.obj.is_archived

    cases = UseIfRequested(
        ToManyDocumentsField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute=lambda xform: _cases_referenced_by_xform(xform)
        )
    )

    attachments = fields.DictField(readonly=True, null=True)

    def dehydrate_attachments(self, bundle):
        attachments_dict = getattr(bundle.obj, 'blobs', None)
        if not attachments_dict:
            return {}

        domain = bundle.obj.domain
        form_id = bundle.obj._id

        def _normalize_meta(name, meta):
            return {
                'content_type': meta.content_type,
                'length': meta.content_length,
                'url': absolute_reverse('api_form_attachment', args=(domain, form_id, name))
            }

        return {
            name: _normalize_meta(name, meta) for name, meta in attachments_dict.items()
        }

    is_phone_submission = fields.BooleanField(readonly=True)

    def dehydrate_is_phone_submission(self, bundle):
        headers = getattr(bundle.obj, 'openrosa_headers', None)
        if not headers:
            return False
        return headers.get('HTTP_X_OPENROSA_VERSION') is not None

    edited_by_user_id = fields.CharField(readonly=True, null=True)

    def dehydrate_edited_by_user_id(self, bundle):
        if bundle.obj.edited_on:
            return (getattr(bundle.obj, 'auth_context') or {}).get('user_id', None)

    def obj_get(self, bundle, **kwargs):
        instance_id = kwargs['pk']
        domain = kwargs['domain']
        return self.xform_es(domain).get_document(instance_id)

    def xform_es(self, domain):
        return MOCK_XFORM_ES or FormESView(domain)

    def obj_get_list(self, bundle, domain, **kwargs):
        try:
            es_query = es_query_from_get_params(bundle.request.GET, domain, ['include_archived'])
        except Http400 as e:
            raise BadRequest(str(e))

        # Note that FormESView is used only as an ES client, for `run_query` against the proper index
        return ElasticAPIQuerySet(
            payload=es_query,
            model=ESXFormInstance,
            es_client=self.xform_es(domain)
        ).order_by('-received_on')

    def detail_uri_kwargs(self, bundle_or_obj):
        return {
            'pk': get_obj(bundle_or_obj).form_id
        }

    class Meta(CustomResourceMeta):
        authentication = RequirePermissionAuthentication(Permissions.edit_data)
        object_class = ESXFormInstance
        list_allowed_methods = ['get']
        detail_allowed_methods = ['get']
        resource_name = 'form'
        ordering = ['received_on', 'server_modified_on', 'indexed_on']
        serializer = XFormInstanceSerializer(formats=['json'])
Esempio n. 8
0
class CommCareCaseResource(SimpleSortableResourceMixin, v0_3.CommCareCaseResource, DomainSpecificResourceMixin):
    xforms_by_name = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_name'
    ))

    xforms_by_xmlns = UseIfRequested(ToManyListDictField(
        'corehq.apps.api.resources.v0_4.XFormInstanceResource',
        attribute='xforms_by_xmlns'
    ))

    child_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='child_cases'
        )
    )

    parent_cases = UseIfRequested(
        ToManyDictField(
            'corehq.apps.api.resources.v0_4.CommCareCaseResource',
            attribute='parent_cases'
        )
    )

    domain = fields.CharField(attribute='domain')

    # Fields that v0.2 assumed were pre-transformed but we are now operating on straight CommCareCase objects again
    date_modified = fields.CharField(attribute='modified_on', default="1900-01-01")
    server_date_modified = fields.CharField(attribute='server_modified_on', default="1900-01-01")
    server_date_opened = fields.CharField(attribute='server_opened_on', default="1900-01-01")

    def obj_get(self, bundle, **kwargs):
        case_id = kwargs['pk']
        domain = kwargs['domain']
        return self.case_es(domain).get_document(case_id)

    def case_es(self, domain):
        return MOCK_CASE_ES or CaseES(domain)

    def obj_get_list(self, bundle, domain, **kwargs):
        filters = v0_3.CaseListFilters(bundle.request.GET).filters

        # Since tastypie handles the "from" and "size" via slicing, we have to wipe them out here
        # since ElasticCaseQuery adds them. I believe other APIs depend on the behavior of ElasticCaseQuery
        # hence I am not modifying that
        query = ElasticCaseQuery(domain, filters).get_query()
        if 'from' in query:
            del query['from']
        if 'size' in query:
            del query['size']

        # Note that CaseES is used only as an ES client, for `run_query` against the proper index
        return ElasticAPIQuerySet(
            payload=query,
            model=ESCase,
            es_client=self.case_es(domain)
        ).order_by('server_modified_on')

    class Meta(v0_3.CommCareCaseResource.Meta):
        max_limit = 1000
        serializer = CommCareCaseSerializer()
        ordering = ['server_date_modified', 'date_modified']
        object_class = ESCase