kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Merge branch '170-channel-description' into 'develop'
See #170: use new content obj for channel description See merge request funkwhale/funkwhale!994merge-requests/1042/head
commit
fc850e6e5d
|
@ -2,6 +2,8 @@ from django.db import transaction
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from funkwhale_api.common import serializers as common_serializers
|
||||
from funkwhale_api.common import utils as common_utils
|
||||
from funkwhale_api.federation import serializers as federation_serializers
|
||||
from funkwhale_api.music import models as music_models
|
||||
from funkwhale_api.music import serializers as music_serializers
|
||||
|
@ -14,25 +16,28 @@ from . import models
|
|||
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"])
|
||||
summary = serializers.CharField(max_length=500, allow_blank=True, allow_null=True)
|
||||
description = common_serializers.ContentSerializer(allow_null=True)
|
||||
tags = tags_serializers.TagsListField()
|
||||
|
||||
@transaction.atomic
|
||||
def create(self, validated_data):
|
||||
description = validated_data.get("description")
|
||||
artist = music_models.Artist.objects.create(
|
||||
attributed_to=validated_data["attributed_to"], name=validated_data["name"]
|
||||
)
|
||||
description_obj = 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"]
|
||||
)
|
||||
|
||||
summary = description_obj.rendered if description_obj else None
|
||||
channel.actor = models.generate_actor(
|
||||
validated_data["username"],
|
||||
summary=validated_data["summary"],
|
||||
name=validated_data["name"],
|
||||
validated_data["username"], summary=summary, name=validated_data["name"],
|
||||
)
|
||||
|
||||
channel.library = music_models.Library.objects.create(
|
||||
|
@ -49,7 +54,7 @@ class ChannelCreateSerializer(serializers.Serializer):
|
|||
|
||||
class ChannelUpdateSerializer(serializers.Serializer):
|
||||
name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
||||
summary = serializers.CharField(max_length=500, allow_blank=True, allow_null=True)
|
||||
description = common_serializers.ContentSerializer(allow_null=True)
|
||||
tags = tags_serializers.TagsListField()
|
||||
|
||||
@transaction.atomic
|
||||
|
@ -58,8 +63,13 @@ class ChannelUpdateSerializer(serializers.Serializer):
|
|||
tags_models.set_tags(obj.artist, *validated_data["tags"])
|
||||
actor_update_fields = []
|
||||
|
||||
if "summary" in validated_data:
|
||||
actor_update_fields.append(("summary", validated_data["summary"]))
|
||||
if "description" in validated_data:
|
||||
description_obj = common_utils.attach_content(
|
||||
obj.artist, "description", validated_data["description"]
|
||||
)
|
||||
if description_obj:
|
||||
actor_update_fields.append(("summary", description_obj.rendered))
|
||||
|
||||
if "name" in validated_data:
|
||||
obj.artist.name = validated_data["name"]
|
||||
obj.artist.save(update_fields=["name"])
|
||||
|
|
|
@ -30,7 +30,7 @@ class ChannelViewSet(
|
|||
serializer_class = serializers.ChannelSerializer
|
||||
queryset = (
|
||||
models.Channel.objects.all()
|
||||
.prefetch_related("library", "attributed_to", "artist", "actor")
|
||||
.prefetch_related("library", "attributed_to", "artist__description", "actor")
|
||||
.order_by("-creation_date")
|
||||
)
|
||||
permission_classes = [
|
||||
|
|
|
@ -289,6 +289,12 @@ class Content(models.Model):
|
|||
text = models.CharField(max_length=CONTENT_TEXT_MAX_LENGTH, blank=True, null=True)
|
||||
content_type = models.CharField(max_length=100)
|
||||
|
||||
@property
|
||||
def rendered(self):
|
||||
from . import utils
|
||||
|
||||
return utils.render_html(self.text, self.content_type)
|
||||
|
||||
|
||||
@receiver(models.signals.post_save, sender=Attachment)
|
||||
def warm_attachment_thumbnails(sender, instance, **kwargs):
|
||||
|
|
|
@ -305,3 +305,4 @@ def attach_content(obj, field, content_data):
|
|||
)
|
||||
setattr(obj, field, content_obj)
|
||||
obj.save(update_fields=[field])
|
||||
return content_obj
|
||||
|
|
|
@ -134,7 +134,7 @@ class ArtistWithAlbumsSerializer(OptionalDescriptionMixin, serializers.Serialize
|
|||
|
||||
|
||||
def serialize_artist_simple(artist):
|
||||
return {
|
||||
data = {
|
||||
"id": artist.id,
|
||||
"fid": artist.fid,
|
||||
"mbid": str(artist.mbid),
|
||||
|
@ -142,6 +142,14 @@ def serialize_artist_simple(artist):
|
|||
"creation_date": DATETIME_FIELD.to_representation(artist.creation_date),
|
||||
"is_local": artist.is_local,
|
||||
}
|
||||
if "description" in artist._state.fields_cache:
|
||||
data["description"] = (
|
||||
common_serializers.ContentSerializer(artist.description).data
|
||||
if artist.description
|
||||
else None
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def serialize_album_track(track):
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
from funkwhale_api.audio import serializers
|
||||
from funkwhale_api.common import serializers as common_serializers
|
||||
from funkwhale_api.common import utils as common_utils
|
||||
from funkwhale_api.federation import serializers as federation_serializers
|
||||
from funkwhale_api.music import serializers as music_serializers
|
||||
|
||||
|
@ -10,7 +12,7 @@ def test_channel_serializer_create(factories):
|
|||
# TODO: cover
|
||||
"name": "My channel",
|
||||
"username": "mychannel",
|
||||
"summary": "This is my channel",
|
||||
"description": {"text": "This is my channel", "content_type": "text/markdown"},
|
||||
"tags": ["hello", "world"],
|
||||
}
|
||||
|
||||
|
@ -25,8 +27,14 @@ def test_channel_serializer_create(factories):
|
|||
sorted(channel.artist.tagged_items.values_list("tag__name", flat=True))
|
||||
== data["tags"]
|
||||
)
|
||||
assert channel.artist.description.text == data["description"]["text"]
|
||||
assert (
|
||||
channel.artist.description.content_type == data["description"]["content_type"]
|
||||
)
|
||||
assert channel.attributed_to == attributed_to
|
||||
assert channel.actor.summary == data["summary"]
|
||||
assert channel.actor.summary == common_utils.render_html(
|
||||
data["description"]["text"], "text/markdown"
|
||||
)
|
||||
assert channel.actor.preferred_username == data["username"]
|
||||
assert channel.actor.name == data["name"]
|
||||
assert channel.library.privacy_level == "everyone"
|
||||
|
@ -39,7 +47,7 @@ def test_channel_serializer_update(factories):
|
|||
data = {
|
||||
# TODO: cover
|
||||
"name": "My channel",
|
||||
"summary": "This is my channel",
|
||||
"description": {"text": "This is my channel", "content_type": "text/markdown"},
|
||||
"tags": ["hello", "world"],
|
||||
}
|
||||
|
||||
|
@ -54,12 +62,17 @@ def test_channel_serializer_update(factories):
|
|||
sorted(channel.artist.tagged_items.values_list("tag__name", flat=True))
|
||||
== data["tags"]
|
||||
)
|
||||
assert channel.actor.summary == data["summary"]
|
||||
assert channel.actor.summary == common_utils.render_html(
|
||||
data["description"]["text"], "text/markdown"
|
||||
)
|
||||
assert channel.artist.description.text == data["description"]["text"]
|
||||
assert channel.artist.description.content_type == "text/markdown"
|
||||
assert channel.actor.name == data["name"]
|
||||
|
||||
|
||||
def test_channel_serializer_representation(factories, to_api_date):
|
||||
channel = factories["audio.Channel"]()
|
||||
content = factories["common.Content"]()
|
||||
channel = factories["audio.Channel"](artist__description=content)
|
||||
|
||||
expected = {
|
||||
"artist": music_serializers.serialize_artist_simple(channel.artist),
|
||||
|
@ -70,5 +83,8 @@ def test_channel_serializer_representation(factories, to_api_date):
|
|||
channel.attributed_to
|
||||
).data,
|
||||
}
|
||||
expected["artist"]["description"] = common_serializers.ContentSerializer(
|
||||
content
|
||||
).data
|
||||
|
||||
assert serializers.ChannelSerializer(channel).data == expected
|
||||
|
|
|
@ -12,16 +12,16 @@ def test_channel_create(logged_in_api_client):
|
|||
# TODO: cover
|
||||
"name": "My channel",
|
||||
"username": "mychannel",
|
||||
"summary": "This is my channel",
|
||||
"description": {"text": "This is my channel", "content_type": "text/markdown"},
|
||||
"tags": ["hello", "world"],
|
||||
}
|
||||
|
||||
url = reverse("api:v1:channels-list")
|
||||
response = logged_in_api_client.post(url, data)
|
||||
response = logged_in_api_client.post(url, data, format="json")
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
channel = actor.owned_channels.latest("id")
|
||||
channel = actor.owned_channels.select_related("artist__description").latest("id")
|
||||
expected = serializers.ChannelSerializer(channel).data
|
||||
|
||||
assert response.data == expected
|
||||
|
@ -32,14 +32,14 @@ def test_channel_create(logged_in_api_client):
|
|||
== data["tags"]
|
||||
)
|
||||
assert channel.attributed_to == actor
|
||||
assert channel.actor.summary == data["summary"]
|
||||
assert channel.actor.summary == channel.artist.description.rendered
|
||||
assert channel.actor.preferred_username == data["username"]
|
||||
assert channel.library.privacy_level == "everyone"
|
||||
assert channel.library.actor == actor
|
||||
|
||||
|
||||
def test_channel_detail(factories, logged_in_api_client):
|
||||
channel = factories["audio.Channel"]()
|
||||
channel = factories["audio.Channel"](artist__description=None)
|
||||
url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
|
||||
expected = serializers.ChannelSerializer(channel).data
|
||||
response = logged_in_api_client.get(url)
|
||||
|
@ -49,7 +49,7 @@ def test_channel_detail(factories, logged_in_api_client):
|
|||
|
||||
|
||||
def test_channel_list(factories, logged_in_api_client):
|
||||
channel = factories["audio.Channel"]()
|
||||
channel = factories["audio.Channel"](artist__description=None)
|
||||
url = reverse("api:v1:channels-list")
|
||||
expected = serializers.ChannelSerializer(channel).data
|
||||
response = logged_in_api_client.get(url)
|
||||
|
|
Ładowanie…
Reference in New Issue