Easy and resusable Audio and AudioCollection serializer
This commit is contained in:
parent
679adfe156
commit
80206761a3
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue