funkwhale/api/funkwhale_api/music/serializers.py

281 wiersze
7.0 KiB
Python
Czysty Zwykły widok Historia

from django.db import transaction
from django.db.models import Q
from rest_framework import serializers
from taggit.models import Tag
2018-03-01 22:41:51 +00:00
from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.federation import utils as federation_utils
from funkwhale_api.federation.models import LibraryTrack
from funkwhale_api.federation.serializers import AP_CONTEXT
from funkwhale_api.users.serializers import UserBasicSerializer
2018-03-01 22:41:51 +00:00
from . import models
from . import tasks
class ArtistAlbumSerializer(serializers.ModelSerializer):
tracks_count = serializers.SerializerMethodField()
class Meta:
model = models.Album
fields = (
'id',
'mbid',
'title',
'artist',
'release_date',
'cover',
'creation_date',
'tracks_count',
)
def get_tracks_count(self, o):
return o._tracks_count
class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
albums = ArtistAlbumSerializer(many=True, read_only=True)
class Meta:
model = models.Artist
fields = (
'id',
'mbid',
'name',
'creation_date',
'albums',
)
class TrackFileSerializer(serializers.ModelSerializer):
path = serializers.SerializerMethodField()
class Meta:
model = models.TrackFile
fields = (
'id',
'path',
'source',
'filename',
'mimetype',
'track',
'duration',
'mimetype',
'bitrate',
'size',
)
read_only_fields = [
'duration',
'mimetype',
'bitrate',
'size',
]
def get_path(self, o):
url = o.path
return url
class AlbumTrackSerializer(serializers.ModelSerializer):
files = TrackFileSerializer(many=True, read_only=True)
class Meta:
model = models.Track
fields = (
'id',
'mbid',
'title',
'album',
'artist',
'creation_date',
'files',
'position',
)
class ArtistSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = models.Artist
fields = (
'id',
'mbid',
'name',
'creation_date',
)
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SerializerMethodField()
artist = ArtistSimpleSerializer(read_only=True)
class Meta:
model = models.Album
fields = (
'id',
'mbid',
'title',
'artist',
'tracks',
'release_date',
'cover',
'creation_date',
)
def get_tracks(self, o):
ordered_tracks = sorted(
o.tracks.all(),
key=lambda v: (v.position, v.title) if v.position else (99999, v.title)
)
return AlbumTrackSerializer(ordered_tracks, many=True).data
class TrackAlbumSerializer(serializers.ModelSerializer):
artist = ArtistSimpleSerializer(read_only=True)
class Meta:
model = models.Album
fields = (
'id',
'mbid',
'title',
'artist',
'release_date',
'cover',
'creation_date',
)
class TrackSerializer(serializers.ModelSerializer):
files = TrackFileSerializer(many=True, read_only=True)
artist = ArtistSimpleSerializer(read_only=True)
album = TrackAlbumSerializer(read_only=True)
lyrics = serializers.SerializerMethodField()
class Meta:
model = models.Track
fields = (
'id',
'mbid',
'title',
'album',
'artist',
'creation_date',
'files',
'position',
'lyrics',
)
def get_lyrics(self, obj):
return obj.get_lyrics_url()
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('id', 'name', 'slug')
class SimpleAlbumSerializer(serializers.ModelSerializer):
class Meta:
model = models.Album
fields = ('id', 'mbid', 'title', 'release_date', 'cover')
class LyricsSerializer(serializers.ModelSerializer):
class Meta:
model = models.Lyrics
fields = ('id', 'work', 'content', 'content_rendered')
class ImportJobSerializer(serializers.ModelSerializer):
track_file = TrackFileSerializer(read_only=True)
class Meta:
model = models.ImportJob
fields = (
'id',
'mbid',
'batch',
'source',
'status',
'track_file',
'audio_file')
2017-12-27 22:32:02 +00:00
read_only_fields = ('status', 'track_file')
class ImportBatchSerializer(serializers.ModelSerializer):
submitted_by = UserBasicSerializer(read_only=True)
class Meta:
model = models.ImportBatch
fields = (
'id',
'submitted_by',
'source',
'status',
'creation_date',
'import_request')
read_only_fields = (
'creation_date', 'submitted_by', 'source')
def to_representation(self, instance):
repr = super().to_representation(instance)
try:
repr['job_count'] = instance.job_count
except AttributeError:
# Queryset was not annotated
pass
return repr
2018-03-01 22:41:51 +00:00
class TrackActivitySerializer(activity_serializers.ModelSerializer):
type = serializers.SerializerMethodField()
name = serializers.CharField(source='title')
artist = serializers.CharField(source='artist.name')
album = serializers.CharField(source='album.title')
class Meta:
model = models.Track
fields = [
'id',
'local_id',
'name',
'type',
'artist',
'album',
]
def get_type(self, obj):
return 'Audio'
class ImportJobRunSerializer(serializers.Serializer):
jobs = serializers.PrimaryKeyRelatedField(
many=True,
queryset=models.ImportJob.objects.filter(
status__in=['pending', 'errored']
)
)
batches = serializers.PrimaryKeyRelatedField(
many=True,
queryset=models.ImportBatch.objects.all()
)
def validate(self, validated_data):
jobs = validated_data['jobs']
batches_ids = [b.pk for b in validated_data['batches']]
query = Q(batch__pk__in=batches_ids)
query |= Q(pk__in=[j.id for j in jobs])
queryset = models.ImportJob.objects.filter(query).filter(
status__in=['pending', 'errored']).distinct()
validated_data['_jobs'] = queryset
return validated_data
def create(self, validated_data):
ids = validated_data['_jobs'].values_list('id', flat=True)
validated_data['_jobs'].update(status='pending')
for id in ids:
tasks.import_job_run.delay(import_job_id=id)
return {'jobs': list(ids)}