206 lines
7.9 KiB
Python
206 lines
7.9 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
|
|
from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ
|
|
from ..serializers.profiles import (BasicProfileSerializer,
|
|
BasicSongRatingsSerializer,
|
|
RateSongSerializer)
|
|
from ..serializers.radio import (AlbumSerializer, ArtistSerializer,
|
|
GameSerializer, FullSongSerializer,
|
|
SongArtistsListSerializer,
|
|
FullSongRetrieveSerializer)
|
|
|
|
|
|
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 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 in ['list', 'retrieve']:
|
|
return FullSongRetrieveSerializer
|
|
return FullSongSerializer
|
|
|
|
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()
|
|
message = 'Artists {} song.'.format(('added to',
|
|
'removed from')[remove])
|
|
return Response({'detail': message})
|
|
else:
|
|
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):
|
|
return self._artists_change(request)
|
|
|
|
@action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
|
|
def artists_remove(self, request, pk=None):
|
|
return self._artists_change(request, remove=True)
|
|
|
|
@action(detail=True, permission_classes=[AllowAny])
|
|
def favorites(self, request, pk=None):
|
|
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):
|
|
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):
|
|
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):
|
|
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):
|
|
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):
|
|
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)
|