Esempio n. 1
0
class AdminLevelSerializer(RemoveNullFieldsMixin, DynamicFieldsMixin,
                           serializers.ModelSerializer):
    """
    Admin Level Model Serializer
    """
    geo_shape_file_details = SimpleFileSerializer(source='geo_shape_file',
                                                  read_only=True)

    geojson_file = URLCachedFileField(required=False, read_only=True)
    bounds_file = URLCachedFileField(required=False, read_only=True)

    class Meta:
        model = AdminLevel
        exclude = ('geo_area_titles', )

    # Validations
    def validate_region(self, region):
        if not region.can_modify(self.context['request'].user):
            raise serializers.ValidationError('Invalid region')
        return region

    def create(self, validated_data):
        admin_level = super().create(validated_data)
        admin_level.stale_geo_areas = True
        admin_level.save()

        region = admin_level.region
        region.modified_by = self.context['request'].user
        region.save()

        if not settings.TESTING:
            transaction.on_commit(lambda: load_geo_areas.delay(region.id))

        return admin_level

    def update(self, instance, validated_data):
        admin_level = super().update(
            instance,
            validated_data,
        )
        admin_level.stale_geo_areas = True
        admin_level.save()

        region = admin_level.region
        region.modified_by = self.context['request'].user
        region.save()

        if not settings.TESTING:
            transaction.on_commit(lambda: load_geo_areas.delay(region.id))

        return admin_level
Esempio n. 2
0
class SimpleOrganizationSerializer(serializers.ModelSerializer):
    logo = URLCachedFileField(source='logo.file', read_only=True)
    merged_as = MergedAsOrganizationSerializer(source='parent', read_only=True)

    class Meta:
        model = Organization
        fields = ('id', 'title', 'short_name', 'merged_as', 'logo')
Esempio n. 3
0
class SimpleFileSerializer(RemoveNullFieldsMixin, serializers.ModelSerializer):
    title = serializers.CharField(required=False, read_only=True)
    file = URLCachedFileField(required=False, read_only=True)
    mime_type = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = File
        fields = ('id', 'title', 'file', 'mime_type')
        read_only_fields = FILE_READONLY_FIELDS
Esempio n. 4
0
class ArySourceOrganizationSerializer(DynamicFieldsMixin, UserResourceSerializer):
    logo = URLCachedFileField(source='logo.file', allow_null=True)
    key = serializers.IntegerField(source='pk')
    merged_as = MergedAsOrganizationSerializer(source='parent', read_only=True)

    class Meta:
        model = Organization
        fields = ('key', 'title', 'long_name',
                  'short_name', 'logo', 'organization_type', 'merged_as')
Esempio n. 5
0
class LeadPreviewImageSerializer(RemoveNullFieldsMixin,
                                 DynamicFieldsMixin,
                                 serializers.ModelSerializer):
    """
    Serializer for lead preview image
    """

    file = URLCachedFileField(read_only=True)

    class Meta:
        model = LeadPreviewImage
        fields = ('id', 'file',)
Esempio n. 6
0
 def batch_load_fn(self, keys):
     display_picture_qs = User.objects.filter(pk__in=keys).values_list(
         'id', 'profile__display_picture__file')
     # Membership map
     display_picture_map = {}
     for user_id, display_picture in display_picture_qs:
         if display_picture:
             display_picture_map[
                 user_id] = self.context.request.build_absolute_uri(
                     URLCachedFileField.name_to_representation(
                         display_picture))
     return Promise.resolve([display_picture_map.get(key) for key in keys])
Esempio n. 7
0
def _get_viz_data(request, project, can_view_confidential, token=None):
    """
    Util function to trigger and serve Project entry/ary viz data
    """
    if (
            project.analysis_framework is None or
            project.analysis_framework.properties is None or
            project.analysis_framework.properties.get('stats_config') is None
    ):
        return {
            'error': f'No configuration provided for current Project: {project.title}, Contact Admin',
        }, status.HTTP_404_NOT_FOUND

    stats, created = ProjectStats.objects.get_or_create(project=project)

    if token and (
        not stats.public_share or token != str(stats.token)
    ):
        return {
            'error': 'Token is invalid or sharing is disabled. Please contact project\'s admin.'
        }, status.HTTP_403_FORBIDDEN

    stat_file = stats.confidential_file if can_view_confidential else stats.file
    file_url = (
        request.build_absolute_uri(URLCachedFileField().to_representation(stat_file))
        if stat_file else None
    )
    stats_meta = {
        'data': file_url,
        'modified_at': stats.modified_at,
        'status': stats.status,
        'public_share': stats.public_share,
        'public_url': stats.get_public_url(request),
    }

    if stats.is_ready():
        return stats_meta, status.HTTP_200_OK
    elif stats.status == ProjectStats.Status.FAILURE:
        return {
            'error': 'Failed to generate stats, Contact Admin',
            **stats_meta,
        }, status.HTTP_200_OK
    transaction.on_commit(lambda: generate_viz_stats.delay(project.pk))
    # NOTE: Not changing modified_at if already pending
    if stats.status != ProjectStats.Status.PENDING:
        stats.status = ProjectStats.Status.PENDING
        stats.save()
    return {
        'message': 'Processing the request, try again later',
        **stats_meta,
    }, status.HTTP_202_ACCEPTED
Esempio n. 8
0
class UserPreferencesSerializer(RemoveNullFieldsMixin,
                                serializers.ModelSerializer):
    display_picture = serializers.PrimaryKeyRelatedField(
        source='profile.display_picture',
        queryset=File.objects.all(),
        allow_null=True,
        required=False,
    )
    display_picture_url = URLCachedFileField(
        source='profile.display_picture.file',
        read_only=True,
    )
    display_name = serializers.CharField(
        source='profile.get_display_name',
        read_only=True,
    )
    last_active_project = serializers.PrimaryKeyRelatedField(
        source='profile.last_active_project',
        queryset=Project.objects.all(),
        allow_null=True,
        required=False,
    )
    language = serializers.CharField(source='profile.language', read_only=True)
    fallback_language = serializers.CharField(
        source='profile.get_fallback_language',
        read_only=True,
    )

    accessible_features = FeatureSerializer(
        source='profile.get_accessible_features',
        many=True,
        read_only=True,
    )

    class Meta:
        model = User
        fields = (
            'display_name',
            'username',
            'email',
            'last_active_project',
            'display_picture',
            'display_picture_url',
            'is_superuser',
            'language',
            'accessible_features',
            'fallback_language',
        )
Esempio n. 9
0
class EntryCommentUserSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='profile.get_display_name',
                                 read_only=True)
    display_picture_url = URLCachedFileField(
        source='profile.display_picture.file',
        read_only=True,
    )
    organization = serializers.CharField(source='profile.organization',
                                         read_only=True)

    class Meta:
        model = User
        fields = (
            'id',
            'name',
            'email',
            'organization',
            'display_picture_url',
        )
Esempio n. 10
0
class SimpleUserSerializer(RemoveNullFieldsMixin, serializers.ModelSerializer):
    display_name = serializers.CharField(
        source='profile.get_display_name',
        read_only=True,
    )
    display_picture = serializers.PrimaryKeyRelatedField(
        source='profile.display_picture',
        read_only=True,
    )
    display_picture_url = URLCachedFileField(
        source='profile.display_picture.file',
        read_only=True,
    )
    organization_title = serializers.CharField(source='profile.organization',
                                               read_only=True)

    class Meta:
        model = User
        fields = ('id', 'display_name', 'email', 'display_picture',
                  'display_picture_url', 'organization_title')
Esempio n. 11
0
class OrganizationSerializer(
    DynamicFieldsMixin, RemoveNullFieldsMixin, UserResourceSerializer,
):
    organization_type_display = OrganizationTypeSerializer(
        source='organization_type', read_only=True,
    )
    regions_display = SimpleRegionSerializer(
        source='regions', read_only=True, many=True,
    )
    logo_url = URLCachedFileField(source='logo.file', allow_null=True, required=False)
    merged_as = MergedAsOrganizationSerializer(source='parent', read_only=True)
    client_id = None

    class Meta:
        model = Organization
        exclude = ('parent',)
        read_only_fields = ('verified', 'logo_url',)

    def create(self, validated_data):
        organization = super().create(validated_data)
        organization.created_by = organization.modified_by = self.context['request'].user
        return organization
Esempio n. 12
0
class FileSerializer(RemoveNullFieldsMixin, DynamicFieldsMixin,
                     UserResourceSerializer):
    file = URLCachedFileField(required=True, read_only=False)

    class Meta:
        model = File
        fields = ('__all__')
        read_only_fields = FILE_READONLY_FIELDS

    # Validations
    def validate_file(self, file):
        extension = os.path.splitext(file.name)[1][1:]
        if file.content_type not in deep_doc_types.DEEP_SUPPORTED_MIME_TYPES\
                and extension not in deep_doc_types.DEEP_SUPPORTED_EXTENSIONS:
            raise serializers.ValidationError(
                'Unsupported file type {}'.format(file.content_type))
        return file

    def _get_metadata(self, file):
        metadata = {'md5_hash': calculate_md5(file.file)}
        mime_type = file.content_type
        if mime_type in deep_doc_types.PDF_MIME_TYPES:
            metadata.update({
                'pages': get_pages_in_pdf(file.file),
            })
        elif mime_type in deep_doc_types.DOCX_MIME_TYPES:
            metadata.update({
                'pages': get_pages_in_docx(file.file),
            })
        return metadata

    def create(self, validated_data):
        validated_data['mime_type'] = validated_data.get('file').content_type
        try:
            validated_data['metadata'] = self._get_metadata(
                validated_data.get('file'))
        except Exception:
            logger.error('File create Failed!!', exc_info=True)
        return super().create(validated_data)
Esempio n. 13
0
class MergedAsOrganizationSerializer(serializers.ModelSerializer):
    logo = URLCachedFileField(source='logo.file', read_only=True)

    class Meta:
        model = Organization
        fields = ('id', 'title', 'logo')
Esempio n. 14
0
class LeadSerializer(
    RemoveNullFieldsMixin, DynamicFieldsMixin, WriteOnlyOnCreateSerializerMixin, UserResourceSerializer,
):
    """
    Lead Model Serializer
    """
    # annotated in lead.get_for
    entries_count = serializers.IntegerField(read_only=True)
    controlled_entries_count = serializers.IntegerField(read_only=True)
    filtered_entries_count = serializers.IntegerField(read_only=True)
    controlled_filtered_entries_count = serializers.IntegerField(read_only=True)

    assessment_id = serializers.IntegerField(read_only=True)

    priority_display = serializers.CharField(source='get_priority_display', read_only=True)

    attachment = SimpleFileSerializer(required=False)
    thumbnail = URLCachedFileField(
        source='leadpreview.thumbnail',
        read_only=True,
    )
    thumbnail_height = serializers.IntegerField(
        source='leadpreview.thumbnail_height',
        read_only=True,
    )
    thumbnail_width = serializers.IntegerField(
        source='leadpreview.thumbnail_width',
        read_only=True,
    )
    word_count = serializers.IntegerField(
        source='leadpreview.word_count',
        read_only=True,
    )
    page_count = serializers.IntegerField(
        source='leadpreview.page_count',
        read_only=True,
    )
    classified_doc_id = serializers.IntegerField(
        source='leadpreview.classified_doc_id',
        read_only=True,
    )

    # TODO: Remove (Legacy)
    author_detail = SimpleOrganizationSerializer(source='author', read_only=True)

    authors_detail = SimpleOrganizationSerializer(source='authors', many=True, read_only=True)
    source_detail = SimpleOrganizationSerializer(source='source', read_only=True)

    assignee_details = SimpleUserSerializer(
        source='get_assignee',
        # many=True,
        read_only=True,
    )
    assignee = SingleValueThayMayBeListField(
        source='get_assignee.id',
        required=False,
    )
    tabular_book = serializers.SerializerMethodField()
    emm_triggers = LeadEMMTriggerSerializer(many=True, required=False)
    emm_entities = EMMEntitySerializer(many=True, required=False)
    # extra fields added from entryleadserializer
    confidentiality_display = serializers.CharField(source='get_confidentiality_display', read_only=True)

    class Meta:
        model = Lead
        fields = ('__all__')
        # Legacy Fields
        read_only_fields = ('author_raw', 'source_raw')
        write_only_on_create_fields = ['emm_triggers', 'emm_entities']

    def get_tabular_book(self, obj):
        file = obj.attachment
        if file and hasattr(file, 'book'):
            return file.book.id
        return None

    @staticmethod
    def add_update__validate(data, instance, attachment=None):
        project = data.get('project', instance and instance.project)
        source_type = data.get('source_type', instance and instance.source_type)
        text = data.get('text', instance and instance.text)
        url = data.get('url', instance and instance.url)

        return raise_or_return_existing_lead(
            project,
            instance,
            source_type,
            url,
            text,
            attachment,
        )

    def validate_is_assessment_lead(self, value):
        # Allow setting True
        # For False make sure there are no assessment attached.
        if value is False and hasattr(self.instance, 'assessment'):
            raise serializers.ValidationError('Lead already has an assessment.')
        return value

    def validate(self, data):
        attachment_id = self.get_initial().get('attachment', {}).get('id')
        LeadSerializer.add_update__validate(
            data, self.instance,
            File.objects.filter(pk=attachment_id).first()
        )
        return data

    # TODO: Probably also validate assignee to valid list of users

    def create(self, validated_data):
        assignee_field = validated_data.pop('get_assignee', None)
        assignee_id = assignee_field and assignee_field.get('id', None)
        assignee = assignee_id and get_object_or_404(User, id=assignee_id)

        emm_triggers = validated_data.pop('emm_triggers', [])
        emm_entities_names = [
            entity['name']
            for entity in validated_data.pop('emm_entities', [])
            if isinstance(entity, dict) and 'name' in entity
        ]

        lead = super().create(validated_data)

        for entity in EMMEntity.objects.filter(name__in=emm_entities_names):
            lead.emm_entities.add(entity)
        lead.save()

        with transaction.atomic():
            for trigger in emm_triggers:
                LeadEMMTrigger.objects.create(**trigger, lead=lead)

        if assignee:
            lead.assignee.add(assignee)
        return lead

    def update(self, instance, validated_data):
        assignee_field = validated_data.pop('get_assignee', None)
        assignee_id = assignee_field and assignee_field.get('id', None)
        assignee = assignee_id and get_object_or_404(User, id=assignee_id)

        # We do not update triggers and entities
        validated_data.pop('emm_entities', None)
        validated_data.pop('emm_triggers', None)

        lead = super().update(instance, validated_data)

        if assignee_field:
            lead.assignee.clear()
            if assignee:
                lead.assignee.add(assignee)
        return lead
Esempio n. 15
0
 def resolve_url(root, info, **kwargs) -> Union[str, None]:
     return info.context.request.build_absolute_uri(
         URLCachedFileField.name_to_representation(root))
Esempio n. 16
0
 def resolve_data_url(root, info, **_):
     url = root.file
     if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD):
         url = root.confidential_file
     return url and info.context.request.build_absolute_uri(
         URLCachedFileField.name_to_representation(url))
Esempio n. 17
0
class UserSerializer(RemoveNullFieldsMixin, WriteOnlyOnCreateSerializerMixin,
                     DynamicFieldsMixin, serializers.ModelSerializer):
    organization = serializers.CharField(source='profile.organization',
                                         allow_blank=True)
    language = serializers.CharField(
        source='profile.language',
        allow_null=True,
        required=False,
    )
    display_picture = serializers.PrimaryKeyRelatedField(
        source='profile.display_picture',
        queryset=File.objects.all(),
        allow_null=True,
        required=False,
    )
    display_picture_url = URLCachedFileField(
        source='profile.display_picture.file',
        read_only=True,
    )
    display_name = serializers.CharField(
        source='profile.get_display_name',
        read_only=True,
    )
    last_active_project = serializers.PrimaryKeyRelatedField(
        source='profile.last_active_project',
        queryset=Project.objects.all(),
        allow_null=True,
        required=False,
    )
    email_opt_outs = serializers.ListField(
        source='profile.email_opt_outs',
        required=False,
    )
    login_attempts = serializers.IntegerField(
        source='profile.login_attempts',
        read_only=True,
    )

    hcaptcha_response = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'first_name', 'last_name', 'display_name',
                  'last_active_project', 'login_attempts', 'hcaptcha_response',
                  'email', 'organization', 'display_picture',
                  'display_picture_url', 'language', 'email_opt_outs')
        write_only_on_create_fields = ('email', 'username')

    @classmethod
    def update_or_create_profile(cls, user, profile_data):
        profile, created = Profile.objects.update_or_create(
            user=user, defaults=profile_data)
        return profile

    def validate_hcaptcha_response(self, captcha):
        validate_hcaptcha(captcha)

    def validate_last_active_project(self, project):
        if project and not project.is_member(self.context['request'].user):
            raise serializers.ValidationError('Invalid project')
        return project

    def create(self, validated_data):
        profile_data = validated_data.pop('profile', None)
        validated_data.pop('hcaptcha_response', None)
        validated_data['email'] = validated_data['username'] = (
            validated_data['email'] or validated_data['email']).lower()
        user = super().create(validated_data)
        user.save()
        user.profile = self.update_or_create_profile(user, profile_data)
        send_password_reset(user=user, welcome=True)
        return user

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile', None)
        user = super().update(instance, validated_data)
        if 'password' in validated_data:
            user.set_password(validated_data['password'])
            user.save()
        user.profile = self.update_or_create_profile(user, profile_data)
        return user