from flask import Flask, request, redirect import spotipy from spotipy.oauth2 import SpotifyOAuth import threading import os import sys import time import requests from datetime import datetime import subprocess app = Flask(__name__) stop_flask = threading.Event() client_id = "c0020cc0e05245efb2ddb61b7045e4f2" client_secret = "2e2e7c98f849403fbacc219c1f01c17d" redirect_uri = "https://elease-uncapsuled-yosef.ngrok-free.dev/callback" # Hardcoded ngrok URL sp_oauth = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope="playlist-modify-private user-library-read") # This will store whether the access token was acquired access_token_obtained = threading.Event() @app.route('/') def index(): return "Welcome! Login to Spotify" @app.route('/login') def login(): return redirect(sp_oauth.get_authorize_url()) @app.route('/callback') def callback(): code = request.args.get('code') token_info = sp_oauth.get_access_token(code) access_token = token_info['access_token'] with open("access_token.txt", "w") as f: f.write(access_token) #print("Authorization complete. You can close this window.", file=sys.stderr) # Signal that the access token has been obtained access_token_obtained.set() return "Authorization complete. You can close this window." def create_playlist(): if not os.path.exists("access_token.txt"): print("No access token found.", file=sys.stderr) return with open("access_token.txt", "r") as f: access_token = f.read().strip() sp = spotipy.Spotify(auth=access_token) print("Fetching liked songs...", file=sys.stderr) liked_songs = [] results = sp.current_user_saved_tracks() while results: for item in results['items']: liked_songs.append(item['track']['id']) if results['next']: results = sp.next(results) else: break playlist_name = datetime.now().strftime("Liked Songs Collection - %Y-%m-%d %H-%M-%S") user_id = sp.me()['id'] new_playlist = sp.user_playlist_create(user_id, playlist_name, public=False) print(f"Created playlist: {playlist_name}", file=sys.stderr) for i in range(0, len(liked_songs), 100): batch = liked_songs[i:i + 100] sp.playlist_add_items(new_playlist['id'], batch) print(f"Added {len(batch)} songs...", file=sys.stderr) playlist_url = new_playlist['external_urls']['spotify'] print(f"Playlist URL: {playlist_url}", file=sys.stderr) return playlist_url def run_flask(): with open(os.devnull, 'w') as fnull: # Redirect both stdout and stderr to devnull sys.stdout = fnull sys.stderr = fnull subprocess.run(["xdg-open", "http://192.168.0.100:8888"]) app.run(host="0.0.0.0", port=8888, use_reloader=False) # sys.stdout = sys.__stdout__ # Restore original stdout # sys.stderr = sys.__stderr__ # Restore original stderr def kill_ngrok(): try: # Find ngrok process and kill it subprocess.call(["pkill", "ngrok"]) except Exception as e: print(f"Error stopping ngrok: {str(e)}", file=sys.stderr) def main(): kill_ngrok() # Start Flask in a background thread flask_thread = threading.Thread(target=run_flask, daemon=True) flask_thread.start() # Allow some time for Flask to start time.sleep(2) # Start ngrok dynamically os.system("ngrok http 8888 &") # Allow time for ngrok to initialize time.sleep(5) # Print out the hardcoded ngrok URL print(f"Ngrok URL: {redirect_uri}", file=sys.stderr ) print("Please authorize access via the following URL:", sp_oauth.get_authorize_url(), file=sys.stderr) # Wait for the access token to be acquired access_token_obtained.wait() # Wait until the access token is provided # Now that we have the token, proceed with creating the playlist playlist_url = create_playlist() print(playlist_url) stop_flask.set() # Signal Flask to stop flask_thread.join() # Wait for the Flask thread to complete sys.exit(0) if __name__ == "__main__": main()