This commit is contained in:
Broque Thomas 2025-07-28 15:00:27 -07:00
parent f456f4a4c2
commit 52695fd6a2
7 changed files with 11734 additions and 18 deletions

View file

@ -1 +1 @@
{"access_token": "BQAGFYuFGcSZ2MXk4qaE7u41ZhYZ2_6EBIrkMAQTBHWVapuPZDvR-laSVBFyPp96cY8-eWl2v0mYJDd7A2MCzXb1hZ8XY3973NxpJOLTlI8MtTwl2IbV5ZPOkA21eVeJGdWAlF8mmU0NPqcBVh0KUzVtGGvaYO3foV2bdgd2gsBnUJYrAGQukwoZ_LVLEF-grSAqIyWE4vLGVawUOnZNTlT0JQtxi4f5gTS-GdJtqqHU-1bjqCkcXoer-p-ywrH_", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1753738591, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}
{"access_token": "BQDOhKfFATvb-8-rw278Xzc-T-QgPJ5_7mWFHT4yw83y2c5yvmDDQ8qdkKuiFc-Hfc8V7L6o_8w9d5Vl9TPuek9pxE-PNeNPwxsRn9CVScttd2_XEuxnR-ag53yqrMP4rSaUZnXT5pd1tqizay2aOpmdfV89BTg7-Vj3SARGgofrhBbJqO4hNZY5EqVGpWpDyzJCUeG4W7jvLC62eO8qFVpnbrqNdRKGMeZ6FfCdiVZfjrxlPv9a-LaUYeazk3aR", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1753742887, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}

11658
logs/app.log

File diff suppressed because it is too large Load diff

View file

@ -176,6 +176,11 @@ class MainWindow(QMainWindow):
self.dashboard_page.add_activity_item
)
# Connect download activities to dashboard
self.downloads_page.download_activity.connect(
self.dashboard_page.add_activity_item
)
self.stacked_widget.addWidget(self.dashboard_page)
self.stacked_widget.addWidget(self.sync_page)
self.stacked_widget.addWidget(self.downloads_page)

View file

@ -90,12 +90,12 @@ class DashboardDataProvider(QObject):
def set_app_start_time(self, start_time):
self.app_start_time = start_time
def increment_completed_downloads(self):
def increment_completed_downloads(self, title="Unknown Track", artist="Unknown Artist"):
"""Increment the session completed downloads counter"""
self.session_completed_downloads += 1
# Emit signal for activity feed
self.activity_item_added.emit("📥", "Download Complete", "File downloaded successfully", "Now")
# Emit signal for activity feed with specific track info
self.activity_item_added.emit("📥", "Download Complete", f"'{title}' by {artist}", "Now")
def update_service_status(self, service: str, connected: bool, response_time: float = 0.0, error: str = ""):
if service in self.service_status:

View file

@ -4687,7 +4687,7 @@ class TabbedDownloadManager(QTabWidget):
while parent_page and not hasattr(parent_page, 'download_session_completed'):
parent_page = parent_page.parent()
if parent_page and hasattr(parent_page, 'download_session_completed'):
parent_page.download_session_completed.emit()
parent_page.download_session_completed.emit(download_item.title, download_item.artist)
# Performance monitoring
end_time = time.time()
@ -4802,8 +4802,11 @@ class DownloadsPage(QWidget):
track_loading_finished = pyqtSignal(object) # Track result object when streaming completes
track_loading_progress = pyqtSignal(float, object) # Progress percentage (0-100), track result object
# Signal for dashboard stats tracking
download_session_completed = pyqtSignal() # Emitted when a download completes (for session tracking)
# Signal for dashboard stats tracking
download_session_completed = pyqtSignal(str, str) # Emitted when a download completes (title, artist)
# Signals for dashboard activity tracking
download_activity = pyqtSignal(str, str, str, str) # icon, title, subtitle, time
# Signal for clear completed downloads completion (thread-safe communication)
clear_completed_finished = pyqtSignal(bool, object) # backend_success, ui_callback
@ -6321,6 +6324,9 @@ class DownloadsPage(QWidget):
self.search_btn.setEnabled(False)
self.update_search_status(f"Searching for '{query}'... Results will appear as they are found", "#1db954")
# Emit activity signal for search start
self.download_activity.emit("🔍", "Search Started", f"Searching for '{query}'", "Now")
# Show loading animations
self.start_search_animations()
@ -6566,6 +6572,10 @@ class DownloadsPage(QWidget):
# Show filter controls when we have results
self.filter_container.setVisible(True)
# Emit activity signal for search completion
search_query = self.search_input.text().strip()
self.download_activity.emit("", "Search Complete", f"Found {total_results} results for '{search_query}'", "Now")
# Update status based on whether there are more results to load
if self.displayed_results < total_results:
remaining = total_results - self.displayed_results
@ -6712,18 +6722,32 @@ class DownloadsPage(QWidget):
if '.' in name_without_ext:
name_without_ext = '.'.join(name_without_ext.split('.')[:-1])
# Remove track number prefix
# Remove track number prefix - handle multiple formats
import re
track_number_match = re.match(r'^(\d+)\.\s*(.+)', name_without_ext)
if track_number_match:
name_without_track_num = track_number_match.group(2)
else:
name_without_track_num = name_without_ext
name_without_track_num = name_without_ext
# Try different track number patterns
track_patterns = [
r'^(\d+)\.\s*(.+)', # "06. Artist - Track"
r'^(\d+)\s*-\s*(.+)', # "06 - Artist - Track"
r'^(\d+)\s+(.+)' # "06 Artist - Track"
]
for pattern in track_patterns:
match = re.match(pattern, name_without_ext)
if match:
name_without_track_num = match.group(2)
break
# Extract artist (first part before " - ")
parts = name_without_track_num.split(' - ')
if len(parts) >= 2:
# First part is artist, second part is track title
artist = parts[0].strip()
# Verify this doesn't look like a track number
if re.match(r'^\d+$', artist.strip()):
# If first part is just a number, use username as fallback
artist = search_result.username
else:
artist = search_result.username
@ -6773,6 +6797,9 @@ class DownloadsPage(QWidget):
print(f"[DEBUG] Created download item with album context: album='{album_name}', track_number={track_number}")
# Emit activity signal for download start
self.download_activity.emit("📥", "Download Started", f"'{title}' by {artist}", "Now")
# Create and start download thread
download_thread = DownloadThread(self.soulseek_client, search_result, download_item)
download_thread.download_completed.connect(self.on_download_completed, Qt.ConnectionType.QueuedConnection)
@ -6974,15 +7001,28 @@ class DownloadsPage(QWidget):
name_without_ext = '.'.join(name_without_ext.split('.')[:-1])
import re
track_number_match = re.match(r'^(\d+)\.\s*(.+)', name_without_ext)
if track_number_match:
name_without_track_num = track_number_match.group(2)
else:
name_without_track_num = name_without_ext
name_without_track_num = name_without_ext
# Try different track number patterns
track_patterns = [
r'^(\d+)\.\s*(.+)', # "06. Artist - Track"
r'^(\d+)\s*-\s*(.+)', # "06 - Artist - Track"
r'^(\d+)\s+(.+)' # "06 Artist - Track"
]
for pattern in track_patterns:
match = re.match(pattern, name_without_ext)
if match:
name_without_track_num = match.group(2)
break
parts = name_without_track_num.split(' - ')
if len(parts) >= 2:
original_artist = parts[0].strip()
# Verify this doesn't look like a track number
if re.match(r'^\d+$', original_artist.strip()):
# If first part is just a number, use username as fallback
original_artist = search_result.username
else:
original_artist = search_result.username
@ -7031,6 +7071,9 @@ class DownloadsPage(QWidget):
download_item.matched_artist = artist
print(f"✅ Matched artist '{artist.name}' assigned to download item '{download_item.title}'")
# Emit activity signal for download start (with matched artist)
self.download_activity.emit("📥", "Download Started", f"'{title}' by {artist.name if artist else original_artist}", "Now")
# Start the download thread
download_thread = DownloadThread(self.soulseek_client, search_result, download_item)
download_thread.download_completed.connect(self.on_download_completed, Qt.ConnectionType.QueuedConnection)
@ -8967,6 +9010,10 @@ class DownloadsPage(QWidget):
# Update download item status to failed
download_item.status = "failed"
download_item.progress = 0
# Emit activity signal for download failure
self.download_activity.emit("", "Download Failed", f"'{download_item.title}' - {error_msg}", "Now")
# Error logged to console for debugging
def on_download_progress(self, message, download_item):
@ -9355,6 +9402,12 @@ class DownloadsPage(QWidget):
# Move to finished queue
self.download_queue.move_to_finished(download_item)
# Emit specific activity signal for failures
if new_status == 'failed':
self.download_activity.emit("", "Download Failed", f"'{download_item.title}' by {download_item.artist}", "Now")
elif new_status == 'cancelled':
self.download_activity.emit("⏹️", "Download Cancelled", f"'{download_item.title}' by {download_item.artist}", "Now")
# Cleanup API if needed
if new_status in ['cancelled', 'failed'] and hasattr(download_item, 'download_id'):
self._schedule_api_cleanup_v2(download_item)