Updated API for new Stores and general cleanup.
This commit is contained in:
parent
3afc5c7a3a
commit
c305a32717
4 changed files with 91 additions and 27 deletions
|
@ -4,7 +4,7 @@ from rest_framework.serializers import (IntegerField, ModelSerializer,
|
|||
Serializer)
|
||||
|
||||
from profiles.models import RadioProfile, SongRequest, Rating
|
||||
from .radio import BasicSongRetrieveSerializer
|
||||
from .radio import SongMinimalSerializer
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -44,7 +44,7 @@ class RateSongSerializer(Serializer):
|
|||
|
||||
class HistorySerializer(ModelSerializer):
|
||||
profile = BasicProfileSerializer()
|
||||
song = BasicSongRetrieveSerializer()
|
||||
song = SongMinimalSerializer()
|
||||
|
||||
class Meta:
|
||||
model = SongRequest
|
||||
|
@ -52,7 +52,7 @@ class HistorySerializer(ModelSerializer):
|
|||
|
||||
|
||||
class BasicProfileRatingsSerializer(ModelSerializer):
|
||||
song = BasicSongRetrieveSerializer()
|
||||
song = SongMinimalSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Rating
|
||||
|
|
|
@ -1,71 +1,127 @@
|
|||
from rest_framework.serializers import (IntegerField, ListField,
|
||||
from rest_framework.serializers import (DecimalField, IntegerField, ListField,
|
||||
ModelSerializer, Serializer,
|
||||
SerializerMethodField,
|
||||
StringRelatedField)
|
||||
|
||||
from core.utils import iri_to_path
|
||||
from radio.models import Album, Artist, Game, Song
|
||||
|
||||
|
||||
class AlbumSerializer(ModelSerializer):
|
||||
'''A base serializer for an album model.'''
|
||||
class Meta:
|
||||
model = Album
|
||||
fields = ('id', 'title')
|
||||
|
||||
|
||||
class ArtistSerializer(ModelSerializer):
|
||||
'''A base serializer for an artist model.'''
|
||||
class Meta:
|
||||
model = Artist
|
||||
fields = ('id', 'alias', 'first_name', 'last_name')
|
||||
|
||||
|
||||
class ArtistFullnameSerializer(ModelSerializer):
|
||||
'''
|
||||
A base serializer for an artist model, but combining all name
|
||||
attributes into one field.
|
||||
'''
|
||||
class Meta:
|
||||
model = Artist
|
||||
fields = ('id', 'full_name')
|
||||
|
||||
|
||||
class GameSerializer(ModelSerializer):
|
||||
'''A base serializer for a game model.'''
|
||||
class Meta:
|
||||
model = Game
|
||||
fields = ('id', 'title')
|
||||
|
||||
|
||||
class BasicSongSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('id', 'album', 'artists', 'game', 'title', 'average_rating',
|
||||
'is_requestable')
|
||||
class SongSerializer(ModelSerializer):
|
||||
'''A base serializer for a song model.'''
|
||||
length = DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
source='current_store.length'
|
||||
)
|
||||
|
||||
|
||||
class FullSongSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('id', 'album', 'artists', 'published_date', 'game',
|
||||
'num_played', 'last_played', 'length', 'song_type', 'title',
|
||||
'average_rating', 'is_requestable')
|
||||
'num_played', 'last_played', 'length', 'next_play',
|
||||
'song_type', 'title', 'average_rating', 'is_requestable')
|
||||
|
||||
|
||||
class BasicSongRetrieveSerializer(BasicSongSerializer):
|
||||
class SongMinimalSerializer(ModelSerializer):
|
||||
'''Minimal song information, usually appended to favorites/ratings.'''
|
||||
album = AlbumSerializer()
|
||||
artists = ArtistFullnameSerializer(many=True)
|
||||
game = GameSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('id', 'album', 'artists', 'game', 'title')
|
||||
|
||||
class FullSongRetrieveSerializer(FullSongSerializer):
|
||||
|
||||
class SongListSerializer(ModelSerializer):
|
||||
'''Song information used in large listings.'''
|
||||
album = AlbumSerializer()
|
||||
artists = ArtistFullnameSerializer(many=True)
|
||||
game = GameSerializer()
|
||||
length = DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
source='current_store.length'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('id', 'album', 'artists', 'game', 'title', 'average_rating',
|
||||
'length', 'is_requestable')
|
||||
|
||||
|
||||
class SongRetrieveSerializer(SongSerializer):
|
||||
'''
|
||||
An almost complete listing of a song's information, based on a single
|
||||
object retrieval.
|
||||
'''
|
||||
album = AlbumSerializer()
|
||||
artists = ArtistSerializer(many=True)
|
||||
game = GameSerializer()
|
||||
|
||||
|
||||
class RadioSongSerializer(ModelSerializer):
|
||||
'''
|
||||
A song serializer that is specific to the radio DJ and the underlying
|
||||
audio manipulation application.
|
||||
'''
|
||||
album = StringRelatedField()
|
||||
artists = StringRelatedField(many=True)
|
||||
game = StringRelatedField()
|
||||
length = DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
source='current_store.length'
|
||||
)
|
||||
path = SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('album', 'artists', 'game', 'song_type', 'title', 'length',
|
||||
'path')
|
||||
|
||||
def get_path(self, obj):
|
||||
'''Converts the IRI into a filesystem path.'''
|
||||
iri = str(obj.current_store.iri)
|
||||
if iri.startswith('file://'):
|
||||
return iri_to_path(iri)
|
||||
return iri
|
||||
|
||||
|
||||
class SongArtistsListSerializer(Serializer):
|
||||
'''
|
||||
A serializer for adding or removing artists from a song based on
|
||||
the song's id number.
|
||||
'''
|
||||
artists = ListField(child=IntegerField(), min_length=1, max_length=10)
|
||||
|
|
|
@ -11,7 +11,7 @@ from ..serializers.profiles import (BasicProfileSerializer,
|
|||
FullProfileSerializer,
|
||||
HistorySerializer,
|
||||
BasicProfileRatingsSerializer)
|
||||
from ..serializers.radio import BasicSongRetrieveSerializer
|
||||
from ..serializers.radio import SongListSerializer
|
||||
|
||||
|
||||
class ProfileViewSet(viewsets.ModelViewSet):
|
||||
|
@ -52,10 +52,10 @@ class ProfileViewSet(viewsets.ModelViewSet):
|
|||
|
||||
page = self.paginate_queryset(favorites)
|
||||
if page is not None:
|
||||
serializer = BasicSongRetrieveSerializer(page, many=True)
|
||||
serializer = SongListSerializer(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
||||
serializer = BasicSongRetrieveSerializer(favorites, many=True)
|
||||
serializer = SongListSerializer(favorites, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=True, permission_classes=[AllowAny])
|
||||
|
|
|
@ -10,9 +10,9 @@ from ..serializers.profiles import (BasicProfileSerializer,
|
|||
BasicSongRatingsSerializer,
|
||||
RateSongSerializer)
|
||||
from ..serializers.radio import (AlbumSerializer, ArtistSerializer,
|
||||
GameSerializer, FullSongSerializer,
|
||||
SongArtistsListSerializer,
|
||||
FullSongRetrieveSerializer)
|
||||
GameSerializer, SongSerializer,
|
||||
SongListSerializer, SongRetrieveSerializer,
|
||||
SongArtistsListSerializer)
|
||||
|
||||
|
||||
class AlbumViewSet(viewsets.ModelViewSet):
|
||||
|
@ -83,9 +83,11 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
|
||||
(Thanks to https://stackoverflow.com/questions/22616973/)
|
||||
'''
|
||||
if self.action in ['list', 'retrieve']:
|
||||
return FullSongRetrieveSerializer
|
||||
return FullSongSerializer
|
||||
if self.action == 'list':
|
||||
return SongListSerializer
|
||||
if self.action == 'retrieve':
|
||||
return SongRetrieveSerializer
|
||||
return SongSerializer
|
||||
|
||||
def _artists_change(self, request, remove=False):
|
||||
song = self.get_object()
|
||||
|
@ -101,20 +103,21 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
message = 'Artists {} song.'.format(('added to',
|
||||
'removed from')[remove])
|
||||
return Response({'detail': message})
|
||||
else:
|
||||
return Response(serializer.errors,
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
|
||||
def artists_add(self, request, pk=None):
|
||||
'''Adds an artist to a song.'''
|
||||
return self._artists_change(request)
|
||||
|
||||
@action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
|
||||
def artists_remove(self, request, pk=None):
|
||||
'''Removes an artist from a song.'''
|
||||
return self._artists_change(request, remove=True)
|
||||
|
||||
@action(detail=True, permission_classes=[AllowAny])
|
||||
def favorites(self, request, pk=None):
|
||||
'''Get a list of users who added this song to their favorites list.'''
|
||||
song = self.get_object()
|
||||
profiles = song.song_favorites.all().order_by('user__name')
|
||||
|
||||
|
@ -130,6 +133,7 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
detail=True,
|
||||
permission_classes=[IsAuthenticatedAndNotDJ])
|
||||
def favorite(self, request, pk=None):
|
||||
'''Add a song to the user's favorites list.'''
|
||||
song = self.get_object()
|
||||
profile = RadioProfile.objects.get(user=request.user)
|
||||
if song not in profile.favorites.all():
|
||||
|
@ -144,6 +148,7 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
detail=True,
|
||||
permission_classes=[IsAuthenticatedAndNotDJ])
|
||||
def unfavorite(self, request, pk=None):
|
||||
'''Remove a song from the user's favorites list.'''
|
||||
song = self.get_object()
|
||||
profile = RadioProfile.objects.get(user=request.user)
|
||||
if song in profile.favorites.all():
|
||||
|
@ -157,6 +162,7 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
|
||||
@action(detail=True, permission_classes=[AllowAny])
|
||||
def ratings(self, request, pk=None):
|
||||
'''Get a list of a song's ratings.'''
|
||||
song = self.get_object()
|
||||
ratings = song.rating_set.all().order_by('-created_date')
|
||||
|
||||
|
@ -172,6 +178,7 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
detail=True,
|
||||
permission_classes=[IsAuthenticatedAndNotDJ])
|
||||
def rate(self, request, pk=None):
|
||||
'''Add a user's rating to a song.'''
|
||||
serializer = RateSongSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
song = self.get_object()
|
||||
|
@ -195,6 +202,7 @@ class SongViewSet(viewsets.ModelViewSet):
|
|||
detail=True,
|
||||
permission_classes=[IsAuthenticatedAndNotDJ])
|
||||
def unrate(self, request, pk=None):
|
||||
'''Remove a user's rating from a song.'''
|
||||
song = self.get_object()
|
||||
profile = RadioProfile.objects.get(user=request.user)
|
||||
rating = song.rating_set.filter(profile=profile)
|
||||
|
|
Loading…
Reference in a new issue