예제 #1
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']
예제 #2
0
class ToManySourceResource(Resource):
    other_model_ids = fields.ListField(attribute='other_model_ids')
    other_models = ToManyDocumentsField('corehq.apps.api.tests.ToManyDestResource', attribute='other_models')

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

    def obj_get_list(self):
        return self.objs

    class Meta:
        model_class = ToManySourceModel
예제 #3
0
class ToManySourceResource(Resource):
    other_model_ids = fields.ListField(attribute='other_model_ids')
    other_models = ToManyDocumentsField(
        'corehq.apps.api.tests.core_api.ToManyDestResource',
        attribute='other_models')

    def __init__(self, objs):
        super(ToManySourceResource, 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).other_model_ids}

    class Meta(object):
        model_class = ToManySourceModel
예제 #4
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'])
예제 #5
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'])