From 7d2926c0aaf14e677fd40bcfe60a2128d88571a5 Mon Sep 17 00:00:00 2001 From: Hima Verma <79623293+hima-v@users.noreply.github.com> Date: Mon, 3 Jul 2023 18:37:26 +0530 Subject: [PATCH] Automate Spotify Discover Weekly Playlist Add a python script which connects to the spotify API and integrates OAuth. Use OAuth to authenticate with Spotify, get an access token and store it in a Flask session retrieving spotify user data from the token. --- Spotify Playlist Automation/README.md | 29 +++++++ Spotify Playlist Automation/config.py | 2 + Spotify Playlist Automation/requirements.txt | 2 + .../spotify_discover_weekly.py | 81 +++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 Spotify Playlist Automation/README.md create mode 100644 Spotify Playlist Automation/config.py create mode 100644 Spotify Playlist Automation/requirements.txt create mode 100644 Spotify Playlist Automation/spotify_discover_weekly.py diff --git a/Spotify Playlist Automation/README.md b/Spotify Playlist Automation/README.md new file mode 100644 index 0000000..38d6976 --- /dev/null +++ b/Spotify Playlist Automation/README.md @@ -0,0 +1,29 @@ +# Spotify Playlist Automation + +# Description +Its an application which allows the user to automate saving the "Discover Weekly" Playlist into a new playlist called as- "Saved Weekly". Since new songs are added every week, the user wont have to add songs everytime. + +# Prerequisite tasks: +1. Make sure you have made the "Discover Weekly" Playlist public by selecting the playlist to be displayed on profile. + +2. Browse to https://developer.spotify.com/dashboard/applications. + +3. Log in with your Spotify account. + +4. Click on ‘Create an app’. + +5. Pick an ‘App name’ and ‘App description’ of your choice and mark the checkboxes. + +6. After creation, you see your ‘Client Id’ and you can click on ‘Show client secret` to unhide your ’Client secret’ + +# Getting Started + +1. Install the dependencies via the requirements txt file: + +$ pip install -r requirements.txt + +2. After installation, Update the client_id and secret_key in the configuration file to authenticate the spotipy api + +3. After updation run the file spotify_discover_weekly.py in the terminal + +4. Click on the link which is generated. It is basically running the app on the port locally. \ No newline at end of file diff --git a/Spotify Playlist Automation/config.py b/Spotify Playlist Automation/config.py new file mode 100644 index 0000000..45ea6cf --- /dev/null +++ b/Spotify Playlist Automation/config.py @@ -0,0 +1,2 @@ +client_id = "" #insert your client id +secret_key = "" #insert your secret key \ No newline at end of file diff --git a/Spotify Playlist Automation/requirements.txt b/Spotify Playlist Automation/requirements.txt new file mode 100644 index 0000000..6d69cd5 --- /dev/null +++ b/Spotify Playlist Automation/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.3.2 +spotipy==2.23.0 \ No newline at end of file diff --git a/Spotify Playlist Automation/spotify_discover_weekly.py b/Spotify Playlist Automation/spotify_discover_weekly.py new file mode 100644 index 0000000..ef74e7f --- /dev/null +++ b/Spotify Playlist Automation/spotify_discover_weekly.py @@ -0,0 +1,81 @@ +import config +import spotipy +import time +from spotipy.oauth2 import SpotifyOAuth +from flask import Flask,request,url_for,session,redirect + +app= Flask(__name__) +app.config['SESSION_COOKIE_NAME']= 'spotify cookie' +app.secret_key='10)293@han2%^s*hka02zkls' +TOKEN_INFO='token_info' +@app.route('/') +def login(): + auth_url=create_spotify_oauth().get_authorize_url() + return redirect(auth_url) + +@app.route('/redirect') +def redirect_page(): + session.clear() + code = request.args.get('code') + token_info = create_spotify_oauth().get_access_token(code) + session[TOKEN_INFO]= token_info + return redirect(url_for('save_discover_weekly', external= True)) + +@app.route('/saveDiscoverWeekly') +def save_discover_weekly(): + try: + token_info =get_token() + except: + print("User not logged in") + return redirect ('/') + sp = spotipy.Spotify(auth= token_info['access_token']) + # to get user's playlists which are public + current_playlists = sp.current_user_playlists()['items'] + discover_weekly_playlist_id = None + saved_weekly_playlist_id = None + user_id= sp.current_user()['id'] + playlist_names=[] + playlist_id=[] + k=0 + # find the Discover Weekly and Saved Weekly playlists + for playlist in current_playlists: + playlist_names.append(playlist['name']) + playlist_id.append(playlist['id']) + for playlist in playlist_names: + if playlist=='Discover Weekly': + discover_weekly_playlist_id=playlist_id[k] + if playlist== 'Saved Weekly': + saved_weekly_playlist_id=playlist_id[k] + k+=1 + if discover_weekly_playlist_id== None: + return 'Discover Weekly not found.' + if saved_weekly_playlist_id== None: + new_playlist= sp.user_playlist_create(user_id, 'Saved Weekly', True) + saved_weekly_playlist_id= new_playlist['id'] + + # get the tracks from the Discover Weekly playlist + discover_weekly_playlist = sp.playlist_items(discover_weekly_playlist_id) + song_uris = [] + for song in discover_weekly_playlist['items']: + song_uri= song['track']['uri'] + song_uris.append(song_uri) + # we need uris because when we want to add songs to the playlist, we need uris parameter + sp.user_playlist_add_tracks(user_id,saved_weekly_playlist_id,song_uris, None) + return("Playlist Update Success") + +def get_token(): + #checking two edge cases, 1. If the token is expired, 2. Token doesn't exist + token_info= session.get(TOKEN_INFO,None ) + if not token_info: + redirect_page(url_for('login', external =False)) + current_time= int(time.time()) + is_expired = token_info['expires_at'] - current_time <60 + if (is_expired): + spotify_oauth= create_spotify_oauth() + token_info= spotify_oauth.refresh_access_token(token_info['refresh_token']) + return token_info + +def create_spotify_oauth(): + return SpotifyOAuth(client_id= config.client_id, client_secret=config.secret_key, redirect_uri= url_for('redirect_page', _external= True), scope='user-library-read playlist-modify-public playlist-modify-private') + +app.run(debug=True) \ No newline at end of file