Exemplo n.º 1
0
class LocalBadgeInstanceUploadSerializerV1(serializers.Serializer):
    image = Base64FileField(required=False, write_only=True)
    url = serializers.URLField(required=False, write_only=True)
    assertion = serializers.CharField(required=False, write_only=True)
    recipient_identifier = serializers.CharField(required=False,
                                                 read_only=True)
    acceptance = serializers.CharField(default='Accepted')
    public = serializers.BooleanField(required=False, default=False)
    include_evidence = serializers.BooleanField(required=False, default=False)
    narrative = MarkdownCharField(required=False, read_only=True)

    extensions = serializers.DictField(source='extension_items',
                                       read_only=True)

    def to_representation(self, obj):
        """
        If the APIView initialized the serializer with the extra context
        variable 'format' from a query param in the GET request with the
        value "plain", make the `json` field for this instance read_only.
        """
        if self.context.get('format', 'v1') == 'plain':
            self.fields.json = serializers.DictField(read_only=True)
        representation = super(LocalBadgeInstanceUploadSerializerV1,
                               self).to_representation(obj)

        representation['id'] = obj.entity_id
        representation['json'] = V1BadgeInstanceSerializer(
            obj, context=self.context).data
        representation['imagePreview'] = {
            "type":
            "image",
            "id":
            "{}{}?type=png".format(
                OriginSetting.HTTP,
                reverse('badgeclass_image',
                        kwargs={'entity_id': obj.cached_badgeclass.entity_id}))
        }
        if obj.cached_issuer.image:
            representation['issuerImagePreview'] = {
                "type":
                "image",
                "id":
                "{}{}?type=png".format(
                    OriginSetting.HTTP,
                    reverse('issuer_image',
                            kwargs={'entity_id': obj.cached_issuer.entity_id}))
            }

        if obj.image:
            representation['image'] = obj.image_url()

        representation['shareUrl'] = obj.share_url

        return representation

    def validate(self, data):
        """
        Ensure only one assertion input field given.
        """

        fields_present = [
            'image' in data, 'url' in data, 'assertion' in data
            and data.get('assertion')
        ]
        if (fields_present.count(True) > 1):
            raise serializers.ValidationError(
                "Only one instance input field allowed.")

        return data

    def create(self, validated_data):
        owner = validated_data.get('created_by')
        try:
            instance, created = BadgeCheckHelper.get_or_create_assertion(
                url=validated_data.get('url', None),
                imagefile=validated_data.get('image', None),
                assertion=validated_data.get('assertion', None),
                created_by=owner,
            )
            if not created:
                if instance.acceptance == BadgeInstance.ACCEPTANCE_ACCEPTED:
                    raise RestframeworkValidationError([{
                        'name':
                        "DUPLICATE_BADGE",
                        'description':
                        "You already have this badge in your backpack"
                    }])
                instance.acceptance = BadgeInstance.ACCEPTANCE_ACCEPTED
                instance.save()
            owner.publish()  # update BadgeUser.cached_badgeinstances()
        except DjangoValidationError as e:
            raise RestframeworkValidationError(e.args[0])
        return instance

    def update(self, instance, validated_data):
        """ Updating acceptance status (to 'Accepted') is permitted as well as changing public status. """
        # Only locally issued badges will ever have an acceptance status other than 'Accepted'
        if instance.acceptance in [
                'Unaccepted', 'Rejected'
        ] and validated_data.get('acceptance') == 'Accepted':
            instance.acceptance = 'Accepted'
            instance.save()
        public = validated_data.get('public', None)
        if public is not None:
            instance.public = public
            instance.include_evidence = validated_data.get(
                'include_evidence', False)
            instance.save()
        return instance
Exemplo n.º 2
0
class LocalBadgeInstanceUploadSerializerV1(serializers.Serializer):
    image = Base64FileField(required=False, write_only=True)
    url = serializers.URLField(required=False, write_only=True)
    assertion = serializers.CharField(required=False, write_only=True)
    recipient_identifier = serializers.CharField(required=False,
                                                 read_only=True)
    acceptance = serializers.CharField(default='Accepted')
    narrative = MarkdownCharField(required=False, read_only=True)
    evidence_items = EvidenceItemSerializer(many=True,
                                            required=False,
                                            read_only=True)
    pending = serializers.ReadOnlyField()

    extensions = serializers.DictField(source='extension_items',
                                       read_only=True)

    # Reinstantiation using fields from badge instance when returned by .create
    # id = serializers.IntegerField(read_only=True)
    # json = V1InstanceSerializer(read_only=True)

    def to_representation(self, obj):
        """
        If the APIView initialized the serializer with the extra context
        variable 'format' from a query param in the GET request with the
        value "plain", make the `json` field for this instance read_only.
        """
        if self.context.get('format', 'v1') == 'plain':
            self.fields.json = serializers.DictField(read_only=True)
        representation = super(LocalBadgeInstanceUploadSerializerV1,
                               self).to_representation(obj)

        # if isinstance(obj, LocalBadgeInstance):
        #     representation['json'] = V1InstanceSerializer(obj.json, context=self.context).data
        #     representation['imagePreview'] = {
        #         "type": "image",
        #         "id": "{}{}?type=png".format(OriginSetting.HTTP, reverse('localbadgeinstance_image', kwargs={'slug': obj.slug}))
        #     }
        # if isinstance(obj, BadgeInstance):

        representation['id'] = obj.entity_id
        representation['json'] = V1BadgeInstanceSerializer(
            obj, context=self.context).data
        representation['imagePreview'] = {
            "type":
            "image",
            "id":
            "{}{}?type=png".format(
                OriginSetting.HTTP,
                reverse('badgeclass_image',
                        kwargs={'entity_id': obj.cached_badgeclass.entity_id}))
        }
        if obj.cached_issuer.image:
            representation['issuerImagePreview'] = {
                "type":
                "image",
                "id":
                "{}{}?type=png".format(
                    OriginSetting.HTTP,
                    reverse('issuer_image',
                            kwargs={'entity_id': obj.cached_issuer.entity_id}))
            }

        if obj.image:
            representation['image'] = obj.image_url()

        representation['shareUrl'] = obj.share_url

        return representation

    # def validate_recipient_identifier(self, data):
    #     user = self.context.get('request').user
    #     current_emails = [e.email for e in user.cached_emails()] + [e.email for e in user.cached_email_variants()]
    #
    #     if data in current_emails:
    #         return None
    #     if user.can_add_variant(data):
    #         return data
    #     raise serializers.ValidationError("Requested recipient ID {} is not one of your verified email addresses.")
    #
    def validate(self, data):
        """
        Ensure only one assertion input field given.
        """

        fields_present = [
            'image' in data, 'url' in data, 'assertion' in data
            and data.get('assertion')
        ]
        if (fields_present.count(True) > 1):
            raise serializers.ValidationError(
                "Only one instance input field allowed.")

        return data

    def create(self, validated_data):
        owner = validated_data.get('created_by')
        try:
            instance, created = BadgeCheckHelper.get_or_create_assertion(
                url=validated_data.get('url', None),
                imagefile=validated_data.get('image', None),
                assertion=validated_data.get('assertion', None),
                created_by=owner,
            )
            if not created:
                if instance.acceptance == BadgeInstance.ACCEPTANCE_ACCEPTED:
                    raise RestframeworkValidationError([{
                        'name':
                        "DUPLICATE_BADGE",
                        'description':
                        "You already have this badge in your backpack"
                    }])
                instance.acceptance = BadgeInstance.ACCEPTANCE_ACCEPTED
                instance.save()
            owner.publish()  # update BadgeUser.cached_badgeinstances()
        except DjangoValidationError as e:
            raise RestframeworkValidationError(e.args[0])
        return instance

    def update(self, instance, validated_data):
        """ Only updating acceptance status (to 'Accepted') is permitted for now. """
        # Only locally issued badges will ever have an acceptance status other than 'Accepted'
        if instance.acceptance == 'Unaccepted' and validated_data.get(
                'acceptance') == 'Accepted':
            instance.acceptance = 'Accepted'

            instance.save()
            owner = instance.user
            if owner:
                owner.publish()

        return instance