Remove MusicBrainz/YT verification (async greenlet conflict), use direct YouTube Music search links
This commit is contained in:
@@ -188,7 +188,7 @@ Already in their library (do NOT recommend these):
|
||||
{disliked_instruction}
|
||||
{exclude_instruction}
|
||||
|
||||
Respond with exactly {count * 3} music recommendations as a JSON array. Give more than requested so we can verify they exist. Each item should have:
|
||||
Respond with exactly {count} music recommendations as a JSON array. Only recommend songs that actually exist — do not invent or guess song titles. Each item should have:
|
||||
- "title": song title
|
||||
- "artist": artist name
|
||||
- "album": album name (if known)
|
||||
@@ -218,48 +218,7 @@ Return ONLY the JSON array, no other text."""
|
||||
except json.JSONDecodeError:
|
||||
return [], remaining
|
||||
|
||||
# Verify recommendations exist using MusicBrainz, get YouTube Music links
|
||||
import asyncio
|
||||
from app.services.musicbrainz import verify_track as mb_verify
|
||||
from app.services.youtube_music import search_track as yt_search
|
||||
|
||||
def verify_and_link(artist: str, title: str) -> dict | None:
|
||||
"""Verify track on MusicBrainz, then get YouTube Music link."""
|
||||
# Step 1: Verify on MusicBrainz
|
||||
mb_result = mb_verify(artist, title)
|
||||
if not mb_result:
|
||||
return None
|
||||
|
||||
real_artist = mb_result["artist"]
|
||||
real_title = mb_result["title"]
|
||||
album = mb_result.get("album")
|
||||
|
||||
# Step 2: Get YouTube Music link for listening
|
||||
youtube_url = None
|
||||
image_url = None
|
||||
try:
|
||||
yt_results = yt_search(f"{real_artist} {real_title}")
|
||||
if yt_results:
|
||||
yt = yt_results[0]
|
||||
yt_id = yt.get("youtube_id")
|
||||
if yt_id:
|
||||
youtube_url = f"https://music.youtube.com/watch?v={yt_id}"
|
||||
image_url = yt.get("image_url")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not youtube_url:
|
||||
youtube_url = f"https://www.youtube.com/results?search_query={quote_plus(f'{real_artist} {real_title}')}"
|
||||
|
||||
return {
|
||||
"artist": real_artist,
|
||||
"title": real_title,
|
||||
"album": album,
|
||||
"youtube_url": youtube_url,
|
||||
"image_url": image_url,
|
||||
}
|
||||
|
||||
# Save to DB — only keep verified tracks
|
||||
# Save to DB with YouTube Music links
|
||||
recommendations = []
|
||||
for rec in recs_data:
|
||||
if len(recommendations) >= count:
|
||||
@@ -269,23 +228,18 @@ Return ONLY the JSON array, no other text."""
|
||||
title = rec.get("title", "Unknown")
|
||||
reason = rec.get("reason", "")
|
||||
|
||||
# Verify on MusicBrainz + get YouTube link (sync, run in thread)
|
||||
verified = await asyncio.to_thread(verify_and_link, artist, title)
|
||||
|
||||
if not verified:
|
||||
continue # Song doesn't exist — AI hallucinated it
|
||||
youtube_url = f"https://music.youtube.com/search?q={quote_plus(f'{artist} {title}')}"
|
||||
|
||||
r = Recommendation(
|
||||
user_id=user.id,
|
||||
playlist_id=playlist_id,
|
||||
title=verified["title"],
|
||||
artist=verified["artist"],
|
||||
album=verified.get("album") or rec.get("album"),
|
||||
image_url=verified.get("image_url"),
|
||||
title=title,
|
||||
artist=artist,
|
||||
album=rec.get("album"),
|
||||
reason=reason,
|
||||
score=rec.get("score"),
|
||||
query=query,
|
||||
youtube_url=verified["youtube_url"],
|
||||
youtube_url=youtube_url,
|
||||
)
|
||||
db.add(r)
|
||||
recommendations.append(r)
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function Discover() {
|
||||
const response = await generateRecommendations(
|
||||
selectedPlaylist || undefined,
|
||||
query.trim() || undefined,
|
||||
bandcampMode,
|
||||
false,
|
||||
mode,
|
||||
adventurousness,
|
||||
excludeGenres.trim() || undefined,
|
||||
@@ -78,14 +78,16 @@ export default function Discover() {
|
||||
const recs = response.recommendations || []
|
||||
setResults(recs)
|
||||
setRemaining(response.remaining_this_week ?? null)
|
||||
if (recs.length === 0) {
|
||||
setError(`Got 0 results back from API. Raw response keys: ${Object.keys(response).join(', ')}`)
|
||||
}
|
||||
// Scroll to results after render
|
||||
if (recs.length > 0) {
|
||||
setTimeout(() => resultsRef.current?.scrollIntoView({ behavior: 'smooth' }), 100)
|
||||
}
|
||||
} catch (err: any) {
|
||||
setError(
|
||||
err.response?.data?.detail || 'Failed to generate recommendations. Please try again.'
|
||||
)
|
||||
const msg = err.response?.data?.detail || err.message || 'Unknown error'
|
||||
setError(`Error: ${msg} (status: ${err.response?.status || 'none'})`)
|
||||
} finally {
|
||||
setDiscovering(false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user