рефакторинг кода + разделение сервисов

This commit is contained in:
Mike0001-droid 2024-07-01 16:23:18 +05:00
parent 3f3086c141
commit 551bdc4898
11 changed files with 110 additions and 75 deletions

View File

@ -1,7 +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 from audio.services.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)
@ -33,8 +33,8 @@ class Song(models.Model):
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)
user = models.ForeignKey(MyUser, verbose_name='Пользователь', on_delete=models.CASCADE, blank=True, null=True) user = models.ForeignKey(MyUser, verbose_name='Пользователь', on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return f"{self.song.title}" return f"{self.song.title}"

View File

@ -17,11 +17,14 @@ class PlayListSerializer(serializers.ModelSerializer):
instance.song.all(), many=True).data instance.song.all(), many=True).data
return rep return rep
class FavoriteSongSerializer(serializers.ModelSerializer): class FavoriteSongSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
self.request_user = kwargs.pop('request_user', None)
super().__init__(*args, **kwargs)
class Meta: class Meta:
model = FavoriteSong model = FavoriteSong
fields = ('id', 'song', 'user') fields = ('id', 'song',)
def to_representation(self, instance): def to_representation(self, instance):
rep = super().to_representation(instance) rep = super().to_representation(instance)

View File

@ -0,0 +1,40 @@
from django.http import HttpResponse
from audio.services import service_azura
class AzuraCast:
azura_requests = service_azura.AzuraCastRequests()
def get_nowplaying(self):
response = self.azura_requests.get_nowplaying()
return response
def get_all_songs(self):
response = self.azura_requests.get_all_songs()
data = []
for i in response.json():
i['azura_id'] = i.pop('song_id')
data.append(i)
return data
def add_to_playlist(self, azura_id, data):
response = self.azura_requests.get_song(azura_id)
file_play = response.json()['unique_id']
data.update(unique_id=file_play)
return data
def delete_song(self, azura_id):
response = self.azura_requests.delete_song(azura_id)
return response
def get_audio(self, song_obj):
response = self.azura_requests.get_blob(song_obj.unique_id)
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
def get_unique_id(self, azura_id):
response = self.azura_requests.get_song(azura_id)
return response.json()['unique_id']

View File

@ -1,6 +1,5 @@
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(method, url):
file_url = url file_url = url
@ -10,7 +9,7 @@ def authorize_url(method, url):
} }
return requests.request(method, file_url, headers=headers) return requests.request(method, file_url, headers=headers)
class AzuraCast: class AzuraCastRequests:
api_key = AZURACAST_API_KEY api_key = AZURACAST_API_KEY
url = AZURACAST_URL url = AZURACAST_URL
@ -22,40 +21,24 @@ class AzuraCast:
@staticmethod @staticmethod
def get_all_songs(): def get_all_songs():
file_url = F"{AZURACAST_URL}api/station/1/files" file_url = F"{AZURACAST_URL}api/station/it-radio/files"
response = authorize_url("get", file_url) response = authorize_url("get", file_url)
data = [] return response
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 get_song(azura_id):
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("get", file_url) response = authorize_url("get", file_url)
file_play = f"{AZURACAST_URL}api/station/it-radio/file/{response.json()['unique_id']}/play" return response
data.update(unique_id=file_play)
return data @staticmethod
def get_blob(unique_id):
file_play = f"{AZURACAST_URL}api/station/it-radio/file/{unique_id}/play"
response = authorize_url("get", file_play)
return response
@staticmethod @staticmethod
def delete_song(azura_id): def delete_song(azura_id):
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("delete", file_url) response = authorize_url("delete", file_url)
return response 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

@ -4,17 +4,17 @@ from rest_framework.decorators import action
from rest_framework import status from rest_framework import status
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.permissions import IsAuthenticated, AllowAny
from audio.service import AzuraCast from audio.services.service import AzuraCast
from audio.schemas import SongSchema, DeleteSongSchema, PlayListSchema from audio.schemas import SongSchema, 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
class PodkastViewSet(GenericViewSet): class PodkastViewSet(GenericViewSet):
queryset = Podkast.objects.all() 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() queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
@ -30,6 +30,7 @@ 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()
@ -112,68 +113,75 @@ class PlayListViewSet(GenericViewSet):
serializer = self.get_serializer(instance) serializer = self.get_serializer(instance)
return Response(serializer.data) return Response(serializer.data)
class SongViewSet(GenericViewSet): class FavoriteSongViewSet(GenericViewSet):
azura = AzuraCast() azura = AzuraCast()
queryset = Song.objects.all() queryset = FavoriteSong.objects.all()
serializer_class = SongSerializer serializer_class = FavoriteSongSerializer
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated, )
lookup_field = 'azura_id' 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) queryset = self.get_queryset()
songs = self.get_queryset().filter(id__in=songs_pk) serializer = self.get_serializer(queryset, many=True, request_user=request.user)
serializer = self.get_serializer(songs, many=True)
return Response(serializer.data) return Response(serializer.data)
@action(detail=True, methods=['get']) @action(detail=False, methods=['get'])
def check_is_favorite(self, request, *args, **kwargs): def check_is_favorite(self, request, azura_id, *args, **kwargs):
try: try:
song_obj = self.get_object() song_obj = Song.objects.get(azura_id=azura_id)
favorite_songs = FavoriteSong.objects.get(user=request.user, song=song_obj) favorite_songs = self.get_queryset().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(detail=True, methods=['get']) @action(detail=False, methods=['post'], schema=SongSchema())
def get_audio(self, request, *args, **kwargs):
song_obj = self.get_object()
unique_id = song_obj.unique_id
response = self.azura.get_audio(song_obj, unique_id)
return response
@action(detail=True, methods=['post'], schema=SongSchema())
def add_favorite(self, request, *args, **kwargs): def add_favorite(self, request, *args, **kwargs):
data = None data = None
try: try:
song = self.get_queryset().get(kwargs.get('azura_id')) song = Song.objects.get(azura_id=request.data.get('azura_id'))
data = { data = {
"song": song.pk, 'song': song.pk,
"user": request.user.pk 'user': request.user.pk
} }
except ObjectDoesNotExist: except ObjectDoesNotExist:
unique_id = self.azura.get_unique_id(kwargs.get('azura_id')) unique_id = self.azura.get_unique_id(azura_id = request.data.get('azura_id'))
data = request.data data = request.data
data.update(unique_id=unique_id) data.update(unique_id=unique_id)
serializer = self.get_serializer(data=data) serializer = SongSerializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
data = { data = {
"song": serializer.data['id'], "song": serializer.data['id'],
"user": request.user.pk "user": request.user.pk
} }
serializer = FavoriteSongSerializer(data=data) serializer = self.get_serializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.data, status=status.HTTP_201_CREATED)
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']) @action(detail=True, methods=['delete'])
def delete_song(self, request): def delete_song(self, request, *args, **kwargs):
song = self.get_object() try:
item = FavoriteSong.objects.get(user=request.user, song=song.pk) song = Song.objects.get(azura_id = kwargs.get('azura_id'))
item.delete() queryset = self.get_queryset().get(user=request.user, song=song.pk)
return Response(status=status.HTTP_202_ACCEPTED) queryset.delete()
return Response(status=status.HTTP_202_ACCEPTED)
except ObjectDoesNotExist:
return Response(
{'detail': 'Объекта не существует', 'error': {'Song': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
class SongViewSet(GenericViewSet):
azura = AzuraCast()
lookup_field = 'azura_id'
@action(detail=True, methods=['get'])
def get_audio(self, *args, **kwargs):
response = self.azura.get_audio(self.get_object())
return response
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def get_all_song(self, request): def get_all_song(self, request):

View File

@ -11,7 +11,7 @@ from rest_framework import routers
from config_site.views import TeamViewSet from config_site.views import TeamViewSet
from django.conf import settings from django.conf import settings
from rubricks.views import RubricViewSet from rubricks.views import RubricViewSet
from audio.views import SongViewSet, PlayListViewSet from audio.views import SongViewSet, PlayListViewSet, FavoriteSongViewSet
router = routers.DefaultRouter() router = routers.DefaultRouter()
@ -19,6 +19,7 @@ router.register(r'teams', TeamViewSet, basename='teams')
router.register(r'rubriks', RubricViewSet, basename='rubriks') router.register(r'rubriks', RubricViewSet, basename='rubriks')
router.register(r'playlists', PlayListViewSet, basename='playlists') router.register(r'playlists', PlayListViewSet, basename='playlists')
router.register(r'song', SongViewSet, basename='song') router.register(r'song', SongViewSet, basename='song')
router.register(r'favorite', FavoriteSongViewSet, basename='favorite')
urlpatterns = [ urlpatterns = [
path('api/admin/', admin.site.urls), path('api/admin/', admin.site.urls),

View File

@ -1,4 +1,4 @@
# Generated by Django 5.0.6 on 2024-06-19 12:09 # Generated by Django 5.0.6 on 2024-07-01 09:51
import django.utils.timezone import django.utils.timezone
from django.db import migrations, models from django.db import migrations, models

View File

@ -1,4 +1,4 @@
# Generated by Django 5.0.6 on 2024-06-19 12:09 # Generated by Django 5.0.6 on 2024-07-01 09:51
from django.db import migrations, models from django.db import migrations, models