This commit is contained in:
Norbaev 2024-07-03 17:49:29 +05:00
commit 24b41d9036
7 changed files with 132 additions and 100 deletions

View File

@ -10,7 +10,7 @@ class SongAdmin(admin.ModelAdmin):
@admin.register(FavoriteSong) @admin.register(FavoriteSong)
class FavoriteSongAdmin(admin.ModelAdmin): class FavoriteSongAdmin(admin.ModelAdmin):
list_display = ('id', 'song', 'user') list_display = ('id', 'user')
@admin.register(PlayList) @admin.register(PlayList)
class PlayListAdmin(admin.ModelAdmin): class PlayListAdmin(admin.ModelAdmin):

View File

@ -19,7 +19,7 @@ class Song(models.Model):
super(Song, self).save(*args, **kwargs) super(Song, self).save(*args, **kwargs)
def __str__(self): def __str__(self):
return f"{self.artist} - {self.title}" return f"{self.title}"
class Meta: class Meta:
verbose_name = 'Треки' verbose_name = 'Треки'
@ -33,14 +33,13 @@ class Song(models.Model):
class FavoriteSong(models.Model): class FavoriteSong(models.Model):
song = models.ForeignKey(Song, verbose_name='Трек', on_delete=models.CASCADE) song = models.ManyToManyField(Song, verbose_name='Трек')
user = models.ForeignKey(MyUser, verbose_name='Пользователь', on_delete=models.CASCADE) user = models.ForeignKey(MyUser, verbose_name='Пользователь', on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return f"{self.song.title}" return f"{self.user.first_name}"
class Meta: class Meta:
verbose_name = 'Избранные Треки' verbose_name = 'Избранные Треки'
unique_together = ('song', 'user')
verbose_name_plural = 'Избранные Треки' verbose_name_plural = 'Избранные Треки'

View File

@ -4,45 +4,62 @@ import coreschema
class SongSchema(AutoSchema): class SongSchema(AutoSchema):
def get_serializer_fields(self, path, method): def get_serializer_fields(self, path, method):
return [ if path.endswith('/get_song_history/'):
return [
coreapi.Field( coreapi.Field(
name='azura_id', name='start',
location='form', location='form',
required=False, required=False,
schema=coreschema.String(description='ID трека с Азуры') schema=coreschema.String(description='Начало периода')
), ),
coreapi.Field( coreapi.Field(
name='title', name='end',
location='form', location='form',
required=False, required=False,
schema=coreschema.String(description='Название трека') schema=coreschema.String(description='Конец периода')
), ),
coreapi.Field( ]
name='artist', if path.endswith('/add_favorite/'):
location='form', return [
required=False, coreapi.Field(
schema=coreschema.String(description='Исполнитель') name='azura_id',
), location='form',
coreapi.Field( required=False,
name='album', schema=coreschema.String(description='ID трека с Азуры')
location='form', ),
required=False, coreapi.Field(
schema=coreschema.String(description='Альбом трека') name='title',
), location='form',
coreapi.Field( required=False,
name='genre', schema=coreschema.String(description='Название трека')
location='form', ),
required=False, coreapi.Field(
schema=coreschema.String(description='Жанр трека') name='artist',
), location='form',
coreapi.Field( required=False,
name='art', schema=coreschema.String(description='Исполнитель')
location='form', ),
required=False, coreapi.Field(
schema=coreschema.String(description='Изображение трека') name='album',
), location='form',
] required=False,
schema=coreschema.String(description='Альбом трека')
),
coreapi.Field(
name='genre',
location='form',
required=False,
schema=coreschema.String(description='Жанр трека')
),
coreapi.Field(
name='art',
location='form',
required=False,
schema=coreschema.String(description='Изображение трека')
),
]
return []
class DeleteSongSchema(AutoSchema): class DeleteSongSchema(AutoSchema):
def get_serializer_fields(self, path, method): def get_serializer_fields(self, path, method):
return [ return [
@ -71,7 +88,7 @@ class PlayListSchema(AutoSchema):
schema=coreschema.Integer(description='Обложка плейлиста') schema=coreschema.Integer(description='Обложка плейлиста')
), ),
] ]
if path.endswith('/update_playlist/') or path.endswith('/delete_song_with_playlist/'): if path.endswith('/delete_song_with_playlist/'):
return [ return [
coreapi.Field( coreapi.Field(
name='azura_id', name='azura_id',
@ -80,6 +97,22 @@ class PlayListSchema(AutoSchema):
schema=coreschema.String(description='ID трека с Азуры') schema=coreschema.String(description='ID трека с Азуры')
), ),
] ]
if path.endswith('/update_playlist/'):
return [
coreapi.Field(
name='name',
location='form',
required=False,
schema=coreschema.String(description='Название плейлиста')
),
coreapi.Field(
name='playlist_art',
location='form',
required=False,
schema=coreschema.Integer(description='Обложка плейлиста')
),
]
if path.endswith('/add_to_playlist/'): if path.endswith('/add_to_playlist/'):
return [ return [
coreapi.Field( coreapi.Field(

View File

@ -1,14 +1,17 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Song, FavoriteSong, PlayList, Podkast from .models import Song, FavoriteSong, PlayList, Podkast
class SongSerializer(serializers.ModelSerializer): class SongSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Song model = Song
fields = ('id', 'unique_id', 'azura_id', 'title', 'artist', 'album', 'genre', 'art') fields = ('id', 'unique_id', 'azura_id', 'title', 'artist', 'album', 'genre', 'art')
class PlayListSerializer(serializers.ModelSerializer): class PlayListSerializer(serializers.ModelSerializer):
def validate(self, attrs): def validate(self, attrs):
if PlayList.objects.filter( if PlayList.objects.filter(
name=attrs.get('name'), name=attrs.get('name'),
user=attrs.get('user') user=attrs.get('user')
@ -22,36 +25,21 @@ class PlayListSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = PlayList model = PlayList
fields = ('id', 'name', 'song', 'user', 'playlist_art') fields = ('id', 'name', 'song', 'user', 'playlist_art')
def to_representation(self, instance): def to_representation(self, instance):
rep = super().to_representation(instance) rep = super().to_representation(instance)
rep["song"] = SongSerializer( rep["song"] = SongSerializer(
instance.song.all(), many=True).data instance.song.all(), many=True).data
return rep return rep
class FavoriteSongSerializer(serializers.ModelSerializer): class FavoriteSongSerializer(serializers.ModelSerializer):
song = SongSerializer(many=True)
def validate(self, attrs):
if FavoriteSong.objects.filter(
song=attrs.get('song'),
user=attrs.get('user')
).exists():
raise serializers.ValidationError(
{
'song': ['Данный трек уже добавлен в избранное']
})
return super().validate(attrs)
class Meta: class Meta:
model = FavoriteSong model = FavoriteSong
fields = ('id', 'song', 'user') fields = '__all__'
def to_representation(self, instance):
rep = super().to_representation(instance)
rep["song"] = SongSerializer(
instance.song).data
return rep
class PodkastSerializer(serializers.ModelSerializer): class PodkastSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Podkast model = Podkast

View File

@ -4,6 +4,11 @@ from audio.services import service_azura
class AzuraCast: class AzuraCast:
azura_requests = service_azura.AzuraCastRequests() azura_requests = service_azura.AzuraCastRequests()
def get_song_history(self, start, end):
print(start, end)
response = self.azura_requests.get_song_history(start, end)
return response
def get_nowplaying(self): def get_nowplaying(self):
response = self.azura_requests.get_nowplaying() response = self.azura_requests.get_nowplaying()
return response return response

View File

@ -13,6 +13,12 @@ class AzuraCastRequests:
api_key = AZURACAST_API_KEY api_key = AZURACAST_API_KEY
url = AZURACAST_URL url = AZURACAST_URL
@staticmethod
def get_song_history(start_time, end_time):
file_url = F"{AZURACAST_URL}api/station/it-radio/history?start={start_time}&end={end_time}"
response = authorize_url("get", file_url)
return response.json()
@staticmethod @staticmethod
def get_nowplaying(): def get_nowplaying():
file_url = F"{AZURACAST_URL}api/nowplaying/it-radio" file_url = F"{AZURACAST_URL}api/nowplaying/it-radio"

View File

@ -54,21 +54,17 @@ class PlayListViewSet(GenericViewSet):
def create_playlist(self, request): def create_playlist(self, request):
if request.data.get('name', False): if request.data.get('name', False):
data = request.data data = request.data
data.update(user=request.user.pk) data.update(user=request.user.pk)
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else: else:
playlist_pk = self.get_queryset().filter(user=request.user.pk) playlist_pk = self.get_queryset().filter(user=request.user.pk)
name = f"Плейлист № {len(playlist_pk)+1}" name = f"Плейлист № {len(playlist_pk)+1}"
data = request.data data = request.data
data.update(user=request.user.pk, name=name) data.update(user=request.user.pk, name=name)
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
return Response(serializer.data) return Response(serializer.data)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['post'], schema=PlayListSchema()) @action(detail=True, methods=['post'], schema=PlayListSchema())
@ -89,21 +85,22 @@ class PlayListViewSet(GenericViewSet):
@action(detail=True, methods=['post'], schema=PlayListSchema()) @action(detail=True, methods=['post'], schema=PlayListSchema())
def delete_song_with_playlist(self, request, *args, **kwargs): def delete_song_with_playlist(self, request, *args, **kwargs):
try: try:
song = Song.objects.get(azura_id=request.data.get('azura_id')) song_obj = Song.objects.get(azura_id=request.data.get('azura_id'))
item = self.get_object()
item.song.remove(song)
return Response({'detail': 'Объект удалён'}, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}}, return Response({'detail': 'Объекта не существует', 'error': {'Song': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND) status=status.HTTP_404_NOT_FOUND)
if not self.get_queryset().filter(user=request.user, song=song_obj).exists():
return Response({'detail': 'Объекта не существует', 'error': {'Song': 'Объекта отсутствует плейлисте'}},
status=status.HTTP_404_NOT_FOUND)
playlist = self.get_object()
playlist.song.remove(song_obj)
serializer = self.get_serializer(playlist)
return Response(serializer.data, status=status.HTTP_200_OK)
@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):
instance = self.get_object() instance = self.get_object()
song = None
try: try:
song = Song.objects.get(azura_id=request.data.get('azura_id')).pk song = Song.objects.get(azura_id=request.data.get('azura_id')).pk
except ObjectDoesNotExist: except ObjectDoesNotExist:
data = self.azura.add_to_playlist(request.data) data = self.azura.add_to_playlist(request.data)
@ -118,7 +115,6 @@ class PlayListViewSet(GenericViewSet):
return Response(serializer.data) return Response(serializer.data)
class FavoriteSongViewSet(GenericViewSet): class FavoriteSongViewSet(GenericViewSet):
azura = AzuraCast() azura = AzuraCast()
queryset = FavoriteSong.objects.all() queryset = FavoriteSong.objects.all()
@ -128,55 +124,48 @@ class FavoriteSongViewSet(GenericViewSet):
def list(self, request): def list(self, request):
queryset = self.get_queryset() queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True, request_user=request.user) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
@action(detail=False, methods=['get']) @action(detail=True, methods=['get'])
def check_is_favorite(self, request, azura_id, *args, **kwargs): def check_is_favorite(self, request, azura_id, *args, **kwargs):
try: try:
song_obj = Song.objects.get(azura_id=azura_id) song_obj = Song.objects.get(azura_id=azura_id)
favorite_songs = self.get_queryset().get(user=request.user, song=song_obj)
return Response({"is_favorite": True}, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({'detail': 'Объекта не существует', 'error': {'Song': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND)
if self.get_queryset().filter(user=request.user, song=song_obj).exists():
return Response({"is_favorite": True}, status=status.HTTP_200_OK)
else:
return Response({"is_favorite": False}, status=status.HTTP_200_OK) return Response({"is_favorite": False}, status=status.HTTP_200_OK)
@action(detail=False, methods=['post'], schema=SongSchema()) @action(detail=False, methods=['post'], schema=SongSchema())
def add_favorite(self, request, *args, **kwargs): def add_favorite(self, request, *args, **kwargs):
data = None
try: try:
song = Song.objects.get(azura_id=request.data.get('azura_id')) song = Song.objects.get(azura_id=request.data.get('azura_id'))
data = {
'song': song.pk,
'user': request.user.pk
}
except ObjectDoesNotExist: except ObjectDoesNotExist:
unique_id = self.azura.get_unique_id(azura_id = request.data.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 = SongSerializer(data=data) serializer = SongSerializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
data = { song = serializer.data['id']
"song": serializer.data['id'],
"user": request.user.pk
}
else: else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
obj, data = self.get_queryset().get_or_create(user=request.user)
serializer = self.get_serializer(data=data) obj.song.add(song)
if serializer.is_valid(data): serializer = self.get_serializer(obj)
serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['delete']) @action(detail=True, methods=['delete'])
def delete_song(self, request, *args, **kwargs): def delete_song(self, request, *args, **kwargs):
try: try:
song = Song.objects.get(azura_id=kwargs.get('azura_id')) song = Song.objects.get(azura_id=kwargs.get('azura_id'))
queryset = self.get_queryset().get(user=request.user, song=song.pk) queryset = self.get_queryset().get(user=request.user, song=song.pk)
queryset.delete() queryset.song.remove(song)
return Response(status=status.HTTP_202_ACCEPTED) serializer = self.get_serializer(queryset)
return Response(serializer.data, status=status.HTTP_200_OK)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({'detail': 'Объекта не существует', 'error': {'Song': 'Объекта не существует'}}, return Response({'detail': 'Объекта не существует', 'error': {'Song': 'Объекта не существует'}},
status=status.HTTP_404_NOT_FOUND) status=status.HTTP_404_NOT_FOUND)
@ -184,6 +173,8 @@ class FavoriteSongViewSet(GenericViewSet):
class SongViewSet(GenericViewSet): class SongViewSet(GenericViewSet):
azura = AzuraCast() azura = AzuraCast()
queryset = Song.objects.all()
permission_classes = (IsAuthenticated, )
lookup_field = 'azura_id' lookup_field = 'azura_id'
@action(detail=True, methods=['get']) @action(detail=True, methods=['get'])
@ -198,3 +189,13 @@ class SongViewSet(GenericViewSet):
@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):
return Response(self.azura.get_nowplaying(), status=status.HTTP_200_OK) return Response(self.azura.get_nowplaying(), status=status.HTTP_200_OK)
@action(detail=False, methods=['get'], permission_classes=(AllowAny,), schema=SongSchema())
def get_song_history(self, request):
return Response(
self.azura.get_song_history(
request.data['start'],
request.data['end']
),
status=status.HTTP_200_OK
)