Skip to content

Commit

Permalink
Merge pull request #45 from enesonus/OVTF-109
Browse files Browse the repository at this point in the history
OVTF-109: Import songs by file implementation
  • Loading branch information
enesonus authored Nov 16, 2023
2 parents 8621f5d + c519a58 commit b6cc76d
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 17 deletions.
3 changes: 3 additions & 0 deletions apps/songs/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
path('api/fetch', views.get_song, name='get-song'),
path('api/add', views.add_song, name='add-song'),
path('api/search', views.search_songs, name='search-songs'),
path('get-all-genres/', views.get_all_genres, name='get-all-genres'),
path('create-genre/', views.create_genre, name='create-genre'),
path('upload-file/', views.import_song_JSON, name='import-song-json'),

]
118 changes: 102 additions & 16 deletions apps/songs/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from django.http import JsonResponse
import json
from datetime import timedelta

from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.core.exceptions import ValidationError
from django.views.decorators.csrf import csrf_exempt
import spotipy
from OVTF_Backend.firebase_auth import token_required
Expand All @@ -8,21 +12,22 @@
import os
import logging


# Create your views here.

@csrf_exempt
@token_required
def get_all_songs(request):
users = Song.objects.all()
def get_all_songs(request, userid):
songs = Song.objects.all().values()
context = {
"users": list(users)
"users": list(songs)
}
return JsonResponse(context, status=200)


@csrf_exempt
@token_required
def get_songs(request):
def get_songs(request, userid):
if request.method == 'GET':
data = request.GET
track_name = data.get('song_name')
Expand Down Expand Up @@ -61,10 +66,11 @@ def get_songs(request):
return JsonResponse({'error': 'An unexpected error occurred'}, status=500)
else:
return JsonResponse({'error': 'Invalid method'}, status=400)



@csrf_exempt
@token_required
def get_song(request):
def get_song(request, userid):
if request.method == 'GET':
data = request.GET
track_id = data.get('song_id')
Expand All @@ -85,7 +91,7 @@ def get_song(request):
'replay_count': song.replay_count,
'version': song.version,
}
return JsonResponse({'message': 'song found','song_info': song_info}, status=200)
return JsonResponse({'message': 'song found', 'song_info': song_info}, status=200)
except Song.DoesNotExist:
return JsonResponse({'error': 'Song not found'}, status=404)
else:
Expand All @@ -94,7 +100,7 @@ def get_song(request):

@csrf_exempt
@token_required
def add_song(request):
def add_song(request, userid):
try:
if request.method == 'POST':
data = request.POST
Expand All @@ -103,7 +109,8 @@ def add_song(request):
if not spotify_id:
return JsonResponse({'error': 'Spotify ID is required'}, status=400)

client_credentials = SpotifyClientCredentials(client_id=os.getenv('SPOTIPY_CLIENT_ID'), client_secret=os.getenv('SPOTIPY_CLIENT_SECRET'))
client_credentials = SpotifyClientCredentials(client_id=os.getenv('SPOTIPY_CLIENT_ID'),
client_secret=os.getenv('SPOTIPY_CLIENT_SECRET'))
sp = spotipy.Spotify(client_credentials_manager=client_credentials)

# Use the provided Spotify ID to get track information directly
Expand All @@ -115,7 +122,8 @@ def add_song(request):
if audio_features:
audio_features = audio_features[0]
recommended_environment = 'L' if audio_features['liveness'] >= 0.8 else 'S'
tempo = 'F' if audio_features['tempo'] >= 120 else ('M' if 76 <= audio_features['tempo'] < 120 else 'S')
tempo = 'F' if audio_features['tempo'] >= 120 else (
'M' if 76 <= audio_features['tempo'] < 120 else 'S')
energy = audio_features['energy']
if 0 <= energy < 0.25:
mood = 'SA' # Sad
Expand Down Expand Up @@ -164,19 +172,21 @@ def add_song(request):
except Exception as e:
logging.error(f"An unexpected error occurred: {str(e)}")
return JsonResponse({'error': 'An unexpected error occurred'}, status=500)



@csrf_exempt
@token_required
def search_songs(request):
def search_songs(request, userid):
try:
if request.method == 'GET':
data = request.GET
search_string = data.get('search_string')

if search_string is None:
return JsonResponse({'error': 'Missing search string'}, status=400)

client_credentials = SpotifyClientCredentials(client_id=os.getenv('SPOTIPY_CLIENT_ID'), client_secret=os.getenv('SPOTIPY_CLIENT_SECRET'))

client_credentials = SpotifyClientCredentials(client_id=os.getenv('SPOTIPY_CLIENT_ID'),
client_secret=os.getenv('SPOTIPY_CLIENT_SECRET'))
sp = spotipy.Spotify(client_credentials_manager=client_credentials)

results = sp.search(q=search_string, type='track', limit=10)
Expand All @@ -189,7 +199,7 @@ def search_songs(request):
'album_name': track['album']['name'],
'artist': ', '.join([artist['name'] for artist in track['artists']]),
'release_year': track['album']['release_date'][:4],
'spotify_id': track['id'],
'spotify_id': track['id'],
}
search_list.append(song_info)
return JsonResponse({'message': 'Search successful', 'results': search_list}, status=200)
Expand All @@ -202,3 +212,79 @@ def search_songs(request):
except Exception as e:
logging.error(f"An unexpected error occurred: {str(e)}")
return JsonResponse({'error': 'An unexpected error occurred'}, status=500)


@csrf_exempt
@token_required
def import_song_JSON(request, userid):
if request.method != 'POST':
return HttpResponse(status=405)
try:
if 'file' in request.FILES:
file = request.FILES['file']
data = json.load(file)
else:
return JsonResponse({'error': 'No file provided'}, status=400)
if isinstance(data, dict):
data = [data]
required_fields = ['track_name', 'release_year', 'length',
'tempo', 'genre', 'mood',
'recommended_environment', 'duration', 'replay_count', 'version']
for song_data in data:
# Assuming genre_id is provided in song_data to link Song with Genre
# return JsonResponse(song_data, safe=False, status=200)
if not all(field in song_data for field in required_fields):
return HttpResponse(status=400)
genre_name = song_data.get('genre', None)
genre, created = Genre.objects.get_or_create(genre_name=genre_name)
song_data['genre'] = genre
hours, minutes, seconds = map(int, song_data['length'].split(':'))
length_timedelta = timedelta(hours=hours, minutes=minutes, seconds=seconds)
song_data['length'] = length_timedelta
song = Song(**song_data)
song.full_clean()
song.save()

return HttpResponse(status=201)
except json.JSONDecodeError as e:
logging.error(f"JSON decode error: {e}")
return HttpResponse(status=400)
except ValidationError as e:
return JsonResponse({'errors': e.message_dict}, status=400)
except Genre.DoesNotExist:
return HttpResponse("Genre not found.", status=400)
except Exception as e:
logging.error(f"Unexpected error: {e}")
return HttpResponse(status=500)


@csrf_exempt
def create_genre(request):
if request.method != 'POST':
return HttpResponse(status=405)
try:
data = json.loads(request.body.decode('utf-8'))
genre_name = data.get('genre_name')
if genre_name is None:
return HttpResponse(status=400)
genre = Genre(genre_name=genre_name)
genre.save()
return HttpResponse(status=201)
except Exception as e:
# TODO logging.("create_user: " + str(e))
return HttpResponse(status=500)


@csrf_exempt
def get_all_genres(request):
if request.method != 'GET':
return HttpResponse(status=405)
try:
genres = Genre.objects.all().values()
except Exception as e:
return JsonResponse({"error": "Database error"}, status=500)

context = {
"genres": list(genres)
}
return JsonResponse(context, status=200)
6 changes: 6 additions & 0 deletions apps/users/files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django import forms


class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
1 change: 1 addition & 0 deletions apps/users/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
path('login/', view=views.login, name='login'),
path('delete-user/', view=views.delete_user, name='delete-user'),
path('update-user/', view=views.update_user, name='update-user'),

]
14 changes: 13 additions & 1 deletion apps/users/views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import json
import logging
from datetime import datetime
from datetime import datetime, timedelta

from django.core.exceptions import ValidationError
from django.http import JsonResponse, HttpResponse
from django.utils import timezone
from django.utils.dateparse import parse_duration
from django.views.decorators.csrf import csrf_exempt

from OVTF_Backend.firebase_auth import token_required
from apps.songs.models import Genre, Song
from apps.users.files import UploadFileForm
from apps.users.models import User


Expand Down Expand Up @@ -108,3 +112,11 @@ def update_user(request, userid):
return HttpResponse(status=204)
except Exception as e:
return HttpResponse(status=404)








0 comments on commit b6cc76d

Please sign in to comment.