mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
129 lines
5.6 KiB
Python
129 lines
5.6 KiB
Python
import spotipy
|
|
from spotipy.oauth2 import SpotifyOAuth
|
|
import logging
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
# Setup basic logging
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
|
# Define paths relative to this file's location (assuming it's in src)
|
|
CONFIG_DIR = os.path.join(os.path.dirname(__file__), '..', 'config')
|
|
SECRETS_PATH = os.path.join(CONFIG_DIR, 'config_secrets.json')
|
|
SPOTIFY_AUTH_CACHE_PATH = os.path.join(CONFIG_DIR, 'spotify_auth.json') # Explicit cache path
|
|
|
|
# Resolve to absolute paths
|
|
CONFIG_DIR = os.path.abspath(CONFIG_DIR)
|
|
SECRETS_PATH = os.path.abspath(SECRETS_PATH)
|
|
SPOTIFY_AUTH_CACHE_PATH = os.path.abspath(SPOTIFY_AUTH_CACHE_PATH)
|
|
|
|
SCOPE = "user-read-currently-playing user-read-playback-state"
|
|
|
|
def load_spotify_credentials():
|
|
"""Loads Spotify credentials from config_secrets.json."""
|
|
if not os.path.exists(SECRETS_PATH):
|
|
logging.error(f"Secrets file not found at {SECRETS_PATH}")
|
|
return None, None, None
|
|
|
|
try:
|
|
with open(SECRETS_PATH, 'r') as f:
|
|
secrets = json.load(f)
|
|
music_secrets = secrets.get("music", {})
|
|
client_id = music_secrets.get("SPOTIFY_CLIENT_ID")
|
|
client_secret = music_secrets.get("SPOTIFY_CLIENT_SECRET")
|
|
redirect_uri = music_secrets.get("SPOTIFY_REDIRECT_URI")
|
|
if not all([client_id, client_secret, redirect_uri]):
|
|
logging.error("One or more Spotify credentials missing in config_secrets.json under the 'music' key.")
|
|
return None, None, None
|
|
return client_id, client_secret, redirect_uri
|
|
except json.JSONDecodeError:
|
|
logging.error(f"Error decoding JSON from {SECRETS_PATH}")
|
|
return None, None, None
|
|
except Exception as e:
|
|
logging.error(f"Error loading Spotify credentials: {e}")
|
|
return None, None, None
|
|
|
|
if __name__ == "__main__":
|
|
logging.info("Starting Spotify Authentication Process...")
|
|
|
|
client_id, client_secret, redirect_uri = load_spotify_credentials()
|
|
|
|
if not all([client_id, client_secret, redirect_uri]):
|
|
logging.error("Could not load Spotify credentials. Please check config/config_secrets.json. Exiting.")
|
|
sys.exit(1)
|
|
|
|
# Ensure the config directory exists for the cache file
|
|
if not os.path.exists(CONFIG_DIR):
|
|
try:
|
|
logging.info(f"Config directory {CONFIG_DIR} not found. Attempting to create it.")
|
|
os.makedirs(CONFIG_DIR)
|
|
logging.info(f"Successfully created config directory: {CONFIG_DIR}")
|
|
except OSError as e:
|
|
logging.error(f"Fatal: Could not create config directory {CONFIG_DIR}: {e}. Please create it manually. Exiting.")
|
|
sys.exit(1)
|
|
|
|
sp_oauth = SpotifyOAuth(
|
|
client_id=client_id,
|
|
client_secret=client_secret,
|
|
redirect_uri=redirect_uri,
|
|
scope=SCOPE,
|
|
cache_path=SPOTIFY_AUTH_CACHE_PATH, # Use explicit cache path
|
|
open_browser=False
|
|
)
|
|
|
|
# Step 1: Get the authorization URL
|
|
auth_url = sp_oauth.get_authorize_url()
|
|
print("-" * 50)
|
|
print("SPOTIFY AUTHORIZATION NEEDED:")
|
|
print("1. Please visit this URL in a browser (on any device):")
|
|
print(f" {auth_url}")
|
|
print("2. Authorize the application.")
|
|
print("3. You will be redirected to a URL (likely showing an error). Copy that FULL redirected URL.")
|
|
print("-" * 50)
|
|
|
|
# Step 2: Get the redirected URL from the user
|
|
redirected_url = input("4. Paste the full redirected URL here and press Enter: ").strip()
|
|
|
|
if not redirected_url:
|
|
logging.error("No redirected URL provided. Exiting.")
|
|
sys.exit(1)
|
|
|
|
# Step 3: Parse the code from the redirected URL
|
|
try:
|
|
# Spotipy's parse_auth_response_url is not directly part of the public API of SpotifyOAuth
|
|
# for this specific flow where we manually handle the redirect.
|
|
# We need to extract the 'code' query parameter.
|
|
# A more robust way would be to use urllib.parse, but for simplicity:
|
|
if "?code=" in redirected_url:
|
|
auth_code = redirected_url.split("?code=")[1].split("&")[0]
|
|
elif "&code=" in redirected_url: # Should not happen if code is first param
|
|
auth_code = redirected_url.split("&code=")[1].split("&")[0]
|
|
else:
|
|
logging.error("Could not find 'code=' in the redirected URL. Please ensure you copied the full URL.")
|
|
logging.error(f"Received URL: {redirected_url}")
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
logging.error(f"Error parsing authorization code from redirected URL: {e}")
|
|
logging.error(f"Received URL: {redirected_url}")
|
|
sys.exit(1)
|
|
|
|
# Step 4: Get the access token using the code and cache it
|
|
try:
|
|
# check_cache=False forces it to use the provided code rather than a potentially stale cached one for this specific step.
|
|
# The token will still be written to the cache_path.
|
|
token_info = sp_oauth.get_access_token(auth_code, check_cache=False)
|
|
if token_info:
|
|
logging.info(f"Spotify authentication successful. Token info cached at {SPOTIFY_AUTH_CACHE_PATH}")
|
|
else:
|
|
logging.error("Failed to obtain Spotify token info with the provided code.")
|
|
logging.error("Please ensure the code was correct and not expired.")
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
logging.error(f"Error obtaining Spotify access token: {e}")
|
|
logging.error("This can happen if the authorization code is incorrect, expired, or already used.")
|
|
sys.exit(1)
|
|
|
|
logging.info("Spotify Authentication Process Finished.") |