сделал большой рефакторинг кода

This commit is contained in:
Mike0001-droid 2024-06-28 16:20:43 +05:00
parent d332dac38f
commit bd49b9c70e
5 changed files with 107 additions and 137 deletions

View File

@ -7,6 +7,7 @@ class SongAdmin(admin.ModelAdmin):
exclude = ('azura_id',) exclude = ('azura_id',)
readonly_fields = ['slug'] readonly_fields = ['slug']
@admin.register(FavoriteSong) @admin.register(FavoriteSong)
class FavoriteSongAdmin(admin.ModelAdmin): class FavoriteSongAdmin(admin.ModelAdmin):
list_display = ('id', 'song', 'user') list_display = ('id', 'song', 'user')

View File

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from account.models import MyUser from account.models import MyUser
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from audio.service import AzuraCast
class Song(models.Model): class Song(models.Model):
unique_id = models.CharField('ID трека для плеера', max_length=255, blank=True, null=True) unique_id = models.CharField('ID трека для плеера', max_length=255, blank=True, null=True)
@ -25,6 +26,11 @@ class Song(models.Model):
unique_together = ('azura_id', ) unique_together = ('azura_id', )
verbose_name_plural = 'Треки' verbose_name_plural = 'Треки'
def delete(self):
azura = AzuraCast()
azura.delete_song(self.azura_id)
super(Song, self).delete()
class FavoriteSong(models.Model): class FavoriteSong(models.Model):
song = models.ForeignKey(Song, verbose_name='Трек', on_delete=models.CASCADE, null=True, blank=True) song = models.ForeignKey(Song, verbose_name='Трек', on_delete=models.CASCADE, null=True, blank=True)
@ -48,6 +54,7 @@ class PlayList(models.Model):
class Meta: class Meta:
verbose_name = 'Плейлисты' verbose_name = 'Плейлисты'
unique_together = ('name', 'user')
verbose_name_plural = 'Плейлисты' verbose_name_plural = 'Плейлисты'
class Podkast(models.Model): class Podkast(models.Model):

View File

@ -63,12 +63,6 @@ class PlayListSchema(AutoSchema):
required=False, required=False,
schema=coreschema.String(description='Название плейлиста') schema=coreschema.String(description='Название плейлиста')
), ),
coreapi.Field(
name='playlist_id',
location='form',
required=False,
schema=coreschema.Integer(description='ID плейлиста')
),
coreapi.Field( coreapi.Field(
name='playlist_art', name='playlist_art',
location='form', location='form',

View File

@ -1,25 +1,61 @@
from conf.settings import AZURACAST_URL, AZURACAST_API_KEY from conf.settings import AZURACAST_URL, AZURACAST_API_KEY
import requests import requests
from django.http import HttpResponse
def authorize_url(method, url):
def authorize_url(url):
file_url = url file_url = url
API_KEY = AZURACAST_API_KEY API_KEY = AZURACAST_API_KEY
headers = { headers = {
"Authorization": f"Bearer {API_KEY}" "Authorization": f"Bearer {API_KEY}"
} }
return requests.get(file_url, headers=headers) return requests.request(method, file_url, headers=headers)
class AzuraCast: class AzuraCast:
api_key = AZURACAST_API_KEY api_key = AZURACAST_API_KEY
url = AZURACAST_URL url = AZURACAST_URL
@staticmethod
def get_nowplaying():
file_url = F"{AZURACAST_URL}api/nowplaying/it-radio"
response = authorize_url("get", file_url)
return response.json()
@staticmethod
def get_all_songs():
file_url = F"{AZURACAST_URL}api/station/1/files"
response = authorize_url("get", file_url)
data = []
for i in response.json():
i['azura_id'] = i.pop('song_id')
data.append(i)
return data
@staticmethod @staticmethod
def add_to_playlist(azura_id, data): def add_to_playlist(azura_id, data):
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{azura_id}" file_url = f"{AZURACAST_URL}api/station/it-radio/file/{azura_id}"
response = authorize_url(file_url) response = authorize_url("get", file_url)
file_play = f"{AZURACAST_URL}api/station/it-radio/file/{response.json()['unique_id']}/play" file_play = f"{AZURACAST_URL}api/station/it-radio/file/{response.json()['unique_id']}/play"
data.update(unique_id=file_play) data.update(unique_id=file_play)
return data return data
@staticmethod
def delete_song(azura_id):
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{azura_id}"
response = authorize_url("delete", file_url)
return response
@staticmethod
def get_audio(song_obj, unique_id):
file_url = f"{AZURACAST_URL}/api/station/it-radio/file/{unique_id}/play"
response = authorize_url("get", file_url)
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
@staticmethod
def get_unique_id(azura_id):
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{azura_id}"
response = authorize_url("get", file_url)
return response.json()['unique_id']

View File

@ -1,39 +1,28 @@
from django.shortcuts import render from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ViewSet, GenericViewSet
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework import status from rest_framework import status
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404, get_list_or_404
from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.permissions import IsAuthenticated, AllowAny
from audio.service import AzuraCast from audio.service import AzuraCast
from django.http import HttpResponse
import requests
from audio.schemas import SongSchema, DeleteSongSchema, PlayListSchema from audio.schemas import SongSchema, DeleteSongSchema, PlayListSchema
from audio.models import Song, FavoriteSong, PlayList, Podkast from audio.models import Song, FavoriteSong, PlayList, Podkast
from audio.serializers import SongSerializer, FavoriteSongSerializer, PlayListSerializer, PodkastSerializer 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): class PodkastViewSet(GenericViewSet):
queryset = Podkast queryset = Podkast.objects.all()
serializer_class = PodkastSerializer serializer_class = PodkastSerializer
permission_classes = (IsAuthenticated, ) permission_classes = (IsAuthenticated, )
def list(self, request): def list(self, request):
queryset = self.get_queryset().objects.all() queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, pk): def retrieve(self, request, pk):
try: try:
queryset = self.get_queryset().objects.get(pk=pk) queryset = self.get_queryset().get(pk=pk)
serializer = self.get_serializer(queryset) serializer = self.get_serializer(queryset)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
@ -41,20 +30,20 @@ class PodkastViewSet(GenericViewSet):
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}}, {'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND) status=status.HTTP_404_NOT_FOUND)
class PlayListViewSet(GenericViewSet): class PlayListViewSet(GenericViewSet):
azura = AzuraCast() azura = AzuraCast()
queryset = PlayList.objects.all() queryset = PlayList.objects.all()
serializer_class = PlayListSerializer serializer_class = PlayListSerializer
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
def list(self, request): def list(self, request):
queryset = self.get_queryset().objects.filter(user=request.user) queryset = self.get_queryset().filter(user=request.user)
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, pk): def retrieve(self, request, pk):
try: try:
queryset = self.get_queryset().objects.get(pk=pk, user=request.user) queryset = self.get_queryset().get(pk=pk, user=request.user)
serializer = self.get_serializer(queryset) serializer = self.get_serializer(queryset)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
@ -65,18 +54,12 @@ class PlayListViewSet(GenericViewSet):
@action(detail=False, methods=['post'], schema=PlayListSchema()) @action(detail=False, methods=['post'], schema=PlayListSchema())
def create_playlist(self, request): def create_playlist(self, request):
if request.data.get('name', False): if request.data.get('name', False):
try: data = request.data
instance = self.get_queryset().objects.get(pk=request.data['playlist_id'], user=request.user.pk) data.update(user=request.user.pk)
data = request.data serializer = self.get_serializer(data=request.data)
data.update(user=request.user.pk) serializer.is_valid(raise_exception=True)
serializer = self.get_serializer(data=request.data, instance=instance) serializer.save()
serializer.is_valid(raise_exception=True) return Response(serializer.data)
serializer.save()
return Response(serializer.data)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
else: else:
playlist_pk = self.get_queryset().objects.filter(user=request.user.pk) playlist_pk = self.get_queryset().objects.filter(user=request.user.pk)
name = f"Плейлист № {len(playlist_pk)+1}" name = f"Плейлист № {len(playlist_pk)+1}"
@ -87,35 +70,25 @@ class PlayListViewSet(GenericViewSet):
serializer.save() serializer.save()
return Response(serializer.data) return Response(serializer.data)
@action(detail=False, methods=['post'], schema=PlayListSchema()) @action(detail=True, methods=['post'], schema=PlayListSchema())
def update_playlist(self, request): def update_playlist(self, request, *args, **kwargs):
try: instance = self.get_object()
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 = self.get_serializer(data=request.data, partial=True, instance=instance) serializer.is_valid(raise_exception=True)
serializer.is_valid(raise_exception=True) serializer.save()
serializer.save() return Response(serializer.data)
return Response(serializer.data)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['post'], schema=PlayListSchema()) @action(detail=True, methods=['post'])
def delete_playlist(self, request): def delete_playlist(self, request, *args, **kwargs):
try: item = self.get_object()
item = self.get_queryset().objects.get(user=request.user, pk=request.data.get('playlist_id')) item.delete()
item.delete() return Response({'detail': 'Объект удалён'}, status=status.HTTP_200_OK)
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()) @action(detail=True, methods=['post'], schema=PlayListSchema())
def delete_song_with_playlist(self, request): def delete_song_with_playlist(self, request, *args, **kwargs):
try: try:
song = Song.objects.get(azura_id=request.data.get('azura_id')) 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 = self.get_object()
item.song.remove(song) item.song.remove(song)
return Response({'detail': 'Объект удалён'}, status=status.HTTP_200_OK) return Response({'detail': 'Объект удалён'}, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
@ -123,7 +96,6 @@ class PlayListViewSet(GenericViewSet):
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}}, {'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND) status=status.HTTP_404_NOT_FOUND)
@action(detail=True, methods=['post'], schema=PlayListSchema()) @action(detail=True, methods=['post'], schema=PlayListSchema())
def add_to_playlist(self, request, *args, **kwargs): def add_to_playlist(self, request, *args, **kwargs):
song = None song = None
@ -134,77 +106,54 @@ class PlayListViewSet(GenericViewSet):
song_serializer = SongSerializer(data=data) song_serializer = SongSerializer(data=data)
if song_serializer.is_valid(): if song_serializer.is_valid():
song_serializer.save() song_serializer.save()
song = song_serializer.data song = song_serializer.data['id']
instance = self.get_object() instance = self.get_object()
instance.song.add(song) instance.song.add(song)
serializer = self.get_serializer(instance) serializer = self.get_serializer(instance)
return Response(serializer.data) return Response(serializer.data)
class SongViewSet(GenericViewSet): class SongViewSet(GenericViewSet):
queryset = Song azura = AzuraCast()
queryset = Song.objects.all()
serializer_class = SongSerializer serializer_class = SongSerializer
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
lookup_field = 'azura_id'
def list(self, request): def list(self, request):
songs_pk = FavoriteSong.objects.filter(user=request.user, song__isnull=False).values_list('song_id', flat=True) 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) songs = self.get_queryset().filter(id__in=songs_pk)
serializer = self.get_serializer(songs, many=True) serializer = self.get_serializer(songs, many=True)
return Response(serializer.data) return Response(serializer.data)
@action( @action(detail=True, methods=['get'])
detail=False, def check_is_favorite(self, request, *args, **kwargs):
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: try:
song_obj = self.get_queryset().objects.get(azura_id=azura_id) song_obj = self.get_object()
favorite_songs = FavoriteSong.objects.get(user=request.user, song=song_obj) favorite_songs = FavoriteSong.objects.get(user=request.user, song=song_obj)
return Response({"is_favorite": True}, status=status.HTTP_200_OK) return Response({"is_favorite": True}, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({"is_favorite": False}, status=status.HTTP_200_OK) return Response({"is_favorite": False}, status=status.HTTP_200_OK)
@action( @action(detail=True, methods=['get'])
detail=False, def get_audio(self, request, *args, **kwargs):
methods=['get'], song_obj = self.get_object()
url_path='get_audio/(?P<azura_id>[a-zA-Z0-9_]+)', unique_id = song_obj.unique_id
url_name='get_audio', response = self.azura.get_audio(song_obj, unique_id)
) return response
def get_audio(self, request, azura_id):
try: @action(detail=True, methods=['post'], schema=SongSchema())
song_obj = self.get_queryset().objects.get(azura_id=azura_id) def add_favorite(self, request, *args, **kwargs):
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 data = None
try: try:
song = self.get_queryset().objects.get(azura_id=request.data.get('azura_id')) song = self.get_queryset().get(kwargs.get('azura_id'))
data = { data = {
"song": song.pk, "song": song.pk,
"user": request.user.pk "user": request.user.pk
} }
except ObjectDoesNotExist: except ObjectDoesNotExist:
file_url = f"{AZURACAST_URL}api/station/it-radio/file/{request.data['azura_id']}" unique_id = self.azura.get_unique_id(kwargs.get('azura_id'))
response = authorize_url(file_url)
data = request.data data = request.data
file_play = f"{AZURACAST_URL}/api/station/it-radio/file/{response.json()['unique_id']}/play" data.update(unique_id=unique_id)
data.update(unique_id=file_play)
serializer = self.get_serializer(data=data) serializer = self.get_serializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
@ -219,34 +168,17 @@ class SongViewSet(GenericViewSet):
else: else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=False, methods=['post'], schema=DeleteSongSchema()) @action(detail=False, methods=['post'])
def delete_song(self, request): def delete_song(self, request):
try: song = self.get_object()
song = self.get_queryset().objects.get(azura_id=request.data.get('azura_id')) item = FavoriteSong.objects.get(user=request.user, song=song.pk)
item = FavoriteSong.objects.get(user=request.user, song=song.pk) item.delete()
item.delete() return Response(status=status.HTTP_202_ACCEPTED)
return Response(status=status.HTTP_202_ACCEPTED)
except ObjectDoesNotExist:
return Response({"error": 'Объекта не существует'}, status=status.HTTP_404_NOT_FOUND)
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def get_all_song(self, request): def get_all_song(self, request):
file_url = F"{AZURACAST_URL}api/station/1/files" return Response(self.azura.get_all_songs(), status=status.HTTP_200_OK)
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,)) @action(detail=False, methods=['get'], permission_classes=(AllowAny,))
def get_nowplaying(self, request): def get_nowplaying(self, request):
file_url = F"{AZURACAST_URL}api/nowplaying/it-radio" return Response(self.azura.get_nowplaying(), status=status.HTTP_200_OK)
response = authorize_url(file_url)
return Response(response.json(), status=status.HTTP_200_OK)