Skip to content

Commit c76b601

Browse files
authored
Spotify Player
A spotify player and playlist generator made 100% in python
1 parent b798fdb commit c76b601

3 files changed

Lines changed: 391 additions & 0 deletions

File tree

projects/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Spotify Playlist Generator
2+
![Current Version](https://img.shields.io/badge/version-1.0.7-green.svg)
3+
4+
Spotipy's full documentation is online at [Spotipy Documentation](http://spotipy.readthedocs.org/).
5+
6+
## Features:
7+
1. Play a song via your terminal
8+
- Enter a song name and it will start playing in your spotify application
9+
2. Get recommended a song based off of user input
10+
- Enter 3 songs and it will generate a song based off of your input
11+
3. Get a generated playlist made off of an existing playlist
12+
- Enter a playlist url and it will generate a brand new playlist with similar songs
13+
14+
<img width="509" alt="image" src="https://user-images.githubusercontent.com/106450097/210877746-35c683d3-00cc-4cfe-91c9-5b29f2a9611c.png">
15+
<img width="1038" alt="Screen Shot 2023-01-05 at 12 52 46 PM" src="https://user-images.githubusercontent.com/106450097/210877856-1c095c39-55d7-449b-9045-c7c3b8cc38c0.png">
16+
17+
# Getting started:
18+
## Create a user_secrets file
19+
1. Create a `utils` folder
20+
2. Add `user_secrets.py to` that folder
21+
3. Enter the following code into that file
22+
```py
23+
username = "YOUR-USERNAME-ID"
24+
clientID = "YOUR-CLIENT-ID"
25+
clientSecret = "YOUR-CLIENT-SECRET"
26+
redirectURI = "YOUR-REDIRECT-URI"
27+
28+
banner = """Welcome, {}!
29+
---------------------------------------
30+
| 0 | Exit |
31+
| 1 | Play a Song |
32+
| 2 | Get a song recommendation |
33+
| 3 | Generate a new playlist |
34+
---------------------------------------"""
35+
```
36+
37+
## How to get secrets:
38+
A full set of examples can be found in the [online documentation](http://spotipy.readthedocs.org/) and in the [Spotipy examples directory](https://github.com/plamere/spotipy/tree/master/examples).
39+
40+
To get started, install spotipy and create an app on https://developers.spotify.com/.
41+
Add your new ID and SECRET to your environment:
42+
43+
## Reporting issues:
44+
If you find any bugs, leave a comment or a pull request

projects/main.py

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
############################
2+
# MADE BY: OMKAR PATEL #
3+
############################
4+
5+
import os
6+
import time
7+
import random
8+
import string
9+
import spotipy
10+
import webbrowser
11+
import spotipy.util as util
12+
from colorama import Fore as fore
13+
from twilio.rest import Client
14+
15+
16+
###########################################
17+
# CONFIG VALUES -> README.md for setup #
18+
###########################################
19+
20+
try:
21+
from utils.user_secrets import username, clientID, clientSecret, redirectURI, banner, account_sid, auth_token , acc_number
22+
except:
23+
print("Error: utils/user_secrets.py NOT found\nView https://github.com/omkarxpatel/Spotify-Playlist-Generator#getting-started")
24+
25+
###########################
26+
# CHECKLIST FUNCTIONS #
27+
###########################
28+
29+
not_completed = "❌"
30+
completed = "✅"
31+
working = "⏳"
32+
33+
topbot = "--------------------------------------------"
34+
step1 = f"| {not_completed} | Extracting songs | |"
35+
step2 = f"| {not_completed} | Extracting song-ids | |"
36+
step3 = f"| {not_completed} | Generating songs | |"
37+
step4 = f"| {not_completed} | Adding songs | |"
38+
step5 = f"| {not_completed} | Playlist finished | |"
39+
40+
41+
def checklist_helper(task):
42+
task = int(task)
43+
taskTime = round(time.time()-task,2)
44+
spacing = " "*(6-len(str(taskTime)))
45+
46+
return([taskTime, spacing])
47+
48+
49+
def checklist(step, working_bool=None, task=None):
50+
clear(0)
51+
global step1,step2,step3,step4,step5
52+
53+
value = completed
54+
if working_bool == True:
55+
value = working
56+
57+
if step == 1:
58+
if task:
59+
val = checklist_helper(task)
60+
step1 = f"| {value} | Extracting songs | ({val[0]}s){val[1]}|"
61+
62+
elif step == 2:
63+
if task:
64+
val = checklist_helper(task)
65+
step2 = f"| {value} | Extracting song-ids | ({val[0]}s){val[1]}|"
66+
67+
elif step == 3:
68+
if task:
69+
val = checklist_helper(task)
70+
step3 = f"| {value} | Generating songs | ({val[0]}s){val[1]}|"
71+
72+
elif step == 4:
73+
if task:
74+
val = checklist_helper(task)
75+
step4 = f"| {value} | Adding songs | ({val[0]}s){val[1]}|"
76+
77+
elif step == 5:
78+
if task:
79+
val = checklist_helper(task)
80+
step5 = f"| {value} | Playlist finished | ({val[0]}s){val[1]}|"
81+
82+
83+
print(topbot); print(step1); print(step2); print(step3); print(step4); print(step5); print(topbot)
84+
85+
########################
86+
# HELPER FUNCTIONS #
87+
########################
88+
89+
def roundPlaylistLen(val):
90+
return (val+(20-val%20))/4
91+
92+
def isvalid(option, min, max):
93+
return min <= option <= max
94+
95+
def raiseError(error):
96+
print(f"{fore.RED}Error: {fore.RESET}{error}")
97+
98+
def clear(val):
99+
if val != 0:
100+
time.sleep(val)
101+
os.system("clear")
102+
103+
###################
104+
# PLAY A SONG #
105+
###################
106+
107+
def playSong(spotifyObject, searchQuery):
108+
searchResults = spotifyObject.search(searchQuery,1,0,"track")
109+
track = searchResults["tracks"]["items"][0]
110+
111+
openSong = input("Would you like to open this song in your browser [yes/no]: ").lower()
112+
song = searchResults["tracks"]["items"][0]["external_urls"]["spotify"]
113+
114+
if openSong in ["y","yes"]:
115+
try:
116+
webbrowser.open(song)
117+
except:
118+
raiseError(f"Could not open: {song}")
119+
120+
print(f"{fore.GREEN}✅ Playing {track['name']} - {track['artists'][0]['name']}{fore.RESET}")
121+
122+
scope = "user-modify-playback-state"
123+
token = util.prompt_for_user_token(username, scope, client_id=clientID, client_secret=clientSecret, redirect_uri=redirectURI)
124+
125+
sp = spotipy.Spotify(auth=token)
126+
sp.start_playback(uris=[song])
127+
128+
##############################
129+
# GET A RECOMMENDED SONG #
130+
##############################
131+
132+
def recommendSong(spotifyObject, song1, song2, song3):
133+
134+
results_1 = spotifyObject.search(q=song1, type="track")
135+
song_1_id = results_1["tracks"]["items"][0]["id"]
136+
137+
results_2 = spotifyObject.search(q=song2, type="track")
138+
song_2_id = results_2["tracks"]["items"][0]["id"]
139+
140+
results_3 = spotifyObject.search(q=song3, type="track")
141+
song_3_id = results_3["tracks"]["items"][0]["id"]
142+
143+
144+
recommendations = spotifyObject.recommendations(seed_tracks=[song_1_id, song_2_id, song_3_id])
145+
recommended_song = recommendations["tracks"][0]["name"]
146+
recommended_song_id = recommendations["tracks"][0]["id"]
147+
recommended_song_url = recommendations["tracks"][0]["external_urls"]["spotify"]
148+
149+
track = spotifyObject.track(recommended_song_id)
150+
artist = track["artists"][0]["name"]
151+
152+
print(f"\nRecommended song: {recommended_song} - {artist}")
153+
play = input("Would you like to play this song [yes/no]: ").lower()
154+
155+
if play in ["y","yes"]:
156+
157+
print(f"{fore.GREEN}✅ Playing {recommended_song} - {artist}{fore.RESET}")
158+
159+
scope = "user-modify-playback-state"
160+
token = util.prompt_for_user_token(username, scope, client_id=clientID, client_secret=clientSecret, redirect_uri=redirectURI)
161+
162+
sp = spotipy.Spotify(auth=token)
163+
sp.start_playback(uris=[recommended_song_url])
164+
165+
#########################
166+
# GENERATE PLAYLIST #
167+
#########################
168+
169+
def generate_similar_playlist(spotifyObject, playlist_url):
170+
tasktime = time.time()
171+
172+
checklist(0, task=tasktime)
173+
checklist(1, True)
174+
onetime = time.time()
175+
176+
playlist_id = playlist_url.split("/")[-1]
177+
playlist = spotifyObject.playlist(playlist_id)
178+
179+
song_names = []
180+
tracks = playlist['tracks']
181+
182+
for z in range(len(tracks['items'])):
183+
item = tracks['items'][z]
184+
song_names.append(item['track']['name'])
185+
186+
checklist(1, True, task=tasktime)
187+
188+
checklist(1, task=onetime)
189+
checklist(2, True)
190+
twotime = time.time()
191+
192+
song_ids = []
193+
total_songs = []
194+
195+
for z in range(len(song_names)):
196+
item = song_names[z]
197+
result = spotifyObject.search(q=item, type="track")
198+
song_id = result["tracks"]["items"][0]["id"]
199+
200+
song_ids.append(song_id)
201+
checklist(2, True, task=twotime)
202+
203+
204+
checklist(2, task=twotime)
205+
checklist(3, True)
206+
threetime = time.time()
207+
208+
for _ in range(int(roundPlaylistLen(len(song_ids))/4)):
209+
recommendations = spotifyObject.recommendations(limit=20, seed_tracks=random.sample(song_ids, 5))
210+
211+
for y in range(len(recommendations["tracks"])):
212+
song = recommendations["tracks"][y]["name"]
213+
song_uri = recommendations["tracks"][y]["uri"]
214+
215+
value = f"{song}:{song_uri}"
216+
total_songs.append(value)
217+
checklist(3, True, task=threetime)
218+
219+
scope = 'playlist-modify-public playlist-modify-private'
220+
token = util.prompt_for_user_token(username, scope, client_id=clientID, client_secret=clientSecret, redirect_uri=redirectURI)
221+
sp = spotipy.Spotify(auth=token)
222+
223+
generated_name = ''.join(random.choices(string.ascii_letters, k=10))
224+
gen_playlist = sp.user_playlist_create(username, name=generated_name)
225+
gen_playlist_id = gen_playlist['id']
226+
227+
checklist(3, task=threetime)
228+
checklist(4, True)
229+
fourtime = time.time()
230+
231+
for item in total_songs:
232+
item = item.split(":")
233+
234+
sp.user_playlist_add_tracks(username, gen_playlist_id, [item[-1]])
235+
checklist(4, True, task=fourtime)
236+
237+
238+
checklist(4, task=fourtime)
239+
checklist(5, True)
240+
241+
time.sleep(1)
242+
checklist(5, task=tasktime)
243+
244+
245+
print(f"Generated playlist: {generated_name}")
246+
print(f"Playlist URL: {gen_playlist['external_urls']['spotify']}")
247+
248+
client = Client(account_sid, auth_token)
249+
250+
message = client.messages.create(
251+
to=acc_number,
252+
from_="+19295773793",
253+
body=f"Your generated playlist is: {gen_playlist['external_urls']['spotify']}")
254+
print(f"Message SID: {message.sid}")
255+
256+
####################
257+
# MAIN STARTER #
258+
####################
259+
260+
def main():
261+
spotifyObject = spotipy.Spotify(auth=spotipy.SpotifyOAuth(clientID,clientSecret,redirectURI).get_access_token()["access_token"])
262+
user = spotifyObject.current_user()
263+
clear(0)
264+
265+
while True:
266+
print(banner.format(user["display_name"]))
267+
268+
while True:
269+
choice = input("Enter a choice: ")
270+
271+
272+
try:
273+
choice = int(choice)
274+
except:
275+
raiseError(f"\"{choice}\" is not an integer")
276+
clear(5)
277+
278+
if isvalid(choice, 0, 4):
279+
clear(0); break
280+
281+
if choice == 0:
282+
clear(0); exit()
283+
284+
elif choice == 1:
285+
searchQuery = input("Enter Song Name: ")
286+
playSong(spotifyObject, searchQuery)
287+
288+
elif choice == 2:
289+
values = []
290+
for x in range(3):
291+
value = input(f"Enter song {x+1}: ")
292+
values.append(value)
293+
294+
recommendSong(spotifyObject, values[0],values[1],values[2])
295+
296+
elif choice == 3:
297+
playlistUrl = input("Enter playlist url: ")
298+
generate_similar_playlist(spotifyObject, playlistUrl)
299+
300+
# DEBUG COMMAND
301+
elif choice == 10:
302+
scope = 'playlist-modify-public playlist-modify-private'
303+
token = util.prompt_for_user_token(username, scope, client_id=clientID, client_secret=clientSecret, redirect_uri=redirectURI)
304+
sp = spotipy.Spotify(auth=token)
305+
306+
generated_name = ''.join(random.choices(string.ascii_letters, k=10))
307+
308+
gen_playlist = sp.user_playlist_create(username, name=generated_name)
309+
gen_playlist_id = gen_playlist['id']
310+
311+
song = input("Enter song name: ")
312+
results = sp.search(q=song, type='track')
313+
314+
song_uri = results["tracks"]["items"][0]["uri"]
315+
316+
sp.user_playlist_add_tracks(username, gen_playlist_id, [song_uri])
317+
318+
print(f"Generated playlist - {generated_name}")
319+
320+
321+
322+
repeat = input("\nWould you like to try again [yes/no]: ").lower()
323+
if repeat in ["y","yes"]:
324+
clear(3)
325+
326+
else:
327+
exit()
328+
329+
main()

projects/user_secrets_example.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
username = "username"
2+
clientID = "client_id"
3+
clientSecret = "client_secret"
4+
redirectURI = "your_redirect_url"
5+
6+
# Your Account SID from twilio.com/console
7+
account_sid = "acc_sid"
8+
# Your Auth Token from twilio.com/console
9+
auth_token = "auth_token"
10+
# Your phone number
11+
acc_number = "phone number"
12+
13+
banner = """Welcome, {}!
14+
---------------------------------------
15+
| 1 | Play a Song by its name |
16+
| 2 | Get a song recommendation |
17+
| 3 | Generate a new playlist |
18+
---------------------------------------"""

0 commit comments

Comments
 (0)