Added progress bars for overall and per track downloading, implemented new version of deezspot-fork-again, simplifided api to just the url (might reduce that to just the id in the future, idk).

This commit is contained in:
architect.in.git
2025-04-22 20:49:19 -06:00
parent 3add9917c8
commit b00115792a
5 changed files with 1189 additions and 371 deletions

1
.gitignore vendored
View File

@@ -33,3 +33,4 @@ queue_state.json
search_demo.py
celery_worker.log
logs/spotizerr.log
/.venv

View File

@@ -52,123 +52,14 @@ def get_prg_file(task_id):
status_count = len(all_statuses)
logger.debug(f"API: Task {task_id} has {status_count} status updates")
# Prepare the response with basic info
# Prepare the simplified response with just the requested info
response = {
"type": task_info.get("type", ""),
"name": task_info.get("name", ""),
"artist": task_info.get("artist", ""),
"last_line": last_status,
"original_request": original_request,
"display_title": original_request.get("display_title", task_info.get("name", "")),
"display_type": original_request.get("display_type", task_info.get("type", "")),
"display_artist": original_request.get("display_artist", task_info.get("artist", "")),
"status_count": status_count,
"timestamp": time.time(),
"task_id": task_id,
"timestamp": time.time()
"status_count": status_count
}
# Handle different status types
if last_status:
status_type = last_status.get("status", "unknown")
# Set event type based on status (like in the previous SSE implementation)
event_type = "update"
if status_type in [ProgressState.COMPLETE, ProgressState.DONE]:
event_type = "complete"
elif status_type == ProgressState.TRACK_COMPLETE:
event_type = "track_complete"
elif status_type == ProgressState.ERROR:
event_type = "error"
elif status_type in [ProgressState.TRACK_PROGRESS, ProgressState.REAL_TIME]:
event_type = "progress"
response["event"] = event_type
# For terminal statuses (complete, error, cancelled)
if status_type in [ProgressState.COMPLETE, ProgressState.ERROR, ProgressState.CANCELLED]:
response["progress_message"] = last_status.get("message", f"Download {status_type}")
# For progress status with track information
elif status_type == "progress" and last_status.get("track"):
# Add explicit track progress fields to the top level for easy access
response["current_track"] = last_status.get("track", "")
response["track_number"] = last_status.get("parsed_current_track", 0)
response["total_tracks"] = last_status.get("parsed_total_tracks", 0)
response["progress_percent"] = last_status.get("overall_progress", 0)
response["album"] = last_status.get("album", "")
# Format a nice progress message for display
track_info = last_status.get("track", "")
current = last_status.get("parsed_current_track", 0)
total = last_status.get("parsed_total_tracks", 0)
progress = last_status.get("overall_progress", 0)
if current and total:
response["progress_message"] = f"Downloading track {current}/{total} ({progress}%): {track_info}"
elif track_info:
response["progress_message"] = f"Downloading: {track_info}"
# For real-time status messages
elif status_type == "real_time":
# Add real-time specific fields
response["current_song"] = last_status.get("song", "")
response["percent"] = last_status.get("percent", 0)
response["percentage"] = last_status.get("percentage", 0)
response["time_elapsed"] = last_status.get("time_elapsed", 0)
# Format a nice progress message for display
song = last_status.get("song", "")
percent = last_status.get("percent", 0)
if song:
response["progress_message"] = f"Downloading {song} ({percent}%)"
else:
response["progress_message"] = f"Downloading ({percent}%)"
# For initializing status
elif status_type == "initializing":
album = last_status.get("album", "")
if album:
response["progress_message"] = f"Initializing download for {album}"
else:
response["progress_message"] = "Initializing download..."
# For processing status (default)
elif status_type == "processing":
# Search for the most recent track progress in all statuses
has_progress = False
for status in reversed(all_statuses):
if status.get("status") == "progress" and status.get("track"):
# Use this track progress information
track_info = status.get("track", "")
current_raw = status.get("current_track", "")
response["current_track"] = track_info
# Try to parse track numbers if available
if isinstance(current_raw, str) and "/" in current_raw:
try:
parts = current_raw.split("/")
current = int(parts[0])
total = int(parts[1])
response["track_number"] = current
response["total_tracks"] = total
response["progress_percent"] = min(int((current / total) * 100), 100)
response["progress_message"] = f"Processing track {current}/{total}: {track_info}"
except (ValueError, IndexError):
response["progress_message"] = f"Processing: {track_info}"
else:
response["progress_message"] = f"Processing: {track_info}"
has_progress = True
break
if not has_progress:
# Just use the processing message
response["progress_message"] = last_status.get("message", "Processing download...")
# For other status types
else:
response["progress_message"] = last_status.get("message", f"Status: {status_type}")
return jsonify(response)
# If not found in new system, try the old PRG file system
@@ -182,19 +73,13 @@ def get_prg_file(task_id):
content = f.read()
lines = content.splitlines()
# If the file is empty, return default values.
# If the file is empty, return default values with simplified format.
if not lines:
return jsonify({
"type": "",
"name": "",
"artist": "",
"last_line": None,
"original_request": None,
"display_title": "",
"display_type": "",
"display_artist": "",
"timestamp": time.time(),
"task_id": task_id,
"event": "unknown"
"status_count": 0
})
# Attempt to extract the original request from the first line.
@@ -248,18 +133,15 @@ def get_prg_file(task_id):
except Exception:
last_line_parsed = last_line_raw # Fallback to raw string if JSON parsing fails.
# Calculate status_count for old PRG files (number of lines in the file)
status_count = len(lines)
# Return simplified response format
return jsonify({
"type": resource_type,
"name": resource_name,
"artist": resource_artist,
"last_line": last_line_parsed,
"original_request": original_request,
"display_title": display_title,
"display_type": display_type,
"display_artist": display_artist,
"timestamp": time.time(),
"task_id": task_id,
"event": "unknown", # Old files don't have event types
"timestamp": time.time()
"status_count": status_count
})
except FileNotFoundError:
abort(404, "Task or file not found")

View File

@@ -1 +0,0 @@

View File

@@ -310,6 +310,96 @@
border-radius: 2px;
}
/* Overall progress container for albums and playlists */
.overall-progress-container {
margin-top: 12px;
padding-top: 8px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
position: relative; /* Positioning context for z-index */
z-index: 2; /* Ensure overall progress appears above track progress */
}
.overall-progress-header {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 11px;
color: #b3b3b3;
}
.overall-progress-label {
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.overall-progress-count {
font-weight: 600;
color: #1DB954;
}
.overall-progress-bar-container {
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
}
.overall-progress-bar {
height: 100%;
background: linear-gradient(90deg, #4a90e2, #7a67ee); /* Changed to blue-purple gradient */
width: 0;
border-radius: 3px;
transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
}
.overall-progress-bar.complete {
background: #4a90e2; /* Changed to solid blue for completed overall progress */
}
/* Track progress bar container */
.track-progress-bar-container {
height: 4px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
overflow: hidden;
margin-top: 8px;
margin-bottom: 4px;
position: relative;
z-index: 1; /* Ensure it's below the overall progress */
}
/* Track progress bar */
.track-progress-bar {
height: 100%;
background: #1DB954; /* Keep green for track-level progress */
width: 0;
border-radius: 2px;
transition: width 0.3s ease;
box-shadow: 0 0 3px rgba(29, 185, 84, 0.5); /* Add subtle glow to differentiate */
}
/* Complete state for track progress */
/* Real-time progress style */
.track-progress-bar.real-time {
background: #1DB954; /* Vivid green for real-time progress */
background: #1DB954;
}
/* Pulsing animation for indeterminate progress */
.track-progress-bar.progress-pulse {
background: linear-gradient(90deg, #1DB954 0%, #2cd267 50%, #1DB954 100%); /* Keep in green family */
background-size: 200% 100%;
animation: progress-pulse-slide 1.5s ease infinite;
}
@keyframes progress-pulse-slide {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* Progress percentage text */
.progress-percent {
text-align: right;

File diff suppressed because it is too large Load Diff