258 lines
13 KiB
Python
Executable File
258 lines
13 KiB
Python
Executable File
import os
|
|
import json
|
|
import traceback
|
|
from deezspot.spotloader import SpoLogin
|
|
from deezspot.deezloader import DeeLogin
|
|
from pathlib import Path
|
|
|
|
def download_album(
|
|
url,
|
|
main,
|
|
fallback=None,
|
|
quality=None,
|
|
fall_quality=None,
|
|
real_time=False,
|
|
custom_dir_format="%ar_album%/%album%/%copyright%",
|
|
custom_track_format="%tracknum%. %music% - %artist%",
|
|
pad_tracks=True,
|
|
save_cover=True,
|
|
initial_retry_delay=5,
|
|
retry_delay_increase=5,
|
|
max_retries=3,
|
|
progress_callback=None,
|
|
convert_to=None,
|
|
bitrate=None
|
|
):
|
|
try:
|
|
# Detect URL source (Spotify or Deezer) from URL
|
|
is_spotify_url = 'open.spotify.com' in url.lower()
|
|
is_deezer_url = 'deezer.com' in url.lower()
|
|
|
|
# Determine service exclusively from URL
|
|
if is_spotify_url:
|
|
service = 'spotify'
|
|
elif is_deezer_url:
|
|
service = 'deezer'
|
|
else:
|
|
# If URL can't be detected, raise an error
|
|
error_msg = "Invalid URL: Must be from open.spotify.com or deezer.com"
|
|
print(f"ERROR: {error_msg}")
|
|
raise ValueError(error_msg)
|
|
|
|
print(f"DEBUG: album.py - URL detection: is_spotify_url={is_spotify_url}, is_deezer_url={is_deezer_url}")
|
|
print(f"DEBUG: album.py - Service determined from URL: {service}")
|
|
print(f"DEBUG: album.py - Credentials: main={main}, fallback={fallback}")
|
|
|
|
# Load Spotify client credentials if available
|
|
spotify_client_id = None
|
|
spotify_client_secret = None
|
|
|
|
# Smartly determine where to look for Spotify search credentials
|
|
if service == 'spotify' and fallback:
|
|
# If fallback is enabled, use the fallback account for Spotify search credentials
|
|
search_creds_path = Path(f'./data/creds/spotify/{fallback}/search.json')
|
|
print(f"DEBUG: Using Spotify search credentials from fallback: {search_creds_path}")
|
|
else:
|
|
# Otherwise use the main account for Spotify search credentials
|
|
search_creds_path = Path(f'./data/creds/spotify/{main}/search.json')
|
|
print(f"DEBUG: Using Spotify search credentials from main: {search_creds_path}")
|
|
|
|
if search_creds_path.exists():
|
|
try:
|
|
with open(search_creds_path, 'r') as f:
|
|
search_creds = json.load(f)
|
|
spotify_client_id = search_creds.get('client_id')
|
|
spotify_client_secret = search_creds.get('client_secret')
|
|
print(f"DEBUG: Loaded Spotify client credentials successfully")
|
|
except Exception as e:
|
|
print(f"Error loading Spotify search credentials: {e}")
|
|
|
|
# For Spotify URLs: check if fallback is enabled, if so use the fallback logic,
|
|
# otherwise download directly from Spotify
|
|
if service == 'spotify':
|
|
if fallback:
|
|
if quality is None:
|
|
quality = 'FLAC'
|
|
if fall_quality is None:
|
|
fall_quality = 'HIGH'
|
|
|
|
# First attempt: use DeeLogin's download_albumspo with the 'main' (Deezer credentials)
|
|
deezer_error = None
|
|
try:
|
|
# Load Deezer credentials from 'main' under deezer directory
|
|
deezer_creds_dir = os.path.join('./data/creds/deezer', main)
|
|
deezer_creds_path = os.path.abspath(os.path.join(deezer_creds_dir, 'credentials.json'))
|
|
|
|
# DEBUG: Print Deezer credential paths being used
|
|
print(f"DEBUG: Looking for Deezer credentials at:")
|
|
print(f"DEBUG: deezer_creds_dir = {deezer_creds_dir}")
|
|
print(f"DEBUG: deezer_creds_path = {deezer_creds_path}")
|
|
print(f"DEBUG: Directory exists = {os.path.exists(deezer_creds_dir)}")
|
|
print(f"DEBUG: Credentials file exists = {os.path.exists(deezer_creds_path)}")
|
|
|
|
# List available directories to compare
|
|
print(f"DEBUG: Available Deezer credential directories:")
|
|
for dir_name in os.listdir('./data/creds/deezer'):
|
|
print(f"DEBUG: ./data/creds/deezer/{dir_name}")
|
|
|
|
with open(deezer_creds_path, 'r') as f:
|
|
deezer_creds = json.load(f)
|
|
# Initialize DeeLogin with Deezer credentials and Spotify client credentials
|
|
dl = DeeLogin(
|
|
arl=deezer_creds.get('arl', ''),
|
|
spotify_client_id=spotify_client_id,
|
|
spotify_client_secret=spotify_client_secret,
|
|
progress_callback=progress_callback
|
|
)
|
|
print(f"DEBUG: Starting album download using Deezer credentials (download_albumspo)")
|
|
# Download using download_albumspo; pass real_time_dl accordingly and the custom formatting
|
|
dl.download_albumspo(
|
|
link_album=url,
|
|
output_dir="./downloads",
|
|
quality_download=quality,
|
|
recursive_quality=True,
|
|
recursive_download=False,
|
|
not_interface=False,
|
|
make_zip=False,
|
|
custom_dir_format=custom_dir_format,
|
|
custom_track_format=custom_track_format,
|
|
pad_tracks=pad_tracks,
|
|
save_cover=save_cover,
|
|
initial_retry_delay=initial_retry_delay,
|
|
retry_delay_increase=retry_delay_increase,
|
|
max_retries=max_retries,
|
|
convert_to=convert_to,
|
|
bitrate=bitrate
|
|
)
|
|
print(f"DEBUG: Album download completed successfully using Deezer credentials")
|
|
except Exception as e:
|
|
deezer_error = e
|
|
# Immediately report the Deezer error
|
|
print(f"ERROR: Deezer album download attempt failed: {e}")
|
|
traceback.print_exc()
|
|
print("Attempting Spotify fallback...")
|
|
|
|
# Load fallback Spotify credentials and attempt download
|
|
try:
|
|
spo_creds_dir = os.path.join('./data/creds/spotify', fallback)
|
|
spo_creds_path = os.path.abspath(os.path.join(spo_creds_dir, 'credentials.json'))
|
|
|
|
print(f"DEBUG: Using Spotify fallback credentials from: {spo_creds_path}")
|
|
print(f"DEBUG: Fallback credentials exist: {os.path.exists(spo_creds_path)}")
|
|
|
|
# We've already loaded the Spotify client credentials above based on fallback
|
|
|
|
spo = SpoLogin(
|
|
credentials_path=spo_creds_path,
|
|
spotify_client_id=spotify_client_id,
|
|
spotify_client_secret=spotify_client_secret,
|
|
progress_callback=progress_callback
|
|
)
|
|
print(f"DEBUG: Starting album download using Spotify fallback credentials")
|
|
spo.download_album(
|
|
link_album=url,
|
|
output_dir="./downloads",
|
|
quality_download=fall_quality,
|
|
recursive_quality=True,
|
|
recursive_download=False,
|
|
not_interface=False,
|
|
make_zip=False,
|
|
real_time_dl=real_time,
|
|
custom_dir_format=custom_dir_format,
|
|
custom_track_format=custom_track_format,
|
|
pad_tracks=pad_tracks,
|
|
save_cover=save_cover,
|
|
initial_retry_delay=initial_retry_delay,
|
|
retry_delay_increase=retry_delay_increase,
|
|
max_retries=max_retries,
|
|
convert_to=convert_to,
|
|
bitrate=bitrate
|
|
)
|
|
print(f"DEBUG: Album download completed successfully using Spotify fallback")
|
|
except Exception as e2:
|
|
# If fallback also fails, raise an error indicating both attempts failed
|
|
print(f"ERROR: Spotify fallback also failed: {e2}")
|
|
raise RuntimeError(
|
|
f"Both main (Deezer) and fallback (Spotify) attempts failed. "
|
|
f"Deezer error: {deezer_error}, Spotify error: {e2}"
|
|
) from e2
|
|
else:
|
|
# Original behavior: use Spotify main
|
|
if quality is None:
|
|
quality = 'HIGH'
|
|
creds_dir = os.path.join('./data/creds/spotify', main)
|
|
credentials_path = os.path.abspath(os.path.join(creds_dir, 'credentials.json'))
|
|
print(f"DEBUG: Using Spotify main credentials from: {credentials_path}")
|
|
print(f"DEBUG: Credentials exist: {os.path.exists(credentials_path)}")
|
|
|
|
spo = SpoLogin(
|
|
credentials_path=credentials_path,
|
|
spotify_client_id=spotify_client_id,
|
|
spotify_client_secret=spotify_client_secret,
|
|
progress_callback=progress_callback
|
|
)
|
|
print(f"DEBUG: Starting album download using Spotify main credentials")
|
|
spo.download_album(
|
|
link_album=url,
|
|
output_dir="./downloads",
|
|
quality_download=quality,
|
|
recursive_quality=True,
|
|
recursive_download=False,
|
|
not_interface=False,
|
|
make_zip=False,
|
|
real_time_dl=real_time,
|
|
custom_dir_format=custom_dir_format,
|
|
custom_track_format=custom_track_format,
|
|
pad_tracks=pad_tracks,
|
|
save_cover=save_cover,
|
|
initial_retry_delay=initial_retry_delay,
|
|
retry_delay_increase=retry_delay_increase,
|
|
max_retries=max_retries,
|
|
convert_to=convert_to,
|
|
bitrate=bitrate
|
|
)
|
|
print(f"DEBUG: Album download completed successfully using Spotify main")
|
|
# For Deezer URLs: download directly from Deezer
|
|
elif service == 'deezer':
|
|
if quality is None:
|
|
quality = 'FLAC'
|
|
# Existing code remains the same, ignoring fallback
|
|
creds_dir = os.path.join('./data/creds/deezer', main)
|
|
creds_path = os.path.abspath(os.path.join(creds_dir, 'credentials.json'))
|
|
print(f"DEBUG: Using Deezer credentials from: {creds_path}")
|
|
print(f"DEBUG: Credentials exist: {os.path.exists(creds_path)}")
|
|
|
|
with open(creds_path, 'r') as f:
|
|
creds = json.load(f)
|
|
dl = DeeLogin(
|
|
arl=creds.get('arl', ''),
|
|
spotify_client_id=spotify_client_id,
|
|
spotify_client_secret=spotify_client_secret,
|
|
progress_callback=progress_callback
|
|
)
|
|
print(f"DEBUG: Starting album download using Deezer credentials (download_albumdee)")
|
|
dl.download_albumdee(
|
|
link_album=url,
|
|
output_dir="./downloads",
|
|
quality_download=quality,
|
|
recursive_quality=True,
|
|
recursive_download=False,
|
|
make_zip=False,
|
|
custom_dir_format=custom_dir_format,
|
|
custom_track_format=custom_track_format,
|
|
pad_tracks=pad_tracks,
|
|
save_cover=save_cover,
|
|
initial_retry_delay=initial_retry_delay,
|
|
retry_delay_increase=retry_delay_increase,
|
|
max_retries=max_retries,
|
|
convert_to=convert_to,
|
|
bitrate=bitrate
|
|
)
|
|
print(f"DEBUG: Album download completed successfully using Deezer direct")
|
|
else:
|
|
raise ValueError(f"Unsupported service: {service}")
|
|
except Exception as e:
|
|
print(f"ERROR: Album download failed with exception: {e}")
|
|
traceback.print_exc()
|
|
raise # Re-raise the exception after logging
|