From 8a48fd3140115835e7452dd1cff40463a5d3ccc7 Mon Sep 17 00:00:00 2001 From: "cool.gitter.choco" Date: Tue, 28 Jan 2025 13:11:32 -0600 Subject: [PATCH] updated utils --- .dockerignore | 3 ++- routes/album.py | 31 +++++++++++-------------------- routes/playlist.py | 11 ++++------- routes/track.py | 8 ++++---- 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/.dockerignore b/.dockerignore index d92ca6a..3d50c99 100755 --- a/.dockerignore +++ b/.dockerignore @@ -11,4 +11,5 @@ /test.sh /__pycache__/ /Dockerfile -/docker-compose.yaml \ No newline at end of file +/docker-compose.yaml +/README.md diff --git a/routes/album.py b/routes/album.py index 31029f8..ae49de5 100755 --- a/routes/album.py +++ b/routes/album.py @@ -5,38 +5,37 @@ import random import string import sys import traceback -from multiprocessing import Process # Use multiprocessing instead of threading +from multiprocessing import Process -# Define the Blueprint for album-related routes album_bp = Blueprint('album', __name__) -# Function to generate random filenames def generate_random_filename(length=6): chars = string.ascii_lowercase + string.digits return ''.join(random.choice(chars) for _ in range(length)) + '.prg' -# File wrapper to flush writes immediately class FlushingFileWrapper: def __init__(self, file): self.file = file def write(self, text): - self.file.write(text) + # Filter lines to only write JSON objects + for line in text.split('\n'): + if line.startswith('{'): + self.file.write(line + '\n') self.file.flush() def flush(self): self.file.flush() -# Define the download task as a top-level function for picklability def download_task(service, url, main, fallback, prg_path): try: from routes.utils.album import download_album with open(prg_path, 'w') as f: flushing_file = FlushingFileWrapper(f) original_stdout = sys.stdout - sys.stdout = flushing_file # Redirect stdout to the file + sys.stdout = flushing_file # Redirect stdout + try: - # Execute the download process download_album( service=service, url=url, @@ -45,7 +44,6 @@ def download_task(service, url, main, fallback, prg_path): ) flushing_file.write(json.dumps({"status": "complete"}) + "\n") except Exception as e: - # Capture exceptions and write to file error_data = json.dumps({ "status": "error", "message": str(e), @@ -53,9 +51,8 @@ def download_task(service, url, main, fallback, prg_path): }) flushing_file.write(error_data + "\n") finally: - sys.stdout = original_stdout # Restore original stdout + sys.stdout = original_stdout # Restore stdout except Exception as e: - # Handle exceptions that occur outside the main download process with open(prg_path, 'w') as f: error_data = json.dumps({ "status": "error", @@ -64,16 +61,13 @@ def download_task(service, url, main, fallback, prg_path): }) f.write(error_data + "\n") -# Define the route to handle album download requests @album_bp.route('/download', methods=['GET']) def handle_download(): - # Extract query parameters service = request.args.get('service') url = request.args.get('url') main = request.args.get('main') - fallback = request.args.get('fallback') # Optional parameter + fallback = request.args.get('fallback') - # Validate required parameters if not all([service, url, main]): return Response( json.dumps({"error": "Missing parameters"}), @@ -81,19 +75,16 @@ def handle_download(): mimetype='application/json' ) - # Generate a unique file for storing the download progress filename = generate_random_filename() prg_dir = './prgs' os.makedirs(prg_dir, exist_ok=True) prg_path = os.path.join(prg_dir, filename) - - # Start a new process for each download task + Process( target=download_task, args=(service, url, main, fallback, prg_path) ).start() - - # Return the filename to the client for progress tracking + return Response( json.dumps({"prg_file": filename}), status=202, diff --git a/routes/playlist.py b/routes/playlist.py index 7cfa095..bf288c5 100755 --- a/routes/playlist.py +++ b/routes/playlist.py @@ -5,12 +5,10 @@ import random import string import sys import traceback -from multiprocessing import Process # Changed from Thread to Process +from multiprocessing import Process playlist_bp = Blueprint('playlist', __name__) -# Removed thread-local stdout setup since we're using process isolation - def generate_random_filename(length=6): chars = string.ascii_lowercase + string.digits return ''.join(random.choice(chars) for _ in range(length)) + '.prg' @@ -20,13 +18,14 @@ class FlushingFileWrapper: self.file = file def write(self, text): - self.file.write(text) + for line in text.split('\n'): + if line.startswith('{'): + self.file.write(line + '\n') self.file.flush() def flush(self): self.file.flush() -# Moved download_task to top-level for picklability def download_task(service, url, main, fallback, prg_path): try: from routes.utils.playlist import download_playlist @@ -53,7 +52,6 @@ def download_task(service, url, main, fallback, prg_path): finally: sys.stdout = original_stdout # Restore original stdout except Exception as e: - # Handle exceptions outside the main logic with open(prg_path, 'w') as f: error_data = json.dumps({ "status": "error", @@ -81,7 +79,6 @@ def handle_download(): os.makedirs(prg_dir, exist_ok=True) prg_path = os.path.join(prg_dir, filename) - # Start a new process with required arguments Process( target=download_task, args=(service, url, main, fallback, prg_path) diff --git a/routes/track.py b/routes/track.py index ab4c6b6..de2da7d 100755 --- a/routes/track.py +++ b/routes/track.py @@ -5,7 +5,7 @@ import random import string import sys import traceback -from multiprocessing import Process # Changed from threading import Thread +from multiprocessing import Process track_bp = Blueprint('track', __name__) @@ -18,13 +18,14 @@ class FlushingFileWrapper: self.file = file def write(self, text): - self.file.write(text) + for line in text.split('\n'): + if line.startswith('{'): + self.file.write(line + '\n') self.file.flush() def flush(self): self.file.flush() -# Moved download_task to top-level for multiprocessing compatibility def download_task(service, url, main, fallback, prg_path): try: from routes.utils.track import download_track @@ -78,7 +79,6 @@ def handle_download(): os.makedirs(prg_dir, exist_ok=True) prg_path = os.path.join(prg_dir, filename) - # Start a new process with required arguments Process( target=download_task, args=(service, url, main, fallback, prg_path)