diff --git a/apps/songs/utils.py b/apps/songs/utils.py index 399987e..ba29b0e 100644 --- a/apps/songs/utils.py +++ b/apps/songs/utils.py @@ -69,9 +69,11 @@ def get_genres_and_artist_info(track_data, sp): artist_data = sp.artists(artist_ids) genres = [] - artist_images = [] + artist_images = {} for artist in artist_data['artists']: + + artist_name = artist['name'] # Check if genres exist for the artist if 'genres' in artist and artist['genres']: # Capitalize the first letter of each genre and add to the list @@ -79,8 +81,9 @@ def get_genres_and_artist_info(track_data, sp): # Check if images exist for the artist if 'images' in artist and artist['images']: + image_url = artist['images'][0]['url'] # Get the URL of the first image - artist_images.append(artist['images'][0]['url']) + artist_images[artist_name.title()] = image_url # Remove duplicate genres unique_genres = list(set(genres)) diff --git a/apps/songs/views.py b/apps/songs/views.py index d4500d5..5bbc7eb 100644 --- a/apps/songs/views.py +++ b/apps/songs/views.py @@ -247,13 +247,13 @@ def add_song(request, userid): if genre_name: genre, genre_created = Genre.objects.get_or_create(name=genre_name) new_song.genres.add(genre) - + for artist in track['artists']: - artist_name = artist['name'] + artist_name = artist['name'].title() artist_bio = get_artist_bio(artist_name) - artist_img_url = artist_img if artist_img is not None else None + artist_img_url = artist_img[artist_name] artist_instance, artist_created = \ - Artist.objects.get_or_create(name=artist_name.title(), + Artist.objects.get_or_create(name=artist_name, id=artist['id'], img_url=artist_img_url, bio=artist_bio) diff --git a/apps/users/urls.py b/apps/users/urls.py index e1855c8..459f6ed 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -44,4 +44,5 @@ path('get-recent-addition-counts/', view=views.get_recent_addition_by_count, name='get-recent-addition-count'), path('get-profile-stats/', view=views.get_profile_stats, name='get-profile-stats'), path('recommend-since-you-like/', view=views.recommend_since_you_like, name='recommend-since-you-like'), + path('recommend-friend-mix/', view=views.recommend_friend_mix, name='recommend-friend-mix'), ] diff --git a/apps/users/views.py b/apps/users/views.py index 268b66e..3423904 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -355,7 +355,7 @@ def delete_song_rating(request, userid): user_rating.delete() - return JsonResponse({'message': 'User rating deleted successfully'}, status=201) + return JsonResponse({'message': 'User rating deleted successfully'}, status=204) else: return JsonResponse({'error': 'Invalid method'}, status=400) except KeyError as e: @@ -1104,7 +1104,7 @@ def recommend_songs(request, userid): user_songs = UserSongRating.objects.filter(user=userid).order_by('-rating')[:20] - if user_songs is None: + if user_songs.exists() is False: return JsonResponse({'error': 'No songs found for the user, cannot make recommendation'}, status=404) client_credentials = SpotifyClientCredentials(client_id=os.getenv('SPOTIPY_CLIENT_ID'), client_secret=os.getenv('SPOTIPY_CLIENT_SECRET')) @@ -1340,6 +1340,60 @@ def recommend_since_you_like(request, userid): except KeyError as e: logging.error(f"A KeyError occurred: {str(e)}") return JsonResponse({'error': 'KeyError occurred'}, status=500) + 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 recommend_friend_mix(request, userid): + try: + if request.method != 'GET': + return JsonResponse({'error': 'Invalid method'}, status=400) + else: + data = request.GET + count = data.get('count') + + count = int(count) + + if count > 100 or count < 1: + return JsonResponse({'error': 'Invalid count'}, status=400) + + try: + user = User.objects.get(id=userid) + friends_list = Friend.objects.filter(user=user) + + if friends_list.exists() is False: + return JsonResponse({'error': 'No friends found for the user, cannot make recommendation'}, status=404) + + songs_seed = [] + for friend in friends_list: + friend_songs = UserSongRating.objects.filter(user=friend.friend).order_by('-rating') + for song in friend_songs: + songs_seed.append(song.song.id) + list(set(songs_seed)) + + if len(songs_seed) > 5: + songs_seed = random.sample(songs_seed, 5) + + params = { + 'limit': count, + 'seed_tracks': songs_seed + } + + 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) + spotify_recommendations = sp.recommendations(**params) + + if spotify_recommendations['tracks'] is None: + return JsonResponse({'error': 'No recommendations based on friends can be made currently, please try again later'}, status=404) + tracks_info = recommendation_creator(spotify_recommendations) + return JsonResponse({'message': 'Recommendation based on friends is successful', 'tracks_info': tracks_info}, status=200) + except User.DoesNotExist: + return JsonResponse({'error': 'User not found'}, status=404) + except KeyError as e: + logging.error(f"A KeyError occurred: {str(e)}") + return JsonResponse({'error': 'KeyError occurred'}, status=500) except Exception as e: logging.error(f"An unexpected error occurred: {str(e)}") return JsonResponse({'error': 'An unexpected error occurred'}, status=500) \ No newline at end of file