ITRadio/server/proj/audio/views.py

252 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
from audio.service import AzuraCast
from django.http import HttpResponse
import requests
from audio.schemas import SongSchema, DeleteSongSchema, PlayListSchema
from audio.models import Song, FavoriteSong, PlayList, Podkast
from audio.serializers import SongSerializer, FavoriteSongSerializer, PlayListSerializer, PodkastSerializer
from conf.settings.base import AZURACAST_URL, AZURACAST_API_KEY
def authorize_url(url):
file_url = url
API_KEY = AZURACAST_API_KEY
headers = {
"Authorization": f"Bearer {API_KEY}"
}
return requests.get(file_url, headers=headers)
class PodkastViewSet(GenericViewSet):
queryset = Podkast
serializer_class = PodkastSerializer
permission_classes = (IsAuthenticated, )
def list(self, request):
queryset = self.get_queryset().objects.all()
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)
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)
class PlayListViewSet(GenericViewSet):
azura = AzuraCast()
queryset = PlayList.objects.all()
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)
name = f"Плейлист № {len(playlist_pk)+1}"
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=True, methods=['post'], schema=PlayListSchema())
def add_to_playlist(self, request, *args, **kwargs):
song = None
try:
song = Song.objects.get(azura_id=request.data.get('azura_id')).pk
except ObjectDoesNotExist:
data = self.azura.add_to_playlist(request.data['azura_id'], request.data)
song_serializer = SongSerializer(data=data)
if song_serializer.is_valid():
song_serializer.save()
song = song_serializer.data
instance = self.get_object()
instance.song.add(song)
serializer = self.get_serializer(instance)
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
response = authorize_url(file_url)
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']}"
response = authorize_url(file_url)
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"
response = authorize_url(file_url)
data = []
for i in response.json():
i['azura_id'] = i.pop('song_id')
data.append(i)
return Response(data, status=status.HTTP_200_OK)
@action(detail=False, methods=['get'], permission_classes=(AllowAny,))
def get_nowplaying(self, request):
file_url = F"{AZURACAST_URL}api/nowplaying/it-radio"
response = authorize_url(file_url)
return Response(response.json(), status=status.HTTP_200_OK)