diff --git a/savepointradio/api/serializers/radio.py b/savepointradio/api/serializers/radio.py index 3313159..a0fdaf4 100644 --- a/savepointradio/api/serializers/radio.py +++ b/savepointradio/api/serializers/radio.py @@ -1,4 +1,5 @@ -from rest_framework.serializers import (DecimalField, IntegerField, ListField, +from rest_framework.serializers import (BooleanField, DecimalField, + IntegerField, ListField, ModelSerializer, Serializer, SerializerMethodField, StringRelatedField) @@ -48,7 +49,7 @@ class StoreSerializer(ModelSerializer): def get_active(self, obj): '''Checks to see if this store is active for a song.''' - if obj.active_for: + if obj.active_for.all(): return True return False @@ -139,4 +140,15 @@ class SongArtistsListSerializer(Serializer): A serializer for adding or removing artists from a song based on the song's id number. ''' + # TODO: Probably should move to PrimaryKeyRelatedField. artists = ListField(child=IntegerField(), min_length=1, max_length=10) + + +class SongStoresSerializer(Serializer): + ''' + A serializer for adding or removing a data store from a song based on + the song's id number. + ''' + # TODO: Probably should move to PrimaryKeyRelatedField. + store = IntegerField() + set_active = BooleanField(default=False) diff --git a/savepointradio/api/urls.py b/savepointradio/api/urls.py index 6049595..2c53d47 100644 --- a/savepointradio/api/urls.py +++ b/savepointradio/api/urls.py @@ -4,8 +4,8 @@ from rest_framework.routers import DefaultRouter from api.views.controls import JustPlayed, MakeRequest, NextRequest from api.views.profiles import HistoryViewSet, ProfileViewSet -from api.views.radio import (AlbumViewSet, ArtistViewSet, - GameViewSet, SongViewSet) +from api.views.radio import (AlbumViewSet, ArtistViewSet, GameViewSet, + StoreViewSet, SongViewSet) class OptionalSlashRouter(DefaultRouter): @@ -28,6 +28,7 @@ router.register(r'profiles', ProfileViewSet, base_name='profile') router.register(r'albums', AlbumViewSet, base_name='album') router.register(r'artists', ArtistViewSet, base_name='artist') router.register(r'games', GameViewSet, base_name='game') +router.register(r'stores', StoreViewSet, base_name='store') router.register(r'songs', SongViewSet, base_name='song') urlpatterns = [ diff --git a/savepointradio/api/views/radio.py b/savepointradio/api/views/radio.py index 80ac724..f6a1a52 100644 --- a/savepointradio/api/views/radio.py +++ b/savepointradio/api/views/radio.py @@ -4,15 +4,17 @@ from rest_framework.permissions import AllowAny, IsAdminUser from rest_framework.response import Response from profiles.models import RadioProfile, Rating -from radio.models import Album, Artist, Game, Song +from radio.models import Album, Artist, Game, Song, Store from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ from ..serializers.profiles import (BasicProfileSerializer, BasicSongRatingsSerializer, RateSongSerializer) from ..serializers.radio import (AlbumSerializer, ArtistSerializer, - GameSerializer, SongSerializer, - SongListSerializer, SongRetrieveSerializer, - SongArtistsListSerializer) + GameSerializer, StoreSerializer, + SongSerializer, SongListSerializer, + SongRetrieveSerializer, + SongArtistsListSerializer, + SongStoresSerializer) class AlbumViewSet(viewsets.ModelViewSet): @@ -63,6 +65,12 @@ class GameViewSet(viewsets.ModelViewSet): return Game.music.available() +class StoreViewSet(viewsets.ModelViewSet): + queryset = Store.objects.all() + permission_classes = [IsAdminUser] + serializer_class = StoreSerializer + + class SongViewSet(viewsets.ModelViewSet): permission_classes = [IsAdminOrReadOnly] @@ -94,12 +102,18 @@ class SongViewSet(viewsets.ModelViewSet): serializer = SongArtistsListSerializer(data=request.data) if serializer.is_valid(): artists = Artist.objects.filter(pk__in=serializer.data['artists']) + for artist in artists: if remove: song.artists.remove(artist) else: song.artists.add(artist) + song.save() + + if song.artists.count() == 0: + song.disable('No artists specified for song.') + message = 'Artists {} song.'.format(('added to', 'removed from')[remove]) return Response({'detail': message}) @@ -115,6 +129,58 @@ class SongViewSet(viewsets.ModelViewSet): '''Removes an artist from a song.''' return self._artists_change(request, remove=True) + def _store_change(self, request, remove=False): + song = self.get_object() + serializer = SongStoresSerializer(data=request.data) + if serializer.is_valid(): + try: + store = Store.objects.get(pk=serializer.data['store']) + except Store.DoesNotExist: + return Response({'detail': 'Store does not exist.'}, + status=status.HTTP_400_BAD_REQUEST) + + if remove: + song.stores.remove(store) + else: + song.stores.add(store) + + if serializer.data['set_active'] and not remove: + song.active_store = store + + song.save() + + if song.stores.count() == 0: + song.disable('No stores specified for song.') + + message = 'Store {} song.'.format(('added to', + 'removed from')[remove]) + return Response({'detail': message}) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + @action(methods=['post'], detail=True, permission_classes=[IsAdminUser]) + def store_add(self, request, pk=None): + '''Adds a data store to a song.''' + return self._store_change(request) + + @action(methods=['post'], detail=True, permission_classes=[IsAdminUser]) + def store_remove(self, request, pk=None): + '''Removes a data store from a song.''' + return self._store_change(request, remove=True) + + @action(detail=True, permission_classes=[IsAdminUser]) + def stores(self, request, pk=None): + '''Get a list of data stores associate with this song.''' + song = self.get_object() + stores = song.stores.all().order_by('-created_date') + + page = self.paginate_queryset(stores) + if page is not None: + serializer = StoreSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = StoreSerializer(stores, many=True) + return Response(serializer.data) + @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.'''