ITRadio/server/proj/audio/views.py

249 lines
11 KiB
Python

from django.shortcuts import render
from rest_framework.viewsets import ViewSet, GenericViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework import status
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.shortcuts import get_object_or_404, get_list_or_404
from rest_framework.permissions import IsAuthenticated, AllowAny
import requests
from django.http import HttpResponse
from .schemas import SongSchema, DeleteSongSchema, PlayListSchema
from .models import Song, FavoriteSong, PlayList
from .serializers import SongSerializer, FavoriteSongSerializer, PlayListSerializer
from conf.settings.base import AZURACAST_URL, AZURACAST_API_KEY
class PlayListViewSet(GenericViewSet):
queryset = PlayList
serializer_class = PlayListSerializer
permission_classes = (IsAuthenticated,)
def list(self, request):
queryset = self.get_queryset().objects.filter(user=request.user)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, pk):
try:
queryset = self.get_queryset().objects.get(pk=pk, user=request.user)
serializer = self.get_serializer(queryset)
return Response(serializer.data, status=status.HTTP_200_OK)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=PlayListSchema())
def create_playlist(self, request):
if request.data.get('name', False):
try:
instance = self.get_queryset().objects.get(pk=request.data['playlist_id'], user=request.user.pk)
data = request.data
data.update(user=request.user.pk)
serializer = self.get_serializer(data=request.data, instance=instance)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
else:
playlist_pk = self.get_queryset().objects.filter(user=request.user.pk)
number_playlist = len(playlist_pk) + 1
name = f"Плейлист № {number_playlist}"
data = request.data
data.update(user=request.user.pk, name=name)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
@action(detail=False, methods=['post'], schema=PlayListSchema())
def update_playlist(self, request):
try:
instance = self.get_queryset().objects.get(pk=request.data['playlist_id'], user=request.user.pk)
serializer = self.get_serializer(data=request.data, partial=True, instance=instance)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=PlayListSchema())
def delete_playlist(self, request):
try:
item = self.get_queryset().objects.get(user=request.user, pk=request.data.get('playlist_id'))
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=PlayListSchema())
def delete_song_with_playlist(self, request):
try:
song = Song.objects.get(azura_id=request.data.get('azura_id'))
item = self.get_queryset().objects.get(user=request.user, pk=request.data.get('playlist_id'))
item.song.remove(song)
return Response({'detail': 'Объект удалён'}, status=status.HTTP_200_OK)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=PlayListSchema())
def add_to_playlist(self, request):
song = None
try:
song = Song.objects.get(azura_id=request.data.get('azura_id')).pk
except ObjectDoesNotExist:
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{request.data['azura_id']}"
API_KEY = AZURACAST_API_KEY
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(file_url, headers=headers)
data = request.data
file_play = f"{AZURACAST_URL}api/station/it-radio/file/{response.json()['unique_id']}/play"
data.update(unique_id=file_play)
song_serializer = SongSerializer(data=data)
if song_serializer.is_valid():
song_serializer.save()
song = song_serializer.data.get('id')
try:
instance = self.get_queryset().objects.get(pk=request.data.get('playlist_id'))
except ObjectDoesNotExist:
return Response(
{'detail': 'Плейлиста не существует', 'error': {'PlayList': 'Плейлиста не существует'}},
status=status.HTTP_404_NOT_FOUND)
songs = list(instance.song.all().values_list('pk', flat=True)) + [song]
data = {
'playlist_id': request.data.get('playlist_id'),
'song': songs
}
serializer = PlayListSerializer(data=data, partial=True, instance=instance)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
class SongViewSet(GenericViewSet):
queryset = Song
serializer_class = SongSerializer
permission_classes = (IsAuthenticated,)
def list(self, request):
songs_pk = FavoriteSong.objects.filter(user=request.user, song__isnull=False).values_list('song_id', flat=True)
songs = self.get_queryset().objects.filter(id__in=songs_pk)
serializer = self.get_serializer(songs, many=True)
return Response(serializer.data)
@action(
detail=False,
methods=['get'],
url_path='check_is_favorite/(?P<azura_id>[a-zA-Z0-9_]+)',
url_name='check_is_favorite',
)
def check_is_favorite(self, request, azura_id):
try:
song_obj = self.get_queryset().objects.get(azura_id=azura_id)
favorite_songs = FavoriteSong.objects.get(user=request.user, song=song_obj)
return Response({"is_favorite": True}, status=status.HTTP_200_OK)
except ObjectDoesNotExist:
return Response({"is_favorite": False}, status=status.HTTP_200_OK)
@action(
detail=False,
methods=['get'],
url_path='get_audio/(?P<azura_id>[a-zA-Z0-9_]+)',
url_name='get_audio',
)
def get_audio(self, request, azura_id):
try:
song_obj = self.get_queryset().objects.get(azura_id=azura_id)
file_url = song_obj.unique_id
API_KEY = AZURACAST_API_KEY
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(file_url, headers=headers)
response.raise_for_status()
file_response = HttpResponse(response.content, content_type='audio/mpeg')
file = f'{song_obj.title}-{song_obj.artist}.mp3'
file_response['Content-Disposition'] = f'attachment; filename={file}'
return file_response
except ObjectDoesNotExist:
return Response({"error": 'Объекта не существует'}, status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=SongSchema())
def add_favorite(self, request):
data = None
try:
song = self.get_queryset().objects.get(azura_id=request.data.get('azura_id'))
data = {
"song": song.pk,
"user": request.user.pk
}
except ObjectDoesNotExist:
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{request.data['azura_id']}"
API_KEY = AZURACAST_API_KEY
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(file_url, headers=headers)
data = request.data
file_play = f"{AZURACAST_URL}/api/station/it-radio/file/{response.json()['unique_id']}/play"
data.update(unique_id=file_play)
serializer = self.get_serializer(data=data)
if serializer.is_valid():
serializer.save()
data = {
"song": serializer.data['id'],
"user": request.user.pk
}
serializer = FavoriteSongSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=False, methods=['post'], schema=DeleteSongSchema())
def delete_song(self, request):
try:
song = self.get_queryset().objects.get(azura_id=request.data.get('azura_id'))
item = FavoriteSong.objects.get(user=request.user, song=song.pk)
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
except ObjectDoesNotExist:
return Response({"error": 'Объекта не существует'}, status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['get'])
def get_all_song(self, request):
file_url = F"{AZURACAST_URL}api/station/1/files"
API_KEY = AZURACAST_API_KEY
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(file_url, headers=headers)
data = []
for i in response.json():
i['azura_id'] = i.pop('song_id')
data.append(i)
return Response(data, status=status.HTTP_200_OK)