示例#1
0
class ImportMetadataSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=500, required=True)
    description = serializers.CharField(
        max_length=5000, required=False, allow_null=True
    )
    mbid = serializers.UUIDField(required=False, allow_null=True)
    copyright = serializers.CharField(max_length=500, required=False, allow_null=True)
    position = serializers.IntegerField(min_value=1, required=False, allow_null=True)
    tags = tags_serializers.TagsListField(required=False)
    license = common_serializers.RelatedField(
        "code", LicenseSerializer(), required=False, allow_null=True
    )
    cover = common_serializers.RelatedField(
        "uuid",
        queryset=common_models.Attachment.objects.all().local(),
        serializer=None,
        queryset_filter=lambda qs, context: qs.filter(actor=context["actor"]),
        write_only=True,
        required=False,
        allow_null=True,
    )
    album = common_serializers.RelatedField(
        "id",
        queryset=models.Album.objects.all(),
        serializer=None,
        queryset_filter=filter_album,
        write_only=True,
        required=False,
        allow_null=True,
    )
示例#2
0
class TagMutation(mutations.UpdateMutationSerializer):
    tags = tags_serializers.TagsListField()

    def get_previous_state_handlers(self):
        handlers = super().get_previous_state_handlers()
        handlers["tags"] = lambda obj: list(
            sorted(obj.tagged_items.values_list("tag__name", flat=True)))
        return handlers

    def update(self, instance, validated_data):
        tags = validated_data.pop("tags", NOOP)
        r = super().update(instance, validated_data)
        if tags != NOOP:
            tags_models.set_tags(instance, *tags)
        return r
示例#3
0
class AlbumCreateSerializer(serializers.Serializer):
    title = serializers.CharField(required=True, max_length=255)
    cover = COVER_WRITE_FIELD
    release_date = serializers.DateField(required=False, allow_null=True)
    tags = tags_serializers.TagsListField(required=False)
    description = common_serializers.ContentSerializer(allow_null=True, required=False)

    artist = common_serializers.RelatedField(
        "id",
        queryset=models.Artist.objects.exclude(channel__isnull=True),
        required=True,
        serializer=None,
        filters=lambda context: {"attributed_to": context["user"].actor},
    )

    def validate(self, validated_data):
        duplicates = validated_data["artist"].albums.filter(
            title__iexact=validated_data["title"]
        )
        if duplicates.exists():
            raise serializers.ValidationError("An album with this title already exist")

        return super().validate(validated_data)

    def to_representation(self, obj):
        obj.artist.attachment_cover
        return AlbumSerializer(obj, context=self.context).data

    def create(self, validated_data):
        instance = models.Album.objects.create(
            attributed_to=self.context["user"].actor,
            artist=validated_data["artist"],
            release_date=validated_data.get("release_date"),
            title=validated_data["title"],
            attachment_cover=validated_data.get("cover"),
        )
        common_utils.attach_content(
            instance, "description", validated_data.get("description")
        )
        tag_models.set_tags(instance, *(validated_data.get("tags", []) or []))
        instance.artist.get_channel()
        return instance
示例#4
0
class ChannelCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
    username = serializers.CharField(
        max_length=music_models.MAX_LENGTHS["ARTIST_NAME"],
        validators=[users_serializers.ASCIIUsernameValidator()],
    )
    description = common_serializers.ContentSerializer(allow_null=True)
    tags = tags_serializers.TagsListField()
    content_category = serializers.ChoiceField(
        choices=music_models.ARTIST_CONTENT_CATEGORY_CHOICES
    )
    metadata = serializers.DictField(required=False)
    cover = music_serializers.COVER_WRITE_FIELD

    def validate(self, validated_data):
        existing_channels = self.context["actor"].owned_channels.count()
        if existing_channels >= preferences.get("audio__max_channels"):
            raise serializers.ValidationError(
                "You have reached the maximum amount of allowed channels"
            )
        validated_data = super().validate(validated_data)
        metadata = validated_data.pop("metadata", {})
        if validated_data["content_category"] == "podcast":
            metadata_serializer = ChannelMetadataSerializer(data=metadata)
            metadata_serializer.is_valid(raise_exception=True)
            metadata = metadata_serializer.validated_data
        validated_data["metadata"] = metadata
        return validated_data

    def validate_username(self, value):
        if value.lower() in [n.lower() for n in settings.ACCOUNT_USERNAME_BLACKLIST]:
            raise serializers.ValidationError("This username is already taken")

        matching = federation_models.Actor.objects.local().filter(
            preferred_username__iexact=value
        )
        if matching.exists():
            raise serializers.ValidationError("This username is already taken")
        return value

    @transaction.atomic
    def create(self, validated_data):
        from . import views

        cover = validated_data.pop("cover", None)
        description = validated_data.get("description")
        artist = music_models.Artist.objects.create(
            attributed_to=validated_data["attributed_to"],
            name=validated_data["name"],
            content_category=validated_data["content_category"],
            attachment_cover=cover,
        )
        common_utils.attach_content(artist, "description", description)

        if validated_data.get("tags", []):
            tags_models.set_tags(artist, *validated_data["tags"])

        channel = models.Channel(
            artist=artist,
            attributed_to=validated_data["attributed_to"],
            metadata=validated_data["metadata"],
        )
        channel.actor = models.generate_actor(
            validated_data["username"], name=validated_data["name"],
        )

        channel.library = music_models.Library.objects.create(
            name=channel.actor.preferred_username,
            privacy_level="everyone",
            actor=validated_data["attributed_to"],
        )
        channel.save()
        channel = views.ChannelViewSet.queryset.get(pk=channel.pk)
        return channel

    def to_representation(self, obj):
        return ChannelSerializer(obj, context=self.context).data
示例#5
0
class ChannelUpdateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
    description = common_serializers.ContentSerializer(allow_null=True)
    tags = tags_serializers.TagsListField()
    content_category = serializers.ChoiceField(
        choices=music_models.ARTIST_CONTENT_CATEGORY_CHOICES
    )
    metadata = serializers.DictField(required=False)
    cover = music_serializers.COVER_WRITE_FIELD

    def validate(self, validated_data):
        validated_data = super().validate(validated_data)
        require_metadata_validation = False
        new_content_category = validated_data.get("content_category")
        metadata = validated_data.pop("metadata", NOOP)
        if (
            new_content_category == "podcast"
            and self.instance.artist.content_category != "postcast"
        ):
            # updating channel, setting as podcast
            require_metadata_validation = True
        elif self.instance.artist.content_category == "postcast" and metadata != NOOP:
            # channel is podcast, and metadata was updated
            require_metadata_validation = True
        else:
            metadata = self.instance.metadata

        if require_metadata_validation:
            metadata_serializer = ChannelMetadataSerializer(data=metadata)
            metadata_serializer.is_valid(raise_exception=True)
            metadata = metadata_serializer.validated_data

        validated_data["metadata"] = metadata
        return validated_data

    @transaction.atomic
    def update(self, obj, validated_data):
        if validated_data.get("tags") is not None:
            tags_models.set_tags(obj.artist, *validated_data["tags"])
        actor_update_fields = []
        artist_update_fields = []

        obj.metadata = validated_data["metadata"]
        obj.save(update_fields=["metadata"])

        if "description" in validated_data:
            common_utils.attach_content(
                obj.artist, "description", validated_data["description"]
            )

        if "name" in validated_data:
            actor_update_fields.append(("name", validated_data["name"]))
            artist_update_fields.append(("name", validated_data["name"]))

        if "content_category" in validated_data:
            artist_update_fields.append(
                ("content_category", validated_data["content_category"])
            )

        if "cover" in validated_data:
            artist_update_fields.append(("attachment_cover", validated_data["cover"]))

        if actor_update_fields:
            for field, value in actor_update_fields:
                setattr(obj.actor, field, value)
            obj.actor.save(update_fields=[f for f, _ in actor_update_fields])

        if artist_update_fields:
            for field, value in artist_update_fields:
                setattr(obj.artist, field, value)
            obj.artist.save(update_fields=[f for f, _ in artist_update_fields])

        return obj

    def to_representation(self, obj):
        return ChannelSerializer(obj, context=self.context).data
def test_tags_list_field_honor_TAGS_MAX_BY_OBJ(max, tags, expected, settings):
    settings.TAGS_MAX_BY_OBJ = max
    field = serializers.TagsListField()
    assert field.to_internal_value(tags) == expected