示例#1
0
class LeadSerializer(RemoveNullFieldsMixin,
                     DynamicFieldsMixin, UserResourceSerializer):
    """
    Lead Model Serializer
    """
    no_of_entries = serializers.IntegerField(
        read_only=True,
    )
    attachment = SimpleFileSerializer(required=False)
    classified_doc_id = serializers.IntegerField(
        source='leadpreview.classified_doc_id',
        read_only=True,
    )

    assignee_details = SimpleUserSerializer(
        source='assignee',
        many=True,
        read_only=True,
    )

    class Meta:
        model = Lead
        fields = ('__all__')

    # validations
    def validate_project(self, project):
        # Make sure we have access to the given project
        if not project.can_get(self.context['request'].user):
            raise serializers.ValidationError(
                'Invalid project: {}'.format(project.id))
        return project
示例#2
0
class SimpleEntrySerializer(serializers.ModelSerializer):
    image_details = SimpleFileSerializer(source='image', read_only=True)
    tabular_field_data = FieldProcessedOnlySerializer(source='tabular_field')

    class Meta:
        model = Entry
        fields = ('id', 'excerpt', 'dropped_excerpt', 'image', 'image_details',
                  'entry_type', 'tabular_field', 'tabular_field_data')
示例#3
0
 def get_gallery_files_details(self, assessment):
     # Right now gallery files are only used in additional_documents
     additional_documents = (assessment.metadata or {}).get('additional_documents')
     if not additional_documents:
         return
     files_id = []
     for items in additional_documents.values():
         for item in items or []:
             if item.get('id') and item.get('type') == 'file':
                 files_id.append(item['id'])
     # TODO:
     qs = File.objects.filter(id__in=files_id).all()
     return SimpleFileSerializer(qs, context=self.context, many=True).data
示例#4
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
示例#5
0
class EntrySerializer(RemoveNullFieldsMixin, DynamicFieldsMixin,
                      DeprecatedUserResourceSerializer):
    attributes = ListToDictField(
        child=SimpleAttributeSerializer(many=True),
        key='widget',
        source='attribute_set',
        required=False,
    )

    project = serializers.PrimaryKeyRelatedField(
        required=False, queryset=Project.objects.all())
    resolved_comment_count = serializers.SerializerMethodField()
    unresolved_comment_count = serializers.SerializerMethodField()
    project_labels = serializers.SerializerMethodField()
    controlled_changed_by_details = SimpleUserSerializer(
        source='controlled_changed_by',
        read_only=True,
    )

    image_details = SimpleFileSerializer(source='image', read_only=True)
    lead_image = serializers.PrimaryKeyRelatedField(
        required=False,
        write_only=True,
        queryset=LeadPreviewImage.objects.all())
    # NOTE: Provided by annotate `annotate_comment_count`
    verified_by_count = serializers.IntegerField(read_only=True)
    is_verified_by_current_user = serializers.BooleanField(read_only=True)

    class Meta:
        model = Entry
        fields = '__all__'

    def get_project_labels(self, entry):
        # Should be provided from view
        label_count = self.context.get('entry_group_label_count')
        if label_count is not None:
            return label_count.get(entry.pk) or []
        # Fallback
        return EntryGroupLabel.get_stat_for_entry(entry.entrygrouplabel_set)

    def get_resolved_comment_count(self, entry):
        if hasattr(entry, 'resolved_comment_count'):
            return entry.resolved_comment_count
        return entry.entrycomment_set.filter(parent=None,
                                             is_resolved=True).count()

    def get_unresolved_comment_count(self, entry):
        if hasattr(entry, 'unresolved_comment_count'):
            return entry.unresolved_comment_count
        return entry.entrycomment_set.filter(parent=None,
                                             is_resolved=False).count()

    def validate(self, data):
        """
        - Lead image is copied to deep gallery files
        - Raw image (base64) are saved as deep gallery files
        """
        request = self.context['request']
        lead = data.get('lead') or (self.instance and self.instance.lead)
        image = data.get('image')
        image_raw = data.pop('image_raw', None)
        lead_image = data.pop('lead_image', None)

        # If gallery file is provided make sure user owns the file
        if image:
            if ((self.instance and self.instance.image) != image
                    and not image.is_public
                    and image.created_by != self.context['request'].user):
                raise serializers.ValidationError({
                    'image':
                    f'You don\'t have permission to attach image: {image}',
                })
            return data
        # If lead image is provided make sure lead are same
        elif lead_image:
            if lead_image.lead != lead:
                raise serializers.ValidationError({
                    'lead_image':
                    f'You don\'t have permission to attach lead image: {lead_image}',
                })
            data['image'] = lead_image.clone_as_deep_file(request.user)
        elif image_raw:
            generated_image = base64_to_deep_image(
                image_raw,
                lead,
                request.user,
            )
            if type(generated_image) == File:
                data['image'] = generated_image
        return data

    def create(self, validated_data):
        if validated_data.get('project') is None:
            validated_data['project'] = validated_data['lead'].project

        return super().create(validated_data)

    def update(self, instance, validated_data):
        # once altered, uncontrol the entry if its uncontrolled
        if instance and instance.controlled:
            validated_data['controlled'] = False
            validated_data['controlled_changed_by'] = self.context[
                'request'].user
            # NOTE: Create a review instance for this action.
            review_comment = EntryReviewComment.objects.create(
                entry=instance,
                created_by=self.context['request'].user,
                comment_type=EntryReviewComment.CommentType.UNCONTROL,
            )
            review_comment.comment_texts.model.objects.create(
                comment=review_comment,
                text='This comment was generated by entry edit action')
        entry = super().update(instance, validated_data)
        return entry
示例#6
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
示例#7
0
class LeadSerializer(RemoveNullFieldsMixin, DynamicFieldsMixin,
                     ProjectEntitySerializer):
    """
    Lead Model Serializer
    """
    no_of_entries = serializers.IntegerField(read_only=True)
    attachment = SimpleFileSerializer(required=False)
    classified_doc_id = serializers.IntegerField(
        source='leadpreview.classified_doc_id',
        read_only=True,
    )

    assignee_details = SimpleUserSerializer(
        source='get_assignee',
        # many=True,
        read_only=True,
    )
    assignee = SingleValueThayMayBeListField(
        source='get_assignee.id',
        required=False,
    )

    class Meta:
        model = Lead
        fields = ('__all__')

    def validate(self, data):
        project = data.get('project', self.instance and self.instance.project)
        source_type = data.get('source_type', self.instance
                               and self.instance.source_type)

        # For website types, check if url has already been added
        if source_type == Lead.WEBSITE:
            url = data.get('url', self.instance and self.instance.url)
            if check_if_url_exists(url, None, project, self.instance
                                   and self.instance.id):
                raise serializers.ValidationError(
                    'A lead with this URL has already been added to '
                    'this project')

        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)

        lead = super().create(validated_data)
        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)

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

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