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, Podkast from .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): 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']}" 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) 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[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[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)