Ejemplo n.º 1
0
class XFormBaseSerializer(XFormMixin, serializers.HyperlinkedModelSerializer):
    formid = serializers.ReadOnlyField(source='id')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='user',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    public = serializers.BooleanField(source='shared')
    public_data = serializers.BooleanField(source='shared_data')
    require_auth = serializers.BooleanField()
    tags = TagListSerializer(read_only=True)
    title = serializers.CharField(max_length=255)
    url = serializers.HyperlinkedIdentityField(
        view_name='xform-detail', lookup_field='pk')
    users = serializers.SerializerMethodField()
    enketo_url = serializers.SerializerMethodField()
    enketo_preview_url = serializers.SerializerMethodField()
    num_of_submissions = serializers.SerializerMethodField()
    data_views = serializers.SerializerMethodField()

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time')
        exclude = ('json', 'xml', 'xls', 'user', 'has_start_time', 'shared',
                   'shared_data', 'deleted_at')
Ejemplo n.º 2
0
class XFormSerializer(serializers.HyperlinkedModelSerializer):
    formid = serializers.ReadOnlyField(source='id')
    metadata = serializers.SerializerMethodField('get_xform_metadata')
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                source='user',
                                                lookup_field='username',
                                                queryset=User.objects.all())
    public = BooleanField(source='shared')
    public_data = BooleanField(source='shared_data')
    require_auth = BooleanField()
    submission_count_for_today = serializers.ReadOnlyField()
    tags = TagListSerializer(read_only=True)
    title = serializers.CharField(max_length=255)
    url = serializers.HyperlinkedIdentityField(view_name='xform-detail',
                                               lookup_field='pk')
    users = serializers.SerializerMethodField('get_xform_permissions')
    hash = serializers.SerializerMethodField()
    has_kpi_hooks = serializers.BooleanField()

    @check_obj
    def get_hash(self, obj):
        return u"md5:%s" % obj.hash

    # Tests are expecting this "public" to be passed only "True" or "False"
    # and as a string. I don't know how it worked pre-migrations to django 1.8
    # but now it must be implemented manually
    def validate(self, attrs):
        shared = attrs.get('shared')
        if shared not in (None, 'True', 'False'):
            msg = "'%s' value must be either True or False." % shared
            raise serializers.ValidationError({'shared': msg})
        attrs['shared'] = shared == 'True'
        return attrs

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time')
        exclude = ('json', 'xml', 'xls', 'user', 'has_start_time', 'shared',
                   'shared_data')

    # Again, this is to match unit tests
    @property
    def data(self):
        data = super(XFormSerializer, self).data
        if 'num_of_submissions' in data and data['num_of_submissions'] is None:
            data['num_of_submissions'] = 0
        return data

    def get_xform_permissions(self, obj):
        return get_object_users_with_permissions(obj, serializable=True)

    def get_xform_metadata(self, obj):
        if obj:
            return MetaDataSerializer(obj.metadata_set.all(),
                                      many=True,
                                      context=self.context).data

        return []
Ejemplo n.º 3
0
class XFormSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='xform-detail',
                                               lookup_field='pk')
    formid = serializers.Field(source='id')
    title = serializers.CharField(max_length=255, source='title')
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                source='user',
                                                lookup_field='username')
    public = BooleanField(source='shared', widget=widgets.CheckboxInput())
    public_data = BooleanField(source='shared_data')
    require_auth = BooleanField(source='require_auth',
                                widget=widgets.CheckboxInput())
    tags = TagListSerializer(read_only=True)
    users = serializers.SerializerMethodField('get_xform_permissions')

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time')
        exclude = ('id', 'json', 'xml', 'xls', 'user', 'has_start_time',
                   'shared', 'shared_data')

    def get_xform_permissions(self, obj):
        return get_object_users_with_permissions(obj)
Ejemplo n.º 4
0
class BaseProjectSerializer(serializers.HyperlinkedModelSerializer):
    projectid = serializers.ReadOnlyField(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='organization',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(required=False)
    starred = serializers.SerializerMethodField()
    users = serializers.SerializerMethodField()
    forms = serializers.SerializerMethodField()
    public = serializers.BooleanField(source='shared')
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField()
    last_submission_date = serializers.SerializerMethodField()
    teams = serializers.SerializerMethodField()

    class Meta:
        model = Project
        exclude = ('shared', 'organization', 'user_stars')

    def get_starred(self, obj):
        return get_starred(obj, self.context['request'])

    def get_users(self, obj):
        owner_query_param_in_request = \
          'request' in self.context and "owner" in self.context['request'].GET
        return get_users(obj, self.context, owner_query_param_in_request)

    @check_obj
    def get_forms(self, obj):
        forms = cache.get('{}{}'.format(PROJ_BASE_FORMS_CACHE, obj.pk))
        if forms:
            return forms

        xforms = get_obj_xforms(obj)
        request = self.context.get('request')
        serializer = BaseProjectXFormSerializer(xforms,
                                                context={'request': request},
                                                many=True)
        forms = list(serializer.data)
        cache.set('{}{}'.format(PROJ_BASE_FORMS_CACHE, obj.pk), forms)

        return forms

    def get_num_datasets(self, obj):
        return get_num_datasets(obj)

    def get_last_submission_date(self, obj):
        return get_last_submission_date(obj)

    def get_teams(self, obj):
        return get_teams(obj)
Ejemplo n.º 5
0
class BaseProjectSerializer(serializers.HyperlinkedModelSerializer):
    projectid = serializers.ReadOnlyField(source='id')
    url = serializers.HyperlinkedIdentityField(
        view_name='project-detail', lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail', source='organization',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME
        )
    )
    created_by = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='username',
        read_only=True
    )
    metadata = JsonField(required=False)
    starred = serializers.SerializerMethodField()
    users = serializers.SerializerMethodField()
    forms = serializers.SerializerMethodField()
    public = serializers.BooleanField(source='shared')
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField()
    last_submission_date = serializers.SerializerMethodField()
    teams = serializers.SerializerMethodField()

    class Meta:
        model = Project
        exclude = ('shared', 'organization', 'user_stars')

    def get_starred(self, obj):
        return get_starred(obj, self.context['request'])

    def get_users(self, obj):
        return get_users(obj, self.context, False)

    @profile("get_project_forms.prof")
    @check_obj
    def get_forms(self, obj):
        xforms = get_obj_xforms(obj)
        request = self.context.get('request')
        serializer = BaseProjectXFormSerializer(
            xforms, context={'request': request}, many=True
        )
        return list(serializer.data)

    def get_num_datasets(self, obj):
        return get_num_datasets(obj)

    def get_last_submission_date(self, obj):
        return get_last_submission_date(obj)

    def get_teams(self, obj):
        return get_teams(obj)
Ejemplo n.º 6
0
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    projectid = serializers.Field(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                source='organization',
                                                lookup_field='username')
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     source='created_by',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(source='metadata', required=False)
    starred = serializers.SerializerMethodField('is_starred_project')
    users = serializers.SerializerMethodField('get_project_permissions')
    forms = serializers.SerializerMethodField('get_project_forms')
    public = BooleanField(source='shared', widget=widgets.CheckboxInput())
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField('get_num_datasets')
    last_submission_date = serializers.SerializerMethodField(
        'get_last_submission_date')

    class Meta:
        model = Project
        exclude = ('organization', 'user_stars')

    def restore_object(self, attrs, instance=None):
        if instance:
            metadata = JsonField.to_json(attrs.get('metadata'))
            owner = attrs.get('organization')

            if self.partial and metadata:
                if not isinstance(instance.metadata, dict):
                    instance.metadata = {}

                instance.metadata.update(metadata)
                attrs['metadata'] = instance.metadata

            if self.partial and owner:
                # give the new owner permissions
                set_owners_permission(owner, instance)

                # clear cache
                safe_delete('{}{}'.format(PROJ_PERM_CACHE, self.object.pk))

            return super(ProjectSerializer,
                         self).restore_object(attrs, instance)

        if 'request' in self.context:
            created_by = self.context['request'].user

            return Project(
                name=attrs.get('name'),
                organization=attrs.get('organization'),
                created_by=created_by,
                metadata=attrs.get('metadata'),
            )

        return attrs

    def save_object(self, obj, **kwargs):
        super(ProjectSerializer, self).save_object(obj, **kwargs)

        obj.xform_set.exclude(shared=obj.shared)\
            .update(shared=obj.shared, shared_data=obj.shared)

    def get_project_permissions(self, obj):
        if obj:
            users = cache.get('{}{}'.format(PROJ_PERM_CACHE, obj.pk))
            if users:
                return users

            user = get_object_users_with_permissions(obj)
            cache.set('{}{}'.format(PROJ_PERM_CACHE, obj.pk), user)

            return user

        return []

    @check_obj
    def get_project_forms(self, obj):
        if obj:
            forms = cache.get('{}{}'.format(PROJ_FORMS_CACHE, obj.pk))
            if forms:
                return forms

            xforms_details = obj.xform_set.values('pk', 'title')

            forms = [{
                'name': form['title'],
                'id': form['pk']
            } for form in xforms_details]
            cache.set('{}{}'.format(PROJ_FORMS_CACHE, obj.pk), forms)
            return forms

        return []

    @check_obj
    def get_num_datasets(self, obj):
        """Return the number of datasets attached to the object.

        :param obj: The project to find datasets for.
        """
        if obj:
            count = cache.get('{}{}'.format(PROJ_NUM_DATASET_CACHE, obj.pk))
            if count:
                return count

            count = obj.xform_set.count()
            cache.set('{}{}'.format(PROJ_NUM_DATASET_CACHE, obj.pk), count)
            return count

        return None

    @check_obj
    def get_last_submission_date(self, obj):
        """Return the most recent submission date to any of the projects
        datasets.

        :param obj: The project to find the last submission date for.
        """
        if obj:
            last_submission = cache.get('{}{}'.format(PROJ_SUB_DATE_CACHE,
                                                      obj.pk))
            if last_submission:
                return last_submission

            xform_ids = obj.xform_set.values_list('pk', flat=True)
            last_submission = Instance.objects.\
                order_by('-date_created').\
                filter(xform_id__in=xform_ids).values_list('date_created',
                                                           flat=True)
            cache.set('{}{}'.format(PROJ_SUB_DATE_CACHE, obj.pk),
                      last_submission and last_submission[0])
            return last_submission and last_submission[0]

        return None

    def is_starred_project(self, obj):
        request = self.context['request']
        user = request.user
        user_stars = obj.user_stars.all()
        if user in user_stars:
            return True

        return False
Ejemplo n.º 7
0
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    projectid = serializers.Field(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                source='organization',
                                                lookup_field='username')
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     source='created_by',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(source='metadata', required=False)
    starred = serializers.SerializerMethodField('is_starred_project')
    users = serializers.SerializerMethodField('get_project_permissions')
    forms = serializers.SerializerMethodField('get_project_forms')
    public = BooleanField(source='shared', widget=widgets.CheckboxInput())
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField('get_num_datasets')
    last_submission_date = serializers.SerializerMethodField(
        'get_last_submission_date')

    class Meta:
        model = Project
        exclude = ('organization', 'user_stars')

    def restore_object(self, attrs, instance=None):
        if instance:
            metadata = JsonField.to_json(attrs.get('metadata'))

            if self.partial and metadata:
                if not isinstance(instance.metadata, dict):
                    instance.metadata = {}

                instance.metadata.update(metadata)
                attrs['metadata'] = instance.metadata

            return super(ProjectSerializer,
                         self).restore_object(attrs, instance)

        if 'request' in self.context:
            created_by = self.context['request'].user

            return Project(
                name=attrs.get('name'),
                organization=attrs.get('organization'),
                created_by=created_by,
                metadata=attrs.get('metadata'),
            )

        return attrs

    def get_project_permissions(self, obj):
        return get_object_users_with_permissions(obj)

    @check_obj
    def get_project_forms(self, obj):
        xforms_details = obj.projectxform_set.values('xform__pk',
                                                     'xform__title')
        return [{
            'name': form['xform__title'],
            'id': form['xform__pk']
        } for form in xforms_details]

    @check_obj
    def get_num_datasets(self, obj):
        """Return the number of datasets attached to the object.

        :param obj: The project to find datasets for.
        """
        return obj.projectxform_set.count()

    @check_obj
    def get_last_submission_date(self, obj):
        """Return the most recent submission date to any of the projects
        datasets.

        :param obj: The project to find the last submission date for.
        """
        xform_ids = obj.projectxform_set.values_list('xform', flat=True)
        last_submission = Instance.objects.\
            order_by('-date_created').\
            filter(xform_id__in=xform_ids).values_list('date_created',
                                                       flat=True)

        return last_submission and last_submission[0]

    def is_starred_project(self, obj):
        request = self.context['request']
        user = request.user
        user_stars = obj.user_stars.all()
        if user in user_stars:
            return True

        return False
Ejemplo n.º 8
0
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    """
    ProjectSerializer class - creates and updates a project.
    """
    projectid = serializers.ReadOnlyField(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='organization',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(required=False)
    starred = serializers.SerializerMethodField()
    users = serializers.SerializerMethodField()
    forms = serializers.SerializerMethodField()
    public = serializers.BooleanField(source='shared')
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField()
    last_submission_date = serializers.SerializerMethodField()
    teams = serializers.SerializerMethodField()
    data_views = serializers.SerializerMethodField()

    class Meta:
        model = Project
        exclude = ('shared', 'user_stars', 'deleted_by')
        extra_kwargs = {
            'organization': {
                'write_only': True,
                'required': False,
                'lookup_field': 'username'
            }
        }

    def validate(self, attrs):
        name = attrs.get('name')
        organization = attrs.get('organization')
        if not self.instance and organization:
            project_w_same_name = Project.objects.filter(
                name__iexact=name, organization=organization)
            if project_w_same_name:
                raise serializers.ValidationError(
                    {'name': _(u"Project {} already exists.".format(name))})
        else:
            organization = organization or self.instance.organization
        request = self.context['request']
        try:
            has_perm = can_add_project_to_profile(request.user, organization)
        except OrganizationProfile.DoesNotExist:
            # most likely when transfering a project to an individual account
            # A user does not require permissions to the user's account forms.
            has_perm = False
        if not has_perm:
            raise serializers.ValidationError({
                'owner':
                _("You do not have permission to create a project "
                  "in the organization %(organization)s." %
                  {'organization': organization})
            })
        return attrs

    def validate_public(self, value):  # pylint: disable=no-self-use
        """
        Validate the public field
        """
        if not settings.ALLOW_PUBLIC_DATASETS and value:
            raise serializers.ValidationError(
                _('Public projects are currently disabled.'))
        return value

    def validate_metadata(self, value):  # pylint: disable=no-self-use
        """
        Validate metadaata is a valid JSON value.
        """
        msg = serializers.ValidationError(_("Invaid value for metadata"))
        try:
            json_val = JsonField.to_json(value)
        except ValueError:
            raise serializers.ValidationError(msg)
        else:
            if json_val is None:
                raise serializers.ValidationError(msg)
        return value

    def update(self, instance, validated_data):
        metadata = JsonField.to_json(validated_data.get('metadata'))
        if metadata is None:
            metadata = dict()
        owner = validated_data.get('organization')

        if self.partial and metadata:
            if not isinstance(instance.metadata, dict):
                instance.metadata = {}

            instance.metadata.update(metadata)
            validated_data['metadata'] = instance.metadata

        if self.partial and owner:
            # give the new owner permissions
            set_owners_permission(owner, instance)

            if is_organization(owner.profile):
                owners_team = get_or_create_organization_owners_team(
                    owner.profile)
                members_team = get_organization_members_team(owner.profile)
                OwnerRole.add(owners_team, instance)
                ReadOnlyRole.add(members_team, instance)

            # clear cache
            safe_delete('{}{}'.format(PROJ_PERM_CACHE, instance.pk))

        project = super(ProjectSerializer, self)\
            .update(instance, validated_data)

        project.xform_set.exclude(shared=project.shared)\
            .update(shared=project.shared, shared_data=project.shared)

        return instance

    def create(self, validated_data):
        metadata = validated_data.get('metadata', dict())
        if metadata is None:
            metadata = dict()
        created_by = self.context['request'].user

        try:
            project = Project.objects.create(  # pylint: disable=E1101
                name=validated_data.get('name'),
                organization=validated_data.get('organization'),
                created_by=created_by,
                shared=validated_data.get('shared', False),
                metadata=metadata)
        except IntegrityError:
            raise serializers.ValidationError(
                "The fields name, organization must make a unique set.")
        else:
            project.xform_set.exclude(shared=project.shared)\
                .update(shared=project.shared, shared_data=project.shared)
            request = self.context.get('request')
            serializer = ProjectSerializer(project,
                                           context={'request': request})
            response = serializer.data
            cache.set(f'{PROJ_OWNER_CACHE}{project.pk}', response)
            return project

    def get_users(self, obj):  # pylint: disable=no-self-use
        """
        Return a list of users and organizations that have access to the
        project.
        """
        return get_users(obj, self.context)

    @check_obj
    def get_forms(self, obj):  # pylint: disable=no-self-use
        """
        Return list of xforms in the project.
        """
        forms = cache.get('{}{}'.format(PROJ_FORMS_CACHE, obj.pk))
        if forms:
            return forms
        xforms = get_project_xforms(obj)
        request = self.context.get('request')
        serializer = ProjectXFormSerializer(xforms,
                                            context={'request': request},
                                            many=True)
        forms = list(serializer.data)
        cache.set('{}{}'.format(PROJ_FORMS_CACHE, obj.pk), forms)

        return forms

    def get_num_datasets(self, obj):  # pylint: disable=no-self-use
        """
        Return the number of datasets attached to the project.
        """
        return get_num_datasets(obj)

    def get_last_submission_date(self, obj):  # pylint: disable=no-self-use
        """
        Return the most recent submission date to any of the projects datasets.
        """
        return get_last_submission_date(obj)

    def get_starred(self, obj):  # pylint: disable=no-self-use
        """
        Return True if request user has starred this project.
        """
        return is_starred(obj, self.context['request'])

    def get_teams(self, obj):  # pylint: disable=no-self-use
        """
        Return the teams with access to the project.
        """
        return get_teams(obj)

    @check_obj
    def get_data_views(self, obj):
        """
        Return a list of filtered datasets.
        """
        data_views = cache.get('{}{}'.format(PROJECT_LINKED_DATAVIEWS, obj.pk))
        if data_views:
            return data_views

        data_views_obj = obj.dataview_prefetch if \
            hasattr(obj, 'dataview_prefetch') else\
            obj.dataview_set.filter(deleted_at__isnull=True)

        serializer = DataViewMinimalSerializer(data_views_obj,
                                               many=True,
                                               context=self.context)
        data_views = list(serializer.data)

        cache.set('{}{}'.format(PROJECT_LINKED_DATAVIEWS, obj.pk), data_views)

        return data_views
Ejemplo n.º 9
0
class BaseProjectSerializer(serializers.HyperlinkedModelSerializer):
    """
    BaseProjectSerializer class.
    """
    projectid = serializers.ReadOnlyField(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='organization',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(required=False)
    starred = serializers.SerializerMethodField()
    users = serializers.SerializerMethodField()
    forms = serializers.SerializerMethodField()
    public = serializers.BooleanField(source='shared')
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField()
    last_submission_date = serializers.SerializerMethodField()
    teams = serializers.SerializerMethodField()

    class Meta:
        model = Project
        fields = [
            'url', 'projectid', 'owner', 'created_by', 'metadata', 'starred',
            'users', 'forms', 'public', 'tags', 'num_datasets',
            'last_submission_date', 'teams', 'name', 'date_created',
            'date_modified', 'deleted_at'
        ]

    def get_starred(self, obj):
        """
        Return True if request user has starred this project.
        """
        return is_starred(obj, self.context['request'])

    def get_users(self, obj):
        """
        Return a list of users and organizations that have access to the
        project.
        """
        owner_query_param_in_request = 'request' in self.context and\
            "owner" in self.context['request'].GET
        return get_users(obj, self.context, owner_query_param_in_request)

    @check_obj
    def get_forms(self, obj):
        """
        Return list of xforms in the project.
        """
        forms = cache.get('{}{}'.format(PROJ_BASE_FORMS_CACHE, obj.pk))
        if forms:
            return forms

        xforms = get_project_xforms(obj)
        request = self.context.get('request')
        serializer = BaseProjectXFormSerializer(xforms,
                                                context={'request': request},
                                                many=True)
        forms = list(serializer.data)
        cache.set('{}{}'.format(PROJ_BASE_FORMS_CACHE, obj.pk), forms)

        return forms

    def get_num_datasets(self, obj):  # pylint: disable=no-self-use
        """
        Return the number of datasets attached to the project.
        """
        return get_num_datasets(obj)

    def get_last_submission_date(self, obj):  # pylint: disable=no-self-use
        """
        Return the most recent submission date to any of the projects datasets.
        """
        return get_last_submission_date(obj)

    def get_teams(self, obj):  # pylint: disable=no-self-use
        """
        Return the teams with access to the project.
        """
        return get_teams(obj)
Ejemplo n.º 10
0
class XFormSerializer(XFormMixin, serializers.HyperlinkedModelSerializer):
    formid = serializers.ReadOnlyField(source='id')
    metadata = serializers.SerializerMethodField()
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='user',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    public = serializers.BooleanField(source='shared')
    public_data = serializers.BooleanField(source='shared_data')
    require_auth = serializers.BooleanField()
    submission_count_for_today = serializers.ReadOnlyField()
    tags = TagListSerializer(read_only=True)
    title = serializers.CharField(max_length=255)
    url = serializers.HyperlinkedIdentityField(
        view_name='xform-detail', lookup_field='pk')
    users = serializers.SerializerMethodField()
    enketo_url = serializers.SerializerMethodField()
    enketo_preview_url = serializers.SerializerMethodField()
    num_of_submissions = serializers.SerializerMethodField()
    form_versions = serializers.SerializerMethodField()
    data_views = serializers.SerializerMethodField()

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time')
        exclude = ('json', 'xml', 'xls', 'user', 'has_start_time', 'shared',
                   'shared_data', 'deleted_at')

    def get_metadata(self, obj):
        xform_metadata = []
        if obj:
            xform_metadata = cache.get(
                '{}{}'.format(XFORM_METADATA_CACHE, obj.pk))
            if xform_metadata:
                return xform_metadata

            xform_metadata = list(
                MetaDataSerializer(
                    obj.metadata_set.all(), many=True, context=self.context)
                .data)
            cache.set('{}{}'.format(XFORM_METADATA_CACHE, obj.pk),
                      xform_metadata)

        return xform_metadata

    def get_form_versions(self, obj):
        versions = []
        if obj:
            versions = cache.get('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk))

            if versions:
                return versions

            versions = list(
                Instance.objects.filter(xform=obj, deleted_at__isnull=True)
                .values('version').annotate(total=Count('version')))

            if versions:
                cache.set('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk),
                          list(versions))

        return versions
Ejemplo n.º 11
0
class XFormSerializer(XFormMixin, serializers.HyperlinkedModelSerializer):
    formid = serializers.ReadOnlyField(source='id')
    metadata = serializers.SerializerMethodField()
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='user',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    public = serializers.BooleanField(source='shared')
    public_data = serializers.BooleanField(source='shared_data')
    public_key = serializers.CharField(required=False)
    require_auth = serializers.BooleanField()
    submission_count_for_today = serializers.ReadOnlyField()
    tags = TagListSerializer(read_only=True)
    title = serializers.CharField(max_length=255)
    url = serializers.HyperlinkedIdentityField(view_name='xform-detail',
                                               lookup_field='pk')
    users = serializers.SerializerMethodField()
    enketo_url = serializers.SerializerMethodField()
    enketo_preview_url = serializers.SerializerMethodField()
    enketo_single_submit_url = serializers.SerializerMethodField()
    num_of_submissions = serializers.SerializerMethodField()
    last_submission_time = serializers.SerializerMethodField()
    form_versions = serializers.SerializerMethodField()
    data_views = serializers.SerializerMethodField()

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time', 'is_merged_dataset')
        exclude = ('json', 'xml', 'xls', 'user', 'has_start_time', 'shared',
                   'shared_data', 'deleted_at', 'deleted_by')

    def get_metadata(self, obj):
        xform_metadata = []
        if obj:
            xform_metadata = cache.get('{}{}'.format(XFORM_METADATA_CACHE,
                                                     obj.pk))
            if xform_metadata:
                return xform_metadata

            xform_metadata = list(
                MetaDataSerializer(obj.metadata_set.all(),
                                   many=True,
                                   context=self.context).data)
            cache.set('{}{}'.format(XFORM_METADATA_CACHE, obj.pk),
                      xform_metadata)

        return xform_metadata

    def validate_public_key(self, value):  # pylint: disable=no-self-use
        """
        Checks that the given RSA public key is a valid key by trying
        to use the key data to create an RSA key object using the cryptography
        package
        """
        try:
            load_pem_public_key(value.encode('utf-8'),
                                backend=default_backend())
        except ValueError:
            raise serializers.ValidationError(
                _('The public key is not a valid base64 RSA key'))
        return clean_public_key(value)

    def _check_if_allowed_public(self, value):  # pylint: disable=no-self-use
        """
        Verify that users are allowed to create public
        forms
        """
        if not settings.ALLOW_PUBLIC_DATASETS and value:
            raise serializers.ValidationError(
                _('Public forms are currently disabled.'))
        return value

    def validate_public_data(self, value):
        """
        Validate the public_data field
        """
        return self._check_if_allowed_public(value)

    def validate_public(self, value):
        """
        Validate the public field
        """
        return self._check_if_allowed_public(value)

    def get_form_versions(self, obj):
        versions = []
        if obj:
            versions = cache.get('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk))

            if versions:
                return versions

            versions = list(
                Instance.objects.filter(
                    xform=obj,
                    deleted_at__isnull=True).values('version').annotate(
                        total=Count('version')))

            if versions:
                cache.set('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk),
                          list(versions))

        return versions
Ejemplo n.º 12
0
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    projectid = serializers.ReadOnlyField(source='id')
    url = serializers.HyperlinkedIdentityField(view_name='project-detail',
                                               lookup_field='pk')
    owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        source='organization',
        lookup_field='username',
        queryset=User.objects.exclude(
            username__iexact=settings.ANONYMOUS_DEFAULT_USERNAME))
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     lookup_field='username',
                                                     read_only=True)
    metadata = JsonField(required=False)
    starred = serializers.SerializerMethodField()
    users = serializers.SerializerMethodField()
    forms = serializers.SerializerMethodField()
    public = serializers.BooleanField(source='shared')
    tags = TagListSerializer(read_only=True)
    num_datasets = serializers.SerializerMethodField()
    last_submission_date = serializers.SerializerMethodField()
    teams = serializers.SerializerMethodField()
    data_views = serializers.SerializerMethodField()

    class Meta:
        model = Project
        exclude = ('shared', 'organization', 'user_stars')

    def validate(self, attrs):
        name = attrs.get('name')
        organization = attrs.get('organization')
        if not self.instance and \
                Project.objects.filter(name__iexact=name,
                                       organization=organization):
            raise serializers.ValidationError(
                {'name': _(u"Project {} already exists.".format(name))})

        return attrs

    def update(self, instance, validated_data):
        metadata = JsonField.to_json(validated_data.get('metadata'))
        owner = validated_data.get('organization')

        if self.partial and metadata:
            if not isinstance(instance.metadata, dict):
                instance.metadata = {}

            instance.metadata.update(metadata)
            validated_data['metadata'] = instance.metadata

        if self.partial and owner:
            # give the new owner permissions
            set_owners_permission(owner, instance)

            if is_organization(owner.profile):
                owners_team = get_organization_owners_team(owner.profile)
                members_team = get_organization_members_team(owner.profile)
                OwnerRole.add(owners_team, instance)
                ReadOnlyRole.add(members_team, instance)

            # clear cache
            safe_delete('{}{}'.format(PROJ_PERM_CACHE, instance.pk))

        project = super(ProjectSerializer, self)\
            .update(instance, validated_data)

        project.xform_set.exclude(shared=project.shared)\
            .update(shared=project.shared, shared_data=project.shared)

        return instance

    def create(self, validated_data):
        created_by = self.context['request'].user
        project = Project.objects.create(
            name=validated_data.get('name'),
            organization=validated_data.get('organization'),
            created_by=created_by,
            shared=validated_data.get('shared', False),
            metadata=validated_data.get('metadata', dict()))

        project.xform_set.exclude(shared=project.shared)\
            .update(shared=project.shared, shared_data=project.shared)

        return project

    def get_users(self, obj):
        return get_users(obj, self.context)

    @check_obj
    def get_forms(self, obj):
        forms = cache.get('{}{}'.format(PROJ_FORMS_CACHE, obj.pk))
        if forms:
            return forms
        xforms = get_obj_xforms(obj)
        request = self.context.get('request')
        serializer = ProjectXFormSerializer(xforms,
                                            context={'request': request},
                                            many=True)
        forms = list(serializer.data)
        cache.set('{}{}'.format(PROJ_FORMS_CACHE, obj.pk), forms)

        return forms

    def get_num_datasets(self, obj):
        return get_num_datasets(obj)

    def get_last_submission_date(self, obj):
        return get_last_submission_date(obj)

    def get_starred(self, obj):
        return get_starred(obj, self.context['request'])

    def get_teams(self, obj):
        return get_teams(obj)

    @check_obj
    def get_data_views(self, obj):
        data_views = cache.get('{}{}'.format(PROJECT_LINKED_DATAVIEWS, obj.pk))
        if data_views:
            return data_views

        data_views_obj = obj.dataview_prefetch if \
            hasattr(obj, 'dataview_prefetch') else obj.dataview_set.all()

        serializer = DataViewMinimalSerializer(data_views_obj,
                                               many=True,
                                               context=self.context)
        data_views = list(serializer.data)

        cache.set('{}{}'.format(PROJECT_LINKED_DATAVIEWS, obj.pk), data_views)

        return data_views
Ejemplo n.º 13
0
class XFormSerializer(serializers.HyperlinkedModelSerializer):
    formid = serializers.Field(source='id')
    metadata = serializers.SerializerMethodField('get_xform_metadata')
    owner = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                source='user',
                                                lookup_field='username')
    created_by = serializers.HyperlinkedRelatedField(view_name='user-detail',
                                                     source='created_by',
                                                     lookup_field='username')
    public = BooleanField(source='shared', widget=widgets.CheckboxInput())
    public_data = BooleanField(source='shared_data')
    require_auth = BooleanField(source='require_auth',
                                widget=widgets.CheckboxInput())
    submission_count_for_today = serializers.Field(
        source='submission_count_for_today')
    tags = TagListSerializer(read_only=True)
    title = serializers.CharField(max_length=255, source='title')
    url = serializers.HyperlinkedIdentityField(view_name='xform-detail',
                                               lookup_field='pk')
    users = serializers.SerializerMethodField('get_xform_permissions')
    enketo_url = serializers.SerializerMethodField('get_enketo_url')
    enketo_preview_url = serializers.SerializerMethodField(
        'get_enketo_preview_url')
    instances_with_geopoints = serializers.SerializerMethodField(
        'get_instances_with_geopoints')
    num_of_submissions = serializers.SerializerMethodField(
        'get_num_of_submissions')
    form_versions = serializers.SerializerMethodField('get_xform_versions')

    class Meta:
        model = XForm
        read_only_fields = ('json', 'xml', 'date_created', 'date_modified',
                            'encrypted', 'bamboo_dataset',
                            'last_submission_time')
        exclude = ('id', 'json', 'xml', 'xls', 'user', 'has_start_time',
                   'shared', 'shared_data', 'deleted_at')

    def get_num_of_submissions(self, obj):
        if obj.num_of_submissions != obj.instances.filter(
                deleted_at__isnull=True).count():
            obj.submission_count(force_update=True)

        return obj.num_of_submissions

    def get_instances_with_geopoints(self, obj):
        if not obj.instances_with_geopoints and obj.instances.exclude(
                geom=None).count() > 0:
            obj.instances_with_geopoints = True
            obj.save()

        return obj.instances_with_geopoints

    def get_xform_permissions(self, obj):
        if obj:
            xform_perms = cache.get('{}{}'.format(XFORM_PERMISSIONS_CACHE,
                                                  obj.pk))
            if xform_perms:
                return xform_perms

            xform_perms = get_object_users_with_permissions(obj)
            cache.set('{}{}'.format(XFORM_PERMISSIONS_CACHE, obj.pk),
                      xform_perms)
            return xform_perms

        return []

    def get_enketo_url(self, obj):
        if obj:
            _enketo_url = cache.get('{}{}'.format(ENKETO_URL_CACHE, obj.pk))
            if _enketo_url:
                return _enketo_url

            try:
                metadata = MetaData.objects.get(xform=obj,
                                                data_type="enketo_url")
            except MetaData.DoesNotExist:
                request = self.context.get('request')
                form_url = _get_form_url(request, obj.user.username)
                url = ""

                try:
                    url = enketo_url(form_url, obj.id_string)
                    MetaData.enketo_url(obj, url)
                except (EnketoError, ConnectionError):
                    pass

                cache.set('{}{}'.format(ENKETO_URL_CACHE, obj.pk), url)
                return url

            _enketo_url = metadata.data_value
            cache.set('{}{}'.format(ENKETO_URL_CACHE, obj.pk), _enketo_url)
            return _enketo_url

        return None

    def get_enketo_preview_url(self, obj):
        if obj:
            _enketo_preview_url = cache.get('{}{}'.format(
                ENKETO_PREVIEW_URL_CACHE, obj.pk))
            if _enketo_preview_url:
                return _enketo_preview_url

            try:
                metadata = MetaData.objects.get(xform=obj,
                                                data_type="enketo_preview_url")
            except MetaData.DoesNotExist:
                request = self.context.get('request')
                preview_url = ""

                try:
                    preview_url = get_enketo_preview_url(
                        request, obj.user.username, obj.id_string)
                    MetaData.enketo_preview_url(obj, preview_url)
                except EnketoError:
                    pass

                cache.set('{}{}'.format(ENKETO_PREVIEW_URL_CACHE, obj.pk),
                          preview_url)
                return preview_url

            _enketo_preview_url = metadata.data_value
            cache.set('{}{}'.format(ENKETO_URL_CACHE, obj.pk),
                      _enketo_preview_url)
            return _enketo_preview_url

        return None

    def get_xform_metadata(self, obj):
        if obj:
            xform_metadata = cache.get('{}{}'.format(XFORM_METADATA_CACHE,
                                                     obj.pk))
            if xform_metadata:
                return xform_metadata

            xform_metadata = MetaDataSerializer(obj.metadata_set.all(),
                                                many=True,
                                                context=self.context).data
            cache.set('{}{}'.format(XFORM_METADATA_CACHE, obj.pk),
                      xform_metadata)
            return xform_metadata

        return []

    def get_xform_versions(self, obj):
        if obj:
            versions = cache.get('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk))

            if versions:
                return versions

            versions = Instance.objects.filter(xform=obj)\
                .values('version')\
                .annotate(total=Count('version'))

            if versions:
                cache.set('{}{}'.format(XFORM_DATA_VERSIONS, obj.pk),
                          list(versions))

            return versions
        return []