Easy and resusable Audio and AudioCollection serializer

This commit is contained in:
Eliot Berriot 2018-04-06 14:26:39 +02:00
parent 679adfe156
commit 80206761a3
No known key found for this signature in database
GPG Key ID: DD6965E2476E5C27
3 changed files with 121 additions and 1 deletions

View File

@ -22,6 +22,7 @@ from versatileimagefield.fields import VersatileImageField
from funkwhale_api import downloader
from funkwhale_api import musicbrainz
from funkwhale_api.federation import utils as federation_utils
from . import importers
from . import utils
@ -69,6 +70,12 @@ class APIModelMixin(models.Model):
pass
return cleaned_data
@property
def musicbrainz_url(self):
if self.mbid:
return 'https://musicbrainz.org/{}/{}'.format(
self.musicbrainz_model, self.mbid)
class Artist(APIModelMixin):
name = models.CharField(max_length=255)
@ -426,6 +433,11 @@ class TrackFile(models.Model):
shutil.rmtree(tmp_dir)
return self.audio_file
def get_federation_url(self):
return federation_utils.full_url(
'/federation/music/file/{}'.format(self.uuid)
)
@property
def path(self):
if settings.PROTECT_AUDIO_FILES:

View File

@ -3,6 +3,8 @@ from rest_framework import serializers
from taggit.models import Tag
from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.federation.serializers import AP_CONTEXT
from funkwhale_api.federation import utils as federation_utils
from . import models
@ -212,6 +214,29 @@ class AudioSerializer(serializers.Serializer):
metadata=metadata,
)
def to_representation(self, instance):
d = {
'type': 'Audio',
'id': instance.get_federation_url(),
'name': instance.track.full_name,
'metadata': {
'artist': instance.track.artist.musicbrainz_url,
'release': instance.track.album.musicbrainz_url,
'track': instance.track.musicbrainz_url,
},
'url': {
'href': federation_utils.full_url(instance.path),
'type': 'Link',
'mediaType': instance.mimetype
},
'attributedTo': [
self.context['actor'].url
]
}
if self.context.get('include_ap_context', True):
d['@context'] = AP_CONTEXT
return d
class AudioCollectionImportSerializer(serializers.Serializer):
id = serializers.URLField()
@ -231,3 +256,24 @@ class AudioCollectionImportSerializer(serializers.Serializer):
s = AudioSerializer(data=i)
job = s.create(i, batch)
return batch
def to_representation(self, instance):
d = {
'id': instance['id'],
'actor': instance['actor'].url,
'totalItems': len(instance['items']),
'type': 'Collection',
'items': [
AudioSerializer(
i,
context={
'actor': instance['actor'],
'include_ap_context': False
}
).data
for i in instance['items']
]
}
if self.context.get('include_ap_context', True):
d['@context'] = AP_CONTEXT
return d

View File

@ -1,7 +1,10 @@
from funkwhale_api.federation import actors
from funkwhale_api.federation import utils as federation_utils
from funkwhale_api.federation.serializers import AP_CONTEXT
from funkwhale_api.music import serializers
def test_activity_pub_audio_collection_serializer(factories):
def test_activity_pub_audio_collection_serializer_to_import(factories):
sender = factories['federation.Actor']()
collection = {
@ -30,3 +33,62 @@ def test_activity_pub_audio_collection_serializer(factories):
assert job.source == a['url']['href']
a['metadata']['mediaType'] = a['url']['mediaType']
assert job.metadata == a['metadata']
def test_activity_pub_audio_serializer_to_ap(factories):
tf = factories['music.TrackFile'](mimetype='audio/mp3')
library = actors.SYSTEM_ACTORS['library'].get_actor_instance()
expected = {
'@context': AP_CONTEXT,
'type': 'Audio',
'id': tf.get_federation_url(),
'name': tf.track.full_name,
'metadata': {
'artist': tf.track.artist.musicbrainz_url,
'release': tf.track.album.musicbrainz_url,
'track': tf.track.musicbrainz_url,
},
'url': {
'href': federation_utils.full_url(tf.path),
'type': 'Link',
'mediaType': 'audio/mp3'
},
'attributedTo': [
library.url
]
}
serializer = serializers.AudioSerializer(tf, context={'actor': library})
assert serializer.data == expected
def test_activity_pub_audio_collection_serializer_to_ap(factories):
tf1 = factories['music.TrackFile'](mimetype='audio/mp3')
tf2 = factories['music.TrackFile'](mimetype='audio/ogg')
library = actors.SYSTEM_ACTORS['library'].get_actor_instance()
expected = {
'@context': AP_CONTEXT,
'id': 'https://test.id',
'actor': library.url,
'totalItems': 2,
'type': 'Collection',
'items': [
serializers.AudioSerializer(
tf1, context={'actor': library, 'include_ap_context': False}
).data,
serializers.AudioSerializer(
tf2, context={'actor': library, 'include_ap_context': False}
).data,
]
}
collection = {
'id': expected['id'],
'actor': library,
'items': [tf1, tf2],
}
serializer = serializers.AudioCollectionImportSerializer(
collection, context={'actor': library, 'id': 'https://test.id'})
assert serializer.data == expected