added endpoints for custom dir and track format

This commit is contained in:
cool.gitter.choco
2025-02-06 14:14:54 -06:00
parent 82bea2da12
commit 2a822c5a9f
6 changed files with 129 additions and 31 deletions

View File

@@ -40,7 +40,8 @@ class FlushingFileWrapper:
def flush(self):
self.file.flush()
def download_task(service, url, main, fallback, quality, fall_quality, real_time, prg_path, orig_request):
def download_task(service, url, main, fallback, quality, fall_quality, real_time, prg_path, orig_request,
custom_dir_format, custom_track_format):
"""
The download task writes out the original request data into the progress file
and then runs the album download.
@@ -69,7 +70,9 @@ def download_task(service, url, main, fallback, quality, fall_quality, real_time
fallback=fallback,
quality=quality,
fall_quality=fall_quality,
real_time=real_time
real_time=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
flushing_file.write(json.dumps({"status": "complete"}) + "\n")
except Exception as e:
@@ -103,6 +106,10 @@ def handle_download():
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)
@@ -177,7 +184,19 @@ def handle_download():
# Create and start the download process, and track it in the global dictionary.
process = Process(
target=download_task,
args=(service, url, main, fallback, quality, fall_quality, real_time, prg_path, orig_request)
args=(
service,
url,
main,
fallback,
quality,
fall_quality,
real_time,
prg_path,
orig_request,
custom_dir_format,
custom_track_format
)
)
process.start()
download_processes[filename] = process

View File

@@ -44,7 +44,8 @@ class FlushingFileWrapper:
def flush(self):
self.file.flush()
def download_artist_task(service, artist_url, main, fallback, quality, fall_quality, real_time, album_type, prg_path, orig_request):
def download_artist_task(service, artist_url, main, fallback, quality, fall_quality, real_time,
album_type, prg_path, orig_request, custom_dir_format, custom_track_format):
"""
This function wraps the call to download_artist_albums, writes the original
request data to the progress file, and then writes JSON status updates.
@@ -75,6 +76,8 @@ def download_artist_task(service, artist_url, main, fallback, quality, fall_qual
fall_quality=fall_quality,
real_time=real_time,
album_type=album_type,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
flushing_file.write(json.dumps({"status": "complete"}) + "\n")
except Exception as e:
@@ -108,6 +111,8 @@ def handle_artist_download():
- fall_quality: string (optional, e.g., "HIGH")
- real_time: bool (e.g., "true" or "false")
- album_type: string(s); one or more of "album", "single", "appears_on", "compilation" (if multiple, comma-separated)
- custom_dir_format: string (optional, default: "%ar_album%/%album%/%copyright%")
- custom_track_format: string (optional, default: "%tracknum%. %music% - %artist%")
"""
service = request.args.get('service')
artist_url = request.args.get('artist_url')
@@ -119,6 +124,10 @@ def handle_artist_download():
real_time_arg = request.args.get('real_time', 'false')
real_time = real_time_arg.lower() in ['true', '1', 'yes']
# New query parameters for custom formatting.
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)
@@ -195,7 +204,20 @@ def handle_artist_download():
# Create and start the download process.
process = Process(
target=download_artist_task,
args=(service, artist_url, main, fallback, quality, fall_quality, real_time, album_type, prg_path, orig_request)
args=(
service,
artist_url,
main,
fallback,
quality,
fall_quality,
real_time,
album_type,
prg_path,
orig_request,
custom_dir_format,
custom_track_format
)
)
process.start()
download_processes[filename] = process

View File

@@ -1,11 +1,12 @@
from flask import Blueprint, Response, request
import json
import os
import json
import traceback
from deezspot.spotloader import SpoLogin
from deezspot.deezloader import DeeLogin
from multiprocessing import Process
import random
import string
import sys
import traceback
from multiprocessing import Process
playlist_bp = Blueprint('playlist', __name__)
@@ -40,7 +41,8 @@ class FlushingFileWrapper:
def flush(self):
self.file.flush()
def download_task(service, url, main, fallback, quality, fall_quality, real_time, prg_path, orig_request):
def download_task(service, url, main, fallback, quality, fall_quality, real_time,
prg_path, orig_request, custom_dir_format, custom_track_format):
try:
from routes.utils.playlist import download_playlist
with open(prg_path, 'w') as f:
@@ -65,7 +67,9 @@ def download_task(service, url, main, fallback, quality, fall_quality, real_time
fallback=fallback,
quality=quality,
fall_quality=fall_quality,
real_time=real_time
real_time=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
flushing_file.write(json.dumps({"status": "complete"}) + "\n")
except Exception as e:
@@ -100,6 +104,10 @@ def handle_download():
real_time_str = request.args.get('real_time', 'false').lower()
real_time = real_time_str in ['true', '1', 'yes']
# New custom formatting parameters, with defaults.
custom_dir_format = request.args.get('custom_dir_format', "%ar_album%/%album%/%copyright%")
custom_track_format = request.args.get('custom_track_format', "%tracknum%. %music% - %artist%")
if not all([service, url, main]):
return Response(
json.dumps({"error": "Missing parameters"}),
@@ -117,7 +125,10 @@ def handle_download():
process = Process(
target=download_task,
args=(service, url, main, fallback, quality, fall_quality, real_time, prg_path, orig_request)
args=(
service, url, main, fallback, quality, fall_quality, real_time,
prg_path, orig_request, custom_dir_format, custom_track_format
)
)
process.start()
# Track the running process using the generated filename.

View File

@@ -4,7 +4,17 @@ import traceback
from deezspot.spotloader import SpoLogin
from deezspot.deezloader import DeeLogin
def download_album(service, url, main, fallback=None, quality=None, fall_quality=None, real_time=False):
def download_album(
service,
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%"
):
try:
if service == 'spotify':
if fallback:
@@ -23,7 +33,7 @@ def download_album(service, url, main, fallback=None, quality=None, fall_quality
dl = DeeLogin(
arl=deezer_creds.get('arl', ''),
)
# Download using download_albumspo; pass real_time_dl accordingly
# Download using download_albumspo; pass real_time_dl accordingly and the custom formatting
dl.download_albumspo(
link_album=url,
output_dir="./downloads",
@@ -32,7 +42,9 @@ def download_album(service, url, main, fallback=None, quality=None, fall_quality
recursive_download=False,
not_interface=False,
make_zip=False,
method_save=1
method_save=1,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
except Exception as e:
# Load fallback Spotify credentials and attempt download
@@ -49,7 +61,9 @@ def download_album(service, url, main, fallback=None, quality=None, fall_quality
not_interface=False,
method_save=1,
make_zip=False,
real_time_dl=real_time
real_time_dl=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
except Exception as e2:
# If fallback also fails, raise an error indicating both attempts failed
@@ -73,7 +87,9 @@ def download_album(service, url, main, fallback=None, quality=None, fall_quality
not_interface=False,
method_save=1,
make_zip=False,
real_time_dl=real_time
real_time_dl=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
elif service == 'deezer':
if quality is None:
@@ -93,7 +109,9 @@ def download_album(service, url, main, fallback=None, quality=None, fall_quality
recursive_quality=True,
recursive_download=False,
method_save=1,
make_zip=False
make_zip=False,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
else:
raise ValueError(f"Unsupported service: {service}")

View File

@@ -43,15 +43,17 @@ def get_artist_discography(url, album_type='album,single,compilation,appears_on'
def download_artist_albums(service, artist_url, main, fallback=None, quality=None,
fall_quality=None, real_time=False, album_type='album,single,compilation,appears_on'):
fall_quality=None, real_time=False, album_type='album,single,compilation,appears_on',
custom_dir_format="%ar_album%/%album%/%copyright%",
custom_track_format="%tracknum%. %music% - %artist%"):
try:
discography = get_artist_discography(artist_url, album_type=album_type)
except Exception as e:
log_json({"status": "error", "message": f"Error retrieving artist discography: {e}"})
raise
albums = discography.get('items', [])
# Extract artist name from the first album's artists
artist_name = artist_url # default fallback
# Extract artist name from the first album's artists as fallback.
artist_name = artist_url
if albums:
first_album = albums[0]
artists = first_album.get('artists', [])
@@ -68,7 +70,13 @@ def download_artist_albums(service, artist_url, main, fallback=None, quality=Non
})
return
log_json({"status": "initializing", "type": "artist", "artist": artist_name, "total_albums": len(albums), "album_type": album_type})
log_json({
"status": "initializing",
"type": "artist",
"artist": artist_name,
"total_albums": len(albums),
"album_type": album_type
})
for album in albums:
try:
@@ -95,7 +103,9 @@ def download_artist_albums(service, artist_url, main, fallback=None, quality=Non
fallback=fallback,
quality=quality,
fall_quality=fall_quality,
real_time=real_time
real_time=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
except Exception as album_error:

View File

@@ -4,7 +4,17 @@ import traceback
from deezspot.spotloader import SpoLogin
from deezspot.deezloader import DeeLogin
def download_playlist(service, url, main, fallback=None, quality=None, fall_quality=None, real_time=False):
def download_playlist(
service,
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%"
):
try:
if service == 'spotify':
if fallback:
@@ -23,7 +33,7 @@ def download_playlist(service, url, main, fallback=None, quality=None, fall_qual
dl = DeeLogin(
arl=deezer_creds.get('arl', ''),
)
# Download using download_playlistspo
# Download using download_playlistspo; pass the custom formatting parameters.
dl.download_playlistspo(
link_playlist=url,
output_dir="./downloads",
@@ -32,7 +42,9 @@ def download_playlist(service, url, main, fallback=None, quality=None, fall_qual
recursive_download=False,
not_interface=False,
make_zip=False,
method_save=1
method_save=1,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
except Exception as e:
# Load fallback Spotify credentials and attempt download
@@ -49,7 +61,9 @@ def download_playlist(service, url, main, fallback=None, quality=None, fall_qual
not_interface=False,
method_save=1,
make_zip=False,
real_time_dl=real_time
real_time_dl=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
except Exception as e2:
# If fallback also fails, raise an error indicating both attempts failed
@@ -73,12 +87,14 @@ def download_playlist(service, url, main, fallback=None, quality=None, fall_qual
not_interface=False,
method_save=1,
make_zip=False,
real_time_dl=real_time
real_time_dl=real_time,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
elif service == 'deezer':
if quality is None:
quality = 'FLAC'
# Existing code for Deezer, using main as Deezer account
# Existing code for Deezer, using main as Deezer account.
creds_dir = os.path.join('./creds/deezer', main)
creds_path = os.path.abspath(os.path.join(creds_dir, 'credentials.json'))
with open(creds_path, 'r') as f:
@@ -93,7 +109,9 @@ def download_playlist(service, url, main, fallback=None, quality=None, fall_qual
recursive_quality=False,
recursive_download=False,
method_save=1,
make_zip=False
make_zip=False,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format
)
else:
raise ValueError(f"Unsupported service: {service}")