fix
This commit is contained in:
parent
f2e62217a0
commit
4324fd54da
6 changed files with 7589 additions and 69 deletions
|
|
@ -1 +1 @@
|
||||||
{"access_token": "BQCzY4NDr26JqIBSxwATrH7MQMG5i9kCZxPvvtjcoVTyFZPRYPOEltaZEqN44ukQhNDo6C8fvkhlSPS6tk2N7zVitnBk9bT2IRAQiQGpxRS67kNlUfxUJSw52YAW83vECziyLfUfOkLs-E2LzoJDQtq_QOx18b_wO883mT1C8OyNFjVGvvjV5Srf8oSMJ4KN6WYwMpllfTbno7YlT7R5oPOtjgNquuUOhLHRWWp9KXEermO-MZWtWl_OxBAlhhmi", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1752342994, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}
|
{"access_token": "BQAn7glyksj8Yn1ryBKRgkrU9oH5tycZC3upkwXmsYo-j0dNX_kwuxaQHVO1yd77aIepn4zkVOeHMdmcyWKiAr3UFHsV5BkZGl28W8RyCuK6geFYbc6eoJ1VnOltZcwtjm7_YsxUlVccHJO7Wrwu12Rt1K_hqPcF8Cyl7rj5qwD_il4OdTipejXhGaACJM5dupAKNZLuTipvPn38bx2dqHdQctUspouiU5B1XRhFnc45GQ10nGXHmOgBX_G26pKc", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1752353180, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}
|
||||||
7422
logs/app.log
7422
logs/app.log
File diff suppressed because it is too large
Load diff
BIN
ui/pages/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
ui/pages/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -644,6 +644,7 @@ class StreamingThread(QThread):
|
||||||
streaming_finished = pyqtSignal(str, object) # Message, search_result
|
streaming_finished = pyqtSignal(str, object) # Message, search_result
|
||||||
streaming_failed = pyqtSignal(str, object) # Error message, search_result
|
streaming_failed = pyqtSignal(str, object) # Error message, search_result
|
||||||
streaming_progress = pyqtSignal(float, object) # Progress percentage (0-100), search_result
|
streaming_progress = pyqtSignal(float, object) # Progress percentage (0-100), search_result
|
||||||
|
streaming_queued = pyqtSignal(str, object) # Queue message, search_result
|
||||||
|
|
||||||
def __init__(self, soulseek_client, search_result):
|
def __init__(self, soulseek_client, search_result):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
@ -699,31 +700,63 @@ class StreamingThread(QThread):
|
||||||
max_wait_time = 45 # Wait up to 45 seconds
|
max_wait_time = 45 # Wait up to 45 seconds
|
||||||
poll_interval = 2 # Check every 2 seconds
|
poll_interval = 2 # Check every 2 seconds
|
||||||
|
|
||||||
# Track elapsed time for fallback progress estimation
|
|
||||||
start_time = time.time()
|
|
||||||
estimated_duration = 15.0 # Estimate 15 seconds for typical download
|
|
||||||
last_progress_sent = 0.0
|
last_progress_sent = 0.0
|
||||||
found_file = None # Initialize found_file outside the loop
|
found_file = None # Initialize found_file outside the loop
|
||||||
|
|
||||||
|
# Queue state tracking
|
||||||
|
queue_start_time = None
|
||||||
|
queue_timeout = 15.0 # 15 seconds max in queue
|
||||||
|
last_download_state = None
|
||||||
|
actively_downloading = False
|
||||||
|
|
||||||
for wait_count in range(max_wait_time // poll_interval):
|
for wait_count in range(max_wait_time // poll_interval):
|
||||||
if self._stop_requested:
|
if self._stop_requested:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate fallback progress based on elapsed time
|
# Only use real API progress data - no time-based estimation
|
||||||
elapsed_time = time.time() - start_time
|
|
||||||
estimated_progress = min(95.0, (elapsed_time / estimated_duration) * 95.0) # Cap at 95%
|
|
||||||
|
|
||||||
# Check download progress via slskd API
|
# Check download progress via slskd API
|
||||||
api_progress = None
|
api_progress = None
|
||||||
|
download_state = None
|
||||||
try:
|
try:
|
||||||
download_status = loop.run_until_complete(self._check_download_progress())
|
# Use the same API call as download queue monitoring for consistency
|
||||||
|
transfers_data = loop.run_until_complete(self.soulseek_client._make_request('GET', 'transfers/downloads'))
|
||||||
|
download_status = self._find_streaming_download_in_transfers(transfers_data)
|
||||||
if download_status:
|
if download_status:
|
||||||
api_progress = download_status.progress
|
api_progress = download_status.get('percentComplete', 0)
|
||||||
print(f"API Download progress: {api_progress:.1f}%")
|
download_state = download_status.get('state', '').lower()
|
||||||
|
print(f"API Download - State: {download_status.get('state')}, Progress: {api_progress:.1f}%")
|
||||||
|
|
||||||
|
# Categorize download state (aligned with download queue logic)
|
||||||
|
original_state = download_status.get('state', '') # Keep original case for completion check
|
||||||
|
is_queued = any(keyword in download_state for keyword in ['queued', 'initializing', 'remote'])
|
||||||
|
is_downloading = 'inprogress' in download_state
|
||||||
|
is_completed = ('Succeeded' in original_state or ('Completed' in original_state and 'Errored' not in original_state)) or api_progress >= 100
|
||||||
|
|
||||||
|
# Track queue state timing
|
||||||
|
if is_queued and queue_start_time is None:
|
||||||
|
queue_start_time = time.time()
|
||||||
|
print(f"📋 Download entered queue state: {original_state}")
|
||||||
|
self.streaming_queued.emit(f"Queuing with uploader...", self.search_result)
|
||||||
|
elif is_downloading and not actively_downloading:
|
||||||
|
actively_downloading = True
|
||||||
|
queue_start_time = None # Reset queue timer
|
||||||
|
print(f"🚀 Download started actively downloading: {original_state}")
|
||||||
|
# Emit a progress update to indicate downloading has started
|
||||||
|
if api_progress > 0:
|
||||||
|
self.streaming_progress.emit(api_progress, self.search_result)
|
||||||
|
|
||||||
|
# Check for queue timeout
|
||||||
|
if is_queued and queue_start_time:
|
||||||
|
queue_elapsed = time.time() - queue_start_time
|
||||||
|
if queue_elapsed > queue_timeout:
|
||||||
|
print(f"⏰ Queue timeout after {queue_elapsed:.1f}s - download stuck in queue")
|
||||||
|
self.streaming_failed.emit(f"Queue timeout - uploader not responding. Try another source.", self.search_result)
|
||||||
|
return
|
||||||
|
|
||||||
# Check if download is complete
|
# Check if download is complete
|
||||||
if download_status.state.lower().startswith('completed') or api_progress >= 100:
|
if is_completed:
|
||||||
print(f"✓ Download completed via API status: {download_status.state}")
|
print(f"✓ Download completed via API status: {original_state}")
|
||||||
# Try to find the actual file - with retries for file system sync
|
# Try to find the actual file - with retries for file system sync
|
||||||
for retry_count in range(5): # Try up to 5 times with delays
|
for retry_count in range(5): # Try up to 5 times with delays
|
||||||
found_file = self._find_downloaded_file(download_path)
|
found_file = self._find_downloaded_file(download_path)
|
||||||
|
|
@ -735,18 +768,42 @@ class StreamingThread(QThread):
|
||||||
time.sleep(1) # Wait 1 second for file system to sync
|
time.sleep(1) # Wait 1 second for file system to sync
|
||||||
|
|
||||||
if found_file:
|
if found_file:
|
||||||
break # Exit main polling loop
|
print(f"✓ Found downloaded file: {found_file}")
|
||||||
|
|
||||||
|
# Move the file to Stream folder with original filename
|
||||||
|
original_filename = os.path.basename(found_file)
|
||||||
|
stream_path = os.path.join(stream_folder, original_filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Move file to Stream folder
|
||||||
|
shutil.move(found_file, stream_path)
|
||||||
|
print(f"✓ Moved file to stream folder: {stream_path}")
|
||||||
|
|
||||||
|
# Clean up empty directories left behind
|
||||||
|
self._cleanup_empty_directories(download_path, found_file)
|
||||||
|
|
||||||
|
# Signal that streaming is ready (100% progress)
|
||||||
|
self.streaming_progress.emit(100.0, self.search_result)
|
||||||
|
self.streaming_finished.emit(f"Stream ready: {os.path.basename(found_file)}", self.search_result)
|
||||||
|
self.temp_file_path = stream_path
|
||||||
|
print(f"✓ Stream file ready for playback: {stream_path}")
|
||||||
|
break # Exit main polling loop
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error moving file to stream folder: {e}")
|
||||||
|
self.streaming_failed.emit(f"Failed to prepare stream file: {e}", self.search_result)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Handle progress updates for active downloads
|
||||||
|
if is_downloading and actively_downloading and api_progress is not None and api_progress > 0:
|
||||||
|
if api_progress != last_progress_sent:
|
||||||
|
self.streaming_progress.emit(api_progress, self.search_result)
|
||||||
|
print(f"Progress update: {api_progress:.1f}% (Real API data)")
|
||||||
|
last_progress_sent = api_progress
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Warning: Could not check download progress: {e}")
|
print(f"Warning: Could not check download progress: {e}")
|
||||||
|
# Continue to next iteration if API call fails
|
||||||
# Use API progress if available, otherwise use estimated progress
|
continue
|
||||||
current_progress = api_progress if api_progress is not None and api_progress > 0 else estimated_progress
|
|
||||||
|
|
||||||
# Only emit progress updates if there's a meaningful change (>5%)
|
|
||||||
if current_progress - last_progress_sent >= 5.0:
|
|
||||||
self.streaming_progress.emit(current_progress, self.search_result)
|
|
||||||
print(f"Progress update: {current_progress:.1f}% (API: {api_progress}, Estimated: {estimated_progress:.1f}%)")
|
|
||||||
last_progress_sent = current_progress
|
|
||||||
|
|
||||||
# Search for the downloaded file in the downloads directory
|
# Search for the downloaded file in the downloads directory
|
||||||
found_file = self._find_downloaded_file(download_path)
|
found_file = self._find_downloaded_file(download_path)
|
||||||
|
|
@ -785,37 +842,6 @@ class StreamingThread(QThread):
|
||||||
# Timed out waiting for file
|
# Timed out waiting for file
|
||||||
print(f"❌ Polling loop completed, timeout reached. found_file = {found_file}")
|
print(f"❌ Polling loop completed, timeout reached. found_file = {found_file}")
|
||||||
self.streaming_failed.emit("Stream download timed out - file not found", self.search_result)
|
self.streaming_failed.emit("Stream download timed out - file not found", self.search_result)
|
||||||
|
|
||||||
# Post-polling file processing
|
|
||||||
print(f"📋 After polling loop: found_file = {found_file}")
|
|
||||||
if found_file:
|
|
||||||
print(f"🎯 Processing found file: {found_file}")
|
|
||||||
|
|
||||||
# Move the file to Stream folder with original filename
|
|
||||||
original_filename = os.path.basename(found_file)
|
|
||||||
stream_path = os.path.join(stream_folder, original_filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Move file to Stream folder
|
|
||||||
print(f"📁 Moving file from {found_file} to {stream_path}")
|
|
||||||
shutil.move(found_file, stream_path)
|
|
||||||
print(f"✅ Successfully moved file to stream folder: {stream_path}")
|
|
||||||
|
|
||||||
# Clean up empty directories left behind
|
|
||||||
self._cleanup_empty_directories(download_path, found_file)
|
|
||||||
|
|
||||||
# Signal that streaming is ready (100% progress)
|
|
||||||
self.streaming_progress.emit(100.0, self.search_result)
|
|
||||||
self.streaming_finished.emit(f"Stream ready: {os.path.basename(found_file)}", self.search_result)
|
|
||||||
self.temp_file_path = stream_path
|
|
||||||
print(f"🎵 Stream file ready for playback: {stream_path}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ Error moving file to stream folder: {e}")
|
|
||||||
self.streaming_failed.emit(f"Failed to prepare stream file: {e}", self.search_result)
|
|
||||||
else:
|
|
||||||
print(f"❌ No file found after polling loop completed")
|
|
||||||
self.streaming_failed.emit("Stream download failed - file not found after completion", self.search_result)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.streaming_failed.emit("Streaming failed to start", self.search_result)
|
self.streaming_failed.emit("Streaming failed to start", self.search_result)
|
||||||
|
|
@ -839,31 +865,42 @@ class StreamingThread(QThread):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error cleaning up streaming event loop: {e}")
|
print(f"Error cleaning up streaming event loop: {e}")
|
||||||
|
|
||||||
async def _check_download_progress(self):
|
def _find_streaming_download_in_transfers(self, transfers_data):
|
||||||
"""Check download progress via slskd API for the current streaming download"""
|
"""Find streaming download in transfer data using same logic as download queue"""
|
||||||
try:
|
try:
|
||||||
# Get all current downloads and find ours by filename match
|
if not transfers_data:
|
||||||
all_downloads = await self.soulseek_client.get_all_downloads()
|
return None
|
||||||
print(f"🔍 Looking for download - Target: {self.search_result.username}:{os.path.basename(self.search_result.filename)}")
|
|
||||||
print(f"🔍 Found {len(all_downloads)} total downloads in API")
|
# Flatten the transfers data structure (same as download queue logic)
|
||||||
|
all_transfers = []
|
||||||
|
for user_data in transfers_data:
|
||||||
|
if 'directories' in user_data:
|
||||||
|
for directory in user_data['directories']:
|
||||||
|
if 'files' in directory:
|
||||||
|
all_transfers.extend(directory['files'])
|
||||||
|
|
||||||
# Look for our specific file by filename and username
|
# Look for our specific file by filename and username
|
||||||
target_filename = os.path.basename(self.search_result.filename)
|
target_filename = os.path.basename(self.search_result.filename)
|
||||||
target_username = self.search_result.username
|
target_username = self.search_result.username
|
||||||
|
|
||||||
for i, download in enumerate(all_downloads):
|
print(f"🔍 Looking for streaming download - Target: {target_username}:{target_filename}")
|
||||||
download_filename = os.path.basename(download.filename)
|
print(f"🔍 Found {len(all_transfers)} total transfers in API")
|
||||||
print(f"📁 Download {i+1}: {download.username}:{download_filename} - State: {download.state} - Progress: {download.progress}%")
|
|
||||||
|
|
||||||
if (download_filename == target_filename and
|
|
||||||
download.username == target_username):
|
|
||||||
print(f"✅ Found matching download: {download.state} - {download.progress}%")
|
|
||||||
return download
|
|
||||||
|
|
||||||
print(f"❌ No matching download found for {target_username}:{target_filename}")
|
for i, transfer in enumerate(all_transfers):
|
||||||
|
transfer_filename = os.path.basename(transfer.get('filename', ''))
|
||||||
|
transfer_username = transfer.get('username', '')
|
||||||
|
|
||||||
|
print(f"📁 Transfer {i+1}: {transfer_username}:{transfer_filename} - State: {transfer.get('state')} - Progress: {transfer.get('percentComplete', 0):.1f}%")
|
||||||
|
|
||||||
|
if (transfer_filename == target_filename and
|
||||||
|
transfer_username == target_username):
|
||||||
|
print(f"✅ Found matching streaming download: {transfer.get('state')} - {transfer.get('percentComplete', 0):.1f}%")
|
||||||
|
return transfer
|
||||||
|
|
||||||
|
print(f"❌ No matching streaming download found for {target_username}:{target_filename}")
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error checking download progress: {e}")
|
print(f"Error finding streaming download in transfers: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _find_downloaded_file(self, download_path):
|
def _find_downloaded_file(self, download_path):
|
||||||
|
|
@ -1070,6 +1107,20 @@ class TrackItem(QFrame):
|
||||||
self.play_btn.setText("⏳")
|
self.play_btn.setText("⏳")
|
||||||
self.play_btn.setEnabled(False)
|
self.play_btn.setEnabled(False)
|
||||||
|
|
||||||
|
def set_queue_state(self):
|
||||||
|
"""Set play button to queue state"""
|
||||||
|
self.play_btn.setText("📋")
|
||||||
|
self.play_btn.setEnabled(False)
|
||||||
|
self.play_btn.setStyleSheet("""
|
||||||
|
QPushButton {
|
||||||
|
background: rgba(255, 165, 0, 0.2);
|
||||||
|
border: 1px solid rgba(255, 165, 0, 0.4);
|
||||||
|
border-radius: 18px;
|
||||||
|
color: rgba(255, 165, 0, 0.8);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
def set_download_queued_state(self):
|
def set_download_queued_state(self):
|
||||||
"""Set download button to queued state (disabled, shows queued)"""
|
"""Set download button to queued state (disabled, shows queued)"""
|
||||||
self.download_btn.setText("⏳")
|
self.download_btn.setText("⏳")
|
||||||
|
|
@ -1927,6 +1978,20 @@ class SearchResultItem(QFrame):
|
||||||
self.play_btn.setText("⌛")
|
self.play_btn.setText("⌛")
|
||||||
self.play_btn.setEnabled(False)
|
self.play_btn.setEnabled(False)
|
||||||
|
|
||||||
|
def set_queue_state(self):
|
||||||
|
"""Set play button to queue state"""
|
||||||
|
self.play_btn.setText("📋")
|
||||||
|
self.play_btn.setEnabled(False)
|
||||||
|
self.play_btn.setStyleSheet("""
|
||||||
|
QPushButton {
|
||||||
|
background: rgba(255, 165, 0, 0.2);
|
||||||
|
border: 1px solid rgba(255, 165, 0, 0.4);
|
||||||
|
border-radius: 18px;
|
||||||
|
color: rgba(255, 165, 0, 0.8);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
def reset_download_state(self):
|
def reset_download_state(self):
|
||||||
"""Reset the download button state"""
|
"""Reset the download button state"""
|
||||||
self.is_downloading = False
|
self.is_downloading = False
|
||||||
|
|
@ -2851,6 +2916,13 @@ class DownloadQueue(QFrame):
|
||||||
self.queue_layout.removeWidget(item)
|
self.queue_layout.removeWidget(item)
|
||||||
item.deleteLater()
|
item.deleteLater()
|
||||||
self.update_queue_count()
|
self.update_queue_count()
|
||||||
|
|
||||||
|
# Notify parent download manager to update tab counts
|
||||||
|
parent_widget = self.parent()
|
||||||
|
while parent_widget and not hasattr(parent_widget, 'update_tab_counts'):
|
||||||
|
parent_widget = parent_widget.parent()
|
||||||
|
if parent_widget and hasattr(parent_widget, 'update_tab_counts'):
|
||||||
|
parent_widget.update_tab_counts()
|
||||||
|
|
||||||
def clear_completed_downloads(self):
|
def clear_completed_downloads(self):
|
||||||
"""Remove all completed and cancelled download items"""
|
"""Remove all completed and cancelled download items"""
|
||||||
|
|
@ -4547,6 +4619,7 @@ class DownloadsPage(QWidget):
|
||||||
streaming_thread.streaming_started.connect(self.on_streaming_started, Qt.ConnectionType.QueuedConnection)
|
streaming_thread.streaming_started.connect(self.on_streaming_started, Qt.ConnectionType.QueuedConnection)
|
||||||
streaming_thread.streaming_finished.connect(self.on_streaming_finished, Qt.ConnectionType.QueuedConnection)
|
streaming_thread.streaming_finished.connect(self.on_streaming_finished, Qt.ConnectionType.QueuedConnection)
|
||||||
streaming_thread.streaming_progress.connect(self.on_streaming_progress, Qt.ConnectionType.QueuedConnection)
|
streaming_thread.streaming_progress.connect(self.on_streaming_progress, Qt.ConnectionType.QueuedConnection)
|
||||||
|
streaming_thread.streaming_queued.connect(self.on_streaming_queued, Qt.ConnectionType.QueuedConnection)
|
||||||
streaming_thread.streaming_failed.connect(self.on_streaming_failed, Qt.ConnectionType.QueuedConnection)
|
streaming_thread.streaming_failed.connect(self.on_streaming_failed, Qt.ConnectionType.QueuedConnection)
|
||||||
streaming_thread.finished.connect(
|
streaming_thread.finished.connect(
|
||||||
functools.partial(self.on_streaming_thread_finished, streaming_thread),
|
functools.partial(self.on_streaming_thread_finished, streaming_thread),
|
||||||
|
|
@ -4676,6 +4749,27 @@ class DownloadsPage(QWidget):
|
||||||
else:
|
else:
|
||||||
print(f"🚫 Ignoring progress for old streaming result: {search_result.filename}")
|
print(f"🚫 Ignoring progress for old streaming result: {search_result.filename}")
|
||||||
|
|
||||||
|
def on_streaming_queued(self, queue_msg, search_result):
|
||||||
|
"""Handle streaming queue state updates"""
|
||||||
|
print(f"Queue status: {queue_msg} for {search_result.filename}")
|
||||||
|
|
||||||
|
# Check if this queue status is for the currently requested track
|
||||||
|
if hasattr(self, 'current_track_result') and self.current_track_result:
|
||||||
|
current_track_id = f"{self.current_track_result.username}:{self.current_track_result.filename}"
|
||||||
|
queued_track_id = f"{search_result.username}:{search_result.filename}"
|
||||||
|
|
||||||
|
if current_track_id == queued_track_id:
|
||||||
|
# Show queue status in button
|
||||||
|
if self.currently_playing_button:
|
||||||
|
try:
|
||||||
|
self.currently_playing_button.set_queue_state()
|
||||||
|
except RuntimeError:
|
||||||
|
# Button was deleted, ignore
|
||||||
|
pass
|
||||||
|
print(f"📋 Showing queue status for current track")
|
||||||
|
else:
|
||||||
|
print(f"🚫 Ignoring queue status for old streaming result: {search_result.filename}")
|
||||||
|
|
||||||
def on_streaming_failed(self, error_msg, search_result):
|
def on_streaming_failed(self, error_msg, search_result):
|
||||||
"""Handle streaming failure"""
|
"""Handle streaming failure"""
|
||||||
print(f"Streaming failed: {error_msg}")
|
print(f"Streaming failed: {error_msg}")
|
||||||
|
|
@ -5203,6 +5297,10 @@ class DownloadsPage(QWidget):
|
||||||
# After processing all download items, check for any that weren't found in the API
|
# After processing all download items, check for any that weren't found in the API
|
||||||
# This handles the case where downloads were removed from slskd externally
|
# This handles the case where downloads were removed from slskd externally
|
||||||
|
|
||||||
|
# Update download counters after processing all transfers
|
||||||
|
self.download_queue.update_tab_counts()
|
||||||
|
print(f"[DEBUG] Updated tab counts - Active: {len(self.download_queue.active_queue.download_items)}, Finished: {len(self.download_queue.finished_queue.download_items)}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ERROR] Error processing transfer status update: {e}")
|
print(f"[ERROR] Error processing transfer status update: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue