280 lines
11 KiB
Python
280 lines
11 KiB
Python
from rest_framework import status, viewsets
|
|
from rest_framework.decorators import action
|
|
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, Store
|
|
from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ
|
|
from ..serializers.profiles import (BasicProfileSerializer,
|
|
BasicSongRatingsSerializer,
|
|
RateSongSerializer)
|
|
from ..serializers.radio import (AlbumSerializer, ArtistSerializer,
|
|
GameSerializer, StoreSerializer,
|
|
SongSerializer, SongListSerializer,
|
|
SongRetrieveSerializer,
|
|
SongArtistsListSerializer,
|
|
SongStoresSerializer)
|
|
|
|
|
|
class AlbumViewSet(viewsets.ModelViewSet):
|
|
permission_classes = [IsAdminOrReadOnly]
|
|
serializer_class = AlbumSerializer
|
|
|
|
def get_queryset(self):
|
|
'''
|
|
Only send full data to an admin. All regular users get filtered
|
|
albums.
|
|
'''
|
|
if (self.request.user.is_authenticated and
|
|
self.request.user.is_staff and
|
|
not self.request.user.is_dj):
|
|
return Album.objects.all()
|
|
return Album.music.available()
|
|
|
|
|
|
class ArtistViewSet(viewsets.ModelViewSet):
|
|
permission_classes = [IsAdminOrReadOnly]
|
|
serializer_class = ArtistSerializer
|
|
|
|
def get_queryset(self):
|
|
'''
|
|
Only send full data to an admin. All regular users get filtered
|
|
artists.
|
|
'''
|
|
if (self.request.user.is_authenticated and
|
|
self.request.user.is_staff and
|
|
not self.request.user.is_dj):
|
|
return Artist.objects.all()
|
|
return Artist.music.available()
|
|
|
|
|
|
class GameViewSet(viewsets.ModelViewSet):
|
|
permission_classes = [IsAdminOrReadOnly]
|
|
serializer_class = GameSerializer
|
|
|
|
def get_queryset(self):
|
|
'''
|
|
Only send full data to an admin. All regular users get filtered
|
|
games.
|
|
'''
|
|
if (self.request.user.is_authenticated and
|
|
self.request.user.is_staff and
|
|
not self.request.user.is_dj):
|
|
return Game.objects.all()
|
|
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]
|
|
|
|
def get_queryset(self):
|
|
'''
|
|
Only send full data to an admin. All regular users get filtered
|
|
songs.
|
|
'''
|
|
if (self.request.user.is_authenticated and
|
|
self.request.user.is_staff and
|
|
not self.request.user.is_dj):
|
|
return Song.objects.all()
|
|
return Song.music.available_songs()
|
|
|
|
def get_serializer_class(self):
|
|
'''
|
|
Choose a different serializer based on what action is chosen.
|
|
|
|
(Thanks to https://stackoverflow.com/questions/22616973/)
|
|
'''
|
|
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()
|
|
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})
|
|
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)
|
|
|
|
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.'''
|
|
song = self.get_object()
|
|
profiles = song.song_favorites.all().order_by('user__name')
|
|
|
|
page = self.paginate_queryset(profiles)
|
|
if page is not None:
|
|
serializer = BasicProfileSerializer(page, many=True)
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
serializer = BasicProfileSerializer(profiles, many=True)
|
|
return Response(serializer.data)
|
|
|
|
@action(methods=['post'],
|
|
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():
|
|
profile.favorites.add(song)
|
|
profile.save()
|
|
return Response({'detail': 'Song has been added to favorites.'})
|
|
message = 'Song is already a favorite.'
|
|
return Response({'detail': message},
|
|
status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
@action(methods=['post'],
|
|
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():
|
|
profile.favorites.remove(song)
|
|
profile.save()
|
|
message = 'Song has been removed from favorites.'
|
|
return Response({'detail': message})
|
|
message = 'Song is already not a favorite.'
|
|
return Response({'detail': message},
|
|
status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
@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')
|
|
|
|
page = self.paginate_queryset(ratings)
|
|
if page is not None:
|
|
serializer = BasicSongRatingsSerializer(page, many=True)
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
serializer = BasicSongRatingsSerializer(ratings, many=True)
|
|
return Response(serializer.data)
|
|
|
|
@action(methods=['post'],
|
|
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()
|
|
profile = RadioProfile.objects.get(user=request.user)
|
|
if 'value' in serializer.data:
|
|
rating, created = Rating.objects.update_or_create(
|
|
profile=profile,
|
|
song=song,
|
|
defaults={'value': serializer.data['value']}
|
|
)
|
|
message = 'Rating {} song.'.format(('updated for',
|
|
'created for')[created])
|
|
return Response({'detail': message})
|
|
message = 'Missing integer \'value\' for song rating.'
|
|
return Response({'detail': message},
|
|
status=status.HTTP_400_BAD_REQUEST)
|
|
return Response(serializer.errors,
|
|
status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
@action(methods=['post'],
|
|
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)
|
|
if rating:
|
|
rating.delete()
|
|
return Response({'detail': 'Rating deleted from song.'})
|
|
message = 'Cannot delete nonexistant rating.'
|
|
return Response({'detail': message},
|
|
status=status.HTTP_400_BAD_REQUEST)
|