-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_playlist.py
145 lines (112 loc) · 3.99 KB
/
generate_playlist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import pyperclip
import pandas as pd
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from config import config
def raw_to_df(raw):
'''
Transform raw table data in <raw> to a pandas dataframe format.
Parameters
----------
raw : str
Raw data string from clipboard
Returns
-------
pandas.DataFrame
DataFrame containing the raw data in a clean table format.
'''
cols = int(input('How many columns does your data have?\n'))
raw = [line.strip() for line in raw.split('\n') if line.strip()]
df = pd.DataFrame([raw[i:i + cols] for i in range(0, len(raw), cols)])
df[df.shape[1]] = ''
print(f'\nPartial table preview ({df.shape[0]} rows in total):\n\n',
df.head(), '\n')
return df
def spotify_auth():
'''
Authenticate with Spotify API based on credentials in config.ini.
Returns
-------
spotipy.Spotify
Spotify API client object used to execute all API calls.
'''
auth = SpotifyOAuth(client_id = config.client_id,
client_secret = config.client_secret,
scope = 'playlist-modify-private',
redirect_uri = config.redirect_uri)
sp = spotipy.Spotify(auth_manager = auth)
return sp
def create_playlist(sp):
'''
Create a Spotify playlist with given name and description.
Parameters
----------
sp : spotipy.Spotify
Spotify API client object used to execute all API calls.
Returns
-------
dict
JSON response from Spotify API containing playlist metadata.
'''
name = input('Give a name for the playlist: ')
desc = input('Give a description for the playlist (optional): ')
playlist = sp.user_playlist_create(sp.me()['id'], name, description = desc,
public = False, collaborative = False)
print(f'Created playlist {name}')
return playlist
def add_uris_to_df(sp, df):
'''
Finds the songs in given dataframe and adds their Spotify URIs to
a new column in the dataframe.
Parameters
----------
sp : spotipy.Spotify
Spotify API client object used to execute all API calls.
df : pandas.DataFrame
DataFrame containing the raw data in a clean table format.
Returns
-------
pandas.DataFrame
Raw data in a clean table format augmented with Spotify song URIs.
'''
song_col = int(input(f'Which column has the song names? '
+ f'(0-{df.shape[1] - 1}): '))
artist_col = int(input(f'Which column has the artist names? '
+ f'(0-{df.shape[1] - 1}): '))
for idx, row in df.iterrows():
result = sp.search(f'{row[artist_col]} {row[song_col]}', limit = 1)
result = result["tracks"]["items"][0]
print(f'Found the song {result["artists"][0]["name"][:40]:40} '
+ f'{result["name"][:40]:40} {result["uri"]}')
df.iloc[idx, df.shape[1] - 1] = result["uri"]
return df
def add_songs_to_playlist(sp, df, playlist):
'''
Add songs from the dataframe to given Spotify playlist.
Parameters
----------
sp : spotipy.Spotify
Spotify API client object used to execute all API calls.
df : pandas.DataFrame
Raw data in a clean table format augmented with Spotify song URIs.
playlist : dict
JSON response from Spotify API containing playlist metadata.
Returns
-------
None
'''
print(f'Adding items to playlist {playlist["name"]}')
sp.playlist_add_items(playlist['id'], df[df.shape[1] - 1].tolist())
return None
if __name__ == '__main__':
raw = pyperclip.paste()
if raw == '':
print('Clipboard is empty. '
+ 'Copy a table to clipboard and restart the script.')
else:
df = raw_to_df(raw)
sp = spotify_auth()
playlist = create_playlist(sp)
df = add_uris_to_df(sp, df)
add_songs_to_playlist(sp, df, playlist)
print("Finished buildng the playlist.")