Files
spotizerr-dev/routes/album.py
cool.gitter.choco ed23ad0f48 added queue system
2025-02-09 16:30:33 -06:00

176 lines
6.3 KiB
Python
Executable File

from flask import Blueprint, Response, request
import json
import os
import traceback
from routes.utils.queue import download_queue_manager
album_bp = Blueprint('album', __name__)
@album_bp.route('/download', methods=['GET'])
def handle_download():
# Retrieve parameters from the request.
service = request.args.get('service')
url = request.args.get('url')
main = request.args.get('main')
fallback = request.args.get('fallback')
quality = request.args.get('quality')
fall_quality = request.args.get('fall_quality')
# Normalize the real_time parameter; default to False.
real_time_arg = request.args.get('real_time', 'false')
real_time = real_time_arg.lower() in ['true', '1', 'yes']
# New custom formatting parameters (with defaults)
custom_dir_format = request.args.get('custom_dir_format', "%ar_album%/%album%")
custom_track_format = request.args.get('custom_track_format', "%tracknum%. %music% - %artist%")
# Sanitize main and fallback to prevent directory traversal.
if main:
main = os.path.basename(main)
if fallback:
fallback = os.path.basename(fallback)
if not all([service, url, main]):
return Response(
json.dumps({"error": "Missing parameters"}),
status=400,
mimetype='application/json'
)
# Validate credentials based on service and fallback.
try:
if service == 'spotify':
if fallback:
# Validate Deezer main and Spotify fallback credentials.
deezer_creds_path = os.path.abspath(os.path.join('./creds/deezer', main, 'credentials.json'))
if not os.path.isfile(deezer_creds_path):
return Response(
json.dumps({"error": "Invalid Deezer credentials directory"}),
status=400,
mimetype='application/json'
)
spotify_fallback_path = os.path.abspath(os.path.join('./creds/spotify', fallback, 'credentials.json'))
if not os.path.isfile(spotify_fallback_path):
return Response(
json.dumps({"error": "Invalid Spotify fallback credentials directory"}),
status=400,
mimetype='application/json'
)
else:
# Validate Spotify main credentials.
spotify_creds_path = os.path.abspath(os.path.join('./creds/spotify', main, 'credentials.json'))
if not os.path.isfile(spotify_creds_path):
return Response(
json.dumps({"error": "Invalid Spotify credentials directory"}),
status=400,
mimetype='application/json'
)
elif service == 'deezer':
# Validate Deezer main credentials.
deezer_creds_path = os.path.abspath(os.path.join('./creds/deezer', main, 'credentials.json'))
if not os.path.isfile(deezer_creds_path):
return Response(
json.dumps({"error": "Invalid Deezer credentials directory"}),
status=400,
mimetype='application/json'
)
else:
return Response(
json.dumps({"error": "Unsupported service"}),
status=400,
mimetype='application/json'
)
except Exception as e:
return Response(
json.dumps({"error": f"Credential validation failed: {str(e)}"}),
status=500,
mimetype='application/json'
)
# Build the task dictionary.
# Note: The new keys "type", "name", and "artist" will be merged into the original_request
# message by the queue handler.
task = {
"download_type": "album", # tells the queue handler which download function to call
"service": service,
"url": url,
"main": main,
"fallback": fallback,
"quality": quality,
"fall_quality": fall_quality,
"real_time": real_time,
"custom_dir_format": custom_dir_format,
"custom_track_format": custom_track_format,
"orig_request": request.args.to_dict(),
# New additional parameters:
"type": "album",
"name": request.args.get('name'),
"artist": request.args.get('artist')
}
# Add the task to the queue and get the generated prg filename.
prg_filename = download_queue_manager.add_task(task)
return Response(
json.dumps({"prg_file": prg_filename}),
status=202,
mimetype='application/json'
)
@album_bp.route('/download/cancel', methods=['GET'])
def cancel_download():
"""
Cancel a running download process by its prg file name.
"""
prg_file = request.args.get('prg_file')
if not prg_file:
return Response(
json.dumps({"error": "Missing process id (prg_file) parameter"}),
status=400,
mimetype='application/json'
)
# Use the queue manager's cancellation method.
result = download_queue_manager.cancel_task(prg_file)
status_code = 200 if result.get("status") == "cancelled" else 404
return Response(
json.dumps(result),
status=status_code,
mimetype='application/json'
)
@album_bp.route('/info', methods=['GET'])
def get_album_info():
"""
Retrieve Spotify album metadata given a Spotify album ID.
Expects a query parameter 'id' that contains the Spotify album ID.
"""
spotify_id = request.args.get('id')
if not spotify_id:
return Response(
json.dumps({"error": "Missing parameter: id"}),
status=400,
mimetype='application/json'
)
try:
# Import and use the get_spotify_info function from the utility module.
from routes.utils.get_info import get_spotify_info
album_info = get_spotify_info(spotify_id, "album")
return Response(
json.dumps(album_info),
status=200,
mimetype='application/json'
)
except Exception as e:
error_data = {
"error": str(e),
"traceback": traceback.format_exc()
}
return Response(
json.dumps(error_data),
status=500,
mimetype='application/json'
)