|
| 1 | +# Ambient music mapper: maps a parsed mood query to a curated open |
| 2 | +# Spotify playlist. Pure keyword matching on the moods/themes already |
| 3 | +# extracted by MoodQueryParser - no extra LLM call, no external API. |
| 4 | + |
| 5 | +from typing import Dict, Optional |
| 6 | + |
| 7 | +# ponytail: static curated list; swap in Spotify API search if curation matters later. |
| 8 | +MOOD_PLAYLISTS = [ |
| 9 | + # (keywords over moods+themes+raw query, genre label, playlist embed URL) |
| 10 | + ( |
| 11 | + {"dark", "mysterious", "gothic", "melancholic"}, |
| 12 | + "Dark Academia Jazz", |
| 13 | + "https://open.spotify.com/embed/playlist/37i9dQZF1DX4sWSpwq3LiO", |
| 14 | + ), |
| 15 | + ( |
| 16 | + {"cozy"}, |
| 17 | + "Cozy Reading Cafe", |
| 18 | + "https://open.spotify.com/embed/playlist/37i9dQZF1DX4WYpdgoIcn6", |
| 19 | + ), |
| 20 | + ( |
| 21 | + {"whimsical", "uplifting"}, |
| 22 | + "Whimsical & Light", |
| 23 | + "https://open.spotify.com/embed/playlist/37i9dQZF1DX7EF8wVxBVhG", |
| 24 | + ), |
| 25 | + ( |
| 26 | + {"atmospheric", "thoughtful"}, |
| 27 | + "Classical Reading", |
| 28 | + "https://open.spotify.com/embed/playlist/37i9dQZF1DX8ymr6UES7vc", |
| 29 | + ), |
| 30 | +] |
| 31 | + |
| 32 | +DEFAULT_PLAYLIST = ( |
| 33 | + {"genre": "Lo-Fi Reading Chill", |
| 34 | + "spotify_embed_url": "https://open.spotify.com/embed/playlist/37i9dQZF1DX889Y07vA7vH"} |
| 35 | +) |
| 36 | + |
| 37 | + |
| 38 | +def get_ambient_music(query: str, primary_moods=None) -> Dict: |
| 39 | + """Return an ambient_music payload for a mood query.""" |
| 40 | + haystack = set((primary_moods or [])) |
| 41 | + tokens = {t.strip(".,!?") for t in query.lower().split()} |
| 42 | + haystack |= tokens |
| 43 | + |
| 44 | + best: Optional[tuple] = None |
| 45 | + best_score = 0 |
| 46 | + for keywords, genre, url in MOOD_PLAYLISTS: |
| 47 | + score = len(keywords & haystack) |
| 48 | + if score > best_score: |
| 49 | + best_score = score |
| 50 | + best = (genre, url) |
| 51 | + |
| 52 | + if best: |
| 53 | + return {"genre": best[0], "spotify_embed_url": best[1]} |
| 54 | + return dict(DEFAULT_PLAYLIST) |
| 55 | + |
| 56 | + |
| 57 | +def self_check(): |
| 58 | + assert get_ambient_music("cozy autumn night with warm tea")["genre"] == "Cozy Reading Cafe" |
| 59 | + assert get_ambient_music("dark academia gothic mystery")["genre"] == "Dark Academia Jazz" |
| 60 | + assert get_ambient_music("something random")["genre"] == DEFAULT_PLAYLIST["genre"] |
| 61 | + r = get_ambient_music("cozy", ["cozy"]) |
| 62 | + assert r["spotify_embed_url"].startswith("https://open.spotify.com/embed/") |
| 63 | + print("ambient_music self-check passed") |
| 64 | + |
| 65 | + |
| 66 | +if __name__ == "__main__": |
| 67 | + self_check() |
0 commit comments