Auto commit: 2025-11-25T16:17:51.853Z
This commit is contained in:
parent
b0df731824
commit
0187c43d11
BIN
assets/pasted-20251125-161531-9dca6399.png
Normal file
BIN
assets/pasted-20251125-161531-9dca6399.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 MiB |
Binary file not shown.
@ -20,6 +20,9 @@ load_dotenv(BASE_DIR.parent / ".env")
|
||||
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "change-me")
|
||||
DEBUG = os.getenv("DJANGO_DEBUG", "true").lower() == "true"
|
||||
|
||||
YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY", "REPLACE_WITH_YOUR_YOUTUBE_API_KEY")
|
||||
|
||||
|
||||
# Trust proxy headers from Cloudflare Tunnel / Apache
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
USE_X_FORWARDED_HOST = True
|
||||
|
||||
Binary file not shown.
@ -33,18 +33,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if playlist %}
|
||||
<div class="playlist-container">
|
||||
<h2 class="playlist-title">Your Playlist</h2>
|
||||
<ul class="playlist">
|
||||
{% for song in playlist %}
|
||||
<li class="playlist-item">
|
||||
<span class="song-title">{{ song.title }}</span> - <span class="song-artist">{{ song.artist }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<script src="{% static 'js/chat.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@ -2,6 +2,23 @@ from django.shortcuts import render
|
||||
from django.http import JsonResponse
|
||||
from ai.local_ai_api import LocalAIApi
|
||||
import json
|
||||
from django.conf import settings
|
||||
from googleapiclient.discovery import build
|
||||
|
||||
def youtube_search(query):
|
||||
if not settings.YOUTUBE_API_KEY or settings.YOUTUBE_API_KEY == "REPLACE_WITH_YOUR_YOUTUBE_API_KEY":
|
||||
return None
|
||||
youtube = build('youtube', 'v3', developerKey=settings.YOUTUBE_API_KEY)
|
||||
request = youtube.search().list(
|
||||
q=query,
|
||||
part='snippet',
|
||||
maxResults=1,
|
||||
type='video'
|
||||
)
|
||||
response = request.execute()
|
||||
if response['items']:
|
||||
return response['items'][0]['id']['videoId']
|
||||
return None
|
||||
|
||||
def get_playlist_for_mood(mood):
|
||||
"""
|
||||
@ -41,7 +58,7 @@ def index(request):
|
||||
|
||||
response = LocalAIApi.create_response({
|
||||
"input": [
|
||||
{'role': 'system', 'content': 'You are a friendly AI that helps users find music based on their mood. Ask up to 6 questions to understand their mood. Once you have determined the mood, respond with ONLY a JSON object with a single key "mood" and the mood as the value (e.g. {"mood": "happy"}).'},
|
||||
{'role': 'system', 'content': 'You are a friendly AI that helps users find music based on their mood. Ask up to 6 questions to understand their mood. Once you have determined the mood, respond with ONLY a JSON object with a single key "playlist" and the value as a list of songs, where each song is a JSON object with "title" and "artist" as keys (e.g. {"playlist": [{"title": "Happy", "artist": "Pharrell Williams"}]}).'},
|
||||
*conversation
|
||||
],
|
||||
})
|
||||
@ -49,10 +66,12 @@ def index(request):
|
||||
ai_message = 'Sorry, I had an error.'
|
||||
if response.get("success"):
|
||||
json_response = LocalAIApi.decode_json_from_response(response)
|
||||
if json_response and 'mood' in json_response:
|
||||
mood = json_response['mood']
|
||||
playlist = get_playlist_for_mood(mood)
|
||||
ai_message = f"I've created a playlist for your {mood} mood. I hope you like it!"
|
||||
if json_response and 'playlist' in json_response:
|
||||
playlist = json_response['playlist']
|
||||
for song in playlist:
|
||||
video_id = youtube_search(f"{song['title']} {song['artist']}")
|
||||
song['video_id'] = video_id
|
||||
ai_message = "I've created a playlist for you. I hope you like it!"
|
||||
else:
|
||||
ai_message = LocalAIApi.extract_text(response)
|
||||
|
||||
@ -67,4 +86,4 @@ def index(request):
|
||||
else:
|
||||
# Start of a new conversation
|
||||
request.session['conversation'] = []
|
||||
return render(request, 'core/index.html', {'ai_message': 'Hi! How are you feeling today?'})
|
||||
return render(request, 'core/index.html', {'ai_message': 'Hi! How are you feeling today?'})
|
||||
@ -1,3 +1,4 @@
|
||||
Django==5.2.7
|
||||
mysqlclient==2.2.7
|
||||
python-dotenv==1.1.1
|
||||
google-api-python-client>=2.136.0
|
||||
|
||||
@ -77,7 +77,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
playlist.forEach(song => {
|
||||
const li = document.createElement('li');
|
||||
li.classList.add('playlist-item');
|
||||
li.innerHTML = `<span class="song-title">${song.title}</span> - <span class="song-artist">${song.artist}</span>`;
|
||||
if (song.video_id) {
|
||||
li.innerHTML = `<iframe width="100%" height="315" src="https://www.youtube.com/embed/${song.video_id}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`;
|
||||
} else {
|
||||
li.innerHTML = `<span class="song-title">${song.title}</span> - <span class="song-artist">${song.artist}</span> (Video not found)`;
|
||||
}
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
|
||||
@ -77,7 +77,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
playlist.forEach(song => {
|
||||
const li = document.createElement('li');
|
||||
li.classList.add('playlist-item');
|
||||
li.innerHTML = `<span class="song-title">${song.title}</span> - <span class="song-artist">${song.artist}</span>`;
|
||||
if (song.video_id) {
|
||||
li.innerHTML = `<iframe width="100%" height="315" src="https://www.youtube.com/embed/${song.video_id}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`;
|
||||
} else {
|
||||
li.innerHTML = `<span class="song-title">${song.title}</span> - <span class="song-artist">${song.artist}</span> (Video not found)`;
|
||||
}
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user